duct tape for block ID remapping

This commit is contained in:
Dylan K. Taylor 2018-03-03 18:52:41 +00:00
parent c81f178cdb
commit 5ce55bd3b0
8 changed files with 72 additions and 22 deletions

View File

@ -2715,7 +2715,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
break; //TODO break; //TODO
case PlayerActionPacket::ACTION_CONTINUE_BREAK: case PlayerActionPacket::ACTION_CONTINUE_BREAK:
$block = $this->level->getBlock($pos); $block = $this->level->getBlock($pos);
$this->level->broadcastLevelEvent($pos, LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, $block->getId() | ($block->getDamage() << 8) | ($packet->face << 16)); $this->level->broadcastLevelEvent($pos, LevelEventPacket::EVENT_PARTICLE_PUNCH_BLOCK, BlockFactory::toStaticRuntimeId($block->getId(), $block->getDamage()) | ($packet->face << 24));
//TODO: destroy-progress level event
break; break;
default: default:
$this->server->getLogger()->debug("Unhandled/unknown player action type " . $packet->action . " from " . $this->getName()); $this->server->getLogger()->debug("Unhandled/unknown player action type " . $packet->action . " from " . $this->getName());

View File

@ -25,6 +25,7 @@ namespace pocketmine\block;
use pocketmine\item\Item; use pocketmine\item\Item;
use pocketmine\level\Position; use pocketmine\level\Position;
use pocketmine\utils\MainLogger;
/** /**
* Manages block registration and instance creation * Manages block registration and instance creation
@ -50,6 +51,14 @@ class BlockFactory{
/** @var \SplFixedArray<float> */ /** @var \SplFixedArray<float> */
public static $blastResistance = null; public static $blastResistance = null;
/**
* @var int[]
*/
public static $staticRuntimeIdMap = [];
/** @var int[] */
public static $legacyIdMap = [];
/** /**
* Initializes the block factory. By default this is called only once on server start, however you may wish to use * 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. * this if you need to reset the block factory back to its original defaults for whatever reason.
@ -326,6 +335,13 @@ class BlockFactory{
} }
} }
} }
$runtimeIdMap = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "runtimeid_table.json"), true);
foreach($runtimeIdMap as $obj){
self::$staticRuntimeIdMap[$obj["id"] << 4 | $obj["data"]] = $obj["runtimeID"];
}
self::$legacyIdMap = array_flip(self::$staticRuntimeIdMap);
} }
/** /**
@ -417,4 +433,34 @@ class BlockFactory{
$b = self::$list[$id]; $b = self::$list[$id];
return $b !== null and !($b instanceof UnknownBlock); return $b !== null and !($b instanceof UnknownBlock);
} }
/**
* @internal
*
* @param int $id
* @param int $meta
*
* @return int
*/
public static function toStaticRuntimeId(int $id, int $meta = 0) : int{
$index = ($id << 4) | $meta;
if(!isset(self::$staticRuntimeIdMap[$index])){
MainLogger::getLogger()->error("ID $id meta $meta does not have a corresponding block runtime ID, returning AIR (0)");
return 0;
}
return self::$staticRuntimeIdMap[$index];
}
/**
* @internal
*
* @param int $runtimeId
*
* @return int[] [id, meta]
*/
public static function fromStaticRuntimeId(int $runtimeId) : array{
$v = self::$legacyIdMap[$runtimeId];
return [$v >> 4, $v & 0xf];
}
} }

View File

