mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-13 13:25:16 +00:00
Avoid bogus assumptions about block and item NBT on tiles
This commit is contained in:
parent
4f2f9b4352
commit
012b668537
@ -31,6 +31,7 @@ use pocketmine\data\SavedDataLoadingException;
|
|||||||
use pocketmine\nbt\tag\CompoundTag;
|
use pocketmine\nbt\tag\CompoundTag;
|
||||||
use pocketmine\nbt\tag\IntTag;
|
use pocketmine\nbt\tag\IntTag;
|
||||||
use pocketmine\nbt\tag\ShortTag;
|
use pocketmine\nbt\tag\ShortTag;
|
||||||
|
use pocketmine\network\mcpe\convert\RuntimeBlockMapping;
|
||||||
use pocketmine\world\format\io\GlobalBlockStateHandlers;
|
use pocketmine\world\format\io\GlobalBlockStateHandlers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,7 +89,7 @@ class FlowerPot extends Spawnable{
|
|||||||
|
|
||||||
protected function addAdditionalSpawnData(CompoundTag $nbt) : void{
|
protected function addAdditionalSpawnData(CompoundTag $nbt) : void{
|
||||||
if($this->plant !== null){
|
if($this->plant !== null){
|
||||||
$nbt->setTag(self::TAG_PLANT_BLOCK, GlobalBlockStateHandlers::getSerializer()->serialize($this->plant->getStateId())->toNbt());
|
$nbt->setTag(self::TAG_PLANT_BLOCK, RuntimeBlockMapping::getInstance()->toStateData($this->plant->getStateId())->toNbt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ use pocketmine\item\Item;
|
|||||||
use pocketmine\item\VanillaItems;
|
use pocketmine\item\VanillaItems;
|
||||||
use pocketmine\math\Vector3;
|
use pocketmine\math\Vector3;
|
||||||
use pocketmine\nbt\tag\CompoundTag;
|
use pocketmine\nbt\tag\CompoundTag;
|
||||||
|
use pocketmine\network\mcpe\convert\ItemTranslator;
|
||||||
use pocketmine\world\World;
|
use pocketmine\world\World;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,7 +100,7 @@ class ItemFrame extends Spawnable{
|
|||||||
$nbt->setFloat(self::TAG_ITEM_DROP_CHANCE, $this->itemDropChance);
|
$nbt->setFloat(self::TAG_ITEM_DROP_CHANCE, $this->itemDropChance);
|
||||||
$nbt->setByte(self::TAG_ITEM_ROTATION, $this->itemRotation);
|
$nbt->setByte(self::TAG_ITEM_ROTATION, $this->itemRotation);
|
||||||
if(!$this->item->isNull()){
|
if(!$this->item->isNull()){
|
||||||
$nbt->setTag(self::TAG_ITEM, $this->item->nbtSerialize());
|
$nbt->setTag(self::TAG_ITEM, ItemTranslator::getInstance()->toNetworkNbt($this->item));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block\tile;
|
|||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\item\Record;
|
use pocketmine\item\Record;
|
||||||
use pocketmine\nbt\tag\CompoundTag;
|
use pocketmine\nbt\tag\CompoundTag;
|
||||||
|
use pocketmine\network\mcpe\convert\ItemTranslator;
|
||||||
|
|
||||||
class Jukebox extends Spawnable{
|
class Jukebox extends Spawnable{
|
||||||
private const TAG_RECORD = "RecordItem"; //Item CompoundTag
|
private const TAG_RECORD = "RecordItem"; //Item CompoundTag
|
||||||
@ -58,7 +59,7 @@ class Jukebox extends Spawnable{
|
|||||||
protected function addAdditionalSpawnData(CompoundTag $nbt) : void{
|
protected function addAdditionalSpawnData(CompoundTag $nbt) : void{
|
||||||
//this is needed for the note particles to show on the client side
|
//this is needed for the note particles to show on the client side
|
||||||
if($this->record !== null){
|
if($this->record !== null){
|
||||||
$nbt->setTag(self::TAG_RECORD, $this->record->nbtSerialize());
|
$nbt->setTag(self::TAG_RECORD, ItemTranslator::getInstance()->toNetworkNbt($this->record));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ namespace pocketmine\block\tile;
|
|||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\item\WritableBookBase;
|
use pocketmine\item\WritableBookBase;
|
||||||
use pocketmine\nbt\tag\CompoundTag;
|
use pocketmine\nbt\tag\CompoundTag;
|
||||||
|
use pocketmine\network\mcpe\convert\ItemTranslator;
|
||||||
use function count;
|
use function count;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -80,7 +81,7 @@ class Lectern extends Spawnable{
|
|||||||
$nbt->setByte(self::TAG_HAS_BOOK, $this->book !== null ? 1 : 0);
|
$nbt->setByte(self::TAG_HAS_BOOK, $this->book !== null ? 1 : 0);
|
||||||
$nbt->setInt(self::TAG_PAGE, $this->viewedPage);
|
$nbt->setInt(self::TAG_PAGE, $this->viewedPage);
|
||||||
if($this->book !== null){
|
if($this->book !== null){
|
||||||
$nbt->setTag(self::TAG_BOOK, $this->book->nbtSerialize());
|
$nbt->setTag(self::TAG_BOOK, ItemTranslator::getInstance()->toNetworkNbt($this->book));
|
||||||
$nbt->setInt(self::TAG_TOTAL_PAGES, count($this->book->getPages()));
|
$nbt->setInt(self::TAG_TOTAL_PAGES, count($this->book->getPages()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ use pocketmine\data\bedrock\item\ItemSerializer;
|
|||||||
use pocketmine\data\bedrock\item\ItemTypeDeserializeException;
|
use pocketmine\data\bedrock\item\ItemTypeDeserializeException;
|
||||||
use pocketmine\data\bedrock\item\ItemTypeSerializeException;
|
use pocketmine\data\bedrock\item\ItemTypeSerializeException;
|
||||||
use pocketmine\data\bedrock\item\SavedItemData;
|
use pocketmine\data\bedrock\item\SavedItemData;
|
||||||
|
use pocketmine\data\bedrock\item\SavedItemStackData;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary;
|
use pocketmine\network\mcpe\protocol\serializer\ItemTypeDictionary;
|
||||||
use pocketmine\utils\AssumptionFailedError;
|
use pocketmine\utils\AssumptionFailedError;
|
||||||
@ -96,6 +97,16 @@ final class ItemTranslator{
|
|||||||
return [$numericId, $itemData->getMeta(), $blockRuntimeId];
|
return [$numericId, $itemData->getMeta(), $blockRuntimeId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws ItemTypeSerializeException
|
||||||
|
*/
|
||||||
|
public function toNetworkNbt(Item $item) : SavedItemStackData{
|
||||||
|
//TODO: this relies on the assumption that network item NBT is the same as disk item NBT, which may not always
|
||||||
|
//be true - if we stick on an older world version while updating network version, this could be a problem (and
|
||||||
|
//may be a problem for multi version implementations)
|
||||||
|
return $this->itemSerializer->serializeStack($item);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws TypeConversionException
|
* @throws TypeConversionException
|
||||||
*/
|
*/
|
||||||
|
@ -94,6 +94,18 @@ final class RuntimeBlockMapping{
|
|||||||
return $this->networkIdCache[$internalStateId] = $networkId;
|
return $this->networkIdCache[$internalStateId] = $networkId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up the network state data associated with the given internal state ID.
|
||||||
|
*/
|
||||||
|
public function toStateData(int $internalStateId) : BlockStateData{
|
||||||
|
//we don't directly use the blockstate serializer here - we can't assume that the network blockstate NBT is the
|
||||||
|
//same as the disk blockstate NBT, in case we decide to have different world version than network version (or in
|
||||||
|
//case someone wants to implement multi version).
|
||||||
|
$networkRuntimeId = $this->toRuntimeId($internalStateId);
|
||||||
|
|
||||||
|
return $this->blockStateDictionary->getDataFromStateId($networkRuntimeId) ?? throw new AssumptionFailedError("We just looked up this state ID, so it must exist");
|
||||||
|
}
|
||||||
|
|
||||||
public function getBlockStateDictionary() : BlockStateDictionary{ return $this->blockStateDictionary; }
|
public function getBlockStateDictionary() : BlockStateDictionary{ return $this->blockStateDictionary; }
|
||||||
|
|
||||||
public function getFallbackStateData() : BlockStateData{ return $this->fallbackStateData; }
|
public function getFallbackStateData() : BlockStateData{ return $this->fallbackStateData; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user