mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-13 05:15:13 +00:00
Some cleanup to item NBT handling
This commit is contained in:
parent
97e2d64592
commit
8c6ab3e634
@ -241,19 +241,11 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function hasCustomBlockData() : bool{
|
public function hasCustomBlockData() : bool{
|
||||||
$tag = $this->getNamedTag();
|
return $this->getNamedTagEntry("BlockEntityTag") instanceof CompoundTag;
|
||||||
|
|
||||||
return isset($tag->BlockEntityTag) and $tag->BlockEntityTag instanceof CompoundTag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function clearCustomBlockData(){
|
public function clearCustomBlockData(){
|
||||||
$tag = $this->getNamedTag();
|
$this->removeNamedTagEntry("BlockEntityTag");
|
||||||
|
|
||||||
if(isset($tag->BlockEntityTag) and $tag->BlockEntityTag instanceof CompoundTag){
|
|
||||||
unset($tag->BlockEntityTag);
|
|
||||||
$this->setNamedTag($tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,10 +257,7 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
public function setCustomBlockData(CompoundTag $compound){
|
public function setCustomBlockData(CompoundTag $compound){
|
||||||
$tags = clone $compound;
|
$tags = clone $compound;
|
||||||
$tags->setName("BlockEntityTag");
|
$tags->setName("BlockEntityTag");
|
||||||
|
$this->setNamedTagEntry($tags);
|
||||||
$tag = $this->getNamedTag();
|
|
||||||
$tag->BlockEntityTag = $tags;
|
|
||||||
$this->setNamedTag($tag);
|
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -277,21 +266,15 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
* @return CompoundTag|null
|
* @return CompoundTag|null
|
||||||
*/
|
*/
|
||||||
public function getCustomBlockData(){
|
public function getCustomBlockData(){
|
||||||
$tag = $this->getNamedTag();
|
$tag = $this->getNamedTagEntry("BlockEntityTag");
|
||||||
if(isset($tag->BlockEntityTag) and $tag->BlockEntityTag instanceof CompoundTag){
|
return $tag instanceof CompoundTag ? $tag : null;
|
||||||
return $tag->BlockEntityTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function hasEnchantments() : bool{
|
public function hasEnchantments() : bool{
|
||||||
$tag = $this->getNamedTag();
|
return $this->getNamedTagEntry("ench") instanceof ListTag;
|
||||||
|
|
||||||
return isset($tag->ench) and $tag->ench instanceof ListTag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -301,17 +284,17 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function hasEnchantment(int $id, int $level = -1) : bool{
|
public function hasEnchantment(int $id, int $level = -1) : bool{
|
||||||
if(!$this->hasEnchantments()){
|
$ench = $this->getNamedTagEntry("ench");
|
||||||
|
if(!($ench instanceof ListTag)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($this->getNamedTag()->ench as $entry){
|
/** @var CompoundTag $entry */
|
||||||
if($entry["id"] === $id){
|
foreach($ench as $entry){
|
||||||
if($level === -1 or $entry["lvl"] === $level){
|
if($entry->getShort("id") === $id and ($level === -1 or $entry->getShort("lvl") === $level)){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -322,15 +305,17 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
* @return Enchantment|null
|
* @return Enchantment|null
|
||||||
*/
|
*/
|
||||||
public function getEnchantment(int $id){
|
public function getEnchantment(int $id){
|
||||||
if(!$this->hasEnchantments()){
|
$ench = $this->getNamedTagEntry("ench");
|
||||||
|
if(!($ench instanceof ListTag)){
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($this->getNamedTag()->ench as $entry){
|
/** @var CompoundTag $entry */
|
||||||
if($entry["id"] === $id){
|
foreach($ench as $entry){
|
||||||
$e = Enchantment::getEnchantment($entry["id"]);
|
if($entry->getShort("id") === $id){
|
||||||
|
$e = Enchantment::getEnchantment($entry->getShort("id"));
|
||||||
if($e !== null){
|
if($e !== null){
|
||||||
$e->setLevel($entry["lvl"]);
|
$e->setLevel($entry->getShort("lvl"));
|
||||||
return $e;
|
return $e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,46 +329,42 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
* @param int $level
|
* @param int $level
|
||||||
*/
|
*/
|
||||||
public function removeEnchantment(int $id, int $level = -1){
|
public function removeEnchantment(int $id, int $level = -1){
|
||||||
if(!$this->hasEnchantments()){
|
$ench = $this->getNamedTagEntry("ench");
|
||||||
|
if(!($ench instanceof ListTag)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tag = $this->getNamedTag();
|
/** @var CompoundTag $entry */
|
||||||
foreach($tag->ench as $k => $entry){
|
foreach($ench as $k => $entry){
|
||||||
if($entry["id"] === $id){
|
if($entry->getShort("id") === $id and ($level === -1 or $entry->getShort("lvl") === $level)){
|
||||||
if($level === -1 or $entry["lvl"] === $level){
|
unset($ench[$k]);
|
||||||
unset($tag->ench[$k]);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
$this->setNamedTag($tag);
|
$this->setNamedTagEntry($ench);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function removeEnchantments(){
|
public function removeEnchantments(){
|
||||||
if($this->hasEnchantments()){
|
$this->removeNamedTagEntry("ench");
|
||||||
$tag = $this->getNamedTag();
|
|
||||||
unset($tag->ench);
|
|
||||||
$this->setNamedTag($tag);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Enchantment $ench
|
* @param Enchantment $enchantment
|
||||||
*/
|
*/
|
||||||
public function addEnchantment(Enchantment $ench){
|
public function addEnchantment(Enchantment $enchantment){
|
||||||
$tag = $this->getNamedTag();
|
|
||||||
|
|
||||||
$found = false;
|
$found = false;
|
||||||
|
|
||||||
if(!isset($tag->ench)){
|
$ench = $this->getNamedTagEntry("ench");
|
||||||
$tag->ench = new ListTag("ench", [], NBT::TAG_Compound);
|
if(!($ench instanceof ListTag)){
|
||||||
|
$ench = new ListTag("ench", [], NBT::TAG_Compound);
|
||||||
}else{
|
}else{
|
||||||
foreach($tag->ench as $k => $entry){
|
/** @var CompoundTag $entry */
|
||||||
if($entry["id"] === $ench->getId()){
|
foreach($ench as $k => $entry){
|
||||||
$tag->ench->{$k} = new CompoundTag("", [
|
if($entry->getShort("id") === $enchantment->getId()){
|
||||||
new ShortTag("id", $ench->getId()),
|
$ench->{$k} = new CompoundTag("", [
|
||||||
new ShortTag("lvl", $ench->getLevel())
|
new ShortTag("id", $enchantment->getId()),
|
||||||
|
new ShortTag("lvl", $enchantment->getLevel())
|
||||||
]);
|
]);
|
||||||
$found = true;
|
$found = true;
|
||||||
break;
|
break;
|
||||||
@ -392,26 +373,29 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!$found){
|
if(!$found){
|
||||||
$tag->ench->{count($tag->ench)} = new CompoundTag("", [
|
$ench->{count($ench)} = new CompoundTag("", [
|
||||||
new ShortTag("id", $ench->getId()),
|
new ShortTag("id", $enchantment->getId()),
|
||||||
new ShortTag("lvl", $ench->getLevel())
|
new ShortTag("lvl", $enchantment->getLevel())
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setNamedTag($tag);
|
$this->setNamedTagEntry($ench);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Enchantment[]
|
* @return Enchantment[]
|
||||||
*/
|
*/
|
||||||
public function getEnchantments() : array{
|
public function getEnchantments() : array{
|
||||||
|
/** @var Enchantment[] $enchantments */
|
||||||
$enchantments = [];
|
$enchantments = [];
|
||||||
|
|
||||||
if($this->hasEnchantments()){
|
$ench = $this->getNamedTagEntry("ench");
|
||||||
foreach($this->getNamedTag()->ench as $entry){
|
if($ench instanceof ListTag){
|
||||||
$e = Enchantment::getEnchantment($entry["id"]);
|
/** @var CompoundTag $entry */
|
||||||
|
foreach($ench as $entry){
|
||||||
|
$e = Enchantment::getEnchantment($entry->getShort("id"));
|
||||||
if($e !== null){
|
if($e !== null){
|
||||||
$e->setLevel($entry["lvl"]);
|
$e->setLevel($entry->getShort("lvl"));
|
||||||
$enchantments[] = $e;
|
$enchantments[] = $e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -424,12 +408,9 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function hasCustomName() : bool{
|
public function hasCustomName() : bool{
|
||||||
$tag = $this->getNamedTag();
|
$display = $this->getNamedTagEntry("display");
|
||||||
if(isset($tag->display)){
|
if($display instanceof CompoundTag){
|
||||||
$tag = $tag->display;
|
return $display->hasTag("Name");
|
||||||
if($tag instanceof CompoundTag and isset($tag->Name) and $tag->Name instanceof StringTag){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -439,12 +420,9 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getCustomName() : string{
|
public function getCustomName() : string{
|
||||||
$tag = $this->getNamedTag();
|
$display = $this->getNamedTagEntry("display");
|
||||||
if(isset($tag->display)){
|
if($display instanceof CompoundTag){
|
||||||
$tag = $tag->display;
|
return $display->getString("Name") ?? "";
|
||||||
if($tag instanceof CompoundTag and isset($tag->Name) and $tag->Name instanceof StringTag){
|
|
||||||
return $tag->Name->getValue();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
@ -460,16 +438,14 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
$this->clearCustomName();
|
$this->clearCustomName();
|
||||||
}
|
}
|
||||||
|
|
||||||
$tag = $this->getNamedTag();
|
/** @var CompoundTag $display */
|
||||||
if(isset($tag->display) and $tag->display instanceof CompoundTag){
|
$display = $this->getNamedTagEntry("display");
|
||||||
$tag->display->Name = new StringTag("Name", $name);
|
if(!($display instanceof CompoundTag)){
|
||||||
}else{
|
$display = new CompoundTag("display");
|
||||||
$tag->display = new CompoundTag("display", [
|
|
||||||
new StringTag("Name", $name)
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setCompoundTag($tag);
|
$display->setString("Name", $name);
|
||||||
|
$this->setNamedTagEntry($display);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -478,30 +454,29 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function clearCustomName(){
|
public function clearCustomName(){
|
||||||
$tag = $this->getNamedTag();
|
$display = $this->getNamedTagEntry("display");
|
||||||
|
if($display instanceof CompoundTag){
|
||||||
|
$display->removeTag("Name");
|
||||||
|
|
||||||
if(isset($tag->display) and $tag->display instanceof CompoundTag){
|
if($display->getCount() === 0){
|
||||||
unset($tag->display->Name);
|
$this->removeNamedTagEntry($display->getName());
|
||||||
if($tag->display->getCount() === 0){
|
}else{
|
||||||
unset($tag->display);
|
$this->setNamedTagEntry($display);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setNamedTag($tag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
public function getLore() : array{
|
public function getLore() : array{
|
||||||
$tag = $this->getNamedTagEntry("display");
|
$display = $this->getNamedTagEntry("display");
|
||||||
if($tag instanceof CompoundTag and isset($tag->Lore) and $tag->Lore instanceof ListTag){
|
if($display instanceof CompoundTag and ($lore = $display->getListTag("Lore")) !== null){
|
||||||
$lines = [];
|
return array_map(function(StringTag $tag) : string{
|
||||||
/** @var StringTag $line */
|
return $tag->getValue();
|
||||||
foreach($tag->Lore->getValue() as $line){
|
}, $lore->getValue());
|
||||||
$lines[] = $line->getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $lines;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
@ -513,17 +488,16 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setLore(array $lines){
|
public function setLore(array $lines){
|
||||||
$tag = $this->getNamedTag();
|
$display = $this->getNamedTagEntry("display");
|
||||||
if(!isset($tag->display)){
|
if(!($display instanceof CompoundTag)){
|
||||||
$tag->display = new CompoundTag("display", []);
|
$display = new CompoundTag("display", []);
|
||||||
}
|
|
||||||
$tag->display->Lore = new ListTag("Lore", [], NBT::TAG_String);
|
|
||||||
$count = 0;
|
|
||||||
foreach($lines as $line){
|
|
||||||
$tag->display->Lore[$count++] = new StringTag("", $line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setNamedTag($tag);
|
$display->setTag(new ListTag("Lore", array_map(function(string $str) : StringTag{
|
||||||
|
return new StringTag("", $str);
|
||||||
|
}, $lines), NBT::TAG_String));
|
||||||
|
|
||||||
|
$this->setNamedTagEntry($display);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -944,22 +918,23 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
* @return CompoundTag
|
* @return CompoundTag
|
||||||
*/
|
*/
|
||||||
public function nbtSerialize(int $slot = -1, string $tagName = "") : CompoundTag{
|
public function nbtSerialize(int $slot = -1, string $tagName = "") : CompoundTag{
|
||||||
$tag = new CompoundTag($tagName, [
|
$result = new CompoundTag($tagName, [
|
||||||
new ShortTag("id", Binary::signShort($this->id)),
|
new ShortTag("id", Binary::signShort($this->id)),
|
||||||
new ByteTag("Count", Binary::signByte($this->count)),
|
new ByteTag("Count", Binary::signByte($this->count)),
|
||||||
new ShortTag("Damage", $this->meta),
|
new ShortTag("Damage", $this->meta)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if($this->hasCompoundTag()){
|
if($this->hasCompoundTag()){
|
||||||
$tag->tag = clone $this->getNamedTag();
|
$itemNBT = clone $this->getNamedTag();
|
||||||
$tag->tag->setName("tag");
|
$itemNBT->setName("tag");
|
||||||
|
$result->setTag($itemNBT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($slot !== -1){
|
if($slot !== -1){
|
||||||
$tag->Slot = new ByteTag("Slot", $slot);
|
$result->setByte("Slot", $slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $tag;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -970,26 +945,28 @@ class Item implements ItemIds, \JsonSerializable{
|
|||||||
* @return Item
|
* @return Item
|
||||||
*/
|
*/
|
||||||
public static function nbtDeserialize(CompoundTag $tag) : Item{
|
public static function nbtDeserialize(CompoundTag $tag) : Item{
|
||||||
if(!isset($tag->id) or !isset($tag->Count)){
|
if(!$tag->hasTag("id") or !$tag->hasTag("Count")){
|
||||||
return ItemFactory::get(0);
|
return ItemFactory::get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
$count = Binary::unsignByte($tag->Count->getValue());
|
$count = Binary::unsignByte($tag->getByte("Count"));
|
||||||
$meta = isset($tag->Damage) ? $tag->Damage->getValue() : 0;
|
$meta = $tag->getShort("Damage") ?? 0;
|
||||||
|
|
||||||
if($tag->id instanceof ShortTag){
|
$idTag = $tag->getTag("id");
|
||||||
$item = ItemFactory::get(Binary::unsignShort($tag->id->getValue()), $meta, $count);
|
if($idTag instanceof ShortTag){
|
||||||
}elseif($tag->id instanceof StringTag){ //PC item save format
|
$item = ItemFactory::get(Binary::unsignShort($idTag->getValue()), $meta, $count);
|
||||||
$item = ItemFactory::fromString($tag->id->getValue());
|
}elseif($idTag instanceof StringTag){ //PC item save format
|
||||||
|
$item = ItemFactory::fromString($idTag->getValue());
|
||||||
$item->setDamage($meta);
|
$item->setDamage($meta);
|
||||||
$item->setCount($count);
|
$item->setCount($count);
|
||||||
}else{
|
}else{
|
||||||
throw new \InvalidArgumentException("Item CompoundTag ID must be an instance of StringTag or ShortTag, " . get_class($tag->id) . " given");
|
throw new \InvalidArgumentException("Item CompoundTag ID must be an instance of StringTag or ShortTag, " . get_class($idTag) . " given");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($tag->tag) and $tag->tag instanceof CompoundTag){
|
$itemNBT = $tag->getCompoundTag("tag");
|
||||||
|
if($itemNBT instanceof CompoundTag){
|
||||||
/** @var CompoundTag $t */
|
/** @var CompoundTag $t */
|
||||||
$t = clone $tag->tag;
|
$t = clone $itemNBT;
|
||||||
$t->setName("");
|
$t->setName("");
|
||||||
$item->setNamedTag($t);
|
$item->setNamedTag($t);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user