From 5b1573a24ebff8d1e11ba3255336fdf4ba8af1db Mon Sep 17 00:00:00 2001 From: Matthew Miller Date: Fri, 19 Apr 2019 23:06:00 +1000 Subject: [PATCH] Replace the message system --- build.gradle | 8 +- worldedit-bukkit/build.gradle | 1 + worldedit-core/build.gradle | 2 + .../worldedit/command/SelectionCommands.java | 12 +- .../worldedit/command/UtilityCommands.java | 23 +- .../extension/platform/CommandManager.java | 3 +- .../util/formatting/ColorCodeBuilder.java | 274 --------------- .../worldedit/util/formatting/Fragment.java | 121 ------- .../worldedit/util/formatting/Style.java | 274 --------------- .../worldedit/util/formatting/StyleSet.java | 320 ------------------ .../util/formatting/StyledFragment.java | 121 ------- .../util/formatting/component/Code.java | 10 +- .../formatting/component/CommandListBox.java | 10 +- .../formatting/component/CommandUsageBox.java | 22 +- .../util/formatting/component/Error.java | 10 +- .../util/formatting/component/Label.java | 10 +- .../util/formatting/component/MessageBox.java | 29 +- .../util/formatting/component/Subtle.java | 10 +- worldedit-forge/build.gradle | 1 + worldedit-sponge/build.gradle | 1 + 20 files changed, 82 insertions(+), 1180 deletions(-) delete mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/ColorCodeBuilder.java delete mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/Fragment.java delete mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/Style.java delete mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/StyleSet.java delete mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/StyledFragment.java diff --git a/build.gradle b/build.gradle index f31f5b6a8..090626cc5 100644 --- a/build.gradle +++ b/build.gradle @@ -142,9 +142,11 @@ subprojects { include(dependency('com.sk89q:jchronic:0.2.4a')) include(dependency('com.thoughtworks.paranamer:paranamer:2.6')) include(dependency('com.sk89q.lib:jlibnoise:1.0.0')) - relocate('net.kyori.text', 'com.sk89q.worldedit.util.formatting.text') { - include(dependency('net.kyori:text-api:2.0.0')) - } + include(dependency('net.kyori:text-api:2.0.0')) + include(dependency("net.kyori:text-serializer-gson:2.0.0")) + include(dependency("net.kyori:text-serializer-legacy:2.0.0")) + + relocate('net.kyori.text', 'com.sk89q.worldedit.util.formatting.text') } exclude 'GradleStart**' exclude '.cache' diff --git a/worldedit-bukkit/build.gradle b/worldedit-bukkit/build.gradle index af7f00114..67ca5e43b 100644 --- a/worldedit-bukkit/build.gradle +++ b/worldedit-bukkit/build.gradle @@ -43,6 +43,7 @@ shadowJar { include(dependency(':worldedit-core')) include(dependency('org.slf4j:slf4j-api')) include(dependency("org.slf4j:slf4j-jdk14")) + include(dependency("net.kyori:text-adapter-bukkit:1.0.3")) relocate ("org.bstats", "com.sk89q.worldedit.bukkit.bstats") { include(dependency("org.bstats:bstats-bukkit:1.4")) } diff --git a/worldedit-core/build.gradle b/worldedit-core/build.gradle index a83565dfc..9d8176407 100644 --- a/worldedit-core/build.gradle +++ b/worldedit-core/build.gradle @@ -16,6 +16,8 @@ dependencies { compile 'com.googlecode.json-simple:json-simple:1.1.1' compile 'org.slf4j:slf4j-api:1.7.26' compile 'net.kyori:text-api:2.0.0' + compile 'net.kyori:text-serializer-gson:2.0.0' + compile 'net.kyori:text-serializer-legacy:2.0.0' //compile 'net.sf.trove4j:trove4j:3.0.3' testCompile 'org.mockito:mockito-core:1.9.0-rc1' } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index 24e92070b..ee93e847c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -55,15 +55,14 @@ import com.sk89q.worldedit.regions.selector.SphereRegionSelector; import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.util.Countable; import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; -import com.sk89q.worldedit.util.formatting.Style; -import com.sk89q.worldedit.util.formatting.StyledFragment; import com.sk89q.worldedit.util.formatting.component.CommandListBox; +import com.sk89q.worldedit.util.formatting.component.Subtle; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.item.ItemTypes; import com.sk89q.worldedit.world.storage.ChunkStore; +import net.kyori.text.Component; import java.util.ArrayList; import java.util.List; @@ -754,9 +753,8 @@ public class SelectionCommands { limit.ifPresent(integer -> player.print(integer + " points maximum.")); } else { CommandListBox box = new CommandListBox("Selection modes"); - StyledFragment contents = box.getContents(); - StyledFragment tip = contents.createFragment(Style.RED); - tip.append("Select one of the modes below:").newLine(); + Component contents = box.getContents(); + contents.append(new Subtle("Select one of the modes below:").append(Component.newline())); box.appendCommand("cuboid", "Select two corners of a cuboid"); box.appendCommand("extend", "Fast cuboid selection mode"); @@ -766,7 +764,7 @@ public class SelectionCommands { box.appendCommand("cyl", "Select a cylinder"); box.appendCommand("convex", "Select a convex polyhedral"); - player.printRaw(ColorCodeBuilder.asColorCodes(box)); + player.print(box); return; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index 8768be6c8..e8ee6275f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -58,15 +58,16 @@ import com.sk89q.worldedit.util.command.CommandMapping; import com.sk89q.worldedit.util.command.Dispatcher; import com.sk89q.worldedit.util.command.PrimaryAliasComparator; import com.sk89q.worldedit.util.command.binding.Text; -import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; -import com.sk89q.worldedit.util.formatting.Style; -import com.sk89q.worldedit.util.formatting.StyledFragment; import com.sk89q.worldedit.util.formatting.component.Code; import com.sk89q.worldedit.util.formatting.component.CommandListBox; import com.sk89q.worldedit.util.formatting.component.CommandUsageBox; +import com.sk89q.worldedit.util.formatting.component.Error; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockTypes; +import net.kyori.text.Component; +import net.kyori.text.TextComponent; +import net.kyori.text.format.TextColor; import java.util.ArrayList; import java.util.List; @@ -669,17 +670,17 @@ public class UtilityCommands { // Box CommandListBox box = new CommandListBox(String.format("Help: page %d/%d ", page + 1, pageTotal)); - StyledFragment contents = box.getContents(); - StyledFragment tip = contents.createFragment(Style.GRAY); + Component contents = box.getContents(); + Component tip = contents.append(TextComponent.of("", TextColor.GRAY)); if (offset >= aliases.size()) { - tip.createFragment(Style.RED).append(String.format("There is no page %d (total number of pages is %d).", page + 1, pageTotal)).newLine(); + tip.append(new Error(String.format("There is no page %d (total number of pages is %d).", page + 1, pageTotal))).append(Component.newline()); } else { List list = aliases.subList(offset, Math.min(offset + perPage, aliases.size())); - tip.append("Type "); - tip.append(new Code().append("//help ").append(" []")); - tip.append(" for more information.").newLine(); + tip.append(TextComponent.of("Type ")); + tip.append(new Code("//help ").append(TextComponent.of(" []"))); + tip.append(TextComponent.of(" for more information.")).append(Component.newline()); // Add each command for (CommandMapping mapping : list) { @@ -696,10 +697,10 @@ public class UtilityCommands { } } - actor.printRaw(ColorCodeBuilder.asColorCodes(box)); + actor.print(box); } else { CommandUsageBox box = new CommandUsageBox(callable, Joiner.on(" ").join(visited)); - actor.printRaw(ColorCodeBuilder.asColorCodes(box)); + actor.print(box); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java index a0be07b65..11257efdf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/CommandManager.java @@ -77,7 +77,6 @@ import com.sk89q.worldedit.util.command.parametric.ExceptionConverter; import com.sk89q.worldedit.util.command.parametric.LegacyCommandsHandler; import com.sk89q.worldedit.util.command.parametric.ParametricBuilder; import com.sk89q.worldedit.util.eventbus.Subscribe; -import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; import com.sk89q.worldedit.util.formatting.component.CommandUsageBox; import com.sk89q.worldedit.util.logging.DynamicStreamHandler; import com.sk89q.worldedit.util.logging.LogFormat; @@ -300,7 +299,7 @@ public final class CommandManager { actor.printError("You are not permitted to do that. Are you in the right mode?"); } catch (InvalidUsageException e) { if (e.isFullHelpSuggested()) { - actor.printRaw(ColorCodeBuilder.asColorCodes(new CommandUsageBox(e.getCommand(), e.getCommandUsed("/", ""), locals))); + actor.print(new CommandUsageBox(e.getCommand(), e.getCommandUsed("/", ""), locals)); String message = e.getMessage(); if (message != null) { actor.printError(message); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/ColorCodeBuilder.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/ColorCodeBuilder.java deleted file mode 100644 index 14e8ddbca..000000000 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/ColorCodeBuilder.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.util.formatting; - -import com.google.common.base.Joiner; - -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -public class ColorCodeBuilder { - - private static final ColorCodeBuilder instance = new ColorCodeBuilder(); - private static final Joiner newLineJoiner = Joiner.on("\n"); - public static final int GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH = 47; - - /** - * Convert a message into color-coded text. - * - * @param message the message - * @return a list of lines - */ - public String[] build(StyledFragment message) { - StringBuilder builder = new StringBuilder(); - buildFragment(builder, message, message.getStyle(), new StyleSet()); - return builder.toString().split("\r?\n"); - } - - /** - * Build a fragment. - * - * @param builder the string builder - * @param message the message - * @param parentStyle the parent style - * @param lastStyle the last style - * @return the last style used - */ - private StyleSet buildFragment(StringBuilder builder, StyledFragment message, StyleSet parentStyle, StyleSet lastStyle) { - for (Fragment node : message.getChildren()) { - if (node instanceof StyledFragment) { - StyledFragment fragment = (StyledFragment) node; - lastStyle = buildFragment( - builder, fragment, - parentStyle.extend(message.getStyle()), lastStyle); - } else { - StyleSet style = parentStyle.extend(message.getStyle()); - builder.append(getAdditive(style, lastStyle)); - builder.append(node); - lastStyle = style; - } - } - - return lastStyle; - } - - /** - * Get the formatting codes. - * - * @param style the style - * @return the color codes - */ - public static String getFormattingCode(StyleSet style) { - StringBuilder builder = new StringBuilder(); - if (style.isBold()) { - builder.append(Style.BOLD); - } - if (style.isItalic()) { - builder.append(Style.ITALIC); - } - if (style.isUnderline()) { - builder.append(Style.UNDERLINE); - } - if (style.isStrikethrough()) { - builder.append(Style.STRIKETHROUGH); - } - if (style.isObfuscated()) { - builder.append(Style.OBFUSCATED); - } - return builder.toString(); - } - - /** - * Get the formatting and color codes. - * - * @param style the style - * @return the color codes - */ - public static String getCode(StyleSet style) { - StringBuilder builder = new StringBuilder(); - builder.append(getFormattingCode(style)); - if (style.getColor() != null) { - builder.append(style.getColor()); - } - return builder.toString(); - } - - /** - * Get the additional color codes needed to set the given style when the current - * style is the other given one. - * - * @param resetTo the style to reset to - * @param resetFrom the style to reset from - * @return the color codes - */ - public static String getAdditive(StyleSet resetTo, StyleSet resetFrom) { - if (!resetFrom.hasFormatting() && resetTo.hasFormatting()) { - StringBuilder builder = new StringBuilder(); - builder.append(getFormattingCode(resetTo)); - if (resetFrom.getColor() != resetTo.getColor()) { - builder.append(resetTo.getColor()); - } - return builder.toString(); - } else if (!resetFrom.hasEqualFormatting(resetTo) || - (resetFrom.getColor() != null && resetTo.getColor() == null)) { - // Have to set reset code and add back all the formatting codes - return Style.RESET + getCode(resetTo); - } else { - if (resetFrom.getColor() != resetTo.getColor()) { - return String.valueOf(resetTo.getColor()); - } - } - - return ""; - } - - /** - * Word wrap the given text and maintain color codes throughout lines. - * - *

This is borrowed from Bukkit.

- * - * @param rawString the raw string - * @param lineLength the maximum line length - * @return a list of lines - */ - private String[] wordWrap(String rawString, int lineLength) { - // A null string is a single line - if (rawString == null) { - return new String[] {""}; - } - - // A string shorter than the lineWidth is a single line - if (rawString.length() <= lineLength && !rawString.contains("\n")) { - return new String[] {rawString}; - } - - char[] rawChars = (rawString + ' ').toCharArray(); // add a trailing space to trigger pagination - StringBuilder word = new StringBuilder(); - StringBuilder line = new StringBuilder(); - List lines = new LinkedList<>(); - int lineColorChars = 0; - - for (int i = 0; i < rawChars.length; i++) { - char c = rawChars[i]; - - // skip chat color modifiers - if (c == Style.COLOR_CHAR) { - word.append(Style.getByChar(rawChars[i + 1])); - lineColorChars += 2; - i++; // Eat the next character as we have already processed it - continue; - } - - if (c == ' ' || c == '\n') { - if (line.length() == 0 && word.length() > lineLength) { // special case: extremely long word begins a line - String wordStr = word.toString(); - String transformed; - if ((transformed = transform(wordStr)) != null) { - line.append(transformed); - } else { - lines.addAll(Arrays.asList(word.toString().split("(?<=\\G.{" + lineLength + "})"))); - } - } else if (line.length() + word.length() - lineColorChars == lineLength) { // Line exactly the correct length...newline - line.append(' '); - line.append(word); - lines.add(line.toString()); - line = new StringBuilder(); - lineColorChars = 0; - } else if (line.length() + 1 + word.length() - lineColorChars > lineLength) { // Line too long...break the line - String wordStr = word.toString(); - String transformed; - if (word.length() > lineLength && (transformed = transform(wordStr)) != null) { - if (line.length() + 1 + transformed.length() - lineColorChars > lineLength) { - lines.add(line.toString()); - line = new StringBuilder(transformed); - lineColorChars = 0; - } else { - if (line.length() > 0) { - line.append(' '); - } - line.append(transformed); - } - } else { - for (String partialWord : wordStr.split("(?<=\\G.{" + lineLength + "})")) { - lines.add(line.toString()); - line = new StringBuilder(partialWord); - } - lineColorChars = 0; - } - } else { - if (line.length() > 0) { - line.append(' '); - } - line.append(word); - } - word = new StringBuilder(); - - if (c == '\n') { // Newline forces the line to flush - lines.add(line.toString()); - line = new StringBuilder(); - } - } else { - word.append(c); - } - } - - if(line.length() > 0) { // Only add the last line if there is anything to add - lines.add(line.toString()); - } - - // Iterate over the wrapped lines, applying the last color from one line to the beginning of the next - if (lines.get(0).isEmpty() || lines.get(0).charAt(0) != Style.COLOR_CHAR) { - lines.set(0, Style.WHITE + lines.get(0)); - } - for (int i = 1; i < lines.size(); i++) { - final String pLine = lines.get(i-1); - final String subLine = lines.get(i); - - char color = pLine.charAt(pLine.lastIndexOf(Style.COLOR_CHAR) + 1); - if (subLine.isEmpty() || subLine.charAt(0) != Style.COLOR_CHAR) { - lines.set(i, Style.getByChar(color) + subLine); - } - } - - return lines.toArray(new String[lines.size()]); - } - - /** - * Callback for transforming a word, such as a URL. - * - * @param word the word - * @return the transformed value, or null to do nothing - */ - protected String transform(String word) { - return null; - } - - /** - * Convert the given styled fragment into color codes. - * - * @param fragment the fragment - * @return color codes - */ - public static String asColorCodes(StyledFragment fragment) { - return newLineJoiner.join(instance.build(fragment)); - } - -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/Fragment.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/Fragment.java deleted file mode 100644 index e49d7c678..000000000 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/Fragment.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.util.formatting; - -import java.util.ArrayList; -import java.util.List; - -/** - * A fragment of text. - */ -public class Fragment { - - private final StringBuilder builder = new StringBuilder(); - private final List children = new ArrayList<>(); - private Fragment lastText; - - Fragment() { - } - - public List getChildren() { - return children; - } - - protected Fragment lastText() { - Fragment text; - if (!children.isEmpty()) { - text = children.get(children.size() - 1); - if (text == lastText) { - return text; - } - } - - text = new Fragment(); - this.lastText = text; - children.add(text); - return text; - } - - public Fragment append(Fragment fragment) { - children.add(fragment); - return this; - } - - public Fragment append(String str) { - builder.append(Style.stripColor(str)); - return this; - } - - public Fragment append(Object obj) { - append(String.valueOf(obj)); - return this; - } - - public Fragment append(StringBuffer sb) { - append(String.valueOf(sb)); - return this; - } - - public Fragment append(CharSequence s) { - append(String.valueOf(s)); - return this; - } - - public Fragment append(boolean b) { - append(String.valueOf(b)); - return this; - } - - public Fragment append(char c) { - append(String.valueOf(c)); - return this; - } - - public Fragment append(int i) { - append(String.valueOf(i)); - return this; - } - - public Fragment append(long lng) { - append(String.valueOf(lng)); - return this; - } - - public Fragment append(float f) { - append(String.valueOf(f)); - return this; - } - - public Fragment append(double d) { - append(String.valueOf(d)); - return this; - } - - public Fragment newLine() { - append("\n"); - return this; - } - - @Override - public String toString() { - return builder.toString(); - } - -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/Style.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/Style.java deleted file mode 100644 index d81774009..000000000 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/Style.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.util.formatting; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.collect.Maps; - -import java.util.Map; -import java.util.regex.Pattern; - -/** - * All supported color values for chat. - */ -public enum Style { - /** - * Represents black - */ - BLACK('0', 0x00), - /** - * Represents dark blue - */ - BLUE_DARK('1', 0x1), - /** - * Represents dark green - */ - GREEN_DARK('2', 0x2), - /** - * Represents dark blue (aqua) - */ - CYAN_DARK('3', 0x3), - /** - * Represents dark red - */ - RED_DARK('4', 0x4), - /** - * Represents dark purple - */ - PURPLE_DARK('5', 0x5), - /** - * Represents gold - */ - YELLOW_DARK('6', 0x6), - /** - * Represents gray - */ - GRAY('7', 0x7), - /** - * Represents dark gray - */ - GRAY_DARK('8', 0x8), - /** - * Represents blue - */ - BLUE('9', 0x9), - /** - * Represents green - */ - GREEN('a', 0xA), - /** - * Represents aqua - */ - CYAN('b', 0xB), - /** - * Represents red - */ - RED('c', 0xC), - /** - * Represents light purple - */ - PURPLE('d', 0xD), - /** - * Represents yellow - */ - YELLOW('e', 0xE), - /** - * Represents white - */ - WHITE('f', 0xF), - /** - * Represents magical characters that change around randomly - */ - OBFUSCATED('k', 0x10, true), - /** - * Makes the text bold. - */ - BOLD('l', 0x11, true), - /** - * Makes a line appear through the text. - */ - STRIKETHROUGH('m', 0x12, true), - /** - * Makes the text appear underlined. - */ - UNDERLINE('n', 0x13, true), - /** - * Makes the text italic. - */ - ITALIC('o', 0x14, true), - /** - * Resets all previous chat colors or formats. - */ - RESET('r', 0x15); - - /** - * The special character which prefixes all chat color codes. Use this if you need to dynamically - * convert color codes from your custom format. - */ - public static final char COLOR_CHAR = '\u00A7'; - private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + COLOR_CHAR + "[0-9A-FK-OR]"); - - private final int intCode; - private final char code; - private final boolean isFormat; - private final String toString; - private final static Map BY_ID = Maps.newHashMap(); - private final static Map BY_CHAR = Maps.newHashMap(); - - Style(char code, int intCode) { - this(code, intCode, false); - } - - Style(char code, int intCode, boolean isFormat) { - this.code = code; - this.intCode = intCode; - this.isFormat = isFormat; - this.toString = new String(new char[] {COLOR_CHAR, code}); - } - - /** - * Gets the char value associated with this color - * - * @return A char value of this color code - */ - public char getChar() { - return code; - } - - @Override - public String toString() { - return toString; - } - - /** - * Checks if this code is a format code as opposed to a color code. - * - * @return the if the code is a formatting code - */ - public boolean isFormat() { - return isFormat; - } - - /** - * Checks if this code is a color code as opposed to a format code. - * - * @return the if the code is a color - */ - public boolean isColor() { - return !isFormat && this != RESET; - } - - /** - * Gets the color represented by the specified color code - * - * @param code Code to check - * @return Associative Style with the given code, or null if it doesn't exist - */ - public static Style getByChar(char code) { - return BY_CHAR.get(code); - } - - /** - * Gets the color represented by the specified color code - * - * @param code Code to check - * @return Associative Style with the given code, or null if it doesn't exist - */ - public static Style getByChar(String code) { - checkNotNull(code); - checkArgument(!code.isEmpty(), "Code must have at least one character"); - - return BY_CHAR.get(code.charAt(0)); - } - - /** - * Strips the given message of all color codes - * - * @param input String to strip of color - * @return A copy of the input string, without any coloring - */ - public static String stripColor(final String input) { - if (input == null) { - return null; - } - - return STRIP_COLOR_PATTERN.matcher(input).replaceAll(""); - } - - /** - * Translates a string using an alternate color code character into a string that uses the internal - * ChatColor.COLOR_CODE color code character. The alternate color code character will only be replaced - * if it is immediately followed by 0-9, A-F, a-f, K-O, k-o, R or r. - * - * @param altColorChar The alternate color code character to replace. Ex: & - * @param textToTranslate Text containing the alternate color code character. - * @return Text containing the ChatColor.COLOR_CODE color code character. - */ - public static String translateAlternateColorCodes(char altColorChar, String textToTranslate) { - char[] b = textToTranslate.toCharArray(); - for (int i = 0; i < b.length - 1; i++) { - if (b[i] == altColorChar && "0123456789AaBbCcDdEeFfKkLlMmNnOoRr".indexOf(b[i+1]) > -1) { - b[i] = Style.COLOR_CHAR; - b[i+1] = Character.toLowerCase(b[i+1]); - } - } - return new String(b); - } - - /** - * Gets the ChatColors used at the end of the given input string. - * - * @param input Input string to retrieve the colors from. - * @return Any remaining ChatColors to pass onto the next line. - */ - public static String getLastColors(String input) { - String result = ""; - int length = input.length(); - - // Search backwards from the end as it is faster - for (int index = length - 1; index > -1; index--) { - char section = input.charAt(index); - if (section == COLOR_CHAR && index < length - 1) { - char c = input.charAt(index + 1); - Style color = getByChar(c); - - if (color != null) { - result = color + result; - - // Once we find a color or reset we can stop searching - if (color.isColor() || color == RESET) { - break; - } - } - } - } - - return result; - } - - static { - for (Style color : values()) { - BY_ID.put(color.intCode, color); - BY_CHAR.put(color.code, color); - } - } -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/StyleSet.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/StyleSet.java deleted file mode 100644 index 2a1c0cf46..000000000 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/StyleSet.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.util.formatting; - -import java.util.Objects; - -/** - * Represents set of styles, such as color, bold, etc. - */ -public class StyleSet { - - private Boolean bold; - private Boolean italic; - private Boolean underline; - private Boolean strikethrough; - private Boolean obfuscated; - private String insertion; - private Style color; - - /** - * Create a new style set with no properties set. - */ - public StyleSet() { - } - - /** - * Create a new style set with the given styles. - * - *

{@link Style#RESET} will be ignored if provided.

- * - * @param styles a list of styles - */ - public StyleSet(Style... styles) { - for (Style style : styles) { - if (style.isColor()) { - color = style; - } else if (style == Style.BOLD) { - bold = true; - } else if (style == Style.ITALIC) { - italic = true; - } else if (style == Style.UNDERLINE) { - underline = true; - } else if (style == Style.STRIKETHROUGH) { - strikethrough = true; - } else if (style == Style.OBFUSCATED) { - obfuscated = true; - } - } - } - - /** - * Get whether this style set is bold. - * - * @return true, false, or null if unset - */ - public Boolean getBold() { - return bold; - } - - /** - * Get whether the text is bold. - * - * @return true if bold - */ - public boolean isBold() { - return getBold() != null && getBold(); - } - - /** - * Set whether the text is bold. - * - * @param bold true, false, or null to unset - */ - public void setBold(Boolean bold) { - this.bold = bold; - } - - /** - * Get whether this style set is italicized. - * - * @return true, false, or null if unset - */ - public Boolean getItalic() { - return italic; - } - - /** - * Get whether the text is italicized. - * - * @return true if italicized - */ - public boolean isItalic() { - return getItalic() != null && getItalic(); - } - - /** - * Set whether the text is italicized. - * - * @param italic false, or null to unset - */ - public void setItalic(Boolean italic) { - this.italic = italic; - } - - /** - * Get whether this style set is underlined. - * - * @return true, false, or null if unset - */ - public Boolean getUnderline() { - return underline; - } - - /** - * Get whether the text is underlined. - * - * @return true if underlined - */ - public boolean isUnderline() { - return getUnderline() != null && getUnderline(); - } - - /** - * Set whether the text is underline. - * - * @param underline false, or null to unset - */ - public void setUnderline(Boolean underline) { - this.underline = underline; - } - - /** - * Get whether this style set is stricken through. - * - * @return true, false, or null if unset - */ - public Boolean getStrikethrough() { - return strikethrough; - } - - /** - * Get whether the text is stricken through. - * - * @return true if there is strikethrough applied - */ - public boolean isStrikethrough() { - return getStrikethrough() != null && getStrikethrough(); - } - - /** - * Set whether the text is stricken through. - * - * @param strikethrough false, or null to unset - */ - public void setStrikethrough(Boolean strikethrough) { - this.strikethrough = strikethrough; - } - - /** - * Get whether this style set is obfuscated. - * - * @return true, false, or null if unset - */ - public Boolean getObfuscated() { - return obfuscated; - } - - /** - * Get whether this style set is obfuscated. - * - * @return true if there is obfuscation applied - */ - public boolean isObfuscated() { - return getObfuscated() != null && getObfuscated(); - } - - /** - * Set whether the text is obfuscated. - * - * @param obfuscated false, or null to unset - */ - public void setObfuscated(Boolean obfuscated) { - this.obfuscated = obfuscated; - } - - /** - * Get this style set's insertion, if present. - * - * @return the insertion, or null if unset - */ - public String getInsertion() { - return insertion; - } - - /** - * Get whether this style set has an insertion. - * - * @return true if there is an insertion - */ - public boolean hasInsertion() { - return insertion != null; - } - - /** - * Set the style set's insertion. - * - * @param insertion the insertion, or null to unset - */ - public void setInsertion(String insertion) { - this.insertion = insertion; - } - - /** - * Get the color of the text. - * - * @return true, false, or null if unset - */ - public Style getColor() { - return color; - } - - /** - * Set the color of the text. - * - * @param color the color - */ - public void setColor(Style color) { - this.color = color; - } - - /** - * Return whether text formatting (bold, italics, underline, strikethrough) is set. - * - * @return true if formatting is set - */ - public boolean hasFormatting() { - return getBold() != null || getItalic() != null - || getUnderline() != null || getStrikethrough() != null - || getObfuscated() != null || getInsertion() != null; - } - - /** - * Return where the text formatting of the given style set is different from - * that assigned to this one. - * - * @param other the other style set - * @return true if there is a difference - */ - public boolean hasEqualFormatting(StyleSet other) { - return getBold() == other.getBold() && getItalic() == other.getItalic() - && getUnderline() == other.getUnderline() && - getStrikethrough() == other.getStrikethrough() && - getObfuscated() == other.getObfuscated() && - Objects.equals(getInsertion(), other.getInsertion()); - } - - /** - * Create a new instance with styles inherited from this one but with new styles - * from the given style set. - * - * @param style the style set - * @return a new style set instance - */ - public StyleSet extend(StyleSet style) { - StyleSet newStyle = clone(); - if (style.getBold() != null) { - newStyle.setBold(style.getBold()); - } - if (style.getItalic() != null) { - newStyle.setItalic(style.getItalic()); - } - if (style.getUnderline() != null) { - newStyle.setUnderline(style.getUnderline()); - } - if (style.getStrikethrough() != null) { - newStyle.setStrikethrough(style.getStrikethrough()); - } - if (style.getObfuscated() != null) { - newStyle.setObfuscated(style.getObfuscated()); - } - if (style.getInsertion() != null) { - newStyle.setInsertion(style.getInsertion()); - } - if (style.getColor() != null) { - newStyle.setColor(style.getColor()); - } - return newStyle; - } - - @Override - public StyleSet clone() { - StyleSet style = new StyleSet(); - style.setBold(getBold()); - style.setItalic(getItalic()); - style.setUnderline(getUnderline()); - style.setStrikethrough(getStrikethrough()); - style.setObfuscated(getObfuscated()); - style.setInsertion(getInsertion()); - style.setColor(getColor()); - return style; - } - -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/StyledFragment.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/StyledFragment.java deleted file mode 100644 index ec0578d47..000000000 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/StyledFragment.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.util.formatting; - -/** - * A fragment of text that can be styled. - */ -public class StyledFragment extends Fragment { - - private StyleSet style; - - public StyledFragment() { - style = new StyleSet(); - } - - public StyledFragment(StyleSet style) { - this.style = style; - } - - public StyledFragment(Style... styles) { - this.style = new StyleSet(styles); - } - - public StyleSet getStyle() { - return style; - } - - public void setStyles(StyleSet style) { - this.style = style; - } - - public StyledFragment createFragment(Style... styles) { - StyledFragment fragment = new StyledFragment(styles); - append(fragment); - return fragment; - } - - @Override - public StyledFragment append(String str) { - lastText().append(str); - return this; - } - - @Override - public StyledFragment append(Object obj) { - append(String.valueOf(obj)); - return this; - } - - @Override - public StyledFragment append(StringBuffer sb) { - append(String.valueOf(sb)); - return this; - } - - @Override - public StyledFragment append(CharSequence s) { - append(String.valueOf(s)); - return this; - } - - @Override - public StyledFragment append(boolean b) { - append(String.valueOf(b)); - return this; - } - - @Override - public StyledFragment append(char c) { - append(String.valueOf(c)); - return this; - } - - @Override - public StyledFragment append(int i) { - append(String.valueOf(i)); - return this; - } - - @Override - public StyledFragment append(long lng) { - append(String.valueOf(lng)); - return this; - } - - @Override - public StyledFragment append(float f) { - append(String.valueOf(f)); - return this; - } - - @Override - public StyledFragment append(double d) { - append(String.valueOf(d)); - return this; - } - - @Override - public StyledFragment newLine() { - append("\n"); - return this; - } - -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Code.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Code.java index 953d83fe3..ec9164c72 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Code.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Code.java @@ -19,19 +19,19 @@ package com.sk89q.worldedit.util.formatting.component; -import com.sk89q.worldedit.util.formatting.Style; -import com.sk89q.worldedit.util.formatting.StyledFragment; +import net.kyori.text.TextComponent; +import net.kyori.text.format.TextColor; /** * Represents a fragment representing a command that is to be typed. */ -public class Code extends StyledFragment { +public class Code extends TextComponent { /** * Create a new instance. */ - public Code() { - super(Style.CYAN); + public Code(String message) { + super(builder(message).color(TextColor.AQUA)); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandListBox.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandListBox.java index 145b6baca..2767ff920 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandListBox.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandListBox.java @@ -19,7 +19,9 @@ package com.sk89q.worldedit.util.formatting.component; -import com.sk89q.worldedit.util.formatting.Style; +import net.kyori.text.Component; +import net.kyori.text.TextComponent; +import net.kyori.text.format.TextColor; public class CommandListBox extends MessageBox { @@ -36,10 +38,10 @@ public class CommandListBox extends MessageBox { public CommandListBox appendCommand(String alias, String description) { if (!first) { - getContents().newLine(); + getContents().append(Component.newline()); } - getContents().createFragment(Style.YELLOW_DARK).append(alias).append(": "); - getContents().append(description); + getContents().append(TextComponent.of(alias, TextColor.GOLD).append(TextComponent.of(": "))); + getContents().append(TextComponent.of(description)); first = false; return this; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandUsageBox.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandUsageBox.java index 00a16c24e..fb0cc5c60 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandUsageBox.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/CommandUsageBox.java @@ -28,7 +28,8 @@ import com.sk89q.worldedit.util.command.CommandMapping; import com.sk89q.worldedit.util.command.Description; import com.sk89q.worldedit.util.command.Dispatcher; import com.sk89q.worldedit.util.command.PrimaryAliasComparator; -import com.sk89q.worldedit.util.formatting.StyledFragment; +import net.kyori.text.Component; +import net.kyori.text.TextComponent; import java.util.ArrayList; import java.util.List; @@ -38,7 +39,7 @@ import javax.annotation.Nullable; /** * A box to describe usage of a command. */ -public class CommandUsageBox extends StyledFragment { +public class CommandUsageBox extends TextComponent { /** * Create a new usage box. @@ -58,6 +59,7 @@ public class CommandUsageBox extends StyledFragment { * @param locals list of locals to use */ public CommandUsageBox(CommandCallable command, String commandString, @Nullable CommandLocals locals) { + super(builder()); checkNotNull(command); checkNotNull(commandString); if (command instanceof Dispatcher) { @@ -85,23 +87,23 @@ public class CommandUsageBox extends StyledFragment { private void attachCommandUsage(Description description, String commandString) { MessageBox box = new MessageBox("Help for " + commandString); - StyledFragment contents = box.getContents(); + Component contents = box.getContents(); if (description.getUsage() != null) { - contents.append(new Label().append("Usage: ")); - contents.append(description.getUsage()); + contents.append(new Label("Usage: ")); + contents.append(TextComponent.of(description.getUsage())); } else { - contents.append(new Subtle().append("Usage information is not available.")); + contents.append(new Subtle("Usage information is not available.")); } - contents.newLine(); + contents.append(Component.newline()); if (description.getHelp() != null) { - contents.append(description.getHelp()); + contents.append(TextComponent.of(description.getHelp())); } else if (description.getDescription() != null) { - contents.append(description.getDescription()); + contents.append(TextComponent.of(description.getDescription())); } else { - contents.append(new Subtle().append("No further help is available.")); + contents.append(new Subtle("No further help is available.")); } append(box); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Error.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Error.java index 056c99c18..5042a3804 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Error.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Error.java @@ -19,19 +19,19 @@ package com.sk89q.worldedit.util.formatting.component; -import com.sk89q.worldedit.util.formatting.Style; -import com.sk89q.worldedit.util.formatting.StyledFragment; +import net.kyori.text.TextComponent; +import net.kyori.text.format.TextColor; /** * Represents a fragment representing an error. */ -public class Error extends StyledFragment { +public class Error extends TextComponent { /** * Create a new instance. */ - public Error() { - super(Style.RED); + public Error(String message) { + super(builder(message).color(TextColor.RED)); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Label.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Label.java index 8a59732b0..bc0e46527 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Label.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Label.java @@ -19,19 +19,19 @@ package com.sk89q.worldedit.util.formatting.component; -import com.sk89q.worldedit.util.formatting.Style; -import com.sk89q.worldedit.util.formatting.StyledFragment; +import net.kyori.text.TextComponent; +import net.kyori.text.format.TextColor; /** * Represents a fragment representing a label. */ -public class Label extends StyledFragment { +public class Label extends TextComponent { /** * Create a new instance. */ - public Label() { - super(Style.YELLOW); + public Label(String message) { + super(builder(message).color(TextColor.YELLOW)); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/MessageBox.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/MessageBox.java index 086ce05e9..7b2dcc72e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/MessageBox.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/MessageBox.java @@ -21,36 +21,39 @@ package com.sk89q.worldedit.util.formatting.component; import static com.google.common.base.Preconditions.checkNotNull; -import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; -import com.sk89q.worldedit.util.formatting.Style; -import com.sk89q.worldedit.util.formatting.StyledFragment; +import net.kyori.text.Component; +import net.kyori.text.TextComponent; +import net.kyori.text.format.TextColor; /** * Makes for a box with a border above and below. */ -public class MessageBox extends StyledFragment { +public class MessageBox extends TextComponent { - private final StyledFragment contents = new StyledFragment(); + public static final int GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH = 47; + + private final Component contents = Component.empty(); /** * Create a new box. */ public MessageBox(String title) { + super(builder()); checkNotNull(title); - int leftOver = ColorCodeBuilder.GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH - title.length() - 2; + int leftOver = GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH - title.length() - 2; int leftSide = (int) Math.floor(leftOver * 1.0/3); int rightSide = (int) Math.floor(leftOver * 2.0/3); if (leftSide > 0) { - createFragment(Style.YELLOW).append(createBorder(leftSide)); + append(TextComponent.of(createBorder(leftSide), TextColor.YELLOW)); } - append(" "); - append(title); - append(" "); + append(Component.space()); + append(TextComponent.of(title)); + append(Component.space()); if (rightSide > 0) { - createFragment(Style.YELLOW).append(createBorder(rightSide)); + append(TextComponent.of(createBorder(rightSide), TextColor.YELLOW)); } - newLine(); + append(Component.newline()); append(contents); } @@ -67,7 +70,7 @@ public class MessageBox extends StyledFragment { * * @return the contents */ - public StyledFragment getContents() { + public Component getContents() { return contents; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Subtle.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Subtle.java index 34316c087..68600f0a3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Subtle.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Subtle.java @@ -19,19 +19,19 @@ package com.sk89q.worldedit.util.formatting.component; -import com.sk89q.worldedit.util.formatting.Style; -import com.sk89q.worldedit.util.formatting.StyledFragment; +import net.kyori.text.TextComponent; +import net.kyori.text.format.TextColor; /** * Represents a subtle part of the message. */ -public class Subtle extends StyledFragment { +public class Subtle extends TextComponent { /** * Create a new instance. */ - public Subtle() { - super(Style.GRAY); + public Subtle(String message) { + super(builder(message).color(TextColor.GRAY)); } } diff --git a/worldedit-forge/build.gradle b/worldedit-forge/build.gradle index 41c798310..c1ce166c1 100644 --- a/worldedit-forge/build.gradle +++ b/worldedit-forge/build.gradle @@ -91,6 +91,7 @@ shadowJar { include(dependency(':worldedit-core')) include(dependency('org.slf4j:slf4j-api')) include(dependency("org.apache.logging.log4j:log4j-slf4j-impl")) + include(dependency("net.kyori:text-serializer-gson:2.0.0")) } } diff --git a/worldedit-sponge/build.gradle b/worldedit-sponge/build.gradle index f65952c91..762557b6e 100644 --- a/worldedit-sponge/build.gradle +++ b/worldedit-sponge/build.gradle @@ -43,6 +43,7 @@ shadowJar { dependencies { include(dependency(':worldedit-core')) include(dependency('org.bstats:bstats-sponge:1.4')) + include(dependency("net.kyori:text-adapter-spongeapi:1.0.3")) } }