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{