Fix sign color changes messing with character count (#2054)

Color changes do not affect the maximum amount of characters allowed on a line.
This commit is contained in:
Camotoy 2021-03-21 11:28:19 -04:00 committed by GitHub
parent 930c4c538e
commit 10c77a3214
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -26,6 +26,7 @@
package org.geysermc.connector.network.translators.world.block.entity; package org.geysermc.connector.network.translators.world.block.entity;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.nukkitx.nbt.NbtMapBuilder; import com.nukkitx.nbt.NbtMapBuilder;
import org.geysermc.connector.network.translators.chat.MessageTranslator; import org.geysermc.connector.network.translators.chat.MessageTranslator;
import org.geysermc.connector.utils.SignUtils; 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. * Maps a color stored in a sign's Color tag to a Bedrock Edition formatting code.
* <br> * <br>
* 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. * @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. * @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), ""); String signLine = getOrDefault(tag.getValue().get("Text" + currentLine), "");
signLine = MessageTranslator.convertMessageLenient(signLine); 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 // 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 // to Java Edition clients but will appear to Bedrock clients
int signWidth = 0; int signWidth = 0;
StringBuilder finalSignLine = new StringBuilder(); StringBuilder finalSignLine = new StringBuilder();
boolean previousCharacterWasFormatting = false; // Color changes do not count for maximum width
for (char c : signLine.toCharArray()) { 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) { if (signWidth <= SignUtils.BEDROCK_CHARACTER_WIDTH_MAX) {
finalSignLine.append(c); finalSignLine.append(c);
} else { } else {
// Adding the character would make Bedrock move to the next line - Java doesn't do that, so we do not want to
break; break;
} }
} }
// Java Edition 1.14 added the ability to change the text color of the whole sign using dye // Java Edition 1.14 added the ability to change the text color of the whole sign using dye
if (tag.contains("Color")) { Tag color = tag.get("Color");
signText.append(getBedrockSignColor(tag.get("Color").getValue().toString())); if (color != null) {
signText.append(getBedrockSignColor(color.getValue().toString()));
} }
signText.append(finalSignLine.toString()); signText.append(finalSignLine.toString());