From 965c19375f91769c99038fbf69058a4ee6deb6f1 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 18 Nov 2017 16:44:21 +0000 Subject: [PATCH 1/3] NBT: Split up concerns of endianness and varint NBT into their own classes, separate stream handling from NBT class The remaining methods, constants and fields in the NBT class now pertain to generic NBT functionality (except for the matchList()/matchTree() methods, but that's a job for another time). All NBT I/O specific logic has now been moved to NBTStream and its descendents. --- src/pocketmine/Player.php | 6 +- src/pocketmine/Server.php | 5 +- src/pocketmine/item/Item.php | 5 +- .../level/format/io/BaseLevelProvider.php | 6 +- .../level/format/io/leveldb/LevelDB.php | 12 +- .../level/format/io/region/Anvil.php | 5 +- .../level/format/io/region/McRegion.php | 7 +- src/pocketmine/nbt/BigEndianNBTStream.php | 83 ++++++ src/pocketmine/nbt/LittleEndianNBTStream.php | 83 ++++++ src/pocketmine/nbt/NBT.php | 274 +----------------- src/pocketmine/nbt/NBTStream.php | 267 +++++++++++++++++ .../nbt/NetworkLittleEndianNBTStream.php | 70 +++++ src/pocketmine/nbt/tag/ByteArrayTag.php | 9 +- src/pocketmine/nbt/tag/ByteTag.php | 5 +- src/pocketmine/nbt/tag/CompoundTag.php | 11 +- src/pocketmine/nbt/tag/DoubleTag.php | 5 +- src/pocketmine/nbt/tag/EndTag.php | 5 +- src/pocketmine/nbt/tag/FloatTag.php | 5 +- src/pocketmine/nbt/tag/IntArrayTag.php | 11 +- src/pocketmine/nbt/tag/IntTag.php | 9 +- src/pocketmine/nbt/tag/ListTag.php | 13 +- src/pocketmine/nbt/tag/LongTag.php | 9 +- src/pocketmine/nbt/tag/ShortTag.php | 5 +- src/pocketmine/nbt/tag/StringTag.php | 9 +- src/pocketmine/nbt/tag/Tag.php | 6 +- src/pocketmine/tile/Spawnable.php | 5 +- 26 files changed, 588 insertions(+), 342 deletions(-) create mode 100644 src/pocketmine/nbt/BigEndianNBTStream.php create mode 100644 src/pocketmine/nbt/LittleEndianNBTStream.php create mode 100644 src/pocketmine/nbt/NBTStream.php create mode 100644 src/pocketmine/nbt/NetworkLittleEndianNBTStream.php diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index e73825f44..ed2afbde8 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -91,7 +91,7 @@ use pocketmine\level\WeakPosition; use pocketmine\math\AxisAlignedBB; use pocketmine\math\Vector3; use pocketmine\metadata\MetadataValue; -use pocketmine\nbt\NBT; +use pocketmine\nbt\NetworkLittleEndianNBTStream; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; @@ -2834,8 +2834,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{ $t = $this->level->getTile($pos); if($t instanceof Spawnable){ - $nbt = new NBT(NBT::LITTLE_ENDIAN); - $nbt->read($packet->namedtag, false, true); + $nbt = new NetworkLittleEndianNBTStream(); + $nbt->read($packet->namedtag); $nbt = $nbt->getData(); if(!$t->updateCompoundTag($nbt, $this)){ $t->spawnTo($this); diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index e8ac70fb2..c8a14d98f 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -67,6 +67,7 @@ use pocketmine\level\LevelException; use pocketmine\metadata\EntityMetadataStore; use pocketmine\metadata\LevelMetadataStore; use pocketmine\metadata\PlayerMetadataStore; +use pocketmine\nbt\BigEndianNBTStream; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; @@ -749,7 +750,7 @@ class Server{ if($this->shouldSavePlayerData()){ if(file_exists($path . "$name.dat")){ try{ - $nbt = new NBT(NBT::BIG_ENDIAN); + $nbt = new BigEndianNBTStream(); $nbt->readCompressed(file_get_contents($path . "$name.dat")); return $nbt->getData(); @@ -815,7 +816,7 @@ class Server{ $this->pluginManager->callEvent($ev); if(!$ev->isCancelled()){ - $nbt = new NBT(NBT::BIG_ENDIAN); + $nbt = new BigEndianNBTStream(); try{ $nbt->setData($ev->getSaveData()); diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index e1b477d2d..5aef7797a 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -34,6 +34,7 @@ use pocketmine\item\enchantment\Enchantment; use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\level\Level; use pocketmine\math\Vector3; +use pocketmine\nbt\LittleEndianNBTStream; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; @@ -64,7 +65,7 @@ class Item implements ItemIds, \JsonSerializable{ } if(self::$cachedParser === null){ - self::$cachedParser = new NBT(NBT::LITTLE_ENDIAN); + self::$cachedParser = new LittleEndianNBTStream(); } self::$cachedParser->read($tag); @@ -79,7 +80,7 @@ class Item implements ItemIds, \JsonSerializable{ private static function writeCompoundTag(CompoundTag $tag) : string{ if(self::$cachedParser === null){ - self::$cachedParser = new NBT(NBT::LITTLE_ENDIAN); + self::$cachedParser = new LittleEndianNBTStream(); } self::$cachedParser->setData($tag); diff --git a/src/pocketmine/level/format/io/BaseLevelProvider.php b/src/pocketmine/level/format/io/BaseLevelProvider.php index 806f1f0db..62d757375 100644 --- a/src/pocketmine/level/format/io/BaseLevelProvider.php +++ b/src/pocketmine/level/format/io/BaseLevelProvider.php @@ -29,7 +29,7 @@ use pocketmine\level\generator\Generator; use pocketmine\level\Level; use pocketmine\level\LevelException; use pocketmine\math\Vector3; -use pocketmine\nbt\NBT; +use pocketmine\nbt\BigEndianNBTStream; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\StringTag; use pocketmine\scheduler\AsyncTask; @@ -48,7 +48,7 @@ abstract class BaseLevelProvider implements LevelProvider{ if(!file_exists($this->path)){ mkdir($this->path, 0777, true); } - $nbt = new NBT(NBT::BIG_ENDIAN); + $nbt = new BigEndianNBTStream(); $nbt->readCompressed(file_get_contents($this->getPath() . "level.dat")); $levelData = $nbt->getData()->getCompoundTag("Data"); if($levelData !== null){ @@ -120,7 +120,7 @@ abstract class BaseLevelProvider implements LevelProvider{ } public function saveLevelData(){ - $nbt = new NBT(NBT::BIG_ENDIAN); + $nbt = new BigEndianNBTStream(); $nbt->setData(new CompoundTag("", [ $this->levelData ])); diff --git a/src/pocketmine/level/format/io/leveldb/LevelDB.php b/src/pocketmine/level/format/io/leveldb/LevelDB.php index d360268c5..b59021bc9 100644 --- a/src/pocketmine/level/format/io/leveldb/LevelDB.php +++ b/src/pocketmine/level/format/io/leveldb/LevelDB.php @@ -32,7 +32,7 @@ use pocketmine\level\generator\Flat; use pocketmine\level\generator\Generator; use pocketmine\level\Level; use pocketmine\level\LevelException; -use pocketmine\nbt\NBT; +use pocketmine\nbt\LittleEndianNBTStream; use pocketmine\nbt\tag\{ ByteTag, CompoundTag, FloatTag, IntTag, LongTag, StringTag }; @@ -94,7 +94,7 @@ class LevelDB extends BaseLevelProvider{ if(!file_exists($this->path)){ mkdir($this->path, 0777, true); } - $nbt = new NBT(NBT::LITTLE_ENDIAN); + $nbt = new LittleEndianNBTStream(); $nbt->read(substr(file_get_contents($this->getPath() . "level.dat"), 8)); $levelData = $nbt->getData(); if($levelData instanceof CompoundTag){ @@ -217,7 +217,7 @@ class LevelDB extends BaseLevelProvider{ new StringTag("generatorOptions", $options["preset"] ?? "") ]); - $nbt = new NBT(NBT::LITTLE_ENDIAN); + $nbt = new LittleEndianNBTStream(); $nbt->setData($levelData); $buffer = $nbt->write(); file_put_contents($path . "level.dat", Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); @@ -247,7 +247,7 @@ class LevelDB extends BaseLevelProvider{ $this->levelData->setInt("NetworkVersion", ProtocolInfo::CURRENT_PROTOCOL); $this->levelData->setInt("StorageVersion", self::CURRENT_STORAGE_VERSION); - $nbt = new NBT(NBT::LITTLE_ENDIAN); + $nbt = new LittleEndianNBTStream(); $nbt->setData($this->levelData); $buffer = $nbt->write(); file_put_contents($this->getPath() . "level.dat", Binary::writeLInt(self::CURRENT_STORAGE_VERSION) . Binary::writeLInt(strlen($buffer)) . $buffer); @@ -416,7 +416,7 @@ class LevelDB extends BaseLevelProvider{ throw new UnsupportedChunkFormatException("don't know how to decode chunk format version $chunkVersion"); } - $nbt = new NBT(NBT::LITTLE_ENDIAN); + $nbt = new LittleEndianNBTStream(); $entities = []; if(($entityData = $this->db->get($index . self::TAG_ENTITY)) !== false and strlen($entityData) > 0){ @@ -553,7 +553,7 @@ class LevelDB extends BaseLevelProvider{ */ private function writeTags(array $targets, string $index){ if(!empty($targets)){ - $nbt = new NBT(NBT::LITTLE_ENDIAN); + $nbt = new LittleEndianNBTStream(); $nbt->setData($targets); $this->db->put($index, $nbt->write()); }else{ diff --git a/src/pocketmine/level/format/io/region/Anvil.php b/src/pocketmine/level/format/io/region/Anvil.php index 7e6b27b43..e6e3ac085 100644 --- a/src/pocketmine/level/format/io/region/Anvil.php +++ b/src/pocketmine/level/format/io/region/Anvil.php @@ -27,6 +27,7 @@ use pocketmine\level\format\Chunk; use pocketmine\level\format\ChunkException; use pocketmine\level\format\io\ChunkUtils; use pocketmine\level\format\SubChunk; +use pocketmine\nbt\BigEndianNBTStream; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; @@ -83,7 +84,7 @@ class Anvil extends McRegion{ //TODO: TileTicks - $writer = new NBT(NBT::BIG_ENDIAN); + $writer = new BigEndianNBTStream(); $nbt->setName("Level"); $writer->setData(new CompoundTag("", [$nbt])); @@ -100,7 +101,7 @@ class Anvil extends McRegion{ } public function nbtDeserialize(string $data){ - $nbt = new NBT(NBT::BIG_ENDIAN); + $nbt = new BigEndianNBTStream(); try{ $nbt->readCompressed($data); diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index addfc9b33..d073c86b0 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -30,6 +30,7 @@ use pocketmine\level\format\io\ChunkUtils; use pocketmine\level\format\SubChunk; use pocketmine\level\generator\Generator; use pocketmine\level\Level; +use pocketmine\nbt\BigEndianNBTStream; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\{ ByteArrayTag, ByteTag, CompoundTag, IntArrayTag, IntTag, ListTag, LongTag, StringTag @@ -102,7 +103,7 @@ class McRegion extends BaseLevelProvider{ $nbt->setTag(new ListTag("TileEntities", $tiles, NBT::TAG_Compound)); - $writer = new NBT(NBT::BIG_ENDIAN); + $writer = new BigEndianNBTStream(); $nbt->setName("Level"); $writer->setData(new CompoundTag("", [$nbt])); @@ -115,7 +116,7 @@ class McRegion extends BaseLevelProvider{ * @return Chunk|null */ public function nbtDeserialize(string $data){ - $nbt = new NBT(NBT::BIG_ENDIAN); + $nbt = new BigEndianNBTStream(); try{ $nbt->readCompressed($data); @@ -258,7 +259,7 @@ class McRegion extends BaseLevelProvider{ new StringTag("LevelName", $name), new CompoundTag("GameRules", []) ]); - $nbt = new NBT(NBT::BIG_ENDIAN); + $nbt = new BigEndianNBTStream(); $nbt->setData(new CompoundTag("", [ $levelData ])); diff --git a/src/pocketmine/nbt/BigEndianNBTStream.php b/src/pocketmine/nbt/BigEndianNBTStream.php new file mode 100644 index 000000000..9c70eb27a --- /dev/null +++ b/src/pocketmine/nbt/BigEndianNBTStream.php @@ -0,0 +1,83 @@ +get(2)); + } + + public function getSignedShort() : int{ + return Binary::readSignedShort($this->get(2)); + } + + public function putShort($v){ + $this->buffer .= Binary::writeShort($v); + } + + public function getInt() : int{ + return Binary::readInt($this->get(4)); + } + + public function putInt($v){ + $this->buffer .= Binary::writeInt($v); + } + + public function getLong() : int{ + return Binary::readLong($this->get(8)); + } + + public function putLong($v){ + $this->buffer .= Binary::writeLong($v); + } + + public function getFloat() : float{ + return Binary::readFloat($this->get(4)); + } + + public function putFloat($v){ + $this->buffer .= Binary::writeFloat($v); + } + + public function getDouble() : float{ + return Binary::readDouble($this->get(8)); + } + + public function putDouble($v){ + $this->buffer .= Binary::writeDouble($v); + } + + public function getIntArray() : array{ + $len = $this->getInt(); + return array_values(unpack("N*", $this->get($len * 4))); + } + + public function putIntArray(array $array) : void{ + $this->putInt(count($array)); + $this->put(pack("N*", ...$array)); + } +} diff --git a/src/pocketmine/nbt/LittleEndianNBTStream.php b/src/pocketmine/nbt/LittleEndianNBTStream.php new file mode 100644 index 000000000..fe1a6ea30 --- /dev/null +++ b/src/pocketmine/nbt/LittleEndianNBTStream.php @@ -0,0 +1,83 @@ +get(2)); + } + + public function getSignedShort() : int{ + return Binary::readSignedLShort($this->get(2)); + } + + public function putShort($v){ + $this->put(Binary::writeLShort($v)); + } + + public function getInt() : int{ + return Binary::readLInt($this->get(4)); + } + + public function putInt($v){ + $this->put(Binary::writeLInt($v)); + } + + public function getLong() : int{ + return Binary::readLLong($this->get(8)); + } + + public function putLong($v){ + $this->put(Binary::writeLLong($v)); + } + + public function getFloat() : float{ + return Binary::readLFloat($this->get(4)); + } + + public function putFloat($v){ + $this->put(Binary::writeLFloat($v)); + } + + public function getDouble() : float{ + return Binary::readLDouble($this->get(8)); + } + + public function putDouble($v){ + $this->put(Binary::writeLDouble($v)); + } + + public function getIntArray() : array{ + $len = $this->getInt(); + return array_values(unpack("V*", $this->get($len * 4))); + } + + public function putIntArray(array $array) : void{ + $this->putInt(count($array)); + $this->put(pack("V*", ...$array)); + } +} diff --git a/src/pocketmine/nbt/NBT.php b/src/pocketmine/nbt/NBT.php index debc56946..8675be59a 100644 --- a/src/pocketmine/nbt/NBT.php +++ b/src/pocketmine/nbt/NBT.php @@ -36,22 +36,11 @@ use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\LongTag; -use pocketmine\nbt\tag\NamedTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\Tag; -#ifndef COMPILE -use pocketmine\utils\Binary; -#endif - - -#include - -/** - * Named Binary Tag encoder/decoder - */ -class NBT{ +abstract class NBT{ public const LITTLE_ENDIAN = 0; public const BIG_ENDIAN = 1; @@ -68,11 +57,6 @@ class NBT{ public const TAG_Compound = 10; public const TAG_IntArray = 11; - public $buffer; - public $offset; - public $endianness; - private $data; - /** * @param int $type * @@ -172,260 +156,4 @@ class NBT{ return true; } - - public function get($len){ - if($len < 0){ - $this->offset = strlen($this->buffer) - 1; - return ""; - }elseif($len === true){ - return substr($this->buffer, $this->offset); - } - - return $len === 1 ? $this->buffer{$this->offset++} : substr($this->buffer, ($this->offset += $len) - $len, $len); - } - - public function put($v){ - $this->buffer .= $v; - } - - public function feof() : bool{ - return !isset($this->buffer{$this->offset}); - } - - public function __construct($endianness = self::LITTLE_ENDIAN){ - $this->offset = 0; - $this->endianness = $endianness & 0x01; - } - - public function read($buffer, $doMultiple = false, bool $network = false){ - $this->offset = 0; - $this->buffer = $buffer; - $this->data = $this->readTag($network); - if($doMultiple and $this->offset < strlen($this->buffer)){ - $this->data = [$this->data]; - do{ - $this->data[] = $this->readTag($network); - }while($this->offset < strlen($this->buffer)); - } - $this->buffer = ""; - } - - public function readCompressed($buffer){ - $this->read(zlib_decode($buffer)); - } - - /** - * @param bool $network - * - * @return string|bool - */ - public function write(bool $network = false){ - $this->offset = 0; - $this->buffer = ""; - - if($this->data instanceof CompoundTag){ - $this->writeTag($this->data, $network); - - return $this->buffer; - }elseif(is_array($this->data)){ - foreach($this->data as $tag){ - $this->writeTag($tag, $network); - } - return $this->buffer; - } - - return false; - } - - public function writeCompressed($compression = ZLIB_ENCODING_GZIP, $level = 7){ - if(($write = $this->write()) !== false){ - return zlib_encode($write, $compression, $level); - } - - return false; - } - - public function readTag(bool $network = false){ - if($this->feof()){ - return new EndTag(); - } - - $tagType = $this->getByte(); - $tag = self::createTag($tagType); - - if($tag instanceof NamedTag){ - $tag->setName($this->getString($network)); - $tag->read($this, $network); - } - - return $tag; - } - - public function writeTag(Tag $tag, bool $network = false){ - $this->putByte($tag->getType()); - if($tag instanceof NamedTag){ - $this->putString($tag->getName(), $network); - } - $tag->write($this, $network); - } - - public function getByte() : int{ - return Binary::readByte($this->get(1)); - } - - public function getSignedByte() : int{ - return Binary::readSignedByte($this->get(1)); - } - - public function putByte($v){ - $this->buffer .= Binary::writeByte($v); - } - - public function getShort() : int{ - return $this->endianness === self::BIG_ENDIAN ? Binary::readShort($this->get(2)) : Binary::readLShort($this->get(2)); - } - - public function getSignedShort() : int{ - return $this->endianness === self::BIG_ENDIAN ? Binary::readSignedShort($this->get(2)) : Binary::readSignedLShort($this->get(2)); - } - - public function putShort($v){ - $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Binary::writeShort($v) : Binary::writeLShort($v); - } - - public function getInt(bool $network = false) : int{ - if($network === true){ - return Binary::readVarInt($this->buffer, $this->offset); - } - return $this->endianness === self::BIG_ENDIAN ? Binary::readInt($this->get(4)) : Binary::readLInt($this->get(4)); - } - - public function putInt($v, bool $network = false){ - if($network === true){ - $this->buffer .= Binary::writeVarInt($v); - }else{ - $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Binary::writeInt($v) : Binary::writeLInt($v); - } - } - - public function getLong(bool $network = false) : int{ - if($network){ - return Binary::readVarLong($this->buffer, $this->offset); - } - return $this->endianness === self::BIG_ENDIAN ? Binary::readLong($this->get(8)) : Binary::readLLong($this->get(8)); - } - - public function putLong($v, bool $network = false){ - if($network){ - $this->buffer .= Binary::writeVarLong($v); - }else{ - $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Binary::writeLong($v) : Binary::writeLLong($v); - } - } - - public function getFloat() : float{ - return $this->endianness === self::BIG_ENDIAN ? Binary::readFloat($this->get(4)) : Binary::readLFloat($this->get(4)); - } - - public function putFloat($v){ - $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Binary::writeFloat($v) : Binary::writeLFloat($v); - } - - public function getDouble() : float{ - return $this->endianness === self::BIG_ENDIAN ? Binary::readDouble($this->get(8)) : Binary::readLDouble($this->get(8)); - } - - public function putDouble($v){ - $this->buffer .= $this->endianness === self::BIG_ENDIAN ? Binary::writeDouble($v) : Binary::writeLDouble($v); - } - - public function getString(bool $network = false){ - $len = $network ? Binary::readUnsignedVarInt($this->buffer, $this->offset) : $this->getShort(); - return $this->get($len); - } - - public function putString($v, bool $network = false){ - if($network === true){ - $this->put(Binary::writeUnsignedVarInt(strlen($v))); - }else{ - $this->putShort(strlen($v)); - } - $this->buffer .= $v; - } - - public function getArray() : array{ - $data = []; - self::toArray($data, $this->data); - return $data; - } - - private static function toArray(array &$data, Tag $tag){ - /** @var CompoundTag[]|ListTag[]|IntArrayTag[] $tag */ - foreach($tag as $key => $value){ - if($value instanceof CompoundTag or $value instanceof ListTag or $value instanceof IntArrayTag){ - $data[$key] = []; - self::toArray($data[$key], $value); - }else{ - $data[$key] = $value->getValue(); - } - } - } - - public static function fromArrayGuesser($key, $value){ - if(is_int($value)){ - return new IntTag($key, $value); - }elseif(is_float($value)){ - return new FloatTag($key, $value); - }elseif(is_string($value)){ - return new StringTag($key, $value); - }elseif(is_bool($value)){ - return new ByteTag($key, $value ? 1 : 0); - } - - return null; - } - - private static function fromArray(Tag $tag, array $data, callable $guesser){ - foreach($data as $key => $value){ - if(is_array($value)){ - $isNumeric = true; - $isIntArray = true; - foreach($value as $k => $v){ - if(!is_numeric($k)){ - $isNumeric = false; - break; - }elseif(!is_int($v)){ - $isIntArray = false; - } - } - $tag{$key} = $isNumeric ? ($isIntArray ? new IntArrayTag($key, []) : new ListTag($key, [])) : new CompoundTag($key, []); - self::fromArray($tag->{$key}, $value, $guesser); - }else{ - $v = call_user_func($guesser, $key, $value); - if($v instanceof Tag){ - $tag{$key} = $v; - } - } - } - } - - public function setArray(array $data, callable $guesser = null){ - $this->data = new CompoundTag("", []); - self::fromArray($this->data, $data, $guesser ?? [self::class, "fromArrayGuesser"]); - } - - /** - * @return CompoundTag|array - */ - public function getData(){ - return $this->data; - } - - /** - * @param CompoundTag|array $data - */ - public function setData($data){ - $this->data = $data; - } - } diff --git a/src/pocketmine/nbt/NBTStream.php b/src/pocketmine/nbt/NBTStream.php new file mode 100644 index 000000000..0ffaad878 --- /dev/null +++ b/src/pocketmine/nbt/NBTStream.php @@ -0,0 +1,267 @@ +offset = strlen($this->buffer) - 1; + return ""; + }elseif($len === true){ + return substr($this->buffer, $this->offset); + } + + return $len === 1 ? $this->buffer{$this->offset++} : substr($this->buffer, ($this->offset += $len) - $len, $len); + } + + public function put($v){ + $this->buffer .= $v; + } + + public function feof() : bool{ + return !isset($this->buffer{$this->offset}); + } + + public function __construct(){ + $this->offset = 0; + $this->buffer = ""; + } + + public function read($buffer, $doMultiple = false){ + $this->offset = 0; + $this->buffer = $buffer; + $this->data = $this->readTag(); + if($doMultiple and $this->offset < strlen($this->buffer)){ + $this->data = [$this->data]; + do{ + $this->data[] = $this->readTag(); + }while($this->offset < strlen($this->buffer)); + } + $this->buffer = ""; + } + + public function readCompressed($buffer){ + $this->read(zlib_decode($buffer)); + } + + /** + * @return bool|string + */ + public function write(){ + $this->offset = 0; + $this->buffer = ""; + + if($this->data instanceof CompoundTag){ + $this->writeTag($this->data); + + return $this->buffer; + }elseif(is_array($this->data)){ + foreach($this->data as $tag){ + $this->writeTag($tag); + } + return $this->buffer; + } + + return false; + } + + public function writeCompressed($compression = ZLIB_ENCODING_GZIP, $level = 7){ + if(($write = $this->write()) !== false){ + return zlib_encode($write, $compression, $level); + } + + return false; + } + + public function readTag(){ + if($this->feof()){ + return new EndTag(); + } + + $tagType = $this->getByte(); + $tag = NBT::createTag($tagType); + + if($tag instanceof NamedTag){ + $tag->setName($this->getString()); + $tag->read($this); + } + + return $tag; + } + + public function writeTag(Tag $tag){ + $this->putByte($tag->getType()); + if($tag instanceof NamedTag){ + $this->putString($tag->getName()); + } + $tag->write($this); + } + + public function getByte() : int{ + return Binary::readByte($this->get(1)); + } + + public function getSignedByte() : int{ + return Binary::readSignedByte($this->get(1)); + } + + public function putByte($v){ + $this->buffer .= Binary::writeByte($v); + } + + abstract public function getShort() : int; + + abstract public function getSignedShort() : int; + + abstract public function putShort($v); + + + abstract public function getInt() : int; + + abstract public function putInt($v); + + abstract public function getLong() : int; + + abstract public function putLong($v); + + + abstract public function getFloat() : float; + + abstract public function putFloat($v); + + + abstract public function getDouble() : float; + + abstract public function putDouble($v); + + public function getString(){ + return $this->get($this->getShort()); + } + + public function putString($v){ + $this->putShort(strlen($v)); + $this->put($v); + } + + abstract public function getIntArray() : array; + + abstract public function putIntArray(array $array) : void; + + + + public function getArray() : array{ + $data = []; + self::toArray($data, $this->data); + return $data; + } + + private static function toArray(array &$data, Tag $tag){ + /** @var CompoundTag[]|ListTag[]|IntArrayTag[] $tag */ + foreach($tag as $key => $value){ + if($value instanceof CompoundTag or $value instanceof ListTag or $value instanceof IntArrayTag){ + $data[$key] = []; + self::toArray($data[$key], $value); + }else{ + $data[$key] = $value->getValue(); + } + } + } + + public static function fromArrayGuesser($key, $value){ + if(is_int($value)){ + return new IntTag($key, $value); + }elseif(is_float($value)){ + return new FloatTag($key, $value); + }elseif(is_string($value)){ + return new StringTag($key, $value); + }elseif(is_bool($value)){ + return new ByteTag($key, $value ? 1 : 0); + } + + return null; + } + + private static function fromArray(Tag $tag, array $data, callable $guesser){ + foreach($data as $key => $value){ + if(is_array($value)){ + $isNumeric = true; + $isIntArray = true; + foreach($value as $k => $v){ + if(!is_numeric($k)){ + $isNumeric = false; + break; + }elseif(!is_int($v)){ + $isIntArray = false; + } + } + $tag{$key} = $isNumeric ? ($isIntArray ? new IntArrayTag($key, []) : new ListTag($key, [])) : new CompoundTag($key, []); + self::fromArray($tag->{$key}, $value, $guesser); + }else{ + $v = call_user_func($guesser, $key, $value); + if($v instanceof Tag){ + $tag{$key} = $v; + } + } + } + } + + public function setArray(array $data, callable $guesser = null){ + $this->data = new CompoundTag("", []); + self::fromArray($this->data, $data, $guesser ?? [self::class, "fromArrayGuesser"]); + } + + /** + * @return CompoundTag|array + */ + public function getData(){ + return $this->data; + } + + /** + * @param CompoundTag|array $data + */ + public function setData($data){ + $this->data = $data; + } +} diff --git a/src/pocketmine/nbt/NetworkLittleEndianNBTStream.php b/src/pocketmine/nbt/NetworkLittleEndianNBTStream.php new file mode 100644 index 000000000..61abc5de5 --- /dev/null +++ b/src/pocketmine/nbt/NetworkLittleEndianNBTStream.php @@ -0,0 +1,70 @@ +buffer, $this->offset); + } + + public function putInt($v){ + $this->put(Binary::writeVarInt($v)); + } + + public function getLong() : int{ + return Binary::readVarLong($this->buffer, $this->offset); + } + + public function putLong($v){ + $this->put(Binary::writeVarLong($v)); + } + + public function getString(){ + return $this->get(Binary::readUnsignedVarInt($this->buffer, $this->offset)); + } + + public function putString($v){ + $this->put(Binary::writeUnsignedVarInt(strlen($v)) . $v); + } + + public function getIntArray() : array{ + $len = $this->getInt(); //varint + $ret = []; + for($i = 0; $i < $len; ++$i){ + $ret[] = $this->getInt(); //varint + } + + return $ret; + } + + public function putIntArray(array $array) : void{ + $this->putInt(count($array)); //varint + foreach($array as $v){ + $this->putInt($v); //varint + } + } +} diff --git a/src/pocketmine/nbt/tag/ByteArrayTag.php b/src/pocketmine/nbt/tag/ByteArrayTag.php index 8d4555d33..0023958c7 100644 --- a/src/pocketmine/nbt/tag/ByteArrayTag.php +++ b/src/pocketmine/nbt/tag/ByteArrayTag.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\nbt\tag; use pocketmine\nbt\NBT; +use pocketmine\nbt\NBTStream; #include @@ -43,12 +44,12 @@ class ByteArrayTag extends NamedTag{ return NBT::TAG_ByteArray; } - public function read(NBT $nbt, bool $network = false) : void{ - $this->value = $nbt->get($nbt->getInt($network)); + public function read(NBTStream $nbt) : void{ + $this->value = $nbt->get($nbt->getInt()); } - public function write(NBT $nbt, bool $network = false) : void{ - $nbt->putInt(strlen($this->value), $network); + public function write(NBTStream $nbt) : void{ + $nbt->putInt(strlen($this->value)); $nbt->put($this->value); } diff --git a/src/pocketmine/nbt/tag/ByteTag.php b/src/pocketmine/nbt/tag/ByteTag.php index aca900764..dd93a7864 100644 --- a/src/pocketmine/nbt/tag/ByteTag.php +++ b/src/pocketmine/nbt/tag/ByteTag.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\nbt\tag; use pocketmine\nbt\NBT; +use pocketmine\nbt\NBTStream; #include @@ -43,11 +44,11 @@ class ByteTag extends NamedTag{ return NBT::TAG_Byte; } - public function read(NBT $nbt, bool $network = false) : void{ + public function read(NBTStream $nbt) : void{ $this->value = $nbt->getSignedByte(); } - public function write(NBT $nbt, bool $network = false) : void{ + public function write(NBTStream $nbt) : void{ $nbt->putByte($this->value); } diff --git a/src/pocketmine/nbt/tag/CompoundTag.php b/src/pocketmine/nbt/tag/CompoundTag.php index 1322e7472..e17f1f495 100644 --- a/src/pocketmine/nbt/tag/CompoundTag.php +++ b/src/pocketmine/nbt/tag/CompoundTag.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\nbt\tag; use pocketmine\nbt\NBT; +use pocketmine\nbt\NBTStream; #include @@ -427,23 +428,23 @@ class CompoundTag extends NamedTag implements \ArrayAccess{ return NBT::TAG_Compound; } - public function read(NBT $nbt, bool $network = false) : void{ + public function read(NBTStream $nbt) : void{ $this->value = []; do{ - $tag = $nbt->readTag($network); + $tag = $nbt->readTag(); if($tag instanceof NamedTag and $tag->__name !== ""){ $this->{$tag->__name} = $tag; } }while(!($tag instanceof EndTag) and !$nbt->feof()); } - public function write(NBT $nbt, bool $network = false) : void{ + public function write(NBTStream $nbt) : void{ foreach($this as $tag){ if($tag instanceof Tag and !($tag instanceof EndTag)){ - $nbt->writeTag($tag, $network); + $nbt->writeTag($tag); } } - $nbt->writeTag(new EndTag, $network); + $nbt->writeTag(new EndTag); } public function __toString(){ diff --git a/src/pocketmine/nbt/tag/DoubleTag.php b/src/pocketmine/nbt/tag/DoubleTag.php index bc3f1cf57..1ce8f91d5 100644 --- a/src/pocketmine/nbt/tag/DoubleTag.php +++ b/src/pocketmine/nbt/tag/DoubleTag.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\nbt\tag; use pocketmine\nbt\NBT; +use pocketmine\nbt\NBTStream; #include @@ -43,11 +44,11 @@ class DoubleTag extends NamedTag{ return NBT::TAG_Double; } - public function read(NBT $nbt, bool $network = false) : void{ + public function read(NBTStream $nbt) : void{ $this->value = $nbt->getDouble(); } - public function write(NBT $nbt, bool $network = false) : void{ + public function write(NBTStream $nbt) : void{ $nbt->putDouble($this->value); } diff --git a/src/pocketmine/nbt/tag/EndTag.php b/src/pocketmine/nbt/tag/EndTag.php index c063196d4..11d692131 100644 --- a/src/pocketmine/nbt/tag/EndTag.php +++ b/src/pocketmine/nbt/tag/EndTag.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\nbt\tag; use pocketmine\nbt\NBT; +use pocketmine\nbt\NBTStream; class EndTag extends Tag{ @@ -31,11 +32,11 @@ class EndTag extends Tag{ return NBT::TAG_End; } - public function read(NBT $nbt, bool $network = false) : void{ + public function read(NBTStream $nbt) : void{ } - public function write(NBT $nbt, bool $network = false) : void{ + public function write(NBTStream $nbt) : void{ } } diff --git a/src/pocketmine/nbt/tag/FloatTag.php b/src/pocketmine/nbt/tag/FloatTag.php index 4855bd916..41424f7fe 100644 --- a/src/pocketmine/nbt/tag/FloatTag.php +++ b/src/pocketmine/nbt/tag/FloatTag.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\nbt\tag; use pocketmine\nbt\NBT; +use pocketmine\nbt\NBTStream; #include @@ -43,11 +44,11 @@ class FloatTag extends NamedTag{ return NBT::TAG_Float; } - public function read(NBT $nbt, bool $network = false) : void{ + public function read(NBTStream $nbt) : void{ $this->value = $nbt->getFloat(); } - public function write(NBT $nbt, bool $network = false) : void{ + public function write(NBTStream $nbt) : void{ $nbt->putFloat($this->value); } diff --git a/src/pocketmine/nbt/tag/IntArrayTag.php b/src/pocketmine/nbt/tag/IntArrayTag.php index bb1c9e8ea..30c61d4f9 100644 --- a/src/pocketmine/nbt/tag/IntArrayTag.php +++ b/src/pocketmine/nbt/tag/IntArrayTag.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\nbt\tag; use pocketmine\nbt\NBT; +use pocketmine\nbt\NBTStream; #include @@ -43,14 +44,12 @@ class IntArrayTag extends NamedTag{ return NBT::TAG_IntArray; } - public function read(NBT $nbt, bool $network = false) : void{ - $size = $nbt->getInt($network); - $this->value = array_values(unpack($nbt->endianness === NBT::LITTLE_ENDIAN ? "V*" : "N*", $nbt->get($size * 4))); + public function read(NBTStream $nbt) : void{ + $this->value = $nbt->getIntArray(); } - public function write(NBT $nbt, bool $network = false) : void{ - $nbt->putInt(count($this->value), $network); - $nbt->put(pack($nbt->endianness === NBT::LITTLE_ENDIAN ? "V*" : "N*", ...$this->value)); + public function write(NBTStream $nbt) : void{ + $nbt->putIntArray($this->value); } public function __toString(){ diff --git a/src/pocketmine/nbt/tag/IntTag.php b/src/pocketmine/nbt/tag/IntTag.php index 093cd9342..ed38d756a 100644 --- a/src/pocketmine/nbt/tag/IntTag.php +++ b/src/pocketmine/nbt/tag/IntTag.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\nbt\tag; use pocketmine\nbt\NBT; +use pocketmine\nbt\NBTStream; #include @@ -41,12 +42,12 @@ class IntTag extends NamedTag{ return NBT::TAG_Int; } - public function read(NBT $nbt, bool $network = false) : void{ - $this->value = $nbt->getInt($network); + public function read(NBTStream $nbt) : void{ + $this->value = $nbt->getInt(); } - public function write(NBT $nbt, bool $network = false) : void{ - $nbt->putInt($this->value, $network); + public function write(NBTStream $nbt) : void{ + $nbt->putInt($this->value); } /** diff --git a/src/pocketmine/nbt/tag/ListTag.php b/src/pocketmine/nbt/tag/ListTag.php index 6b3db2636..b7f723c88 100644 --- a/src/pocketmine/nbt/tag/ListTag.php +++ b/src/pocketmine/nbt/tag/ListTag.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\nbt\tag; use pocketmine\nbt\NBT; +use pocketmine\nbt\NBTStream; #include @@ -163,20 +164,20 @@ class ListTag extends NamedTag implements \ArrayAccess, \Countable{ return $this->tagType; } - public function read(NBT $nbt, bool $network = false) : void{ + public function read(NBTStream $nbt) : void{ $this->value = []; $this->tagType = $nbt->getByte(); - $size = $nbt->getInt($network); + $size = $nbt->getInt(); $tagBase = NBT::createTag($this->tagType); for($i = 0; $i < $size and !$nbt->feof(); ++$i){ $tag = clone $tagBase; - $tag->read($nbt, $network); + $tag->read($nbt); $this->{$i} = $tag; } } - public function write(NBT $nbt, bool $network = false) : void{ + public function write(NBTStream $nbt) : void{ if($this->tagType === NBT::TAG_End){ //previously empty list, try detecting type from tag children $id = NBT::TAG_End; foreach($this as $tag){ @@ -200,9 +201,9 @@ class ListTag extends NamedTag implements \ArrayAccess, \Countable{ $tags[] = $tag; } } - $nbt->putInt(count($tags), $network); + $nbt->putInt(count($tags)); foreach($tags as $tag){ - $tag->write($nbt, $network); + $tag->write($nbt); } } diff --git a/src/pocketmine/nbt/tag/LongTag.php b/src/pocketmine/nbt/tag/LongTag.php index 5fe001327..e435afefc 100644 --- a/src/pocketmine/nbt/tag/LongTag.php +++ b/src/pocketmine/nbt/tag/LongTag.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\nbt\tag; use pocketmine\nbt\NBT; +use pocketmine\nbt\NBTStream; #include @@ -43,12 +44,12 @@ class LongTag extends NamedTag{ return NBT::TAG_Long; } - public function read(NBT $nbt, bool $network = false) : void{ - $this->value = $nbt->getLong($network); + public function read(NBTStream $nbt) : void{ + $this->value = $nbt->getLong(); } - public function write(NBT $nbt, bool $network = false) : void{ - $nbt->putLong($this->value, $network); + public function write(NBTStream $nbt) : void{ + $nbt->putLong($this->value); } /** diff --git a/src/pocketmine/nbt/tag/ShortTag.php b/src/pocketmine/nbt/tag/ShortTag.php index f3b5b5705..6eabeb222 100644 --- a/src/pocketmine/nbt/tag/ShortTag.php +++ b/src/pocketmine/nbt/tag/ShortTag.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\nbt\tag; use pocketmine\nbt\NBT; +use pocketmine\nbt\NBTStream; #include @@ -43,11 +44,11 @@ class ShortTag extends NamedTag{ return NBT::TAG_Short; } - public function read(NBT $nbt, bool $network = false) : void{ + public function read(NBTStream $nbt) : void{ $this->value = $nbt->getSignedShort(); } - public function write(NBT $nbt, bool $network = false) : void{ + public function write(NBTStream $nbt) : void{ $nbt->putShort($this->value); } diff --git a/src/pocketmine/nbt/tag/StringTag.php b/src/pocketmine/nbt/tag/StringTag.php index f0ad886b8..53deb5d87 100644 --- a/src/pocketmine/nbt/tag/StringTag.php +++ b/src/pocketmine/nbt/tag/StringTag.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace pocketmine\nbt\tag; use pocketmine\nbt\NBT; +use pocketmine\nbt\NBTStream; #include @@ -43,12 +44,12 @@ class StringTag extends NamedTag{ return NBT::TAG_String; } - public function read(NBT $nbt, bool $network = false) : void{ - $this->value = $nbt->getString($network); + public function read(NBTStream $nbt) : void{ + $this->value = $nbt->getString(); } - public function write(NBT $nbt, bool $network = false) : void{ - $nbt->putString($this->value, $network); + public function write(NBTStream $nbt) : void{ + $nbt->putString($this->value); } /** diff --git a/src/pocketmine/nbt/tag/Tag.php b/src/pocketmine/nbt/tag/Tag.php index 74e4d7b78..f4233378e 100644 --- a/src/pocketmine/nbt/tag/Tag.php +++ b/src/pocketmine/nbt/tag/Tag.php @@ -26,7 +26,7 @@ declare(strict_types=1); */ namespace pocketmine\nbt\tag; -use pocketmine\nbt\NBT; +use pocketmine\nbt\NBTStream; abstract class Tag extends \stdClass{ @@ -42,9 +42,9 @@ abstract class Tag extends \stdClass{ $this->value = $value; } - abstract public function write(NBT $nbt, bool $network = false) : void; + abstract public function write(NBTStream $nbt) : void; - abstract public function read(NBT $nbt, bool $network = false) : void; + abstract public function read(NBTStream $nbt) : void; public function __toString(){ return (string) $this->value; diff --git a/src/pocketmine/tile/Spawnable.php b/src/pocketmine/tile/Spawnable.php index 598f6211c..427512577 100644 --- a/src/pocketmine/tile/Spawnable.php +++ b/src/pocketmine/tile/Spawnable.php @@ -25,6 +25,7 @@ namespace pocketmine\tile; use pocketmine\level\Level; use pocketmine\nbt\NBT; +use pocketmine\nbt\NetworkLittleEndianNBTStream; use pocketmine\nbt\tag\CompoundTag; use pocketmine\network\mcpe\protocol\BlockEntityDataPacket; use pocketmine\Player; @@ -92,11 +93,11 @@ abstract class Spawnable extends Tile{ final public function getSerializedSpawnCompound() : string{ if($this->spawnCompoundCache === null){ if(self::$nbtWriter === null){ - self::$nbtWriter = new NBT(NBT::LITTLE_ENDIAN); + self::$nbtWriter = new NetworkLittleEndianNBTStream(); } self::$nbtWriter->setData($this->getSpawnCompound()); - $this->spawnCompoundCache = self::$nbtWriter->write(true); + $this->spawnCompoundCache = self::$nbtWriter->write(); } return $this->spawnCompoundCache; From a67f7e3930241746d75aac8514e8ee7fbfcca68e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 30 Dec 2017 13:36:20 +0000 Subject: [PATCH 2/3] Add header includes and preprocessor checks --- src/pocketmine/nbt/BigEndianNBTStream.php | 4 ++++ src/pocketmine/nbt/LittleEndianNBTStream.php | 4 ++++ src/pocketmine/nbt/NBTStream.php | 4 ++++ src/pocketmine/nbt/NetworkLittleEndianNBTStream.php | 4 ++++ tests/preprocessor | 2 +- 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/pocketmine/nbt/BigEndianNBTStream.php b/src/pocketmine/nbt/BigEndianNBTStream.php index 9c70eb27a..fd12fd459 100644 --- a/src/pocketmine/nbt/BigEndianNBTStream.php +++ b/src/pocketmine/nbt/BigEndianNBTStream.php @@ -23,7 +23,11 @@ declare(strict_types=1); namespace pocketmine\nbt; +#ifndef COMPILE use pocketmine\utils\Binary; +#endif + +#include class BigEndianNBTStream extends NBTStream{ diff --git a/src/pocketmine/nbt/LittleEndianNBTStream.php b/src/pocketmine/nbt/LittleEndianNBTStream.php index fe1a6ea30..fd89fd5ae 100644 --- a/src/pocketmine/nbt/LittleEndianNBTStream.php +++ b/src/pocketmine/nbt/LittleEndianNBTStream.php @@ -23,7 +23,11 @@ declare(strict_types=1); namespace pocketmine\nbt; +#ifndef COMPILE use pocketmine\utils\Binary; +#endif + +#include class LittleEndianNBTStream extends NBTStream{ diff --git a/src/pocketmine/nbt/NBTStream.php b/src/pocketmine/nbt/NBTStream.php index 0ffaad878..358ca88e0 100644 --- a/src/pocketmine/nbt/NBTStream.php +++ b/src/pocketmine/nbt/NBTStream.php @@ -33,7 +33,11 @@ use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\NamedTag; use pocketmine\nbt\tag\StringTag; use pocketmine\nbt\tag\Tag; +#ifndef COMPILE use pocketmine\utils\Binary; +#endif + +#include /** * Base Named Binary Tag encoder/decoder diff --git a/src/pocketmine/nbt/NetworkLittleEndianNBTStream.php b/src/pocketmine/nbt/NetworkLittleEndianNBTStream.php index 61abc5de5..dff11c537 100644 --- a/src/pocketmine/nbt/NetworkLittleEndianNBTStream.php +++ b/src/pocketmine/nbt/NetworkLittleEndianNBTStream.php @@ -23,7 +23,11 @@ declare(strict_types=1); namespace pocketmine\nbt; +#ifndef COMPILE use pocketmine\utils\Binary; +#endif + +#include class NetworkLittleEndianNBTStream extends LittleEndianNBTStream{ diff --git a/tests/preprocessor b/tests/preprocessor index 86961f819..316fd5606 160000 --- a/tests/preprocessor +++ b/tests/preprocessor @@ -1 +1 @@ -Subproject commit 86961f81970a49f8c25e18d0d414961d7142a84d +Subproject commit 316fd5606fef1191e7f228d3156dd1518c33aba4 From be02fbb352461d405cb3c0ad877892a16237ba85 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sat, 30 Dec 2017 15:07:50 +0000 Subject: [PATCH 3/3] NBT: Add typehints to PHP 7.2 standards --- src/pocketmine/nbt/BigEndianNBTStream.php | 10 ++--- src/pocketmine/nbt/LittleEndianNBTStream.php | 10 ++--- src/pocketmine/nbt/NBT.php | 2 +- src/pocketmine/nbt/NBTStream.php | 40 +++++++++---------- .../nbt/NetworkLittleEndianNBTStream.php | 8 ++-- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/pocketmine/nbt/BigEndianNBTStream.php b/src/pocketmine/nbt/BigEndianNBTStream.php index fd12fd459..d86d850d8 100644 --- a/src/pocketmine/nbt/BigEndianNBTStream.php +++ b/src/pocketmine/nbt/BigEndianNBTStream.php @@ -39,7 +39,7 @@ class BigEndianNBTStream extends NBTStream{ return Binary::readSignedShort($this->get(2)); } - public function putShort($v){ + public function putShort(int $v) : void{ $this->buffer .= Binary::writeShort($v); } @@ -47,7 +47,7 @@ class BigEndianNBTStream extends NBTStream{ return Binary::readInt($this->get(4)); } - public function putInt($v){ + public function putInt(int $v) : void{ $this->buffer .= Binary::writeInt($v); } @@ -55,7 +55,7 @@ class BigEndianNBTStream extends NBTStream{ return Binary::readLong($this->get(8)); } - public function putLong($v){ + public function putLong(int $v) : void{ $this->buffer .= Binary::writeLong($v); } @@ -63,7 +63,7 @@ class BigEndianNBTStream extends NBTStream{ return Binary::readFloat($this->get(4)); } - public function putFloat($v){ + public function putFloat(float $v) : void{ $this->buffer .= Binary::writeFloat($v); } @@ -71,7 +71,7 @@ class BigEndianNBTStream extends NBTStream{ return Binary::readDouble($this->get(8)); } - public function putDouble($v){ + public function putDouble(float $v) : void{ $this->buffer .= Binary::writeDouble($v); } diff --git a/src/pocketmine/nbt/LittleEndianNBTStream.php b/src/pocketmine/nbt/LittleEndianNBTStream.php index fd89fd5ae..c51c85ce1 100644 --- a/src/pocketmine/nbt/LittleEndianNBTStream.php +++ b/src/pocketmine/nbt/LittleEndianNBTStream.php @@ -39,7 +39,7 @@ class LittleEndianNBTStream extends NBTStream{ return Binary::readSignedLShort($this->get(2)); } - public function putShort($v){ + public function putShort(int $v) : void{ $this->put(Binary::writeLShort($v)); } @@ -47,7 +47,7 @@ class LittleEndianNBTStream extends NBTStream{ return Binary::readLInt($this->get(4)); } - public function putInt($v){ + public function putInt(int $v) : void{ $this->put(Binary::writeLInt($v)); } @@ -55,7 +55,7 @@ class LittleEndianNBTStream extends NBTStream{ return Binary::readLLong($this->get(8)); } - public function putLong($v){ + public function putLong(int $v) : void{ $this->put(Binary::writeLLong($v)); } @@ -63,7 +63,7 @@ class LittleEndianNBTStream extends NBTStream{ return Binary::readLFloat($this->get(4)); } - public function putFloat($v){ + public function putFloat(float $v) : void{ $this->put(Binary::writeLFloat($v)); } @@ -71,7 +71,7 @@ class LittleEndianNBTStream extends NBTStream{ return Binary::readLDouble($this->get(8)); } - public function putDouble($v){ + public function putDouble(float $v) : void{ $this->put(Binary::writeLDouble($v)); } diff --git a/src/pocketmine/nbt/NBT.php b/src/pocketmine/nbt/NBT.php index 8675be59a..3827884e6 100644 --- a/src/pocketmine/nbt/NBT.php +++ b/src/pocketmine/nbt/NBT.php @@ -62,7 +62,7 @@ abstract class NBT{ * * @return Tag */ - public static function createTag(int $type){ + public static function createTag(int $type) : Tag{ switch($type){ case self::TAG_End: return new EndTag(); diff --git a/src/pocketmine/nbt/NBTStream.php b/src/pocketmine/nbt/NBTStream.php index 358ca88e0..8531fb34e 100644 --- a/src/pocketmine/nbt/NBTStream.php +++ b/src/pocketmine/nbt/NBTStream.php @@ -48,7 +48,7 @@ abstract class NBTStream{ public $offset; private $data; - public function get($len){ + public function get($len) : string{ if($len < 0){ $this->offset = strlen($this->buffer) - 1; return ""; @@ -59,7 +59,7 @@ abstract class NBTStream{ return $len === 1 ? $this->buffer{$this->offset++} : substr($this->buffer, ($this->offset += $len) - $len, $len); } - public function put($v){ + public function put(string $v) : void{ $this->buffer .= $v; } @@ -72,7 +72,7 @@ abstract class NBTStream{ $this->buffer = ""; } - public function read($buffer, $doMultiple = false){ + public function read(string $buffer, bool $doMultiple = false) : void{ $this->offset = 0; $this->buffer = $buffer; $this->data = $this->readTag(); @@ -85,7 +85,7 @@ abstract class NBTStream{ $this->buffer = ""; } - public function readCompressed($buffer){ + public function readCompressed(string $buffer) : void{ $this->read(zlib_decode($buffer)); } @@ -110,7 +110,7 @@ abstract class NBTStream{ return false; } - public function writeCompressed($compression = ZLIB_ENCODING_GZIP, $level = 7){ + public function writeCompressed(int $compression = ZLIB_ENCODING_GZIP, int $level = 7){ if(($write = $this->write()) !== false){ return zlib_encode($write, $compression, $level); } @@ -118,7 +118,7 @@ abstract class NBTStream{ return false; } - public function readTag(){ + public function readTag() : Tag{ if($this->feof()){ return new EndTag(); } @@ -134,7 +134,7 @@ abstract class NBTStream{ return $tag; } - public function writeTag(Tag $tag){ + public function writeTag(Tag $tag) : void{ $this->putByte($tag->getType()); if($tag instanceof NamedTag){ $this->putString($tag->getName()); @@ -150,7 +150,7 @@ abstract class NBTStream{ return Binary::readSignedByte($this->get(1)); } - public function putByte($v){ + public function putByte(int $v) : void{ $this->buffer .= Binary::writeByte($v); } @@ -158,32 +158,32 @@ abstract class NBTStream{ abstract public function getSignedShort() : int; - abstract public function putShort($v); + abstract public function putShort(int $v) : void; abstract public function getInt() : int; - abstract public function putInt($v); + abstract public function putInt(int $v) : void; abstract public function getLong() : int; - abstract public function putLong($v); + abstract public function putLong(int $v) : void; abstract public function getFloat() : float; - abstract public function putFloat($v); + abstract public function putFloat(float $v) : void; abstract public function getDouble() : float; - abstract public function putDouble($v); + abstract public function putDouble(float $v) : void; - public function getString(){ + public function getString() : string{ return $this->get($this->getShort()); } - public function putString($v){ + public function putString(string $v) : void{ $this->putShort(strlen($v)); $this->put($v); } @@ -200,7 +200,7 @@ abstract class NBTStream{ return $data; } - private static function toArray(array &$data, Tag $tag){ + private static function toArray(array &$data, Tag $tag) : void{ /** @var CompoundTag[]|ListTag[]|IntArrayTag[] $tag */ foreach($tag as $key => $value){ if($value instanceof CompoundTag or $value instanceof ListTag or $value instanceof IntArrayTag){ @@ -212,7 +212,7 @@ abstract class NBTStream{ } } - public static function fromArrayGuesser($key, $value){ + public static function fromArrayGuesser(string $key, $value) : ?NamedTag{ if(is_int($value)){ return new IntTag($key, $value); }elseif(is_float($value)){ @@ -226,7 +226,7 @@ abstract class NBTStream{ return null; } - private static function fromArray(Tag $tag, array $data, callable $guesser){ + private static function fromArray(Tag $tag, array $data, callable $guesser) : void{ foreach($data as $key => $value){ if(is_array($value)){ $isNumeric = true; @@ -250,7 +250,7 @@ abstract class NBTStream{ } } - public function setArray(array $data, callable $guesser = null){ + public function setArray(array $data, callable $guesser = null) : void{ $this->data = new CompoundTag("", []); self::fromArray($this->data, $data, $guesser ?? [self::class, "fromArrayGuesser"]); } @@ -265,7 +265,7 @@ abstract class NBTStream{ /** * @param CompoundTag|array $data */ - public function setData($data){ + public function setData($data) : void{ $this->data = $data; } } diff --git a/src/pocketmine/nbt/NetworkLittleEndianNBTStream.php b/src/pocketmine/nbt/NetworkLittleEndianNBTStream.php index dff11c537..4bb583783 100644 --- a/src/pocketmine/nbt/NetworkLittleEndianNBTStream.php +++ b/src/pocketmine/nbt/NetworkLittleEndianNBTStream.php @@ -35,7 +35,7 @@ class NetworkLittleEndianNBTStream extends LittleEndianNBTStream{ return Binary::readVarInt($this->buffer, $this->offset); } - public function putInt($v){ + public function putInt(int $v) : void{ $this->put(Binary::writeVarInt($v)); } @@ -43,15 +43,15 @@ class NetworkLittleEndianNBTStream extends LittleEndianNBTStream{ return Binary::readVarLong($this->buffer, $this->offset); } - public function putLong($v){ + public function putLong(int $v) : void{ $this->put(Binary::writeVarLong($v)); } - public function getString(){ + public function getString() : string{ return $this->get(Binary::readUnsignedVarInt($this->buffer, $this->offset)); } - public function putString($v){ + public function putString(string $v) : void{ $this->put(Binary::writeUnsignedVarInt(strlen($v)) . $v); }