@ -71,7 +71,7 @@ class FallingSand extends Entity{
$this->block = BlockFactory::get($blockId, $damage); $this->block = BlockFactory::get($blockId, $damage);
$this->propertyManager->setInt(self::DATA_VARIANT, $this->block->getId() | ($this->block->getDamage() << 8)); $this->propertyManager->setInt(self::DATA_VARIANT, BlockFactory::toStaticRuntimeId($this->block->getId(), $this->block->getDamage()));
} }
public function canCollideWith(Entity $entity) : bool{ public function canCollideWith(Entity $entity) : bool{

View File

@ -907,14 +907,16 @@ class Level implements ChunkManager, Metadatable{
$pk->z = $b->z; $pk->z = $b->z;
if($b instanceof Block){ if($b instanceof Block){
$pk->blockId = $b->getId(); $blockId = $b->getId();
$pk->blockData = $b->getDamage(); $blockData = $b->getDamage();
}else{ }else{
$fullBlock = $this->getFullBlock($b->x, $b->y, $b->z); $fullBlock = $this->getFullBlock($b->x, $b->y, $b->z);
$pk->blockId = $fullBlock >> 4; $blockId = $fullBlock >> 4;
$pk->blockData = $fullBlock & 0xf; $blockData = $fullBlock & 0xf;
} }
$pk->blockRuntimeId = BlockFactory::toStaticRuntimeId($blockId, $blockData);
$pk->flags = $first ? $flags : UpdateBlockPacket::FLAG_NONE; $pk->flags = $first ? $flags : UpdateBlockPacket::FLAG_NONE;
$packets[] = $pk; $packets[] = $pk;
@ -931,14 +933,16 @@ class Level implements ChunkManager, Metadatable{
$pk->z = $b->z; $pk->z = $b->z;
if($b instanceof Block){ if($b instanceof Block){
$pk->blockId = $b->getId(); $blockId = $b->getId();
$pk->blockData = $b->getDamage(); $blockData = $b->getDamage();
}else{ }else{
$fullBlock = $this->getFullBlock($b->x, $b->y, $b->z); $fullBlock = $this->getFullBlock($b->x, $b->y, $b->z);
$pk->blockId = $fullBlock >> 4; $blockId = $fullBlock >> 4;
$pk->blockData = $fullBlock & 0xf; $blockData = $fullBlock & 0xf;
} }
$pk->blockRuntimeId = BlockFactory::toStaticRuntimeId($blockId, $blockData);
$pk->flags = $flags; $pk->flags = $flags;
$packets[] = $pk; $packets[] = $pk;
@ -1938,7 +1942,7 @@ class Level implements ChunkManager, Metadatable{
} }
if($playSound){ if($playSound){
$this->broadcastLevelSoundEvent($hand, LevelSoundEventPacket::SOUND_PLACE, 1, $hand->getId()); $this->broadcastLevelSoundEvent($hand, LevelSoundEventPacket::SOUND_PLACE, 1, BlockFactory::toStaticRuntimeId($hand->getId(), $hand->getDamage()));
} }
$item->pop(); $item->pop();

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\level\particle; namespace pocketmine\level\particle;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\block\BlockFactory;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
use pocketmine\network\mcpe\protocol\LevelEventPacket; use pocketmine\network\mcpe\protocol\LevelEventPacket;
@ -33,7 +34,7 @@ class DestroyBlockParticle extends Particle{
public function __construct(Vector3 $pos, Block $b){ public function __construct(Vector3 $pos, Block $b){
parent::__construct($pos->x, $pos->y, $pos->z); parent::__construct($pos->x, $pos->y, $pos->z);
$this->data = $b->getId() | ($b->getDamage() << 8); $this->data = BlockFactory::toStaticRuntimeId($b->getId(), $b->getDamage());
} }
public function encode(){ public function encode(){

View File

@ -24,10 +24,11 @@ declare(strict_types=1);
namespace pocketmine\level\particle; namespace pocketmine\level\particle;
use pocketmine\block\Block; use pocketmine\block\Block;
use pocketmine\block\BlockFactory;
use pocketmine\math\Vector3; use pocketmine\math\Vector3;
class TerrainParticle extends GenericParticle{ class TerrainParticle extends GenericParticle{
public function __construct(Vector3 $pos, Block $b){ public function __construct(Vector3 $pos, Block $b){
parent::__construct($pos, Particle::TYPE_TERRAIN, ($b->getDamage() << 8) | $b->getId()); parent::__construct($pos, Particle::TYPE_TERRAIN, BlockFactory::toStaticRuntimeId($b->getId(), $b->getDamage()));
} }
} }

View File

@ -47,24 +47,20 @@ class UpdateBlockPacket extends DataPacket{
/** @var int */ /** @var int */
public $y; public $y;
/** @var int */ /** @var int */
public $blockId; public $blockRuntimeId;
/** @var int */
public $blockData;
/** @var int */ /** @var int */
public $flags; public $flags;
protected function decodePayload(){ protected function decodePayload(){
$this->getBlockPosition($this->x, $this->y, $this->z); $this->getBlockPosition($this->x, $this->y, $this->z);
$this->blockId = $this->getUnsignedVarInt(); $this->blockRuntimeId = $this->getUnsignedVarInt();
$aux = $this->getUnsignedVarInt(); $this->flags = $this->getUnsignedVarInt();
$this->blockData = $aux & 0x0f;
$this->flags = $aux >> 4;
} }
protected function encodePayload(){ protected function encodePayload(){
$this->putBlockPosition($this->x, $this->y, $this->z); $this->putBlockPosition($this->x, $this->y, $this->z);
$this->putUnsignedVarInt($this->blockId); $this->putUnsignedVarInt($this->blockRuntimeId);
$this->putUnsignedVarInt(($this->flags << 4) | $this->blockData); $this->putUnsignedVarInt($this->flags);
} }
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{

File diff suppressed because one or more lines are too long