From 554bfb4855183d7da8ac5bc69ccafc0ecfa5c374 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Thu, 6 Aug 2015 21:09:37 +0200 Subject: [PATCH] Added methods for adding custom names directly to items --- src/pocketmine/item/Item.php | 161 ++++++++++++++++++++++++---- src/pocketmine/level/Level.php | 2 +- src/pocketmine/nbt/tag/Compound.php | 11 ++ src/pocketmine/nbt/tag/Enum.php | 11 ++ src/pocketmine/utils/Terminal.php | 2 +- 5 files changed, 162 insertions(+), 25 deletions(-) diff --git a/src/pocketmine/item/Item.php b/src/pocketmine/item/Item.php index 1186e79470..e35a778de3 100644 --- a/src/pocketmine/item/Item.php +++ b/src/pocketmine/item/Item.php @@ -32,11 +32,41 @@ use pocketmine\entity\Villager; use pocketmine\entity\Zombie; use pocketmine\inventory\Fuel; use pocketmine\level\Level; +use pocketmine\nbt\tag\String; use pocketmine\Player; use pocketmine\nbt\tag\Compound; use pocketmine\nbt\NBT; class Item{ + + private static $cachedParser = null; + + /** + * @param $tag + * @return Compound + */ + private static function parseCompoundTag($tag){ + if(self::$cachedParser === null){ + self::$cachedParser = new NBT(NBT::LITTLE_ENDIAN); + } + + self::$cachedParser->read($tag); + return self::$cachedParser->getData(); + } + + /** + * @param Compound $tag + * @return string + */ + private static function writeCompoundTag(Compound $tag){ + if(self::$cachedParser === null){ + self::$cachedParser = new NBT(NBT::LITTLE_ENDIAN); + } + + self::$cachedParser->setData($tag); + return self::$cachedParser->write(); + } + //All Block IDs are here too const AIR = 0; const STONE = 1; @@ -406,7 +436,8 @@ class Item{ protected $block; protected $id; protected $meta; - protected $nbt = ""; + private $tags = ""; + private $cachedNBT = null; public $count; protected $durability = 0; protected $name; @@ -856,18 +887,18 @@ class Item{ return -1; } - public static function get($id, $meta = 0, $count = 1, $nbt = ""){ + public static function get($id, $meta = 0, $count = 1, $tags = ""){ try{ $class = self::$list[$id]; if($class === null){ - return (new Item($id, $meta, $count))->setCompoundTag($nbt); + return (new Item($id, $meta, $count))->setCompoundTag($tags); }elseif($id < 256){ - return (new ItemBlock(new $class($meta), $meta, $count))->setCompoundTag($nbt); + return (new ItemBlock(new $class($meta), $meta, $count))->setCompoundTag($tags); }else{ - return (new $class($meta, $count))->setCompoundTag($nbt); + return (new $class($meta, $count))->setCompoundTag($tags); } }catch(\RuntimeException $e){ - return (new Item($id, $meta, $count))->setCompoundTag($nbt); + return (new Item($id, $meta, $count))->setCompoundTag($tags); } } @@ -911,11 +942,12 @@ class Item{ } } - public function setCompoundTag($nbt){ - if($nbt instanceof Compound){ - $this->setNamedTag($nbt); + public function setCompoundTag($tags){ + if($tags instanceof Compound){ + $this->setNamedTag($tags); }else{ - $this->nbt = $nbt; + $this->tags = $tags; + $this->cachedNBT = null; } return $this; @@ -925,30 +957,113 @@ class Item{ * @return string */ public function getCompoundTag(){ - return $this->nbt; + return $this->tags; } public function hasCompoundTag(){ - return $this->nbt !== ""; + return $this->tags !== "" and $this->tags !== null; + } + + public function hasCustomName(){ + if(!$this->hasCompoundTag()){ + return false; + } + + $tag = $this->getNamedTag(); + if(isset($tag->display)){ + $tag = $tag->display; + if($tag instanceof Compound and isset($tag->Name) and $tag->Name instanceof String){ + return true; + } + } + + return false; + } + + public function getCustomName(){ + if(!$this->hasCompoundTag()){ + return ""; + } + + $tag = $this->getNamedTag(); + if(isset($tag->display)){ + $tag = $tag->display; + if($tag instanceof Compound and isset($tag->Name) and $tag->Name instanceof String){ + return $tag->Name->getValue(); + } + } + + return ""; + } + + public function setCustomName($name){ + if((string) $name === ""){ + $this->clearCustomName(); + } + + if(!$this->hasCompoundTag()){ + $tag = new Compound("", []); + }else{ + $tag = $this->getNamedTag(); + } + + if(isset($tag->display) and $tag->display instanceof Compound){ + $tag->display->Name = new String("Name", $name); + }else{ + $tag->display = new Compound("display", [ + "Name" => new String("Name", $name) + ]); + } + + return $this; + } + + public function clearCustomName(){ + if(!$this->hasCompoundTag()){ + return $this; + } + $tag = $this->getNamedTag(); + + if(isset($tag->display) and $tag->display instanceof Compound){ + unset($tag->display->Name); + if($tag->display->getCount() === 0){ + unset($tag->display); + } + }else{ + $tag->display = new Compound("display", [ + "Name" => new String("Name", $name) + ]); + } + + $this->setNamedTag($tag); + + return $this; } public function getNamedTag(){ - if($this->nbt === ""){ + if(!$this->hasCompoundTag()){ return null; + }elseif($this->cachedNBT !== null){ + return $this->cachedNBT; } - $nbt = new NBT(NBT::LITTLE_ENDIAN); - $nbt->read($this->nbt); - return $nbt->getData(); + return $this->cachedNBT = self::parseCompoundTag($this->tags); } public function setNamedTag(Compound $tag){ - $nbt = new NBT(NBT::LITTLE_ENDIAN); - $nbt->setData($tag); - $this->nbt = $nbt->write($this->nbt); - + if($tag->getCount() === 0){ + return $this->clearNamedTag(); + } + + $this->cachedNBT = $tag; + $this->tags = self::writeCompoundTag($tag); + return $this; } + public function clearNamedTag(){ + return $this->setCompoundTag(""); + } + public function getCount(){ return $this->count; } @@ -958,11 +1073,11 @@ class Item{ } final public function getName(){ - return $this->name; + return $this->hasCustomName() ? $this->getCustomName() : $this->name; } - final public function isPlaceable(){ - return (($this->block instanceof Block) and $this->block->isPlaceable === true); + final public function canBePlaced(){ + return $this->block !== null and $this->block->canBePlaced(); } public function getBlock(){ diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index 6d4b301d4d..cfa5e360f9 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -1661,7 +1661,7 @@ class Level implements ChunkManager, Metadatable{ return true; } - if($item->isPlaceable()){ + if($item->canBePlaced()){ $hand = $item->getBlock(); $hand->position($block); }elseif($block->getId() === Item::FIRE){ diff --git a/src/pocketmine/nbt/tag/Compound.php b/src/pocketmine/nbt/tag/Compound.php index 1bd6802855..7cb58a6d4c 100644 --- a/src/pocketmine/nbt/tag/Compound.php +++ b/src/pocketmine/nbt/tag/Compound.php @@ -38,6 +38,17 @@ class Compound extends NamedTag implements \ArrayAccess{ } } + public function getCount(){ + $count = 0; + foreach($this as $tag){ + if($tag instanceof Tag){ + ++$count; + } + } + + return $count; + } + public function offsetExists($offset){ return isset($this->{$offset}); } diff --git a/src/pocketmine/nbt/tag/Enum.php b/src/pocketmine/nbt/tag/Enum.php index 12e2a076bb..c72b1b28ee 100644 --- a/src/pocketmine/nbt/tag/Enum.php +++ b/src/pocketmine/nbt/tag/Enum.php @@ -48,6 +48,17 @@ class Enum extends NamedTag implements \ArrayAccess, \Countable{ return $value; } + public function getCount(){ + $count = 0; + foreach($this as $tag){ + if($tag instanceof Tag){ + ++$count; + } + } + + return $count; + } + public function offsetExists($offset){ return isset($this->{$offset}); } diff --git a/src/pocketmine/utils/Terminal.php b/src/pocketmine/utils/Terminal.php index b34351bb01..8669d8cd46 100644 --- a/src/pocketmine/utils/Terminal.php +++ b/src/pocketmine/utils/Terminal.php @@ -55,7 +55,7 @@ abstract class Terminal{ if(isset($opts["disable-ansi"])){ self::$formattingCodes = false; }else{ - self::$formattingCodes = ((Utils::getOS() !== "win" and getenv("TERM") != "" and (!function_exists("posix_ttyname") or posix_ttyname(STDOUT) !== false)) or isset($opts["enable-ansi"])); + self::$formattingCodes = ((Utils::getOS() !== "win" and getenv("TERM") != "" and (!function_exists("posix_ttyname") or !defined("STDOUT") or posix_ttyname(STDOUT) !== false)) or isset($opts["enable-ansi"])); } }