hasTag(self::TAG_TEXT_BLOB, StringTag::class)){ //MCPE 1.2 save format $this->text = self::fixTextBlob($nbt->getString(self::TAG_TEXT_BLOB)); }else{ for($i = 1; $i <= 4; ++$i){ $textKey = sprintf(self::TAG_TEXT_LINE, $i); if($nbt->hasTag($textKey, StringTag::class)){ $this->text[$i - 1] = $nbt->getString($textKey); } } } $this->text = array_map(function(string $line) : string{ return mb_scrub($line, 'UTF-8'); }, $this->text); } protected function writeSaveData(CompoundTag $nbt) : void{ $nbt->setString(self::TAG_TEXT_BLOB, implode("\n", $this->text)); for($i = 1; $i <= 4; ++$i){ //Backwards-compatibility $textKey = sprintf(self::TAG_TEXT_LINE, $i); $nbt->setString($textKey, $this->getLine($i - 1)); } } /** * Changes contents of the specific lines to the string provided. * Leaves contents of the specific lines as is if null is provided. * * @param null|string $line1 * @param null|string $line2 * @param null|string $line3 * @param null|string $line4 */ public function setText(?string $line1 = "", ?string $line2 = "", ?string $line3 = "", ?string $line4 = "") : void{ if($line1 !== null){ $this->setLine(0, $line1, false); } if($line2 !== null){ $this->setLine(1, $line2, false); } if($line3 !== null){ $this->setLine(2, $line3, false); } if($line4 !== null){ $this->setLine(3, $line4, false); } $this->onChanged(); } /** * @param int $index 0-3 * @param string $line * @param bool $update */ public function setLine(int $index, string $line, bool $update = true) : void{ if($index < 0 or $index > 3){ throw new \InvalidArgumentException("Index must be in the range 0-3!"); } if(!mb_check_encoding($line, 'UTF-8')){ throw new \InvalidArgumentException("Text must be valid UTF-8"); } $this->text[$index] = $line; if($update){ $this->onChanged(); } } /** * @param int $index 0-3 * * @return string */ public function getLine(int $index) : string{ if($index < 0 or $index > 3){ throw new \InvalidArgumentException("Index must be in the range 0-3!"); } return $this->text[$index]; } /** * @return string[] */ public function getText() : array{ return $this->text; } protected function addAdditionalSpawnData(CompoundTag $nbt) : void{ $nbt->setString(self::TAG_TEXT_BLOB, implode("\n", $this->text)); } public function updateCompoundTag(CompoundTag $nbt, Player $player) : bool{ if($nbt->getString("id") !== Tile::SIGN){ return false; } if($nbt->hasTag(self::TAG_TEXT_BLOB, StringTag::class)){ $lines = self::fixTextBlob($nbt->getString(self::TAG_TEXT_BLOB)); }else{ return false; } $removeFormat = $player->getRemoveFormat(); $ev = new SignChangeEvent($this->getBlock(), $player, array_map(function(string $line) use ($removeFormat){ return TextFormat::clean($line, $removeFormat); }, $lines)); $ev->call(); if(!$ev->isCancelled()){ $this->setText(...$ev->getLines()); return true; }else{ return false; } } }