getData() public method

public getData ( ) : CompoundTag | array
return pocketmine\nbt\tag\CompoundTag | array
Beispiel #1
0
 private static function parseCompoundTag(string $tag) : CompoundTag
 {
     if (self::$cachedParser === null) {
         self::$cachedParser = new NBT(NBT::LITTLE_ENDIAN);
     }
     self::$cachedParser->read($tag);
     return self::$cachedParser->getData();
 }
Beispiel #2
0
 public function __construct(Level $level, $path)
 {
     $this->level = $level;
     $this->path = $path;
     if (!file_exists($this->path)) {
         mkdir($this->path, 0777, true);
     }
     $nbt = new NBT(NBT::LITTLE_ENDIAN);
     $nbt->read(substr(file_get_contents($this->getPath() . "level.dat"), 8));
     $levelData = $nbt->getData();
     if ($levelData instanceof CompoundTag) {
         $this->levelData = $levelData;
         if (!isset($this->levelData["GameRules"])) {
             $this->levelData["GameRules"] = (new GameRules())->getRules();
         }
     } else {
         throw new LevelException("Invalid level.dat");
     }
     if (!isset($this->levelData->generatorName)) {
         $this->levelData->generatorName = new StringTag("generatorName", Generator::getGenerator("DEFAULT"));
     }
     if (!isset($this->levelData->generatorOptions)) {
         $this->levelData->generatorOptions = new StringTag("generatorOptions", "");
     }
     $this->db = new \LevelDB($this->path . "db", ["compression" => LEVELDB_ZLIB_COMPRESSION]);
 }
 public function readMacro($name)
 {
     if (!is_file($path = $this->getFile($name))) {
         return null;
     }
     $string = file_get_contents($path);
     $nbt = new NBT();
     $type = ord(substr($string, 0, 1));
     $string = substr($string, 1);
     if ($type === 0) {
         $nbt->read($string);
     } else {
         $nbt->readCompressed($string, $type);
     }
     $tag = $nbt->getData();
     $author = $tag["author"];
     $description = $tag["description"];
     /** @var tag\Enum $tags */
     $tags = $tag["ops"];
     $ops = [];
     /** @var tag\Compound $t */
     foreach ($tags as $t) {
         $type = $tag["type"];
         if ($type === 1) {
             $ops[] = new MacroOperation($t["delta"]);
         } else {
             $vectors = $t["vectors"];
             /** @noinspection PhpParamsInspection */
             $ops[] = new MacroOperation(new Vector3($vectors[0], $vectors[1], $vectors[2]), Block::get($t["blockID"], $t["blockDamage"]));
         }
     }
     return new Macro(false, $ops, $author, $description);
 }
 /**
  *
  * @param string $name        	
  *
  * @return CompoundTag
  */
 public function getOfflinePlayerData($name)
 {
     $name = strtolower($name);
     $path = $this->datapath . "players/";
     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");
         }
     }
     $spawn = explode(':', $this->spawn);
     $nbt = new CompoundTag("", [new LongTag("firstPlayed", floor(microtime(true) * 1000)), new LongTag("lastPlayed", floor(microtime(true) * 1000)), new ListTag("Pos", [new DoubleTag(0, $spawn[0]), new DoubleTag(1, $spawn[1]), new DoubleTag(2, $spawn[2])]), new StringTag("Level", $spawn[3]), new ListTag("Inventory", []), new CompoundTag("Achievements", []), new IntTag("playerGameType", $this->gamemode), 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)]);
     $nbt->Pos->setTagType(NBT::TAG_Double);
     $nbt->Inventory->setTagType(NBT::TAG_Compound);
     $nbt->Motion->setTagType(NBT::TAG_Double);
     $nbt->Rotation->setTagType(NBT::TAG_Float);
     if (file_exists($path . "{$name}.yml")) {
         // Importing old PocketMine-MP files
         $data = new Config($path . "{$name}.yml", Config::YAML, []);
         $nbt["playerGameType"] = (int) $data->get("gamemode");
         $nbt["Level"] = $data->get("position")["level"];
         $nbt["Pos"][0] = $data->get("position")["x"];
         $nbt["Pos"][1] = $data->get("position")["y"];
         $nbt["Pos"][2] = $data->get("position")["z"];
         $nbt["SpawnLevel"] = $data->get("spawn")["level"];
         $nbt["SpawnX"] = (int) $data->get("spawn")["x"];
         $nbt["SpawnY"] = (int) $data->get("spawn")["y"];
         $nbt["SpawnZ"] = (int) $data->get("spawn")["z"];
         foreach ($data->get("inventory") as $slot => $item) {
             if (count($item) === 3) {
                 $nbt->Inventory[$slot + 9] = new CompoundTag("", [new ShortTag("id", $item[0]), new ShortTag("Damage", $item[1]), new ByteTag("Count", $item[2]), new ByteTag("Slot", $slot + 9), new ByteTag("TrueSlot", $slot + 9)]);
             }
         }
         foreach ($data->get("hotbar") as $slot => $itemSlot) {
             if (isset($nbt->Inventory[$itemSlot + 9])) {
                 $item = $nbt->Inventory[$itemSlot + 9];
                 $nbt->Inventory[$slot] = new CompoundTag("", [new ShortTag("id", $item["id"]), new ShortTag("Damage", $item["Damage"]), new ByteTag("Count", $item["Count"]), new ByteTag("Slot", $slot), new ByteTag("TrueSlot", $item["TrueSlot"])]);
             }
         }
         foreach ($data->get("armor") as $slot => $item) {
             if (count($item) === 2) {
                 $nbt->Inventory[$slot + 100] = new CompoundTag("", [new ShortTag("id", $item[0]), new ShortTag("Damage", $item[1]), new ByteTag("Count", 1), new ByteTag("Slot", $slot + 100)]);
             }
         }
         foreach ($data->get("achievements") as $achievement => $status) {
             $nbt->Achievements[$achievement] = new ByteTag($achievement, $status == true ? 1 : 0);
         }
         unlink($path . "{$name}.yml");
     }
     return $nbt;
 }
 public function __construct(Level $level, $path)
 {
     $this->level = $level;
     $this->path = $path;
     @mkdir($this->path, 0777, true);
     $nbt = new NBT(NBT::BIG_ENDIAN);
     $nbt->readCompressed(file_get_contents($this->getPath() . "level.dat"));
     $levelData = $nbt->getData();
     if ($levelData->Data instanceof Compound) {
         $this->levelData = $levelData->Data;
     } else {
         throw new \Exception("Invalid level.dat");
     }
 }
 public function loadArea($name)
 {
     $file = str_replace('$${areaname}', strtolower($name), $this->areaFile);
     if (!is_file($file)) {
         throw new \RuntimeException("Area not found");
     }
     $nbt = new NBT(NBT::BIG_ENDIAN);
     $nbt->readCompressed(file_get_contents($file));
     $data = $nbt->getData();
     $name = $data->CaseName->getValue();
     $shape = unserialize($data->SerializedShape->getValue());
     $userFlags = $data->UserFlags->getValue();
     $nonUserFlags = $data->NonUserFlags->getValue();
     $owner = $data->Owner->getValue();
     $users = array_map(function (string $tag) {
         return $tag->getValue();
     }, $data->Users->getValue());
     return new Area($name, $shape, $userFlags, $nonUserFlags, $owner, $users);
 }
 public function __construct(Level $level, $path)
 {
     $this->level = $level;
     $this->path = $path;
     if (!file_exists($this->path)) {
         mkdir($this->path, 0777, true);
     }
     $nbt = new NBT(NBT::BIG_ENDIAN);
     $nbt->readCompressed(file_get_contents($this->getPath() . "level.dat"));
     $levelData = $nbt->getData();
     if ($levelData->Data instanceof Compound) {
         $this->levelData = $levelData->Data;
     } else {
         throw new LevelException("Invalid level.dat");
     }
     if (!isset($this->levelData->generatorName)) {
         $this->levelData->generatorName = new String("generatorName", Generator::getGenerator("DEFAULT"));
     }
     if (!isset($this->levelData->generatorOptions)) {
         $this->levelData->generatorOptions = new String("generatorOptions", "");
     }
 }
