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
case PlayerActionPacket::ACTION_CONTINUE_BREAK:
$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;
default:
$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\level\Position;
use pocketmine\utils\MainLogger;
/**
* Manages block registration and instance creation
@ -50,6 +51,14 @@ class BlockFactory{
/** @var \SplFixedArray<float> */
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
* 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];
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->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{

View File

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

View File

@ -24,6 +24,7 @@ declare(strict_types=1);
namespace pocketmine\level\particle;
use pocketmine\block\Block;
use pocketmine\block\BlockFactory;
use pocketmine\math\Vector3;
use pocketmine\network\mcpe\protocol\LevelEventPacket;
@ -33,7 +34,7 @@ class DestroyBlockParticle extends Particle{
public function __construct(Vector3 $pos, Block $b){
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(){

View File

@ -24,10 +24,11 @@ declare(strict_types=1);
namespace pocketmine\level\particle;
use pocketmine\block\Block;
use pocketmine\block\BlockFactory;
use pocketmine\math\Vector3;
class TerrainParticle extends GenericParticle{
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 */
public $y;
/** @var int */
public $blockId;
/** @var int */
public $blockData;
public $blockRuntimeId;
/** @var int */
public $flags;
protected function decodePayload(){
$this->getBlockPosition($this->x, $this->y, $this->z);
$this->blockId = $this->getUnsignedVarInt();
$aux = $this->getUnsignedVarInt();
$this->blockData = $aux & 0x0f;
$this->flags = $aux >> 4;
$this->blockRuntimeId = $this->getUnsignedVarInt();
$this->flags = $this->getUnsignedVarInt();
}
protected function encodePayload(){
$this->putBlockPosition($this->x, $this->y, $this->z);
$this->putUnsignedVarInt($this->blockId);
$this->putUnsignedVarInt(($this->flags << 4) | $this->blockData);
$this->putUnsignedVarInt($this->blockRuntimeId);
$this->putUnsignedVarInt($this->flags);
}
public function handle(NetworkSession $session) : bool{

File diff suppressed because one or more lines are too long