public function getOfflinePlayerData($name)
{
$name = strtolower($name);
$path = $this->getDataPath() . "players/";
if ($this->shouldSavePlayerData()) {
if (file_exists($path . "{$name}.dat")) {
try {
$nbt = new NBT(NBT::BIG_ENDIAN);
$nbt->readCompressed(file_get_contents($path . "{$name}.dat"));
return $nbt->getData();
} catch (\Throwable $e) {
//zlib decode error / corrupt data
rename($path . "{$name}.dat", $path . "{$name}.dat.bak");
$this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerCorrupted", [$name]));
}
} else {
$this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerNotFound", [$name]));
}
}
$spawn = $this->getDefaultLevel()->getSafeSpawn();
$nbt = new CompoundTag("", [new LongTag("firstPlayed", floor(microtime(true) * 1000)), new LongTag("lastPlayed", floor(microtime(true) * 1000)), new ListTag("Pos", [new DoubleTag(0, $spawn->x), new DoubleTag(1, $spawn->y), new DoubleTag(2, $spawn->z)]), new StringTag("Level", $this->getDefaultLevel()->getName()), new ListTag("Inventory", []), new CompoundTag("Achievements", []), new IntTag("playerGameType", $this->getGamemode()), new ListTag("Motion", [new DoubleTag(0, 0.0), new DoubleTag(1, 0.0), new DoubleTag(2, 0.0)]), new ListTag("Rotation", [new FloatTag(0, 0.0), new FloatTag(1, 0.0)]), 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), new ShortTag("foodLevel", 20), new ShortTag("Health", 20), new ShortTag("MaxHealth", 20), new IntTag("XpLevel", 0)]);
$nbt->Pos->setTagType(NBT::TAG_Double);
$nbt->Inventory->setTagType(NBT::TAG_Compound);
$nbt->Motion->setTagType(NBT::TAG_Double);
$nbt->Rotation->setTagType(NBT::TAG_Float);
$this->saveOfflinePlayerData($name, $nbt);
return $nbt;
}