diff --git a/src/main/java/net/minecraft/server/NetServerHandler.java b/src/main/java/net/minecraft/server/NetServerHandler.java index 5afc92fbec..a87d7f7421 100644 --- a/src/main/java/net/minecraft/server/NetServerHandler.java +++ b/src/main/java/net/minecraft/server/NetServerHandler.java @@ -15,9 +15,7 @@ import org.bukkit.ChatColor; import org.bukkit.craftbukkit.ChunkCompressionThread; import org.bukkit.Location; import org.bukkit.command.CommandException; -import org.bukkit.conversations.Conversable; import org.bukkit.craftbukkit.CraftWorld; -import org.bukkit.craftbukkit.inventory.CraftInventoryCustom; import org.bukkit.craftbukkit.inventory.CraftInventoryView; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.block.CraftBlock; @@ -718,10 +716,7 @@ public class NetServerHandler extends NetHandler implements ICommandListener { this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.x, packet6.y, packet6.z); } else if (packet instanceof Packet3Chat) { String message = ((Packet3Chat) packet).message; - boolean first = true; - for (String line : TextWrapper.wrapText(message)) { - if (!first) line = " " + line; - first = false; + for (final String line : TextWrapper.wrapText(message)) { this.networkManager.queue(new Packet3Chat(line)); } packet = null; diff --git a/src/main/java/org/bukkit/craftbukkit/TextWrapper.java b/src/main/java/org/bukkit/craftbukkit/TextWrapper.java index 588b59ee1b..015ea85756 100644 --- a/src/main/java/org/bukkit/craftbukkit/TextWrapper.java +++ b/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