diff --git a/src/pocketmine/OfflinePlayer.php b/src/pocketmine/OfflinePlayer.php index 0e631ee6264..2b1d87a85b5 100644 --- a/src/pocketmine/OfflinePlayer.php +++ b/src/pocketmine/OfflinePlayer.php @@ -26,6 +26,7 @@ use pocketmine\metadata\Metadatable; use pocketmine\metadata\MetadataValue; use pocketmine\nbt\tag\CompoundTag; +use pocketmine\nbt\tag\LongTag; use pocketmine\plugin\Plugin; class OfflinePlayer implements IPlayer, Metadatable{ @@ -106,15 +107,15 @@ public function getPlayer(){ } public function getFirstPlayed(){ - return $this->namedtag instanceof CompoundTag ? $this->namedtag->getLong("firstPlayed", 0, true) : null; + return ($this->namedtag !== null and $this->namedtag->hasTag("firstPlayed", LongTag::class)) ? $this->namedtag->getInt("firstPlayed") : null; } public function getLastPlayed(){ - return $this->namedtag instanceof CompoundTag ? $this->namedtag->getLong("lastPlayed", 0, true) : null; + return ($this->namedtag !== null and $this->namedtag->hasTag("lastPlayed", LongTag::class)) ? $this->namedtag->getLong("lastPlayed") : null; } public function hasPlayedBefore() : bool{ - return $this->namedtag instanceof CompoundTag; + return $this->namedtag !== null; } public function setMetadata(string $metadataKey, MetadataValue $newMetadataValue){ diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index fae95601a48..ac06b7123b2 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1891,10 +1891,7 @@ protected function initEntity(CompoundTag $nbt) : void{ $this->firstPlayed = $nbt->getLong("firstPlayed", $now = (int) (microtime(true) * 1000)); $this->lastPlayed = $nbt->getLong("lastPlayed", $now); - $this->gamemode = $nbt->getInt("playerGameType", GameMode::SURVIVAL) & 0x03; - if($this->server->getForceGamemode()){ - $this->gamemode = $this->server->getGamemode(); - } + $this->gamemode = $this->server->getForceGamemode() ? $this->server->getGamemode() : $nbt->getInt("playerGameType", $this->server->getGamemode()) & 0x03; $this->allowFlight = $this->isCreative(); $this->keepMovement = $this->isSpectator() || $this->allowMovementCheats(); @@ -1907,10 +1904,12 @@ protected function initEntity(CompoundTag $nbt) : void{ $this->setCanClimb(); $this->achievements = []; - $achievements = $nbt->getCompoundTag("Achievements") ?? []; - /** @var ByteTag $achievement */ - foreach($achievements as $achievement){ - $this->achievements[$achievement->getName()] = $achievement->getValue() !== 0; + $achievements = $nbt->getCompoundTag("Achievements"); + if($achievements !== null){ + /** @var ByteTag $achievement */ + foreach($achievements as $achievement){ + $this->achievements[$achievement->getName()] = $achievement->getValue() !== 0; + } } if(!$this->hasValidSpawnPosition()){ diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 8b0568381d6..235b276bfc8 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -58,17 +58,8 @@ use pocketmine\metadata\LevelMetadataStore; use pocketmine\metadata\PlayerMetadataStore; use pocketmine\nbt\BigEndianNbtSerializer; -use pocketmine\nbt\NBT; use pocketmine\nbt\NbtDataException; -use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; -use pocketmine\nbt\tag\DoubleTag; -use pocketmine\nbt\tag\FloatTag; -use pocketmine\nbt\tag\IntTag; -use pocketmine\nbt\tag\ListTag; -use pocketmine\nbt\tag\LongTag; -use pocketmine\nbt\tag\ShortTag; -use pocketmine\nbt\tag\StringTag; use pocketmine\network\AdvancedNetworkInterface; use pocketmine\network\mcpe\CompressBatchPromise; use pocketmine\network\mcpe\CompressBatchTask; @@ -686,45 +677,14 @@ public function getOfflinePlayerData(string $name) : CompoundTag{ $this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerNotFound", [$name])); } $spawn = $this->levelManager->getDefaultLevel()->getSafeSpawn(); - $currentTimeMillis = (int) (microtime(true) * 1000); - - $nbt = new CompoundTag("", [ - new LongTag("firstPlayed", $currentTimeMillis), - new LongTag("lastPlayed", $currentTimeMillis), - new ListTag("Pos", [ - new DoubleTag("", $spawn->x), - new DoubleTag("", $spawn->y), - new DoubleTag("", $spawn->z) - ], NBT::TAG_Double), - new StringTag("Level", $this->levelManager->getDefaultLevel()->getFolderName()), - //new StringTag("SpawnLevel", $this->getDefaultLevel()->getFolderName()), - //new IntTag("SpawnX", $spawn->getFloorX()), - //new IntTag("SpawnY", $spawn->getFloorY()), - //new IntTag("SpawnZ", $spawn->getFloorZ()), - //new ByteTag("SpawnForced", 1), //TODO - new ListTag("Inventory", [], NBT::TAG_Compound), - new ListTag("EnderChestInventory", [], NBT::TAG_Compound), - new CompoundTag("Achievements", []), - new IntTag("playerGameType", $this->getGamemode()), - new ListTag("Motion", [ - new DoubleTag("", 0.0), - new DoubleTag("", 0.0), - new DoubleTag("", 0.0) - ], NBT::TAG_Double), - new ListTag("Rotation", [ - new FloatTag("", 0.0), - new FloatTag("", 0.0) - ], NBT::TAG_Float), - new FloatTag("FallDistance", 0.0), - new ShortTag("Fire", 0), - new ShortTag("Air", 300), - new ByteTag("OnGround", 1), - new ByteTag("Invulnerable", 0), - new StringTag("NameTag", $name) - ]); - return $nbt; + $nbt = EntityFactory::createBaseNBT($spawn); + + $nbt->setString("Level", $this->levelManager->getDefaultLevel()->getFolderName()); + $nbt->setByte("OnGround", 1); //TODO: this hack is needed for new players in-air ticks - they don't get detected as on-ground until they move + //TODO: old code had a TODO for SpawnForced + return $nbt; } /**