Repository: pmmp/PocketMine-MP (language: php)

Issue:
Sign text in vanilla worlds is no longer loaded correctly
### Issue description
This is due to the changed NBT structure in newer versions.

### Steps to reproduce the issue
1. Create a world in 1.20
2. Add a sign with text
3. Load the world in PM
4. Notice the sign is blank

### OS and versions
<!-- try the `version` command | LATEST IS NOT A VALID VERSION -->
* PocketMine-MP: 5.5.0


Discussion / hints:

Fix patch:
diff --git a/src/block/tile/Sign.php b/src/block/tile/Sign.php
index d5d314ee31f..2ced414ff92 100644
--- a/src/block/tile/Sign.php
+++ b/src/block/tile/Sign.php
@@ -77,22 +77,30 @@ public function __construct(World $world, Vector3 $pos){
 		parent::__construct($world, $pos);
 	}
 
+	private function readTextTag(CompoundTag $nbt, bool $lightingBugResolved) : void{
+		$baseColor = new Color(0, 0, 0);
+		$glowingText = false;
+		if(($baseColorTag = $nbt->getTag(self::TAG_TEXT_COLOR)) instanceof IntTag){
+			$baseColor = Color::fromARGB(Binary::unsignInt($baseColorTag->getValue()));
+		}
+		if($lightingBugResolved && ($glowingTextTag = $nbt->getTag(self::TAG_GLOWING_TEXT)) instanceof ByteTag){
+			//both of these must be 1 - if only one is set, it's a leftover from 1.16.210 experimental features
+			//see https://bugs.mojang.com/browse/MCPE-117835
+			$glowingText = $glowingTextTag->getValue() !== 0;
+		}
+		$this->text = SignText::fromBlob(mb_scrub($nbt->getString(self::TAG_TEXT_BLOB), 'UTF-8'), $baseColor, $glowingText);
+	}
+
 	public function readSaveData(CompoundTag $nbt) : void{
-		if(($textBlobTag = $nbt->getTag(self::TAG_TEXT_BLOB)) instanceof StringTag){ //MCPE 1.2 save format
-			$baseColor = new Color(0, 0, 0);
-			$glowingText = false;
-			if(($baseColorTag = $nbt->getTag(self::TAG_TEXT_COLOR)) instanceof IntTag){
-				$baseColor = Color::fromARGB(Binary::unsignInt($baseColorTag->getValue()));
-			}
-			if(
-				($glowingTextTag = $nbt->getTag(self::TAG_GLOWING_TEXT)) instanceof ByteTag &&
-				($lightingBugResolvedTag = $nbt->getTag(self::TAG_LEGACY_BUG_RESOLVE)) instanceof ByteTag
-			){
-				//both of these must be 1 - if only one is set, it's a leftover from 1.16.210 experimental features
-				//see https://bugs.mojang.com/browse/MCPE-117835
-				$glowingText = $glowingTextTag->getValue() !== 0 && $lightingBugResolvedTag->getValue() !== 0;
+		$frontTextTag = $nbt->getTag(self::TAG_FRONT_TEXT);
+		if($frontTextTag instanceof CompoundTag){
+			$this->readTextTag($frontTextTag, true);
+		}elseif($nbt->getTag(self::TAG_TEXT_BLOB) instanceof StringTag){ //MCPE 1.2 save format
+			$lightingBugResolved = false;
+			if(($lightingBugResolvedTag = $nbt->getTag(self::TAG_LEGACY_BUG_RESOLVE)) instanceof ByteTag){
+				$lightingBugResolved = $lightingBugResolvedTag->getValue() !== 0;
 			}
-			$this->text = SignText::fromBlob(mb_scrub($textBlobTag->getValue(), 'UTF-8'), $baseColor, $glowingText);
+			$this->readTextTag($nbt, $lightingBugResolved);
 		}else{
 			$text = [];
 			for($i = 0; $i < SignText::LINE_COUNT; ++$i){
@@ -107,15 +115,19 @@ public function readSaveData(CompoundTag $nbt) : void{
 	}
 
 	protected function writeSaveData(CompoundTag $nbt) : void{
-		$nbt->setString(self::TAG_TEXT_BLOB, implode("\n", $this->text->getLines()));
+		$nbt->setTag(self::TAG_FRONT_TEXT, CompoundTag::create()
+			->setString(self::TAG_TEXT_BLOB, implode("\n", $this->text->getLines()))
+			->setInt(self::TAG_TEXT_COLOR, Binary::signInt($this->text->getBaseColor()->toARGB()))
+			->setByte(self::TAG_GLOWING_TEXT, $this->text->isGlowing() ? 1 : 0)
+			->setByte(self::TAG_PERSIST_FORMATTING, 1)
+		);
+		$nbt->setTag(self::TAG_BACK_TEXT, CompoundTag::create()
+			->setString(self::TAG_TEXT_BLOB, "")
+			->setInt(self::TAG_TEXT_COLOR, Binary::signInt(0xff_00_00_00))
+			->setByte(self::TAG_GLOWING_TEXT, 0)
+			->setByte(self::TAG_PERSIST_FORMATTING, 1)
+		);
 
-		for($i = 0; $i < SignText::LINE_COUNT; ++$i){ //Backwards-compatibility
-			$textKey = sprintf(self::TAG_TEXT_LINE, $i + 1);
-			$nbt->setString($textKey, $this->text->getLine($i));
-		}
-		$nbt->setInt(self::TAG_TEXT_COLOR, Binary::signInt($this->text->getBaseColor()->toARGB()));
-		$nbt->setByte(self::TAG_GLOWING_TEXT, $this->text->isGlowing() ? 1 : 0);
-		$nbt->setByte(self::TAG_LEGACY_BUG_RESOLVE, 1);
 		$nbt->setByte(self::TAG_WAXED, $this->waxed ? 1 : 0);
 	}
 


Test patch: