mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 00:33:59 +00:00
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:
parent
48a7627b96
commit
665130561e
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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){
|
||||
|
Loading…
x
Reference in New Issue
Block a user