diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java index 55929af02..7f48b193d 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitCommandSender.java @@ -26,6 +26,7 @@ import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.session.SessionKey; import com.sk89q.worldedit.util.auth.AuthorizationException; +import com.sk89q.worldedit.util.formatting.Fragment; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -91,6 +92,12 @@ public class BukkitCommandSender implements Actor { } } + @Override + public void print(Fragment fragment) { + // TODO Bukkit is bad and the API is somewhat lacking + printRaw(fragment.toString()); + } + @Override public boolean canDestroyBedrock() { return true; diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index d814cc7ba..8ef240f2c 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -31,6 +31,7 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.session.SessionKey; import com.sk89q.worldedit.util.HandSide; +import com.sk89q.worldedit.util.formatting.Fragment; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; @@ -125,6 +126,12 @@ public class BukkitPlayer extends AbstractPlayerActor { } } + @Override + public void print(Fragment fragment) { + // TODO Bukkit is bad and the API is somewhat lacking + printRaw(fragment.toString()); + } + @Override public void setPosition(Vector3 pos, float pitch, float yaw) { player.teleport(new Location(player.getWorld(), pos.getX(), pos.getY(), diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Actor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Actor.java index cf64b5974..c5fb1b6b1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Actor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Actor.java @@ -23,6 +23,7 @@ import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.session.SessionOwner; import com.sk89q.worldedit.util.Identifiable; import com.sk89q.worldedit.util.auth.Subject; +import com.sk89q.worldedit.util.formatting.Fragment; import java.io.File; @@ -75,6 +76,13 @@ public interface Actor extends Identifiable, SessionOwner, Subject { */ void printError(String msg); + /** + * Print a {@link Fragment}. + * + * @param fragment The fragment to print + */ + void print(Fragment fragment); + /** * Returns true if the actor can destroy bedrock. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java index 48173abbc..54700aeea 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java @@ -31,6 +31,7 @@ import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.session.SessionKey; import com.sk89q.worldedit.util.HandSide; import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.util.formatting.Fragment; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.gamemode.GameMode; @@ -132,6 +133,11 @@ class PlayerProxy extends AbstractPlayerActor { basePlayer.printError(msg); } + @Override + public void print(Fragment fragment) { + basePlayer.print(fragment); + } + @Override public String[] getGroups() { return permActor.getGroups(); 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 index dbaa904ce..14e8ddbca 100644 --- 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 @@ -90,6 +90,9 @@ public class ColorCodeBuilder { if (style.isStrikethrough()) { builder.append(Style.STRIKETHROUGH); } + if (style.isObfuscated()) { + builder.append(Style.OBFUSCATED); + } return builder.toString(); } 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 index 3d1add7f4..e49d7c678 100644 --- 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 @@ -19,16 +19,45 @@ 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; 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 index d6c70eeb8..d81774009 100644 --- 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 @@ -29,8 +29,6 @@ import java.util.regex.Pattern; /** * All supported color values for chat. - * - *

From Bukkit.

*/ public enum Style { /** @@ -100,7 +98,7 @@ public enum Style { /** * Represents magical characters that change around randomly */ - RANDOMIZE('k', 0x10, true), + OBFUSCATED('k', 0x10, true), /** * Makes the text bold. */ 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 index 408dc1e43..2a1c0cf46 100644 --- 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 @@ -19,6 +19,8 @@ package com.sk89q.worldedit.util.formatting; +import java.util.Objects; + /** * Represents set of styles, such as color, bold, etc. */ @@ -28,6 +30,8 @@ public class StyleSet { private Boolean italic; private Boolean underline; private Boolean strikethrough; + private Boolean obfuscated; + private String insertion; private Style color; /** @@ -55,6 +59,8 @@ public class StyleSet { underline = true; } else if (style == Style.STRIKETHROUGH) { strikethrough = true; + } else if (style == Style.OBFUSCATED) { + obfuscated = true; } } } @@ -167,6 +173,60 @@ public class StyleSet { 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. * @@ -192,7 +252,8 @@ public class StyleSet { */ public boolean hasFormatting() { return getBold() != null || getItalic() != null - || getUnderline() != null || getStrikethrough() != null; + || getUnderline() != null || getStrikethrough() != null + || getObfuscated() != null || getInsertion() != null; } /** @@ -205,7 +266,9 @@ public class StyleSet { public boolean hasEqualFormatting(StyleSet other) { return getBold() == other.getBold() && getItalic() == other.getItalic() && getUnderline() == other.getUnderline() && - getStrikethrough() == other.getStrikethrough(); + getStrikethrough() == other.getStrikethrough() && + getObfuscated() == other.getObfuscated() && + Objects.equals(getInsertion(), other.getInsertion()); } /** @@ -229,6 +292,12 @@ public class StyleSet { 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()); } @@ -242,6 +311,8 @@ public class StyleSet { 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 index 9ef38446b..ec0578d47 100644 --- 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 @@ -19,18 +19,13 @@ package com.sk89q.worldedit.util.formatting; -import java.util.ArrayList; -import java.util.List; - /** * A fragment of text that can be styled. */ public class StyledFragment extends Fragment { - private final List children = new ArrayList<>(); private StyleSet style; - private Fragment lastText; - + public StyledFragment() { style = new StyleSet(); } @@ -51,36 +46,12 @@ public class StyledFragment extends Fragment { this.style = style; } - 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 StyledFragment createFragment(Style... styles) { StyledFragment fragment = new StyledFragment(styles); append(fragment); return fragment; } - public StyledFragment append(StyledFragment fragment) { - children.add(fragment); - return this; - } - @Override public StyledFragment append(String str) { lastText().append(str); 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 new file mode 100644 index 000000000..056c99c18 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/formatting/component/Error.java @@ -0,0 +1,37 @@ +/* + * 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.component; + +import com.sk89q.worldedit.util.formatting.Style; +import com.sk89q.worldedit.util.formatting.StyledFragment; + +/** + * Represents a fragment representing an error. + */ +public class Error extends StyledFragment { + + /** + * Create a new instance. + */ + public Error() { + super(Style.RED); + } + +}