diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/TextWrapper.java b/paper-server/src/main/java/org/bukkit/craftbukkit/TextWrapper.java index 588b59ee1b..015ea85756 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/TextWrapper.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/TextWrapper.java @@ -1,20 +1,88 @@ package org.bukkit.craftbukkit; -import org.bukkit.ChatColor; - public class TextWrapper { + private static final int[] characterWidths = new int[] { + 1, 9, 9, 8, 8, 8, 8, 7, 9, 8, 9, 9, 8, 9, 9, 9, + 8, 8, 8, 8, 9, 9, 8, 9, 8, 8, 8, 8, 8, 9, 9, 9, + 4, 2, 5, 6, 6, 6, 6, 3, 5, 5, 5, 6, 2, 6, 2, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 5, 6, 5, 6, + 7, 6, 6, 6, 6, 6, 6, 6, 6, 4, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 6, 4, 6, 6, + 3, 6, 6, 6, 6, 6, 5, 6, 6, 2, 6, 5, 3, 6, 6, 6, + 6, 6, 6, 6, 4, 6, 6, 6, 6, 6, 6, 5, 2, 5, 7, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 6, 3, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 6, + 6, 3, 6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 2, 6, 6, + 8, 9, 9, 6, 6, 6, 8, 8, 6, 8, 8, 8, 8, 8, 6, 6, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 9, 9, 5, 9, 9, + 8, 7, 7, 8, 7, 8, 8, 8, 7, 8, 8, 7, 9, 9, 6, 7, + 7, 7, 7, 7, 9, 6, 7, 8, 7, 6, 6, 9, 7, 6, 7, 1 + }; + private static final char COLOR_CHAR = '\u00A7'; + private static final int CHAT_WINDOW_WIDTH = 320; private static final int CHAT_STRING_LENGTH = 119; + private static final String allowedChars = net.minecraft.server.SharedConstants.allowedCharacters; public static String[] wrapText(final String text) { - return insertLineBreaks(text).split("\n"); + final StringBuilder out = new StringBuilder(); + char colorChar = 'f'; + int lineWidth = 0; + int lineLength = 0; + + // Go over the message char by char. + for (int i = 0; i < text.length(); i++) { + char ch = text.charAt(i); + + // Get the color + if (ch == COLOR_CHAR && i < text.length() - 1) { + // We might need a linebreak ... so ugly ;( + if (lineLength + 2 > CHAT_STRING_LENGTH) { + out.append('\n'); + lineLength = 0; + if (colorChar != 'f' && colorChar != 'F') { + out.append(COLOR_CHAR).append(colorChar); + lineLength += 2; + } + } + colorChar = text.charAt(++i); + out.append(COLOR_CHAR).append(colorChar); + lineLength += 2; + continue; + } + + // Figure out if it's allowed + int index = allowedChars.indexOf(ch); + if (index == -1) { + // Invalid character .. skip it. + continue; + } else { + // Sadly needed as the allowedChars string misses the first + index += 32; + } + + // Find the width + final int width = characterWidths[index]; + + // See if we need a linebreak + if (lineLength + 1 > CHAT_STRING_LENGTH || lineWidth + width >= CHAT_WINDOW_WIDTH) { + out.append('\n'); + lineLength = 0; + + // Re-apply the last color if it isn't the default + if (colorChar != 'f' && colorChar != 'F') { + out.append(COLOR_CHAR).append(colorChar); + lineLength += 2; + } + lineWidth = width; + } else { + lineWidth += width; + } + out.append(ch); + lineLength++; + } + + // Return it split + return out.toString().split("\n"); } - - public static String insertLineBreaks(String input) { - if (input.length() <= CHAT_STRING_LENGTH) return input; - - String head = input.substring(0, CHAT_STRING_LENGTH); - String tail = ChatColor.getLastColors(head) + input.substring(CHAT_STRING_LENGTH + (input.charAt(CHAT_STRING_LENGTH) == ' ' ? 1 : 0)); - - return head + "\n" + insertLineBreaks(tail); - } -} +} \ No newline at end of file