From f3c38700f57ed5b72ee9e2e0983f6dc19f55c708 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Sun, 14 May 2017 20:48:58 +0100 Subject: [PATCH 1/6] Removed options for disabling assertion exceptions --- src/pocketmine/Server.php | 2 +- src/pocketmine/resources/pocketmine.yml | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 4af97a252..da78efb94 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1506,7 +1506,7 @@ class Server{ $this->logger->warning("Debugging assertions are enabled, this may impact on performance. To disable them, set `zend.assertions = -1` in php.ini."); } - ini_set('assert.exception', (bool) $this->getProperty("debug.assertions.throw-exception", 0)); + ini_set('assert.exception', '1'); if($this->logger instanceof MainLogger){ $this->logger->setLogDebug(\pocketmine\DEBUG > 1); diff --git a/src/pocketmine/resources/pocketmine.yml b/src/pocketmine/resources/pocketmine.yml index 8efe10809..5fa080618 100644 --- a/src/pocketmine/resources/pocketmine.yml +++ b/src/pocketmine/resources/pocketmine.yml @@ -88,9 +88,6 @@ debug: assertions: #Warn if assertions are enabled in php.ini, due to assertions may impact on runtime performance if enabled. warn-if-enabled: true - #Enable throwing exceptions when assertions fail, will allow obtaining more detailed information on the failed assertion, but may cause a server crash. - #If set to false, a warning will be raised instead of throwing an exception. - throw-exception: false #If > 1, it will show debug messages in the console level: 1 #Enables /status, /gc From f6c0ba9846426cedf2ab219f8adc3b95a3637667 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 May 2017 18:30:32 +0100 Subject: [PATCH 2/6] Cleaned up some duplicated code in NBT parser --- src/pocketmine/nbt/NBT.php | 187 +++++++++-------------------- src/pocketmine/nbt/tag/ListTag.php | 62 +--------- 2 files changed, 59 insertions(+), 190 deletions(-) diff --git a/src/pocketmine/nbt/NBT.php b/src/pocketmine/nbt/NBT.php index f929f58e3..a3cd0df12 100644 --- a/src/pocketmine/nbt/NBT.php +++ b/src/pocketmine/nbt/NBT.php @@ -71,6 +71,42 @@ class NBT{ public $endianness; private $data; + /** + * @param int $type + * + * @return Tag + */ + public static function createTag(int $type){ + switch($type){ + case self::TAG_End: + return new EndTag(); + case self::TAG_Byte: + return new ByteTag(); + case self::TAG_Short: + return new ShortTag(); + case self::TAG_Int: + return new IntTag(); + case self::TAG_Long: + return new LongTag(); + case self::TAG_Float: + return new FloatTag(); + case self::TAG_Double: + return new DoubleTag(); + case self::TAG_ByteArray: + return new ByteArrayTag(); + case self::TAG_String: + return new StringTag(); + case self::TAG_List: + return new ListTag(); + case self::TAG_Compound: + return new CompoundTag(); + case self::TAG_IntArray: + return new IntArrayTag(); + default: + throw new \InvalidArgumentException("Unknown NBT tag type $type"); + } + } + public static function matchList(ListTag $tag1, ListTag $tag2){ if($tag1->getName() !== $tag2->getName() or $tag1->getCount() !== $tag2->getCount()){ return false; @@ -170,40 +206,11 @@ class NBT{ $value = self::readValue($str, $offset, $type); - switch($type){ - case NBT::TAG_Byte: - $data[$key] = new ByteTag($key, $value); - break; - case NBT::TAG_Short: - $data[$key] = new ShortTag($key, $value); - break; - case NBT::TAG_Int: - $data[$key] = new IntTag($key, $value); - break; - case NBT::TAG_Long: - $data[$key] = new LongTag($key, $value); - break; - case NBT::TAG_Float: - $data[$key] = new FloatTag($key, $value); - break; - case NBT::TAG_Double: - $data[$key] = new DoubleTag($key, $value); - break; - case NBT::TAG_ByteArray: - $data[$key] = new ByteArrayTag($key, $value); - break; - case NBT::TAG_String: - $data[$key] = new StringTag($key, $value); - break; - case NBT::TAG_List: - $data[$key] = new ListTag($key, $value); - break; - case NBT::TAG_Compound: - $data[$key] = new CompoundTag($key, $value); - break; - case NBT::TAG_IntArray: - $data[$key] = new IntArrayTag($key, $value); - break; + $tag = self::createTag($type); + if($tag instanceof NamedTag){ + $tag->setName($key); + $tag->setValue($value); + $data[$key] = $tag; } $key++; @@ -228,40 +235,11 @@ class NBT{ $key = self::readKey($str, $offset); $value = self::readValue($str, $offset, $type); - switch($type){ - case NBT::TAG_Byte: - $data[$key] = new ByteTag($key, $value); - break; - case NBT::TAG_Short: - $data[$key] = new ShortTag($key, $value); - break; - case NBT::TAG_Int: - $data[$key] = new IntTag($key, $value); - break; - case NBT::TAG_Long: - $data[$key] = new LongTag($key, $value); - break; - case NBT::TAG_Float: - $data[$key] = new FloatTag($key, $value); - break; - case NBT::TAG_Double: - $data[$key] = new DoubleTag($key, $value); - break; - case NBT::TAG_ByteArray: - $data[$key] = new ByteArrayTag($key, $value); - break; - case NBT::TAG_String: - $data[$key] = new StringTag($key, $value); - break; - case NBT::TAG_List: - $data[$key] = new ListTag($key, $value); - break; - case NBT::TAG_Compound: - $data[$key] = new CompoundTag($key, $value); - break; - case NBT::TAG_IntArray: - $data[$key] = new IntArrayTag($key, $value); - break; + $tag = self::createTag($type); + if($tag instanceof NamedTag){ + $tag->setName($key); + $tag->setValue($value); + $data[$key] = $tag; } } @@ -427,11 +405,6 @@ class NBT{ $this->read(zlib_decode($buffer)); } - public function readNetworkCompressed($buffer){ - $this->read(zlib_decode($buffer), false, true); - } - - /** * @param bool $network * @@ -463,71 +436,19 @@ class NBT{ return false; } - public function writeNetworkCompressed($compression = ZLIB_ENCODING_GZIP, $level = 7){ - if(($write = $this->write(true)) !== false){ - return zlib_encode($write, $compression, $level); - } - - return false; - } - public function readTag(bool $network = false){ if($this->feof()){ - $tagType = -1; //prevent crashes for empty tags - }else{ - $tagType = $this->getByte(); + return new EndTag(); } - switch($tagType){ - case NBT::TAG_Byte: - $tag = new ByteTag($this->getString($network)); - $tag->read($this, $network); - break; - case NBT::TAG_Short: - $tag = new ShortTag($this->getString($network)); - $tag->read($this, $network); - break; - case NBT::TAG_Int: - $tag = new IntTag($this->getString($network)); - $tag->read($this, $network); - break; - case NBT::TAG_Long: - $tag = new LongTag($this->getString($network)); - $tag->read($this, $network); - break; - case NBT::TAG_Float: - $tag = new FloatTag($this->getString($network)); - $tag->read($this, $network); - break; - case NBT::TAG_Double: - $tag = new DoubleTag($this->getString($network)); - $tag->read($this, $network); - break; - case NBT::TAG_ByteArray: - $tag = new ByteArrayTag($this->getString($network)); - $tag->read($this, $network); - break; - case NBT::TAG_String: - $tag = new StringTag($this->getString($network)); - $tag->read($this, $network); - break; - case NBT::TAG_List: - $tag = new ListTag($this->getString($network)); - $tag->read($this, $network); - break; - case NBT::TAG_Compound: - $tag = new CompoundTag($this->getString($network)); - $tag->read($this, $network); - break; - case NBT::TAG_IntArray: - $tag = new IntArrayTag($this->getString($network)); - $tag->read($this, $network); - break; - case NBT::TAG_End: //No named tag - default: - $tag = new EndTag; - break; + $tagType = $this->getByte(); + $tag = self::createTag($tagType); + + if($tag instanceof NamedTag){ + $tag->setName($this->getString($network)); + $tag->read($this, $network); } + return $tag; } diff --git a/src/pocketmine/nbt/tag/ListTag.php b/src/pocketmine/nbt/tag/ListTag.php index 361db14d6..821744c61 100644 --- a/src/pocketmine/nbt/tag/ListTag.php +++ b/src/pocketmine/nbt/tag/ListTag.php @@ -118,64 +118,12 @@ class ListTag extends NamedTag implements \ArrayAccess, \Countable{ $this->value = []; $this->tagType = $nbt->getByte(); $size = $nbt->getInt($network); + + $tagBase = NBT::createTag($this->tagType); for($i = 0; $i < $size and !$nbt->feof(); ++$i){ - switch($this->tagType){ - case NBT::TAG_Byte: - $tag = new ByteTag(""); - $tag->read($nbt, $network); - $this->{$i} = $tag; - break; - case NBT::TAG_Short: - $tag = new ShortTag(""); - $tag->read($nbt, $network); - $this->{$i} = $tag; - break; - case NBT::TAG_Int: - $tag = new IntTag(""); - $tag->read($nbt, $network); - $this->{$i} = $tag; - break; - case NBT::TAG_Long: - $tag = new LongTag(""); - $tag->read($nbt, $network); - $this->{$i} = $tag; - break; - case NBT::TAG_Float: - $tag = new FloatTag(""); - $tag->read($nbt, $network); - $this->{$i} = $tag; - break; - case NBT::TAG_Double: - $tag = new DoubleTag(""); - $tag->read($nbt, $network); - $this->{$i} = $tag; - break; - case NBT::TAG_ByteArray: - $tag = new ByteArrayTag(""); - $tag->read($nbt, $network); - $this->{$i} = $tag; - break; - case NBT::TAG_String: - $tag = new StringTag(""); - $tag->read($nbt, $network); - $this->{$i} = $tag; - break; - case NBT::TAG_List: - $tag = new TagEnum(""); - $tag->read($nbt, $network); - $this->{$i} = $tag; - break; - case NBT::TAG_Compound: - $tag = new CompoundTag(""); - $tag->read($nbt, $network); - $this->{$i} = $tag; - break; - case NBT::TAG_IntArray: - $tag = new IntArrayTag(""); - $tag->read($nbt, $network); - $this->{$i} = $tag; - break; - } + $tag = clone $tagBase; + $tag->read($nbt, $network); + $this->{$i} = $tag; } } From d4cc7d13cd33568c881ab7bca18f2267cbde5542 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 May 2017 19:11:36 +0100 Subject: [PATCH 3/6] Fixed setValue() being useless for CompoundTags and ListTags --- src/pocketmine/nbt/tag/CompoundTag.php | 10 ++++++++++ src/pocketmine/nbt/tag/ListTag.php | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/pocketmine/nbt/tag/CompoundTag.php b/src/pocketmine/nbt/tag/CompoundTag.php index 45ab5bf6d..0448f0580 100644 --- a/src/pocketmine/nbt/tag/CompoundTag.php +++ b/src/pocketmine/nbt/tag/CompoundTag.php @@ -49,6 +49,16 @@ class CompoundTag extends NamedTag implements \ArrayAccess{ return $count; } + public function setValue($value){ + if(is_array($value)){ + foreach($value as $name => $tag){ + if($tag instanceof NamedTag){ + $this->{$name} = $tag; + } + } + } + } + public function offsetExists($offset){ return isset($this->{$offset}) and $this->{$offset} instanceof Tag; } diff --git a/src/pocketmine/nbt/tag/ListTag.php b/src/pocketmine/nbt/tag/ListTag.php index 821744c61..6c8e70a68 100644 --- a/src/pocketmine/nbt/tag/ListTag.php +++ b/src/pocketmine/nbt/tag/ListTag.php @@ -48,6 +48,16 @@ class ListTag extends NamedTag implements \ArrayAccess, \Countable{ return $value; } + public function setValue($value){ + if(is_array($value)){ + foreach($value as $name => $tag){ + if($tag instanceof NamedTag){ + $this->{$name} = $tag; + } + } + } + } + public function getCount(){ $count = 0; foreach($this as $tag){ From 2e480b5ea1ee8d0959efc7818bc24a531d04cb2a Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 May 2017 19:15:08 +0100 Subject: [PATCH 4/6] Fixed broken logic for recursive counts of ListTag --- src/pocketmine/nbt/tag/ListTag.php | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/pocketmine/nbt/tag/ListTag.php b/src/pocketmine/nbt/tag/ListTag.php index 6c8e70a68..e02835611 100644 --- a/src/pocketmine/nbt/tag/ListTag.php +++ b/src/pocketmine/nbt/tag/ListTag.php @@ -98,18 +98,16 @@ class ListTag extends NamedTag implements \ArrayAccess, \Countable{ } public function count($mode = COUNT_NORMAL){ - for($i = 0; true; $i++){ - if(!isset($this->{$i})){ - return $i; - } - if($mode === COUNT_RECURSIVE){ - if($this->{$i} instanceof \Countable){ - $i += count($this->{$i}); - } + $count = 0; + for($i = 0; isset($this->{$i}); $i++){ + if($mode === COUNT_RECURSIVE and $this->{$i} instanceof \Countable){ + $count += count($this->{$i}); + }else{ + $count++; } } - return $i; + return $count; } public function getType(){ From afd90adb1ccbbf7b43e35098e45816a75b466c00 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 May 2017 20:02:43 +0100 Subject: [PATCH 5/6] Refactored JSON-parsing NBT utilities into their own class --- .../command/defaults/GiveCommand.php | 4 +- src/pocketmine/nbt/JsonNBTParser.php | 259 ++++++++++++++++++ src/pocketmine/nbt/NBT.php | 193 ------------- 3 files changed, 261 insertions(+), 195 deletions(-) create mode 100644 src/pocketmine/nbt/JsonNBTParser.php diff --git a/src/pocketmine/command/defaults/GiveCommand.php b/src/pocketmine/command/defaults/GiveCommand.php index f26f8b688..a8bcb84e2 100644 --- a/src/pocketmine/command/defaults/GiveCommand.php +++ b/src/pocketmine/command/defaults/GiveCommand.php @@ -25,7 +25,7 @@ use pocketmine\command\Command; use pocketmine\command\CommandSender; use pocketmine\event\TranslationContainer; use pocketmine\item\Item; -use pocketmine\nbt\NBT; +use pocketmine\nbt\JsonNBTParser; use pocketmine\nbt\tag\CompoundTag; use pocketmine\Player; use pocketmine\utils\TextFormat; @@ -65,7 +65,7 @@ class GiveCommand extends VanillaCommand{ $tags = $exception = null; $data = implode(" ", array_slice($args, 3)); try{ - $tags = NBT::parseJSON($data); + $tags = JsonNBTParser::parseJSON($data); }catch(\Throwable $ex){ $exception = $ex; } diff --git a/src/pocketmine/nbt/JsonNBTParser.php b/src/pocketmine/nbt/JsonNBTParser.php new file mode 100644 index 000000000..f8c8d6a2b --- /dev/null +++ b/src/pocketmine/nbt/JsonNBTParser.php @@ -0,0 +1,259 @@ +setName($key); + $tag->setValue($value); + $data[$key] = $tag; + } + + $key++; + } + + return $data; + } + + /** + * @param string $str + * @param int $offset + * + * @return NamedTag[] + */ + private static function parseCompound(string $str, int &$offset = 0) : array{ + $len = strlen($str); + + $data = []; + + for(; $offset < $len; ++$offset){ + if($str{$offset - 1} === "}"){ + break; + }elseif($str{$offset} === "}"){ + ++$offset; + break; + } + + $key = self::readKey($str, $offset); + $value = self::readValue($str, $offset, $type); + + $tag = NBT::createTag($type); + if($tag instanceof NamedTag){ + $tag->setName($key); + $tag->setValue($value); + $data[$key] = $tag; + } + } + + return $data; + } + + /** + * @param string $data + * @param int $offset + * @param int|null $type + * + * @return mixed + * @throws \Exception + */ + private static function readValue(string $data, int &$offset, &$type = null){ + $value = ""; + $type = null; + $inQuotes = false; + + $len = strlen($data); + for(; $offset < $len; ++$offset){ + $c = $data{$offset}; + + if(!$inQuotes and ($c === " " or $c === "\r" or $c === "\n" or $c === "\t" or $c === "," or $c === "}" or $c === "]")){ + if($c === "," or $c === "}" or $c === "]"){ + break; + } + }elseif($c === '"'){ + $inQuotes = !$inQuotes; + if($type === null){ + $type = NBT::TAG_String; + }elseif($inQuotes){ + throw new \Exception("Syntax error: invalid quote at offset $offset"); + } + }elseif($c === "\\"){ + $value .= $data{$offset + 1} ?? ""; + ++$offset; + }elseif($c === "{" and !$inQuotes){ + if($value !== ""){ + throw new \Exception("Syntax error: invalid compound start at offset $offset"); + } + ++$offset; + $value = self::parseCompound($data, $offset); + $type = NBT::TAG_Compound; + break; + }elseif($c === "[" and !$inQuotes){ + if($value !== ""){ + throw new \Exception("Syntax error: invalid list start at offset $offset"); + } + ++$offset; + $value = self::parseList($data, $offset); + $type = NBT::TAG_List; + break; + }else{ + $value .= $c; + } + } + + if($value === ""){ + throw new \Exception("Syntax error: invalid empty value at offset $offset"); + } + + if($type === null and strlen($value) > 0){ + $value = trim($value); + $last = strtolower(substr($value, -1)); + $part = substr($value, 0, -1); + + if($last !== "b" and $last !== "s" and $last !== "l" and $last !== "f" and $last !== "d"){ + $part = $value; + $last = null; + } + + if($last !== "f" and $last !== "d" and ((string) ((int) $part)) === $part){ + if($last === "b"){ + $type = NBT::TAG_Byte; + }elseif($last === "s"){ + $type = NBT::TAG_Short; + }elseif($last === "l"){ + $type = NBT::TAG_Long; + }else{ + $type = NBT::TAG_Int; + } + $value = (int) $part; + }elseif(is_numeric($part)){ + if($last === "f" or $last === "d" or strpos($part, ".") !== false){ + if($last === "f"){ + $type = NBT::TAG_Float; + }elseif($last === "d"){ + $type = NBT::TAG_Double; + }else{ + $type = NBT::TAG_Float; + } + $value = (float) $part; + }else{ + if($last === "l"){ + $type = NBT::TAG_Long; + }else{ + $type = NBT::TAG_Int; + } + + $value = $part; + } + }else{ + $type = NBT::TAG_String; + } + } + + return $value; + } + + /** + * @param string $data + * @param int $offset + * + * @return string + * @throws \Exception + */ + private static function readKey(string $data, int &$offset){ + $key = ""; + + $len = strlen($data); + for(; $offset < $len; ++$offset){ + $c = $data{$offset}; + + if($c === ":"){ + ++$offset; + break; + }elseif($c !== " " and $c !== "\r" and $c !== "\n" and $c !== "\t" and $c !== "\""){ + $key .= $c; + } + } + + if($key === ""){ + throw new \Exception("Syntax error: invalid empty key at offset $offset"); + } + + return $key; + } +} \ No newline at end of file diff --git a/src/pocketmine/nbt/NBT.php b/src/pocketmine/nbt/NBT.php index a3cd0df12..b3380c8e4 100644 --- a/src/pocketmine/nbt/NBT.php +++ b/src/pocketmine/nbt/NBT.php @@ -171,199 +171,6 @@ class NBT{ return true; } - public static function parseJSON($data, &$offset = 0){ - $len = strlen($data); - for(; $offset < $len; ++$offset){ - $c = $data{$offset}; - if($c === "{"){ - ++$offset; - $data = self::parseCompound($data, $offset); - return new CompoundTag("", $data); - }elseif($c !== " " and $c !== "\r" and $c !== "\n" and $c !== "\t"){ - throw new \Exception("Syntax error: unexpected '$c' at offset $offset"); - } - } - - return null; - } - - private static function parseList($str, &$offset = 0){ - $len = strlen($str); - - - $key = 0; - $value = null; - - $data = []; - - for(; $offset < $len; ++$offset){ - if($str{$offset - 1} === "]"){ - break; - }elseif($str{$offset} === "]"){ - ++$offset; - break; - } - - $value = self::readValue($str, $offset, $type); - - $tag = self::createTag($type); - if($tag instanceof NamedTag){ - $tag->setName($key); - $tag->setValue($value); - $data[$key] = $tag; - } - - $key++; - } - - return $data; - } - - private static function parseCompound($str, &$offset = 0){ - $len = strlen($str); - - $data = []; - - for(; $offset < $len; ++$offset){ - if($str{$offset - 1} === "}"){ - break; - }elseif($str{$offset} === "}"){ - ++$offset; - break; - } - - $key = self::readKey($str, $offset); - $value = self::readValue($str, $offset, $type); - - $tag = self::createTag($type); - if($tag instanceof NamedTag){ - $tag->setName($key); - $tag->setValue($value); - $data[$key] = $tag; - } - } - - return $data; - } - - private static function readValue($data, &$offset, &$type = null){ - $value = ""; - $type = null; - $inQuotes = false; - - $len = strlen($data); - for(; $offset < $len; ++$offset){ - $c = $data{$offset}; - - if(!$inQuotes and ($c === " " or $c === "\r" or $c === "\n" or $c === "\t" or $c === "," or $c === "}" or $c === "]")){ - if($c === "," or $c === "}" or $c === "]"){ - break; - } - }elseif($c === '"'){ - $inQuotes = !$inQuotes; - if($type === null){ - $type = self::TAG_String; - }elseif($inQuotes){ - throw new \Exception("Syntax error: invalid quote at offset $offset"); - } - }elseif($c === "\\"){ - $value .= $data{$offset + 1} ?? ""; - ++$offset; - }elseif($c === "{" and !$inQuotes){ - if($value !== ""){ - throw new \Exception("Syntax error: invalid compound start at offset $offset"); - } - ++$offset; - $value = self::parseCompound($data, $offset); - $type = self::TAG_Compound; - break; - }elseif($c === "[" and !$inQuotes){ - if($value !== ""){ - throw new \Exception("Syntax error: invalid list start at offset $offset"); - } - ++$offset; - $value = self::parseList($data, $offset); - $type = self::TAG_List; - break; - }else{ - $value .= $c; - } - } - - if($value === ""){ - throw new \Exception("Syntax error: invalid empty value at offset $offset"); - } - - if($type === null and strlen($value) > 0){ - $value = trim($value); - $last = strtolower(substr($value, -1)); - $part = substr($value, 0, -1); - - if($last !== "b" and $last !== "s" and $last !== "l" and $last !== "f" and $last !== "d"){ - $part = $value; - $last = null; - } - - if($last !== "f" and $last !== "d" and ((string) ((int) $part)) === $part){ - if($last === "b"){ - $type = self::TAG_Byte; - }elseif($last === "s"){ - $type = self::TAG_Short; - }elseif($last === "l"){ - $type = self::TAG_Long; - }else{ - $type = self::TAG_Int; - } - $value = (int) $part; - }elseif(is_numeric($part)){ - if($last === "f" or $last === "d" or strpos($part, ".") !== false){ - if($last === "f"){ - $type = self::TAG_Float; - }elseif($last === "d"){ - $type = self::TAG_Double; - }else{ - $type = self::TAG_Float; - } - $value = (float) $part; - }else{ - if($last === "l"){ - $type = self::TAG_Long; - }else{ - $type = self::TAG_Int; - } - - $value = $part; - } - }else{ - $type = self::TAG_String; - } - } - - return $value; - } - - private static function readKey($data, &$offset){ - $key = ""; - - $len = strlen($data); - for(; $offset < $len; ++$offset){ - $c = $data{$offset}; - - if($c === ":"){ - ++$offset; - break; - }elseif($c !== " " and $c !== "\r" and $c !== "\n" and $c !== "\t" and $c !== "\""){ - $key .= $c; - } - } - - if($key === ""){ - throw new \Exception("Syntax error: invalid empty key at offset $offset"); - } - - return $key; - } - public function get($len){ if($len < 0){ $this->offset = strlen($this->buffer) - 1; From a77c1ce13c5ef279b5131b68d92e9b3340554fbf Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 19 May 2017 20:03:11 +0100 Subject: [PATCH 6/6] remove leftover --- src/pocketmine/nbt/tag/ListTag.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pocketmine/nbt/tag/ListTag.php b/src/pocketmine/nbt/tag/ListTag.php index e02835611..405402eae 100644 --- a/src/pocketmine/nbt/tag/ListTag.php +++ b/src/pocketmine/nbt/tag/ListTag.php @@ -22,7 +22,6 @@ namespace pocketmine\nbt\tag; use pocketmine\nbt\NBT; -use pocketmine\nbt\tag\ListTag as TagEnum; #include