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.
This commit is contained in:
Dylan K. Taylor 2018-12-28 14:33:09 +00:00
parent 333773bf14
commit 78a80a6958
43 changed files with 222 additions and 59 deletions

View File

@ -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{

View File

@ -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.

View File

@ -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;
}

View File

@ -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
}

View File

@ -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;
try{
$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);
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)){

View File

@ -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;
}

View File

@ -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{

View File

@ -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{

View File

@ -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{

View File

@ -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{

View File

@ -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{

View File

@ -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{

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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{

View File

@ -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{

View File

@ -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;
}

View File

@ -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{

View File

@ -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{

View File

@ -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{

View File

@ -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{

View File

@ -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{

View File

@ -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;

View File

@ -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;
}

View File

@ -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{

View File

@ -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{

View File

@ -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{

View File

@ -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;
}
}

View File

@ -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{

View File

@ -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{

View File

@ -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{

View File

@ -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{

View File

@ -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;
}

View File

@ -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{

View File

@ -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{

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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{

View File

@ -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{

View File

@ -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{

View File

@ -0,0 +1,85 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block\utils;
use pocketmine\math\Bearing;
use pocketmine\math\Facing;
final class BlockDataValidator{
private function __construct(){
}
/**
* @param int $facing
*
* @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);
}
return $facing;
}
/**
* @param int $facing
*
* @return int
* @throws InvalidBlockStateException
*/
public static function readHorizontalFacing(int $facing) : int{
$facing = self::readFacing($facing);
if(Facing::axis($facing) === Facing::AXIS_Y){
throw new InvalidBlockStateException("Invalid Y-axis facing $facing");
}
return $facing;
}
/**
* @param int $facing
*
* @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");
}
return self::readHorizontalFacing($facing);
}
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");
}
return $v;
}
}

View File

@ -0,0 +1,28 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\block\utils;
class InvalidBlockStateException extends \UnexpectedValueException{
}

View File

@ -62,10 +62,13 @@ trait PillarRotationTrait{
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?
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{