From 10c77a3214ffb03c93a5b4401c89be36150b3c8d Mon Sep 17 00:00:00 2001 From: Camotoy <20743703+Camotoy@users.noreply.github.com> Date: Sun, 21 Mar 2021 11:28:19 -0400 Subject: [PATCH] Fix sign color changes messing with character count (#2054) Color changes do not affect the maximum amount of characters allowed on a line. --- .../entity/SignBlockEntityTranslator.java | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java index a92fac599..61ca4fa9c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/SignBlockEntityTranslator.java @@ -26,6 +26,7 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; import com.nukkitx.nbt.NbtMapBuilder; import org.geysermc.connector.network.translators.chat.MessageTranslator; import org.geysermc.connector.utils.SignUtils; @@ -35,7 +36,7 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { /** * Maps a color stored in a sign's Color tag to a Bedrock Edition formatting code. *
- * The color names correspond to dye names, because of this we can't use {@link MessageTranslator#getColor(String)}. + * The color names correspond to dye names, because of this we can't use a more global method. * * @param javaColor The dye color stored in the sign's Color tag. * @return A Bedrock Edition formatting code for valid dye colors, otherwise an empty string. @@ -101,27 +102,34 @@ public class SignBlockEntityTranslator extends BlockEntityTranslator { String signLine = getOrDefault(tag.getValue().get("Text" + currentLine), ""); signLine = MessageTranslator.convertMessageLenient(signLine); - // Trim any trailing formatting codes - if (signLine.length() > 2 && signLine.toCharArray()[signLine.length() - 2] == '\u00a7') { - signLine = signLine.substring(0, signLine.length() - 2); - } - // Check the character width on the sign to ensure there is no overflow that is usually hidden // to Java Edition clients but will appear to Bedrock clients int signWidth = 0; StringBuilder finalSignLine = new StringBuilder(); + boolean previousCharacterWasFormatting = false; // Color changes do not count for maximum width for (char c : signLine.toCharArray()) { - signWidth += SignUtils.getCharacterWidth(c); + if (c == '\u00a7') { + // Don't count this character + previousCharacterWasFormatting = true; + } else if (previousCharacterWasFormatting) { + // Don't count this character either + previousCharacterWasFormatting = false; + } else { + signWidth += SignUtils.getCharacterWidth(c); + } + if (signWidth <= SignUtils.BEDROCK_CHARACTER_WIDTH_MAX) { finalSignLine.append(c); } else { + // Adding the character would make Bedrock move to the next line - Java doesn't do that, so we do not want to break; } } // Java Edition 1.14 added the ability to change the text color of the whole sign using dye - if (tag.contains("Color")) { - signText.append(getBedrockSignColor(tag.get("Color").getValue().toString())); + Tag color = tag.get("Color"); + if (color != null) { + signText.append(getBedrockSignColor(color.getValue().toString())); } signText.append(finalSignLine.toString());