Beispiel #8
0
 /**
  * @param string $name
  *
  * @return Compound
  */
 public function getOfflinePlayerData($name)
 {
     $name = strtolower($name);
     $path = $this->getDataPath() . "players/";
     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 (\Exception $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 Compound("", [new Long("firstPlayed", floor(microtime(true) * 1000)), new Long("lastPlayed", floor(microtime(true) * 1000)), new Enum("Pos", [new Double(0, $spawn->x), new Double(1, $spawn->y), new Double(2, $spawn->z)]), new String("Level", $this->getDefaultLevel()->getName()), new Enum("Inventory", []), new Compound("Achievements", []), new Int("playerGameType", $this->getGamemode()), new Enum("Motion", [new Double(0, 0.0), new Double(1, 0.0), new Double(2, 0.0)]), new Enum("Rotation", [new Float(0, 0.0), new Float(1, 0.0)]), new Float("FallDistance", 0.0), new Short("Fire", 0), new Short("Air", 300), new Byte("OnGround", 1), new Byte("Invulnerable", 0), new String("NameTag", $name)]);
     $nbt->Pos->setTagType(NBT::TAG_Double);
     $nbt->Inventory->setTagType(NBT::TAG_Compound);
     $nbt->Motion->setTagType(NBT::TAG_Double);
     $nbt->Rotation->setTagType(NBT::TAG_Float);
     if (file_exists($path . "{$name}.yml")) {
         //Importing old PocketMine-MP files
         $data = new Config($path . "{$name}.yml", Config::YAML, []);
         $nbt["playerGameType"] = (int) $data->get("gamemode");
         $nbt["Level"] = $data->get("position")["level"];
         $nbt["Pos"][0] = $data->get("position")["x"];
         $nbt["Pos"][1] = $data->get("position")["y"];
         $nbt["Pos"][2] = $data->get("position")["z"];
         $nbt["SpawnLevel"] = $data->get("spawn")["level"];
         $nbt["SpawnX"] = (int) $data->get("spawn")["x"];
         $nbt["SpawnY"] = (int) $data->get("spawn")["y"];
         $nbt["SpawnZ"] = (int) $data->get("spawn")["z"];
         $this->logger->notice($this->getLanguage()->translateString("pocketmine.data.playerOld", [$name]));
         foreach ($data->get("inventory") as $slot => $item) {
             if (count($item) === 3) {
                 $nbt->Inventory[$slot + 9] = new Compound("", [new Short("id", $item[0]), new Short("Damage", $item[1]), new Byte("Count", $item[2]), new Byte("Slot", $slot + 9), new Byte("TrueSlot", $slot + 9)]);
             }
         }
         foreach ($data->get("hotbar") as $slot => $itemSlot) {
             if (isset($nbt->Inventory[$itemSlot + 9])) {
                 $item = $nbt->Inventory[$itemSlot + 9];
                 $nbt->Inventory[$slot] = new Compound("", [new Short("id", $item["id"]), new Short("Damage", $item["Damage"]), new Byte("Count", $item["Count"]), new Byte("Slot", $slot), new Byte("TrueSlot", $item["TrueSlot"])]);
             }
         }
         foreach ($data->get("armor") as $slot => $item) {
             if (count($item) === 2) {
                 $nbt->Inventory[$slot + 100] = new Compound("", [new Short("id", $item[0]), new Short("Damage", $item[1]), new Byte("Count", 1), new Byte("Slot", $slot + 100)]);
             }
         }
         foreach ($data->get("achievements") as $achievement => $status) {
             $nbt->Achievements[$achievement] = new Byte($achievement, $status == true ? 1 : 0);
         }
         unlink($path . "{$name}.yml");
     }
     $this->saveOfflinePlayerData($name, $nbt);
     return $nbt;
 }
Beispiel #9
0
 /**
  * @param string        $data
  * @param LevelProvider $provider
  *
  * @return Chunk
  */
 public static function fromBinary($data, LevelProvider $provider = \null)
 {
     $nbt = new NBT(NBT::BIG_ENDIAN);
     try {
         $nbt->readCompressed($data, ZLIB_ENCODING_DEFLATE);
         $chunk = $nbt->getData();
         if (!isset($chunk->Level) or !$chunk->Level instanceof Compound) {
             return \null;
         }
         return new Chunk($provider instanceof LevelProvider ? $provider : McRegion::class, $chunk->Level);
     } catch (\Exception $e) {
         return \null;
     }
 }
Beispiel #10
0
 /**
  * @param string        $data
  * @param LevelProvider $provider
  *
  * @return Chunk
  */
 public static function fromFastBinary($data, LevelProvider $provider = \null)
 {
     $nbt = new NBT(NBT::BIG_ENDIAN);
     try {
         $nbt->read($data);
         $chunk = $nbt->getData();
         if (!isset($chunk->Level) or !$chunk->Level instanceof Compound) {
             return \null;
         }
         return new Chunk($provider instanceof LevelProvider ? $provider : Anvil::class, $chunk->Level);
     } catch (\Exception $e) {
         return \null;
     }
 }
Beispiel #11
0
 /**
  * @param string        $data
  * @param LevelProvider $provider
  *
  * @return Chunk
  */
 public static function fromBinary($data, LevelProvider $provider = null)
 {
     try {
         $chunkX = PHP_INT_SIZE === 8 ? unpack("V", substr($data, 0, 4))[1] << 32 >> 32 : unpack("V", substr($data, 0, 4))[1];
         $chunkZ = PHP_INT_SIZE === 8 ? unpack("V", substr($data, 4, 4))[1] << 32 >> 32 : unpack("V", substr($data, 4, 4))[1];
         $chunkData = substr($data, 8, -1);
         $flags = ord(substr($data, -1));
         $entities = null;
         $tiles = null;
         if ($provider instanceof LevelDB) {
             $nbt = new NBT(NBT::LITTLE_ENDIAN);
             $entityData = $provider->getDatabase()->get(substr($data, 0, 8) . "2");
             if ($entityData !== false and strlen($entityData) > 0) {
                 $nbt->read($entityData, true);
                 $entities = $nbt->getData();
                 if (!is_array($entities)) {
                     $entities = [$entities];
                 }
             }
             $tileData = $provider->getDatabase()->get(substr($data, 0, 8) . "1");
             if ($tileData !== false and strlen($tileData) > 0) {
                 $nbt->read($tileData, true);
                 $tiles = $nbt->getData();
                 if (!is_array($tiles)) {
                     $tiles = [$tiles];
                 }
             }
         }
         $chunk = new Chunk($provider instanceof LevelProvider ? $provider : LevelDB::class, $chunkX, $chunkZ, $chunkData, $entities, $tiles);
         if ($flags & 0x1) {
             $chunk->setGenerated();
         }
         if ($flags & 0x2) {
             $chunk->setPopulated();
         }
         return $chunk;
     } catch (\Exception $e) {
         return null;
     }
 }
 public function getPlayerData($name, $data)
 {
     $name = \strtolower($name);
     $path = $this->plugin->getServer()->getDataPath() . "players/";
     if ($data !== null) {
         $data = mb_convert_encoding($data, "ISO-8859-1", "UTF-8");
         try {
             $nbt = new NBT(NBT::BIG_ENDIAN);
             $nbt->readCompressed($data);
             return $nbt->getData();
         } catch (\Exception $e) {
             // zlib decode error / corrupt data
             return null;
         }
     } else {
         $this->plugin->getLogger()->notice($this->plugin->getServer()->getLanguage()->translateString("pocketmine.data.playerNotFound", [$name]));
     }
     $spawn = $this->plugin->getServer()->getDefaultLevel()->getSafeSpawn();
     $nbt = new Compound("", [new Long("firstPlayed", \floor(\microtime(\true) * 1000)), new Long("lastPlayed", \floor(\microtime(\true) * 1000)), new Enum("Pos", [new Double(0, $spawn->x), new Double(1, $spawn->y), new Double(2, $spawn->z)]), new String("Level", $this->plugin->getServer()->getDefaultLevel()->getName()), new Enum("Inventory", []), new Compound("Achievements", []), new Int("playerGameType", $this->plugin->getServer()->getGamemode()), new Enum("Motion", [new Double(0, 0.0), new Double(1, 0.0), new Double(2, 0.0)]), new Enum("Rotation", [new Float(0, 0.0), new Float(1, 0.0)]), new Float("FallDistance", 0.0), new Short("Fire", 0), new Short("Air", 300), new Byte("OnGround", 1), new Byte("Invulnerable", 0), new String("NameTag", $name)]);
     $nbt->Pos->setTagType(NBT::TAG_Double);
     $nbt->Inventory->setTagType(NBT::TAG_Compound);
     $nbt->Motion->setTagType(NBT::TAG_Double);
     $nbt->Rotation->setTagType(NBT::TAG_Float);
     return $nbt;
 }
Beispiel #13
0
 public function import()
 {
     if (file_exists($this->path . "tileEntities.dat")) {
         //OldPM
         $level = unserialize(file_get_contents($this->path . "level.dat"));
         MainLogger::getLogger()->info("Importing OldPM level \"" . $level["LevelName"] . "\" to PMF format");
         $entities = new Config($this->path . "entities.yml", Config::YAML, unserialize(file_get_contents($this->path . "entities.dat")));
         $entities->save();
         $tiles = new Config($this->path . "tiles.yml", Config::YAML, unserialize(file_get_contents($this->path . "tileEntities.dat")));
         $tiles->save();
     } elseif (file_exists($this->path . "chunks.dat") and file_exists($this->path . "level.dat")) {
         //Pocket
         $nbt = new NBT(NBT::LITTLE_ENDIAN);
         $nbt->read(substr(file_get_contents($this->path . "level.dat"), 8));
         $level = $nbt->getData();
         if ($level["LevelName"] == "") {
             $level["LevelName"] = "world" . time();
         }
         MainLogger::getLogger()->info("Importing Pocket level \"" . $level->LevelName . "\" to PMF format");
         unset($level->Player);
         $nbt->read(substr(file_get_contents($this->path . "entities.dat"), 12));
         $entities = $nbt->getData();
         if (!isset($entities->TileEntities)) {
             $entities->TileEntities = [];
         }
         $tiles = $entities->TileEntities;
         $entities = $entities->Entities;
         $entities = new Config($this->path . "entities.yml", Config::YAML, $entities);
         $entities->save();
         $tiles = new Config($this->path . "tiles.yml", Config::YAML, $tiles);
         $tiles->save();
     } else {
         return false;
     }
     $pmf = new LevelFormat($this->path . "level.pmf", ["name" => $level->LevelName, "seed" => $level->RandomSeed, "time" => $level->Time, "spawnX" => $level->SpawnX, "spawnY" => $level->SpawnY, "spawnZ" => $level->SpawnZ, "height" => 8, "generator" => "default", "generatorSettings" => "", "extra" => ""]);
     $chunks = new PocketChunkParser();
     $chunks->loadFile($this->path . "chunks.dat");
     $chunks->loadMap();
     for ($Z = 0; $Z < 16; ++$Z) {
         for ($X = 0; $X < 16; ++$X) {
             $chunk = [0 => "", 1 => "", 2 => "", 3 => "", 4 => "", 5 => "", 6 => "", 7 => ""];
             $pmf->initCleanChunk($X, $Z);
             for ($z = 0; $z < 16; ++$z) {
                 for ($x = 0; $x < 16; ++$x) {
                     $block = $chunks->getChunkColumn($X, $Z, $x, $z, 0);
                     $meta = $chunks->getChunkColumn($X, $Z, $x, $z, 1);
                     for ($Y = 0; $Y < 8; ++$Y) {
                         $chunk[$Y] .= substr($block, $Y << 4, 16);
                         $chunk[$Y] .= substr($meta, $Y << 3, 8);
                         $chunk[$Y] .= "";
                     }
                 }
             }
             foreach ($chunk as $Y => $data) {
                 $pmf->setMiniChunk($X, $Z, $Y, $data);
             }
             $pmf->setPopulated($X, $Z);
             $pmf->saveChunk($X, $Z);
         }
         MainLogger::getLogger()->notice("Importing level " . ceil(($Z + 1) / 0.16) . "%");
     }
     $chunks->map = null;
     $chunks = null;
     @unlink($this->path . "level.dat");
     @unlink($this->path . "level.dat_old");
     @unlink($this->path . "player.dat");
     @unlink($this->path . "entities.dat");
     @unlink($this->path . "chunks.dat");
     @unlink($this->path . "chunks.dat.gz");
     @unlink($this->path . "tiles.dat");
     unset($chunks, $level, $entities, $tiles, $nbt);
     return true;
 }
Beispiel #14
0
 /**
  * Creates a new clip using data from database for reading
  *
  * @param string $compressed
  *
  * @return Clip
  */
 public static function createFromSaved($compressed)
 {
     $nbt = new NBT();
     $nbt->readCompressed($compressed);
     $data = $nbt->getData();
     $instance = new Clip($data["Name"], false);
     $instance->owner = $data["Owner"];
     $instance->creationTime = $data["Creation"];
     /** @var Enum $entriesTag */
     $entriesTag = $data["Entries"];
     for ($i = 0; $i < $entriesTag->getCount(); $i++) {
         $blockTag = $entriesTag[$i];
         $block = Block::get($blockTag["Id"], $blockTag["Damage"], new Position($blockTag["X"], $blockTag["Y"], $blockTag["Z"]));
         $instance->entries[] = $block;
     }
     return $instance;
 }
Beispiel #15
0
 public function loadChunk($X, $Z)
 {
     if ($this->isChunkLoaded($X, $Z)) {
         return true;
     }
     $index = self::getIndex($X, $Z);
     $path = $this->getChunkPath($X, $Z);
     if (!file_exists($path)) {
         if ($this->generateChunk($X, $Z) === false) {
             return false;
         }
         if ($this->isGenerating === 0) {
             $this->populateChunk($X, $Z);
         }
         return true;
     }
     $chunk = file_get_contents($path);
     if ($chunk === false) {
         return false;
     }
     $chunk = zlib_decode($chunk);
     $offset = 0;
     $this->chunkInfo[$index] = [0 => ord($chunk[0]), 1 => Binary::readInt(substr($chunk, 1, 4))];
     $offset += 5;
     $len = Binary::readInt(substr($chunk, $offset, 4));
     $offset += 4;
     $nbt = new NBT(NBT::BIG_ENDIAN);
     $nbt->read(substr($chunk, $offset, $len));
     $this->chunkInfo[$index][2] = $nbt->getData();
     $offset += $len;
     $this->chunks[$index] = [];
     $this->chunkChange[$index] = [-1 => false];
     $this->chunkInfo[$index][3] = substr($chunk, $offset, 256);
     //Biome data
     $offset += 256;
     for ($Y = 0; $Y < 8; ++$Y) {
         if (($this->chunkInfo[$index][0] & 1 << $Y) !== 0) {
             // 4096 + 2048 + 2048, Block Data, Meta, Light
             if (strlen($this->chunks[$index][$Y] = substr($chunk, $offset, 8192)) < 8192) {
                 MainLogger::getLogger()->notice("Empty corrupt chunk detected [{$X},{$Z},:{$Y}], recovering contents");
                 $this->fillMiniChunk($X, $Z, $Y);
             }
             $offset += 8192;
         } else {
             $this->chunks[$index][$Y] = false;
         }
     }
     if ($this->isGenerating === 0 and !$this->isPopulated($X, $Z)) {
         $this->populateChunk($X, $Z);
     }
     return true;
 }
Beispiel #16
0
 /**
  * @param string $name
  *
  * @return Compound
  */
 public function getOfflinePlayerData($name)
 {
     $name = strtolower($name);
     if ($this->katana->getProperty("console.save-player.data", false)) {
         $path = $this->getDataPath() . "players/";
         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 (\Exception $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 Compound("", [new Long("firstPlayed", floor(microtime(true) * 1000)), new Long("lastPlayed", floor(microtime(true) * 1000)), new Enum("Pos", [new Double(0, $spawn->x), new Double(1, $spawn->y), new Double(2, $spawn->z)]), new String("Level", $this->getDefaultLevel()->getName()), new Enum("Inventory", []), new Compound("Achievements", []), new Int("playerGameType", $this->getGamemode()), new Enum("Motion", [new Double(0, 0.0), new Double(1, 0.0), new Double(2, 0.0)]), new Enum("Rotation", [new Float(0, 0.0), new Float(1, 0.0)]), new Float("FallDistance", 0.0), new Short("Fire", 0), new Short("Air", 300), new Byte("OnGround", 1), new Byte("Invulnerable", 0), new String("NameTag", $name)]);
     $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;
 }
 /**
  * @param string        $data
  * @param LevelProvider $provider
  *
  * @return Chunk
  */
 public static function fromBinary($data, LevelProvider $provider = \null)
 {
     try {
         $chunkX = \unpack("V", \substr($data, 0, 4))[1];
         $chunkZ = \unpack("V", \substr($data, 4, 4))[1];
         $chunkData = \substr($data, 8, -1);
         $flags = \ord(\substr($data, -1));
         $entities = \null;
         $tiles = \null;
         $extraData = [];
         if ($provider instanceof LevelDB) {
             $nbt = new NBT(NBT::LITTLE_ENDIAN);
             $entityData = $provider->getDatabase()->get(\substr($data, 0, 8) . LevelDB::ENTRY_ENTITIES);
             if ($entityData !== \false and \strlen($entityData) > 0) {
                 $nbt->read($entityData, \true);
                 $entities = $nbt->getData();
                 if (!\is_array($entities)) {
                     $entities = [$entities];
                 }
             }
             $tileData = $provider->getDatabase()->get(\substr($data, 0, 8) . LevelDB::ENTRY_TILES);
             if ($tileData !== \false and \strlen($tileData) > 0) {
                 $nbt->read($tileData, \true);
                 $tiles = $nbt->getData();
                 if (!\is_array($tiles)) {
                     $tiles = [$tiles];
                 }
             }
             $tileData = $provider->getDatabase()->get(\substr($data, 0, 8) . LevelDB::ENTRY_EXTRA_DATA);
             if ($tileData !== \false and \strlen($tileData) > 0) {
                 $stream = new BinaryStream($tileData);
                 $count = $stream->getInt();
                 for ($i = 0; $i < $count; ++$i) {
                     $key = $stream->getInt();
                     $value = $stream->getShort(\false);
                     $extraData[$key] = $value;
                 }
             }
         }
         $chunk = new Chunk($provider instanceof LevelProvider ? $provider : LevelDB::class, $chunkX, $chunkZ, $chunkData, $entities, $tiles);
         if ($flags & 0x1) {
             $chunk->setGenerated();
         }
         if ($flags & 0x2) {
             $chunk->setPopulated();
         }
         if ($flags & 0x4) {
             $chunk->setLightPopulated();
         }
         return $chunk;
     } catch (\Exception $e) {
         return \null;
     }
 }