fixed explicit-mixed errors exposed by upgrading pocketmine/nbt

This commit is contained in:
Dylan K. Taylor 2020-08-28 15:47:41 +01:00
parent b47d6bbc22
commit 09eb904f6b
3 changed files with 18 additions and 11 deletions

View File

@ -45,6 +45,7 @@ use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\FloatTag; use pocketmine\nbt\tag\FloatTag;
use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\ShortTag;
use pocketmine\network\mcpe\protocol\ActorEventPacket; use pocketmine\network\mcpe\protocol\ActorEventPacket;
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket; use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\MobEffectPacket;
@ -97,17 +98,15 @@ abstract class Living extends Entity implements Damageable{
//TODO: load/save armor inventory contents //TODO: load/save armor inventory contents
$this->armorInventory->setEventProcessor(new ArmorInventoryEventProcessor($this)); $this->armorInventory->setEventProcessor(new ArmorInventoryEventProcessor($this));
$health = $this->getMaxHealth();
if($this->namedtag->hasTag("HealF", FloatTag::class)){ if($this->namedtag->hasTag("HealF", FloatTag::class)){
$health = $this->namedtag->getFloat("HealF"); $health = $this->namedtag->getFloat("HealF");
$this->namedtag->removeTag("HealF"); $this->namedtag->removeTag("HealF");
}elseif($this->namedtag->hasTag("Health")){ }elseif($this->namedtag->hasTag("Health", ShortTag::class)){
$healthTag = $this->namedtag->getTag("Health"); //Older versions of PocketMine-MP incorrectly saved this as a short instead of a float
$health = (float) $healthTag->getValue(); //Older versions of PocketMine-MP incorrectly saved this as a short instead of a float $health = $this->namedtag->getShort("Health");
if(!($healthTag instanceof FloatTag)){
$this->namedtag->removeTag("Health"); $this->namedtag->removeTag("Health");
} }else{
$health = $this->namedtag->getFloat("Health");
} }
$this->setHealth($health); $this->setHealth($health);

View File

@ -42,6 +42,7 @@ use pocketmine\nbt\tag\NamedTag;
use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\ShortTag;
use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\StringTag;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\utils\AssumptionFailedError;
use pocketmine\utils\Binary; use pocketmine\utils\Binary;
use function array_map; use function array_map;
use function base64_decode; use function base64_decode;
@ -475,7 +476,12 @@ class Item implements ItemIds, \JsonSerializable{
public function getLore() : array{ public function getLore() : array{
$display = $this->getNamedTagEntry(self::TAG_DISPLAY); $display = $this->getNamedTagEntry(self::TAG_DISPLAY);
if($display instanceof CompoundTag and ($lore = $display->getListTag(self::TAG_DISPLAY_LORE)) !== null){ if($display instanceof CompoundTag and ($lore = $display->getListTag(self::TAG_DISPLAY_LORE)) !== null){
return $lore->getAllValues(); return array_map(function(NamedTag $line) : string{
if(!($line instanceof StringTag)){
throw new AssumptionFailedError("Nobody bothered to handle this error case and we can't fix it until PM4, oops ... #blameshoghi");
}
return $line->getValue();
}, $lore->getValue());
} }
return []; return [];

View File

@ -30,6 +30,7 @@ use pocketmine\block\BlockFactory;
use pocketmine\entity\Entity; use pocketmine\entity\Entity;
use pocketmine\level\Level; use pocketmine\level\Level;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntTag;
use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\StringTag;
use pocketmine\Player; use pocketmine\Player;
use pocketmine\tile\Spawnable; use pocketmine\tile\Spawnable;
@ -691,13 +692,14 @@ class Chunk{
$level->timings->syncChunkLoadEntitiesTimer->startTiming(); $level->timings->syncChunkLoadEntitiesTimer->startTiming();
foreach($this->NBTentities as $nbt){ foreach($this->NBTentities as $nbt){
if(!$nbt->hasTag("id")){ //allow mixed types (because of leveldb) $idTag = $nbt->getTag("id");
if(!($idTag instanceof IntTag) && !($idTag instanceof StringTag)){ //allow mixed types (because of leveldb)
$changed = true; $changed = true;
continue; continue;
} }
try{ try{
$entity = Entity::createEntity($nbt->getTag("id")->getValue(), $level, $nbt); $entity = Entity::createEntity($idTag->getValue(), $level, $nbt);
if(!($entity instanceof Entity)){ if(!($entity instanceof Entity)){
$changed = true; $changed = true;
continue; continue;