Further cleanup on NBT dynamic field access

not sure how I missed so many of these... there are probably lots more besides :(
This commit is contained in:
Dylan K. Taylor 2017-11-17 11:19:36 +00:00
parent 48a7627b96
commit 665130561e
3 changed files with 32 additions and 32 deletions

View File

@ -73,8 +73,11 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
protected $baseOffset = 1.62;
public function __construct(Level $level, CompoundTag $nbt){
if($this->skin === null and (!isset($nbt->Skin) or !isset($nbt->Skin->Data) or !Player::isValidSkin($nbt->Skin->Data->getValue()))){
throw new \InvalidStateException((new \ReflectionClass($this))->getShortName() . " must have a valid skin set");
if($this->skin === null){
$skinTag = $nbt->getCompoundTag("Skin");
if($skinTag === null or !self::isValidSkin($skinTag->getString("Data", "", true))){
throw new \InvalidStateException((new \ReflectionClass($this))->getShortName() . " must have a valid skin set");
}
}
parent::__construct($level, $nbt);

View File

@ -30,6 +30,7 @@ use pocketmine\block\BlockFactory;
use pocketmine\entity\Entity;
use pocketmine\level\Level;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\Player;
use pocketmine\tile\Spawnable;
use pocketmine\tile\Tile;
@ -729,7 +730,7 @@ class Chunk{
$level->timings->syncChunkLoadEntitiesTimer->startTiming();
foreach($this->NBTentities as $nbt){
if($nbt instanceof CompoundTag){
if(!isset($nbt->id)){
if(!$nbt->hasTag("id")){ //allow mixed types (because of leveldb)
$changed = true;
continue;
}
@ -740,7 +741,7 @@ class Chunk{
}
try{
$entity = Entity::createEntity($nbt["id"], $level, $nbt);
$entity = Entity::createEntity($nbt->getTag("id")->getValue(), $level, $nbt);
if(!($entity instanceof Entity)){
$changed = true;
continue;
@ -757,17 +758,17 @@ class Chunk{
$level->timings->syncChunkLoadTileEntitiesTimer->startTiming();
foreach($this->NBTtiles as $nbt){
if($nbt instanceof CompoundTag){
if(!isset($nbt->id)){
if(!$nbt->hasTag(Tile::TAG_ID, StringTag::class)){
$changed = true;
continue;
}
if(($nbt["x"] >> 4) !== $this->x or ($nbt["z"] >> 4) !== $this->z){
if(($nbt->getInt(Tile::TAG_X) >> 4) !== $this->x or ($nbt->getInt(Tile::TAG_Z) >> 4) !== $this->z){
$changed = true;
continue; //Fixes tiles allocated in wrong chunks.
}
if(Tile::createTile($nbt["id"], $level, $nbt) === null){
if(Tile::createTile($nbt->getString(Tile::TAG_ID), $level, $nbt) === null){
$changed = true;
continue;
}

View File

@ -121,19 +121,17 @@ class McRegion extends BaseLevelProvider{
try{
$nbt->readCompressed($data);
$chunk = $nbt->getData();
$chunk = $nbt->getData()->getCompoundTag("Level");
if(!isset($chunk->Level) or !($chunk->Level instanceof CompoundTag)){
throw new ChunkException("Invalid NBT format");
if($chunk === null){
throw new ChunkException("Invalid NBT format, 'Level' key not found");
}
$chunk = $chunk->Level;
$subChunks = [];
$fullIds = isset($chunk->Blocks) ? $chunk->Blocks->getValue() : str_repeat("\x00", 32768);
$fullData = isset($chunk->Data) ? $chunk->Data->getValue() : str_repeat("\x00", 16384);
$fullSkyLight = isset($chunk->SkyLight) ? $chunk->SkyLight->getValue() : str_repeat("\xff", 16384);
$fullBlockLight = isset($chunk->BlockLight) ? $chunk->BlockLight->getValue() : str_repeat("\x00", 16384);
$fullIds = $chunk->hasTag("Blocks", ByteArrayTag::class) ? $chunk->getByteArray("Blocks") : str_repeat("\x00", 32768);
$fullData = $chunk->hasTag("Data", ByteArrayTag::class) ? $chunk->getByteArray("Data") : str_repeat("\x00", 16384);
$fullSkyLight = $chunk->hasTag("SkyLight", ByteArrayTag::class) ? $chunk->getByteArray("SkyLight") : str_repeat("\xff", 16384);
$fullBlockLight = $chunk->hasTag("BlockLight", ByteArrayTag::class) ? $chunk->getByteArray("BlockLight") : str_repeat("\x00", 16384);
for($y = 0; $y < 8; ++$y){
$offset = ($y << 4);
@ -163,34 +161,32 @@ class McRegion extends BaseLevelProvider{
$subChunks[$y] = new SubChunk($ids, $data, $skyLight, $blockLight);
}
if(isset($chunk->BiomeColors)){
$biomeIds = ChunkUtils::convertBiomeColors($chunk->BiomeColors->getValue()); //Convert back to original format
}elseif(isset($chunk->Biomes)){
$biomeIds = $chunk->Biomes->getValue();
if($chunk->hasTag("BiomeColors", IntArrayTag::class)){
$biomeIds = ChunkUtils::convertBiomeColors($chunk->getIntArray("BiomeColors")); //Convert back to original format
}elseif($chunk->hasTag("Biomes", ByteArrayTag::class)){
$biomeIds = $chunk->getByteArray("Biomes");
}else{
$biomeIds = "";
}
$heightMap = [];
if(isset($chunk->HeightMap)){
if($chunk->HeightMap instanceof ByteArrayTag){
$heightMap = array_values(unpack("C*", $chunk->HeightMap->getValue()));
}elseif($chunk->HeightMap instanceof IntArrayTag){
$heightMap = $chunk->HeightMap->getValue(); #blameshoghicp
}
if($chunk->hasTag("HeightMap", ByteArrayTag::class)){
$heightMap = array_values(unpack("C*", $chunk->getByteArray("HeightMap")));
}elseif($chunk->hasTag("HeightMap", IntArrayTag::class)){
$heightMap = $chunk->getIntArray("HeightMap"); #blameshoghicp
}
$result = new Chunk(
$chunk["xPos"],
$chunk["zPos"],
$chunk->getInt("xPos"),
$chunk->getInt("zPos"),
$subChunks,
isset($chunk->Entities) ? $chunk->Entities->getValue() : [],
isset($chunk->TileEntities) ? $chunk->TileEntities->getValue() : [],
$chunk->hasTag("Entities", ListTag::class) ? $chunk->getListTag("Entities")->getValue() : [],
$chunk->hasTag("TileEntities", ListTag::class) ? $chunk->getListTag("TileEntities")->getValue() : [],
$biomeIds,
$heightMap
);
$result->setLightPopulated(isset($chunk->LightPopulated) ? ((bool) $chunk->LightPopulated->getValue()) : false);
$result->setPopulated(isset($chunk->TerrainPopulated) ? ((bool) $chunk->TerrainPopulated->getValue()) : false);
$result->setLightPopulated($chunk->getByte("LightPopulated", 0) !== 0);
$result->setPopulated($chunk->getByte("TerrainPopulated", 0) !== 0);
$result->setGenerated(true);
return $result;
}catch(\Throwable $e){