Pretty big commit with lot of unrelated changes

This commit is contained in:
2020-11-02 23:23:41 +01:00
parent 34e015cb01
commit ea39a7a84a
25 changed files with 1654 additions and 743 deletions

View File

@@ -0,0 +1,309 @@
package fr.pandacube.util.text_display;
import java.awt.Color;
import java.util.UUID;
import fr.pandacube.Pandacube;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.ItemTag;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.hover.content.Content;
import net.md_5.bungee.api.chat.hover.content.Entity;
import net.md_5.bungee.api.chat.hover.content.Item;
import net.md_5.bungee.api.chat.hover.content.Text;
public abstract class Chat extends ChatStatic {
protected BaseComponent component;
protected boolean console = false;
public Chat(BaseComponent c) {
component = c;
}
public BaseComponent get() {
return component;
}
public BaseComponent[] getAsArray() {
return new BaseComponent[] { component };
}
public String getLegacyText() {
return component.toLegacyText();
}
public Chat then(BaseComponent subComponent) {
// here are some optimizations to avoid unnecessary component nesting
if (subComponent instanceof TextComponent) {
TextComponent txtComp = (TextComponent) subComponent;
if (!txtComp.hasFormatting() && (txtComp.getText() == null || txtComp.getText().isEmpty())) {
// no need to add the provided component to the current component.
// but eventual child component must be added
if (txtComp.getExtra() != null) {
for (BaseComponent child : txtComp.getExtra())
then(child);
}
return this;
}
}
component.addExtra(subComponent);
return this;
}
public Chat then(Chat comp) { return then(comp.get()); }
public Chat then(BaseComponent[] components) {
if (components != null) {
for (BaseComponent c : components) {
then(c);
}
}
return this;
}
public Chat thenText(Object plainText) { return then(text(plainText)); }
public Chat thenInfo(Object plainText) { return then(infoText(plainText)); }
public Chat thenSuccess(Object plainText) { return then(successText(plainText)); }
public Chat thenFailure(Object plainText) { return then(failureText(plainText)); }
public Chat thenData(Object plainText) { return then(dataText(plainText)); }
public Chat thenDecoration(Object plainText) { return then(decorationText(plainText)); }
public Chat thenPlayerName(String legacyText) { return then(playerNameText(legacyText)); }
public Chat thenNewLine() { return thenText("\n"); }
public Chat thenLegacyText(Object legacyText) { return then(legacyText(legacyText)); }
public Chat thenTranslation(String key, Object... with) { return then(translation(key, with)); }
public Chat thenKeyBind(String key) { return then(keybind(key)); }
public Chat thenScore(String name, String objective, String value) { return then(score(name, objective, value)); }
public Chat thenURLLink(Chat inner, String url, Chat hover) { return then(ChatUtil.createURLLink(inner, url, hover)); }
public Chat thenURLLink(Chat inner, String url) { return thenURLLink(inner, url, null); }
public Chat thenURLLink(String url, Chat hover) { return thenURLLink(text(url), url, hover); }
public Chat thenURLLink(String url) { return thenURLLink(text(url), url); }
public Chat thenCommandLink(Chat inner, String cmdWithSlash, Chat hover) { return then(ChatUtil.createCommandLink(inner, cmdWithSlash, hover)); }
public Chat thenCommandLink(Chat inner, String cmdWithSlash) { return thenCommandLink(inner, cmdWithSlash, null); }
public Chat thenCommandLink(String cmdWithSlash, Chat hover) { return thenCommandLink(text(cmdWithSlash), cmdWithSlash, hover); }
public Chat thenCommandLink(String cmdWithSlash) { return thenCommandLink(text(cmdWithSlash), cmdWithSlash); }
public Chat thenCommandSuggest(Chat inner, String cmdWithSlash, Chat hover) { return then(ChatUtil.createCommandSuggest(inner, cmdWithSlash, hover)); }
public Chat thenCommandSuggest(Chat inner, String cmdWithSlash) { return thenCommandSuggest(inner, cmdWithSlash, null); }
public Chat thenCommandSuggest(String cmdWithSlash, Chat hover) { return thenCommandSuggest(text(cmdWithSlash), cmdWithSlash, hover); }
public Chat thenCommandSuggest(String cmdWithSlash) { return thenCommandSuggest(text(cmdWithSlash), cmdWithSlash); }
/**
* Draws a full line with the default decoration char, colored with the default decoration color.
* @return this, for method chaining
*/
public Chat thenEmptyCharLine() {
return then(ChatUtil.emptyLine(Pandacube.CHAT_DECORATION_CHAR, Pandacube.CHAT_DECORATION_COLOR, console));
}
/**
* Draws a full line with the default decoration char, colored with the default decoration color,
* and with the provided Chat left aligned on the line, default to the decoration color, and surrounded with 1 space on each side.
* @return this, for method chaining
*/
public Chat thenLeftTextCharLine(Chat leftText) {
return then(ChatUtil.leftText(chat().decorationColor().thenText(" ").then(leftText).thenText(" ").get(), Pandacube.CHAT_DECORATION_CHAR,
Pandacube.CHAT_DECORATION_COLOR, Pandacube.CHAT_NB_CHAR_MARGIN, console));
}
/**
* Draws a full line with the default decoration char, colored with the default decoration color,
* and with the provided component left aligned on the line, default to the decoration color, and surrounded with 1 space on each side.
* @return this, for method chaining
*/
public Chat thenLeftTextCharLine(BaseComponent leftText) {
return thenLeftTextCharLine(chatComponent(leftText));
}
/**
* Draws a full line with the default decoration char, colored with the default decoration color,
* and with the provided Chat right aligned on the line, default to the decoration color, and surrounded with 1 space on each side.
* @return this, for method chaining
*/
public Chat thenRightTextCharLine(Chat rightText) {
return then(ChatUtil.rightText(chat().decorationColor().thenText(" ").then(rightText).thenText(" ").get(), Pandacube.CHAT_DECORATION_CHAR,
Pandacube.CHAT_DECORATION_COLOR, Pandacube.CHAT_NB_CHAR_MARGIN, console));
}
/**
* Draws a full line with the default decoration char, colored with the default decoration color,
* and with the provided component right aligned on the line, default to the decoration color, and surrounded with 1 space on each side.
* @return this, for method chaining
*/
public Chat thenRightTextCharLine(BaseComponent leftText) {
return thenRightTextCharLine(chatComponent(leftText));
}
/**
* Draws a full line with the default decoration char, colored with the default decoration color,
* and with the provided Chat centered on the line, default to the decoration color, and surrounded with 1 space on each side.
* @return this, for method chaining
*/
public Chat thenCenterTextCharLine(Chat centerText) {
return then(ChatUtil.centerText(chat().decorationColor().thenText(" ").then(centerText).thenText(" ").get(), Pandacube.CHAT_DECORATION_CHAR,
Pandacube.CHAT_DECORATION_COLOR, console));
}
/**
* Draws a full line with the default decoration char, colored with the default decoration color,
* and with the provided component centered on the line, default to the decoration color, and surrounded with 1 space on each side.
* @return this, for method chaining
*/
public Chat thenCenterTextCharLine(BaseComponent leftText) {
return thenCenterTextCharLine(chatComponent(leftText));
}
public static class FormatableChat extends Chat {
public FormatableChat(BaseComponent c) {
super(c);
}
public FormatableChat console(boolean c) { console = c; return this; }
public FormatableChat color(ChatColor c) { component.setColor(c); return this; }
public FormatableChat color(Color c) { return color(ChatColor.of(c)); }
public FormatableChat color(String c) { return color(ChatColor.of(c)); }
public FormatableChat black() { return color(ChatColor.BLACK); }
public FormatableChat darkBlue() { return color(ChatColor.DARK_BLUE); }
public FormatableChat darkGreen() { return color(ChatColor.DARK_GREEN); }
public FormatableChat darkAqua() { return color(ChatColor.DARK_AQUA); }
public FormatableChat darkRed() { return color(ChatColor.DARK_RED); }
public FormatableChat darkPurple() { return color(ChatColor.DARK_PURPLE); }
public FormatableChat gold() { return color(ChatColor.GOLD); }
public FormatableChat gray() { return color(ChatColor.GRAY); }
public FormatableChat darkGray() { return color(ChatColor.DARK_GRAY); }
public FormatableChat blue() { return color(ChatColor.BLUE); }
public FormatableChat green() { return color(ChatColor.GREEN); }
public FormatableChat aqua() { return color(ChatColor.AQUA); }
public FormatableChat red() { return color(ChatColor.RED); }
public FormatableChat lightPurple() { return color(ChatColor.LIGHT_PURPLE); }
public FormatableChat yellow() { return color(ChatColor.YELLOW); }
public FormatableChat white() { return color(ChatColor.WHITE); }
public FormatableChat successColor() { return color(Pandacube.CHAT_SUCCESS_COLOR); }
public FormatableChat failureColor() { return color(Pandacube.CHAT_FAILURE_COLOR); }
public FormatableChat infoColor() { return color(Pandacube.CHAT_INFO_COLOR); }
public FormatableChat dataColor() { return color(Pandacube.CHAT_DATA_COLOR); }
public FormatableChat decorationColor() { return color(Pandacube.CHAT_DECORATION_COLOR); }
public FormatableChat font(String f) { component.setFont(f); return this; }
public FormatableChat bold(Boolean b) { component.setBold(b); return this; }
public FormatableChat bold() { return bold(true); }
public FormatableChat italic(Boolean i) { component.setItalic(i); return this; }
public FormatableChat italic() { return italic(true); }
public FormatableChat underlined(Boolean u) { component.setUnderlined(u); return this; }
public FormatableChat underlined() { return underlined(true); }
public FormatableChat strikethrough(Boolean s) { component.setStrikethrough(s); return this; }
public FormatableChat strikethrough() { return strikethrough(true); }
public FormatableChat obfuscated(Boolean o) { component.setObfuscated(o); return this; }
public FormatableChat obfuscated() { return obfuscated(true); }
public FormatableChat shiftClickInsertion(String i) { component.setInsertion(i); return this; }
private FormatableChat clickEvent(ClickEvent e) { component.setClickEvent(e); return this; }
private FormatableChat clickEvent(ClickEvent.Action a, String v) { return clickEvent(new ClickEvent(a, v)); }
public FormatableChat clickCommand(String cmdWithSlash) { return clickEvent(ClickEvent.Action.RUN_COMMAND, cmdWithSlash); }
public FormatableChat clickSuggest(String cmdWithSlash) { return clickEvent(ClickEvent.Action.SUGGEST_COMMAND, cmdWithSlash); }
public FormatableChat clickClipboard(String value) { return clickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, value); }
public FormatableChat clickURL(String url) { return clickEvent(ClickEvent.Action.OPEN_URL, url); }
public FormatableChat clickBookPage(int page) { return clickEvent(ClickEvent.Action.CHANGE_PAGE, Integer.toString(page)); }
private FormatableChat hoverEvent(HoverEvent e) { component.setHoverEvent(e); return this; }
private FormatableChat hoverEvent(HoverEvent.Action a, Content v) { return hoverEvent(new HoverEvent(a, v)); }
private FormatableChat hoverText(Text v) { return hoverEvent(HoverEvent.Action.SHOW_TEXT, v); }
@SuppressWarnings("deprecation")
public FormatableChat hoverText(BaseComponent v) {
try {
return hoverText(new Text( new BaseComponent[] {v}));
} catch (NoSuchMethodError e) {
return hoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[] {v}));
}
}
public FormatableChat hoverText(Chat v) { return hoverText(v.get()); }
public FormatableChat hoverText(String legacyText) { return hoverText(legacyText(legacyText)); }
private FormatableChat hoverItem(Item v) { return hoverEvent(HoverEvent.Action.SHOW_ITEM, v); }
/** @param id namespaced item id */
public FormatableChat hoverItem(String id, int stackSize, ItemTag tag) { return hoverItem(new Item(id, stackSize, tag)); }
/** @param id namespaced item id */
public FormatableChat hoverItem(String id, int stackSize) { return hoverItem(id, stackSize, null); }
/** @param id namespaced item id */
public FormatableChat hoverItem(String id, ItemTag tag) { return hoverItem(id, -1, tag); }
/** @param id namespaced item id */
public FormatableChat hoverItem(String id) { return hoverItem(id, -1, null); }
public FormatableChat hoverEntity(Entity e) { return hoverEvent(HoverEvent.Action.SHOW_ENTITY, e); }
/** @param type namespaced entity type
* @param id cannot be null */
public FormatableChat hoverEntity(String type, UUID id, BaseComponent displayName) { return hoverEntity(new Entity(type, id.toString(), displayName)); }
/** @param type namespaced entity type
* @param id cannot be null */
public FormatableChat hoverEntity(String type, UUID id) { return hoverEntity(type, id, null); }
}
/* package */ static Object[] filterChatToBaseComponent(Object[] values) {
if (values == null)
return null;
for (int i = 0; i < values.length; i++) {
Object v = values[i];
if (v instanceof Chat)
values[i] = ((Chat) v).get();
}
return values;
}
}

View File

@@ -0,0 +1,293 @@
package fr.pandacube.util.text_display;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.javatuples.Pair;
import net.md_5.bungee.api.ChatColor;
public class ChatColorUtil {
public static final String ALL_CODES = "0123456789AaBbCcDdEeFfKkLlMmNnOoPpRr";
public static final String ALL_COLORS = "0123456789AaBbCcDdEeFf";
private static Pattern HEX_COLOR_PATTERN = Pattern.compile("§x(?>§[0-9a-f]){6}", Pattern.CASE_INSENSITIVE);
private static Pattern ESS_COLOR_PATTERN = Pattern.compile("§#[0-9a-f]{6}", Pattern.CASE_INSENSITIVE);
/**
* Return the legacy format needed to reproduce the format at the end of the provided legacy text.
* Supports standard chat colors and formats, BungeeCord Chat rgb format and EssentialsX rgb format.
* The RGB value from EssentialsX format is converted to BungeeCord Chat when included in the returned value.
* @param legacyText
* @return
*/
public static String getLastColors(String legacyText) {
String result = "";
int length = legacyText.length();
for (int index = length - 2; index >= 0; index--) {
if (legacyText.charAt(index) == ChatColor.COLOR_CHAR) {
// detection of rgb color §x§0§1§2§3§4§5
String rgb;
if (index > 11
&& legacyText.charAt(index - 12) == ChatColor.COLOR_CHAR
&& (legacyText.charAt(index - 11) == 'x'
|| legacyText.charAt(index - 11) == 'X')
&& HEX_COLOR_PATTERN.matcher(rgb = legacyText.substring(index - 12, index + 2)).matches()) {
result = rgb + result;
break;
}
// detection of rgb color §#012345 (and converting it to bungee chat format)
if (index < length - 7
&& legacyText.charAt(index + 1) == '#'
&& ESS_COLOR_PATTERN.matcher(rgb = legacyText.substring(index, index + 8)).matches()) {
rgb = "§x§" + rgb.charAt(2) + "§" + rgb.charAt(3)
+ "§" + rgb.charAt(4) + "§" + rgb.charAt(5)
+ "§" + rgb.charAt(6) + "§" + rgb.charAt(7);
result = rgb + result;
break;
}
// try detect non-rgb format
char colorChar = legacyText.charAt(index + 1);
ChatColor legacyColor = getChatColorByChar(colorChar);
if (legacyColor != null) {
result = legacyColor.toString() + result;
// Once we find a color or reset we can stop searching
char col = legacyColor.toString().charAt(1);
if ((col >= '0' && col <= '9')
|| (col >= 'a' && col <= 'f')
|| col == 'r') {
break;
}
}
}
}
return result;
}
public static ChatColor getChatColorByChar(char code) {
return ChatColor.getByChar(Character.toLowerCase(code));
}
/**
* Translate the color code of the provided string, that uses the the color char, to
* the {@code §} color code format.
* <p>
* This method is the improved version of {@link ChatColor#translateAlternateColorCodes(char, String)},
* because it takes into account essentials RGB color code, and {@code altColorChar} escaping (by doubling it).
* Essentials RGB color code are converted to Bungee chat RGB format, so the returned string can be converted
* to component (see {@link Chat#legacyText(Object)}).
* <p>
* This method should be used for user input (no permission check) or string configuration, but not string
* from another API or containing URLs.
*/
public static String translateAlternateColorCodes(char altColorChar, String textToTranslate)
{
char colorChar = ChatColor.COLOR_CHAR;
StringBuilder acc = new StringBuilder();
char[] b = textToTranslate.toCharArray();
for ( int i = 0; i < b.length; i++ )
{
if (i < b.length - 1 // legacy chat format
&& b[i] == altColorChar && ALL_CODES.indexOf(b[i + 1]) > -1)
{
acc.append(colorChar);
acc.append(lowerCase(b[i + 1]));
i++;
}
else if (i < b.length - 13 // bungee chat RGB format
&& b[i] == altColorChar
&& lowerCase(b[i + 1]) == 'x'
&& b[i + 2] == altColorChar && ALL_COLORS.indexOf(b[i + 3]) > -1
&& b[i + 4] == altColorChar && ALL_COLORS.indexOf(b[i + 5]) > -1
&& b[i + 6] == altColorChar && ALL_COLORS.indexOf(b[i + 7]) > -1
&& b[i + 8] == altColorChar && ALL_COLORS.indexOf(b[i + 9]) > -1
&& b[i + 10] == altColorChar && ALL_COLORS.indexOf(b[i + 11]) > -1
&& b[i + 12] == altColorChar && ALL_COLORS.indexOf(b[i + 13]) > -1) {
acc.append(colorChar).append(lowerCase(b[i + 1]));
acc.append(colorChar).append(lowerCase(b[i + 3]));
acc.append(colorChar).append(lowerCase(b[i + 5]));
acc.append(colorChar).append(lowerCase(b[i + 7]));
acc.append(colorChar).append(lowerCase(b[i + 9]));
acc.append(colorChar).append(lowerCase(b[i + 11]));
acc.append(colorChar).append(lowerCase(b[i + 13]));
i+=13;
}
else if (i < b.length - 7 // Essentials chat RGB format
&& b[i] == altColorChar
&& b[i + 1] == '#'
&& ALL_COLORS.indexOf(b[i + 2]) > -1 && ALL_COLORS.indexOf(b[i + 3]) > -1
&& ALL_COLORS.indexOf(b[i + 4]) > -1 && ALL_COLORS.indexOf(b[i + 5]) > -1
&& ALL_COLORS.indexOf(b[i + 6]) > -1 && ALL_COLORS.indexOf(b[i + 7]) > -1) {
acc.append(colorChar).append('x');
acc.append(colorChar).append(lowerCase(b[i + 2]));
acc.append(colorChar).append(lowerCase(b[i + 3]));
acc.append(colorChar).append(lowerCase(b[i + 4]));
acc.append(colorChar).append(lowerCase(b[i + 5]));
acc.append(colorChar).append(lowerCase(b[i + 6]));
acc.append(colorChar).append(lowerCase(b[i + 7]));
i+=7;
}
else if (i < b.length - 1 && b[i] == altColorChar && b[i + 1] == altColorChar) {
acc.append(altColorChar);
i++;
}
else {
acc.append(b[i]);
}
}
return acc.toString();
}
private static char lowerCase(char c) { return Character.toLowerCase(c); }
/**
* Force a text to be italic, while keeping other formatting and colors.
* The text is prefixed with the ITALIC tag, but is not reset at the end.
* @param legacyText the original text
* @return the text fully italic
*/
public static String forceItalic(String legacyText) {
return forceFormat(legacyText, ChatColor.ITALIC);
}
/**
* Force a text to be bold, while keeping other formatting and colors.
* The text is prefixed with the BOLD tag, but is not reset at the end.
* @param legacyText the original text
* @return the text fully bold
*/
public static String forceBold(String legacyText) {
return forceFormat(legacyText, ChatColor.BOLD);
}
/**
* Force a text to be underlined, while keeping other formatting and colors.
* The text is prefixed with the UNDERLINE tag, but is not reset at the end.
* @param legacyText the original text
* @return the text fully underlined
*/
public static String forceUnderline(String legacyText) {
return forceFormat(legacyText, ChatColor.UNDERLINE);
}
/**
* Force a text to be stroked through, while keeping other formatting and colors.
* The text is prefixed with the STRIKETHROUGH tag, but is not reset at the end.
* @param legacyText the original text
* @return the text fully stroked through
*/
public static String forceStrikethrough(String legacyText) {
return forceFormat(legacyText, ChatColor.STRIKETHROUGH);
}
/**
* Force a text to be obfuscated, while keeping other formatting and colors.
* The text is prefixed with the MAGIC tag, but is not reset at the end.
* @param legacyText the original text
* @return the text fully obfuscated
*/
public static String forceObfuscated(String legacyText) {
return forceFormat(legacyText, ChatColor.MAGIC);
}
private static String forceFormat(String legacyText, ChatColor format) {
return format + legacyText
.replace(format.toString(), "") // remove previous tag to make the result cleaner
.replaceAll("§([a-frA-FR0-9])", "§$1" + format);
}
/**
* Replace the RESET tag of the input string to the specified color tag.
* @param legacyText the original text
* @param color the color to used to replace the RESET tag
* (can be a combination of a color tag followed by multiple format tag)
* @return the resulting text
*/
public static String resetToColor(String legacyText, String color) {
return legacyText.replace(ChatColor.RESET.toString(), color);
}
public static ChatColor interpolateColor(float v0, float v1, float v, ChatColor cc0, ChatColor cc1) {
Color c0 = cc0.getColor(), c1 = cc1.getColor();
int r0 = c0.getRed(), g0 = c0.getGreen(), b0 = c0.getBlue(),
r1 = c1.getRed(), g1 = c1.getGreen(), b1 = c1.getBlue();
float normV = (v - v0) / (v1 - v0);
return ChatColor.of(new Color(
(int) (r0 + (r1 - r0) * normV),
(int) (g0 + (g1 - g0) * normV),
(int) (b0 + (b1 - b0) * normV)));
}
public static class ChatValueGradient {
List<Pair<Float, ChatColor>> colors = new ArrayList<>();
public synchronized ChatValueGradient add(float v, ChatColor col) {
colors.add(Pair.with(v, col));
return this;
}
public synchronized ChatColor pickColorAt(float v) {
if (colors.isEmpty())
throw new IllegalStateException("Must define at least one color in this ChatValueGradient instance.");
if (colors.size() == 1)
return colors.get(0).getValue1();
colors.sort((p1, p2) -> Float.compare(p1.getValue0(), p2.getValue0()));
if (v <= colors.get(0).getValue0())
return colors.get(0).getValue1();
if (v >= colors.get(colors.size() - 1).getValue0())
return colors.get(colors.size() - 1).getValue1();
int p1 = 1;
for (; p1 < colors.size(); p1++) {
if (colors.get(p1).getValue0() >= v)
break;
}
int p0 = p1 - 1;
float v0 = colors.get(p0).getValue0(), v1 = colors.get(p1).getValue0();
ChatColor cc0 = colors.get(p0).getValue1(), cc1 = colors.get(p1).getValue1();
return interpolateColor(v0, v1, v, cc0, cc1);
}
}
}

View File

@@ -0,0 +1,73 @@
package fr.pandacube.util.text_display;
import java.util.Objects;
import fr.pandacube.util.text_display.Chat.FormatableChat;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.KeybindComponent;
import net.md_5.bungee.api.chat.Keybinds;
import net.md_5.bungee.api.chat.ScoreComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.TranslatableComponent;
public abstract class ChatStatic {
public static FormatableChat chatComponent(BaseComponent c) {
return new FormatableChat(c);
}
public static FormatableChat chat() {
return chatComponent(new TextComponent());
}
public static FormatableChat chatComponent(BaseComponent[] c) {
return chatComponent(new TextComponent(c));
}
public static FormatableChat text(Object plainText) {
return chatComponent(new TextComponent(Objects.toString(plainText)));
}
public static FormatableChat legacyText(Object legacyText) {
return chatComponent(TextComponent.fromLegacyText(Objects.toString(legacyText), null));
}
public static FormatableChat infoText(Object plainText) {
return text(plainText).infoColor();
}
public static FormatableChat dataText(Object plainText) {
return text(plainText).dataColor();
}
public static FormatableChat decorationText(Object plainText) {
return text(plainText).decorationColor();
}
public static FormatableChat successText(Object plainText) {
return text(plainText).successColor();
}
public static FormatableChat failureText(Object plainText) {
return text(plainText).failureColor();
}
public static FormatableChat playerNameText(String legacyText) {
return legacyText(legacyText).white();
}
public static FormatableChat translation(String key, Object... with) {
return chatComponent(new TranslatableComponent(key, Chat.filterChatToBaseComponent(with)));
}
/** @param key one of the values in {@link Keybinds}. */
public static FormatableChat keybind(String key) {
return chatComponent(new KeybindComponent(key));
}
public static FormatableChat score(String name, String objective, String value) {
return chatComponent(new ScoreComponent(name, objective, value));
}
}

View File

@@ -1,5 +1,10 @@
package fr.pandacube.util.text_display;
import static fr.pandacube.util.text_display.Chat.chatComponent;
import static fr.pandacube.util.text_display.ChatStatic.chat;
import static fr.pandacube.util.text_display.ChatStatic.legacyText;
import static fr.pandacube.util.text_display.ChatStatic.text;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -9,12 +14,14 @@ import java.util.TreeSet;
import com.google.common.collect.ImmutableMap;
import fr.pandacube.Pandacube;
import fr.pandacube.util.text_display.Chat.FormatableChat;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.TranslatableComponent;
public class DisplayUtil {
public class ChatUtil {
public static final int DEFAULT_CHAR_SIZE = 6;
public static final Map<Integer, String> CHARS_SIZE = new ImmutableMap.Builder<Integer, String>()
@@ -34,33 +41,31 @@ public class DisplayUtil {
public static final int BOOK_WIDTH = 116;
public static final int CONSOLE_NB_CHAR_DEFAULT = 50;
public static final ChatColor COLOR_TITLE = ChatColor.GOLD;
public static final ChatColor COLOR_LINK = ChatColor.GREEN;
public static final ChatColor COLOR_COMMAND = ChatColor.GRAY;
public static BaseComponent createURLLink(String text, String url) {
return createURLLink(legacyText(text), url, null);
}
public static BaseComponent createURLLink(String text, String url, String hoverText) {
return _createURLLink(new Display(text), url, hoverText);
}
public static BaseComponent createURLLink(BaseComponent text, String url, String hoverText) {
return _createURLLink(new Display(text), url, hoverText);
}
public static BaseComponent createURLLink(BaseComponent[] text, String url, String hoverText) {
return _createURLLink(new Display(text), url, hoverText);
return createURLLink(legacyText(text), url, hoverText != null ? legacyText(hoverText) : null);
}
private static BaseComponent _createURLLink(Display d, String url, String hoverText) {
/* package */ static BaseComponent createURLLink(Chat element, String url, Chat hover) {
String dispURL = (url.length() > 50) ? (url.substring(0, 48) + "...") : url;
return d.clickURL(url)
.hoverText(ChatColor.GRAY + ((hoverText == null) ? "Cliquez pour accéder au site :" : hoverText) + "\n"
+ ChatColor.GRAY + dispURL)
.color(COLOR_LINK).get();
return chat()
.clickURL(url)
.color(Pandacube.CHAT_URL_COLOR)
.hoverText(
hover != null ? hover : Chat.text(dispURL)
)
.then(element)
.get();
}
@@ -71,19 +76,19 @@ public class DisplayUtil {
public static BaseComponent createCommandLink(String text, String commandWithSlash, String hoverText) {
return createCommandLink(text, commandWithSlash, hoverText == null ? null : TextComponent.fromLegacyText(hoverText));
return createCommandLink(text, commandWithSlash, hoverText == null ? null : legacyText(hoverText));
}
public static BaseComponent createCommandLink(String text, String commandWithSlash, BaseComponent hoverText) {
return createCommandLink(text, commandWithSlash, hoverText == null ? null : new BaseComponent[] {hoverText});
}
public static BaseComponent createCommandLink(String text, String commandWithSlash, BaseComponent[] hoverText) {
return _createCommandLink(new Display(text), commandWithSlash, hoverText);
public static BaseComponent createCommandLink(String text, String commandWithSlash, Chat hoverText) {
return createCommandLink(legacyText(text), commandWithSlash, hoverText);
}
private static BaseComponent _createCommandLink(Display d, String commandWithSlash, BaseComponent[] hoverText) {
d.clickCommand(commandWithSlash).color(COLOR_COMMAND);
if (hoverText != null) d.hoverText(hoverText);
return d.get();
/* package */ static BaseComponent createCommandLink(Chat d, String commandWithSlash, Chat hoverText) {
FormatableChat c = chat()
.clickCommand(commandWithSlash)
.color(Pandacube.CHAT_COMMAND_COLOR);
if (hoverText != null)
c.hoverText(hoverText);
return c.then(d).get();
}
@@ -96,19 +101,19 @@ public class DisplayUtil {
public static BaseComponent createCommandSuggest(String text, String commandWithSlash, String hoverText) {
return createCommandSuggest(text, commandWithSlash, hoverText == null ? null : TextComponent.fromLegacyText(hoverText));
return createCommandSuggest(text, commandWithSlash, hoverText == null ? null : legacyText(hoverText));
}
public static BaseComponent createCommandSuggest(String text, String commandWithSlash, BaseComponent hoverText) {
return createCommandSuggest(text, commandWithSlash, hoverText == null ? null : new BaseComponent[] {hoverText});
}
public static BaseComponent createCommandSuggest(String text, String commandWithSlash, BaseComponent[] hoverText) {
return _createCommandSuggest(new Display(text), commandWithSlash, hoverText);
public static BaseComponent createCommandSuggest(String text, String commandWithSlash, Chat hoverText) {
return createCommandSuggest(legacyText(text), commandWithSlash, hoverText);
}
private static BaseComponent _createCommandSuggest(Display d, String commandWithSlash, BaseComponent[] hoverText) {
d.clickSuggest(commandWithSlash).color(COLOR_COMMAND);
if (hoverText != null) d.hoverText(hoverText);
return d.get();
/* package */ static BaseComponent createCommandSuggest(Chat d, String commandWithSlash, Chat hoverText) {
FormatableChat c = chat()
.clickSuggest(commandWithSlash)
.color(Pandacube.CHAT_COMMAND_COLOR);
if (hoverText != null)
c.hoverText(hoverText);
return c.then(d).get();
}
@@ -134,32 +139,33 @@ public class DisplayUtil {
pagesToDisplay.add(i);
}
Display d = new Display(prefix);
Chat d = chat().thenLegacyText(prefix);
boolean first = true;
int previous = 0;
for (int page : pagesToDisplay) {
if (!first) {
if (page == previous + 1) {
d.next(" ");
d.thenText(" ");
}
else {
if (cmdFormat.endsWith("%d")) {
d.next(" ");
d.next(createCommandSuggest("...", cmdFormat.substring(0, cmdFormat.length() - 2), "Choisir la page"));
d.next(" ");
d.thenText(" ");
d.then(createCommandSuggest("...", cmdFormat.substring(0, cmdFormat.length() - 2), "Choisir la page"));
d.thenText(" ");
}
else
d.next(" ... ");
d.thenText(" ... ");
}
}
else
first = false;
d.next(createCommandLink(Integer.toString(page), String.format(cmdFormat, page), "Aller à la page " + page));
FormatableChat pDisp = chatComponent(createCommandLink(Integer.toString(page), String.format(cmdFormat, page), "Aller à la page " + page));
if (page == currentPage) {
d.color(ChatColor.WHITE);
pDisp.color(Pandacube.CHAT_COMMAND_HIGHLIGHTED_COLOR);
}
d.then(pDisp);
previous = page;
}
@@ -175,33 +181,31 @@ public class DisplayUtil {
// TODO refaire les 4 methodes ci-dessous
public static BaseComponent centerText(BaseComponent text, char repeatedChar, ChatColor decorationColor,
boolean console) {
int textWidth = strWidth(text.toPlainText(), console, false);
if (textWidth > ((console) ? CONSOLE_NB_CHAR_DEFAULT : DEFAULT_CHAT_WIDTH)) return text;
int textWidth = componentWidth(text, console);
int maxWidth = (console) ? CONSOLE_NB_CHAR_DEFAULT : DEFAULT_CHAT_WIDTH;
if (textWidth > maxWidth)
return text;
int repeatedCharWidth = charW(repeatedChar, console, false);
int sideWidth = (maxWidth - textWidth) / 2;
int sideNbChar = sideWidth / repeatedCharWidth;
if (sideNbChar == 0)
return text;
String sideChars = repeatedChar(repeatedChar, sideNbChar);
String current = text.toPlainText();
int count = 0;
do {
count++;
current = repeatedChar + current + repeatedChar;
} while (strWidth(current, console, false) <= ((console) ? CONSOLE_NB_CHAR_DEFAULT : DEFAULT_CHAT_WIDTH));
count--;
String finalLeftOrRight = "";
for (int i = 0; i < count; i++)
finalLeftOrRight += repeatedChar;
Display d = new Display().next(finalLeftOrRight).color(decorationColor).next(text);
if (repeatedChar != ' ') d.next(finalLeftOrRight).color(decorationColor);
Chat d = Chat.chat()
.then(text(sideChars).color(decorationColor))
.then(text);
if (repeatedChar != ' ')
d.then(text(sideChars).color(decorationColor));
return d.get();
@@ -209,91 +213,60 @@ public class DisplayUtil {
public static BaseComponent leftText(BaseComponent text, char repeatedChar, ChatColor decorationColor, int nbLeft,
boolean console) {
int textWidth = strWidth(text.toPlainText(), console, false);
if (textWidth > ((console) ? CONSOLE_NB_CHAR_DEFAULT : DEFAULT_CHAT_WIDTH) || textWidth
+ nbLeft * charW(repeatedChar, console, false) > ((console) ? CONSOLE_NB_CHAR_DEFAULT : DEFAULT_CHAT_WIDTH))
int textWidth = componentWidth(text, console);
int maxWidth = (console) ? CONSOLE_NB_CHAR_DEFAULT : DEFAULT_CHAT_WIDTH;
int repeatedCharWidth = charW(repeatedChar, console, false);
int leftWidth = nbLeft * repeatedCharWidth;
if (textWidth + leftWidth > maxWidth)
return text;
Display d = new Display();
String finalLeft = "";
if (nbLeft > 0) {
for (int i = 0; i < nbLeft; i++)
finalLeft += repeatedChar;
d.next(finalLeft).color(decorationColor);
}
d.next(text);
int count = 0;
String current = finalLeft + text.toPlainText();
do {
count++;
current += repeatedChar;
} while (strWidth(current, console, false) <= ((console) ? CONSOLE_NB_CHAR_DEFAULT : DEFAULT_CHAT_WIDTH));
count--;
int rightNbChar = (maxWidth - (textWidth + leftWidth)) / repeatedCharWidth;
Chat d = chat()
.then(text(repeatedChar(repeatedChar, nbLeft)).color(decorationColor))
.then(text);
if (repeatedChar != ' ') {
String finalRight = "";
for (int i = 0; i < count; i++)
finalRight += repeatedChar;
d.next(finalRight).color(decorationColor);
d.then(text(repeatedChar(repeatedChar, rightNbChar)).color(decorationColor));
}
return d.get();
}
public static BaseComponent rightText(BaseComponent text, char repeatedChar, ChatColor decorationColor, int nbRight,
boolean console) {
int textWidth = strWidth(text.toPlainText(), console, false);
if (textWidth > ((console) ? CONSOLE_NB_CHAR_DEFAULT : DEFAULT_CHAT_WIDTH) || textWidth
+ nbRight * charW(repeatedChar, console, false) > ((console) ? CONSOLE_NB_CHAR_DEFAULT : DEFAULT_CHAT_WIDTH))
int textWidth = componentWidth(text, console);
int maxWidth = (console) ? CONSOLE_NB_CHAR_DEFAULT : DEFAULT_CHAT_WIDTH;
int repeatedCharWidth = charW(repeatedChar, console, false);
int rightWidth = nbRight * repeatedCharWidth;
if (textWidth + rightWidth > maxWidth)
return text;
String tempText = text.toPlainText();
if (nbRight > 0) {
tempText += decorationColor;
for (int i = 0; i < nbRight; i++)
tempText += repeatedChar;
}
int count = 0;
String current = tempText;
do {
count++;
current = repeatedChar + current;
} while (strWidth(current, console, false) <= ((console) ? CONSOLE_NB_CHAR_DEFAULT : DEFAULT_CHAT_WIDTH));
count--;
String finalLeft = "";
for (int i = 0; i < count; i++)
finalLeft += repeatedChar;
Display d = new Display().next(finalLeft).color(decorationColor).next(text);
int leftNbChar = (maxWidth - (textWidth + rightWidth)) / repeatedCharWidth;
Chat d = chat()
.then(text(repeatedChar(repeatedChar, leftNbChar)).color(decorationColor))
.then(text);
if (repeatedChar != ' ') {
String finalRight = "";
for (int i = 0; i < nbRight; i++)
finalRight += repeatedChar;
d.next(finalRight).color(decorationColor);
d.then(text(repeatedChar(repeatedChar, nbRight)).color(decorationColor));
}
return d.get();
}
public static BaseComponent emptyLine(char repeatedChar, ChatColor decorationColor, boolean console) {
int count = ((console) ? CONSOLE_NB_CHAR_DEFAULT : DEFAULT_CHAT_WIDTH) / charW(repeatedChar, console, false);
String finalLine = "";
for (int i = 0; i < count; i++)
finalLine += repeatedChar;
return new Display().next(finalLine).color(decorationColor).get();
return text(repeatedChar(repeatedChar, count)).color(decorationColor).get();
}
private static String repeatedChar(char repeatedChar, int count) {
char[] c = new char[count];
Arrays.fill(c, repeatedChar);
return new String(c);
}
@@ -304,13 +277,23 @@ public class DisplayUtil {
public static int componentWidth(BaseComponent[] components, boolean console) {
return Arrays.stream(components).mapToInt(c -> componentWidth(c, console)).sum();
if (components == null)
return 0;
int count = 0;
for (BaseComponent c : components)
count += componentWidth(c, console);
return count;
}
public static int componentWidth(BaseComponent component, boolean console) {
if (component == null)
return 0;
int count = 0;
for (BaseComponent c : component.getExtra())
count += componentWidth(c, console);
if (component instanceof TextComponent) {
count += strWidth(((TextComponent)component).getText(), console, component.isBold());
}
@@ -318,6 +301,11 @@ public class DisplayUtil {
for (BaseComponent c : ((TranslatableComponent)component).getWith())
count += componentWidth(c, console);
}
if (component.getExtra() != null) {
for (BaseComponent c : component.getExtra())
count += componentWidth(c, console);
}
return count;
}
@@ -368,14 +356,15 @@ public class DisplayUtil {
if ((c >= '0' && c <= '9') // reset bold
|| (c >= 'a' && c <= 'f')
|| (c >= 'A' && c <= 'F')
|| c == 'r' || c == 'R')
|| c == 'r' || c == 'R'
|| c == 'x' || c == 'X')
bold = false;
}
else if (c == ' ') {
if (currentLineSize + currentWordSize > pixelWidth && currentLineSize > 0) { // wrap before word
lines.add(currentLine);
String lastStyle = getLastColors(currentLine);
String lastStyle = ChatColorUtil.getLastColors(currentLine);
if (currentWord.charAt(0) == ' ') {
currentWord = currentWord.substring(1);
currentWordSize -= charW(' ', false, firstCharCurrentWorldBold);
@@ -394,7 +383,7 @@ public class DisplayUtil {
else if (c == '\n') {
if (currentLineSize + currentWordSize > pixelWidth && currentLineSize > 0) { // wrap before word
lines.add(currentLine);
String lastStyle = getLastColors(currentLine);
String lastStyle = ChatColorUtil.getLastColors(currentLine);
if (currentWord.charAt(0) == ' ') {
currentWord = currentWord.substring(1);
currentWordSize -= charW(' ', false, firstCharCurrentWorldBold);
@@ -408,7 +397,7 @@ public class DisplayUtil {
}
// wrap after
lines.add(currentLine);
String lastStyle = getLastColors(currentLine);
String lastStyle = ChatColorUtil.getLastColors(currentLine);
currentLine = lastStyle.equals("§r") ? "" : lastStyle;
currentLineSize = 0;
@@ -438,123 +427,46 @@ public class DisplayUtil {
public static String getLastColors(String legacyText) {
String result = "";
int length = legacyText.length();
// Search backwards from the end as it is faster
for (int index = length - 1; index > -1; index--) {
char section = legacyText.charAt(index);
if (section == ChatColor.COLOR_CHAR && index < length - 1) {
char c = legacyText.charAt(index + 1);
ChatColor color = getChatColorByChar(c);
if (color != null) {
result = color.toString() + result;
// Once we find a color or reset we can stop searching
char col = color.toString().charAt(1);
if ((col >= '0' && col <= '9')
|| (col >= 'a' && col <= 'f')
|| col == 'r') {
break;
}
}
}
}
return result;
}
public static ChatColor getChatColorByChar(char code) {
return ChatColor.getByChar(Character.toLowerCase(code));
}
public static String truncatePrefix(String prefix, int maxLength) {
if (prefix.length() > maxLength) {
String lastColor = ChatColorUtil.getLastColors(prefix);
prefix = truncateAtLengthWithoutReset(prefix, maxLength);
if (!ChatColorUtil.getLastColors(prefix).equals(lastColor))
prefix = truncateAtLengthWithoutReset(prefix, maxLength - lastColor.length()) + lastColor;
}
return prefix;
}
public static String truncateAtLengthWithoutReset(String prefix, int l) {
if (prefix.length() > l) {
prefix = prefix.substring(0, l);
if (prefix.endsWith("§"))
prefix = prefix.substring(0, prefix.length()-1);
}
return prefix;
}
/**
* Force a text to be italic, while keeping other formatting and colors.
* The text is prefixed with the ITALIC tag, but is not reset at the end.
* @param legacyText the original text
* @return the text fully italic
*/
public static String forceItalic(String legacyText) {
return forceFormat(legacyText, ChatColor.ITALIC);
public static BaseComponent toUniqueBaseComponent(BaseComponent... baseComponents) {
if (baseComponents == null || baseComponents.length == 0)
return new TextComponent();
if (baseComponents.length == 1)
return baseComponents[0];
return new TextComponent(baseComponents);
}
/**
* Force a text to be bold, while keeping other formatting and colors.
* The text is prefixed with the BOLD tag, but is not reset at the end.
* @param legacyText the original text
* @return the text fully bold
*/
public static String forceBold(String legacyText) {
return forceFormat(legacyText, ChatColor.BOLD);
}
/**
* Force a text to be underlined, while keeping other formatting and colors.
* The text is prefixed with the UNDERLINE tag, but is not reset at the end.
* @param legacyText the original text
* @return the text fully underlined
*/
public static String forceUnderline(String legacyText) {
return forceFormat(legacyText, ChatColor.UNDERLINE);
}
/**
* Force a text to be stroked through, while keeping other formatting and colors.
* The text is prefixed with the STRIKETHROUGH tag, but is not reset at the end.
* @param legacyText the original text
* @return the text fully stroked through
*/
public static String forceStrikethrough(String legacyText) {
return forceFormat(legacyText, ChatColor.STRIKETHROUGH);
}
/**
* Force a text to be obfuscated, while keeping other formatting and colors.
* The text is prefixed with the MAGIC tag, but is not reset at the end.
* @param legacyText the original text
* @return the text fully obfuscated
*/
public static String forceObfuscated(String legacyText) {
return forceFormat(legacyText, ChatColor.MAGIC);
}
private static String forceFormat(String legacyText, ChatColor format) {
return format + legacyText
.replace(format.toString(), "") // remove previous tag to make the result cleaner
.replaceAll("§([a-frA-FR0-9])", "§$1" + format);
}
/**
* Replace the RESET tag of the input string to the specified color tag.
* @param legacyText the original text
* @param color the color to used to replace the RESET tag
* (can be a combination of a color tag followed by multiple format tag)
* @return the resulting text
*/
public static String resetToColor(String legacyText, String color) {
return legacyText.replace(ChatColor.RESET.toString(), color);
}

View File

@@ -1,331 +0,0 @@
package fr.pandacube.util.text_display;
import java.util.Arrays;
import java.util.List;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
public class Display {
private BaseComponent root = new TextComponent("");
private BaseComponent current = null;
/*
* ****************
* * Constructors *
* ****************
*/
/**
* Create a new instance. The current component is not initialized.
*/
public Display() {}
/**
* Create a new instance, with the current component already initialized with the parameter.
* @param legacyText a text that will be converted to a component and set to the current compoment.
*/
public Display(String legacyText) {
next(legacyText);
}
/**
* Create a new instance, with the current component already initialized with the parameter.
* @param legacyText a list of text that will be joined by a line return followed by ChatColor.RESET,
* then converted to a component and set to the current component.
*/
public Display(List<String> legacyText) {
this(String.join("\n"+ChatColor.RESET, legacyText));
}
/**
* Create a new instance, with the current component already initialized with the parameter.
* @param legacyText an array of text that will be joined by a line return followed by ChatColor.RESET,
* then converted to a component and set to the current component.
*/
public Display(String[] legacyText) {
this(Arrays.asList(legacyText));
}
/**
* Create a new instance, with the current component already initialized with the parameter.
* @param firstComponent a component corresponding to the current component.
*/
public Display(BaseComponent firstComponent) {
next(firstComponent);
}
/**
* Create a new instance, with the current component already initialized with the parameter.
* @param components an array of component that will be inside the current component.
*/
public Display(BaseComponent[] components) {
if (components == null) throw new IllegalArgumentException("le paramètre ne doit pas être null");
next(components);
}
/*
* ******************
* * next() methods *
* ******************
*/
/**
* Initialize the current component with the parameter.
* The previous component is stored in the root component.
* @param cmp a component corresponding to the new component.
* @return this
*/
public Display next(BaseComponent cmp) {
if (cmp == null) throw new IllegalArgumentException("le paramètre ne doit pas être null");
finalizeCurrentComponent();
current = cmp;
return this;
}
/**
* Initialize the current component with the parameter.
* The previous component is stored in the root component.
* @param str a text that will be converted to a component and set to the current compoment.
* @return this
*/
public Display next(String str) {
return next(TextComponent.fromLegacyText(str == null ? "" : str));
}
/**
* Initialize the current component with the parameter.
* The previous component is stored in the root component.
* @param components an array of component that will be inside the current component.
* @return this
*/
public Display next(BaseComponent[] components) {
if (components != null && components.length == 1)
return next(components[0]);
BaseComponent bc = new TextComponent();
for (BaseComponent c : components)
bc.addExtra(c);
return next(bc);
}
/**
* Initialize the current component with the parameter.
* The previous component is stored in the root component.
* @param cmp an other instance of Display that the root component become the current component of this instance.
* @return this
*/
public Display next(Display cmp) {
if (cmp == null) throw new IllegalArgumentException("le paramètre ne doit pas être null");
return next(cmp.get());
}
/**
* Initialize the current component with the text "\n".
* The previous component is stored in the root component.
* @return this
*/
public Display nextLine() {
finalizeCurrentComponent();
current = new TextComponent("\n");
return this;
}
/*
* **************************
* * Style and behaviour of *
* *** current component ****
* **************************
*/
/**
* Set the color of the current component.
* @param color the colour. Can be null;
* @return this
*/
public Display color(ChatColor color) {
current.setColor(color);
return this;
}
/**
* Set if the current component is bold.
* @param b true if bold, false if not, null if undefined
* @return this
*/
public Display bold(Boolean b) {
current.setBold(b);
return this;
}
/**
* Set if the current component is italic.
* @param b true if italic, false if not, null if undefined
* @return this
*/
public Display italic(Boolean i) {
current.setItalic(i);
return this;
}
/**
* Set if the current component is underlined.
* @param b true if underlined, false if not, null if undefined
* @return this
*/
public Display underlined(Boolean u) {
current.setUnderlined(u);
return this;
}
/**
* Set if the current component is obfuscated.
* In Minecraft user interface, obfuscated text displays randomly generated character in place of the originals. The random text regenerate each frame.
* @param b true if obfuscated, false if not, null if undefined
* @return this
*/
public Display obfuscated(Boolean o) {
current.setObfuscated(o);
return this;
}
/**
* Set if the current component is strikethrough.
* @param b true if strikethrough, false if not, null if undefined
* @return this
*/
public Display strikethrough(Boolean s) {
current.setStrikethrough(s);
return this;
}
/**
* Set a text displayed as a tooltip when the cursor is hover the current component.
* This method is only relevant if this Display is intended to be displayed in the chat or in a book
* @param content the text as an array of component.
* @return this
*/
public Display hoverText(BaseComponent[] content) {
current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, content));
return this;
}
/**
* Set a text displayed as a tooltip when the cursor is hover the current component.
* This method is only relevant if this Display is intended to be displayed in the chat or in a book
* @param content the text as a component
* @return this
*/
public Display hoverText(BaseComponent content) {
return hoverText(new BaseComponent[] {content});
}
/**
* Set a text displayed as a tooltip when the cursor is hover the current component.
* This method is only relevant if this Display is intended to be displayed in the chat or in a book
* @param content the text as a legacy string.
* @return this
*/
public Display hoverText(String legacyContent) {
return hoverText(TextComponent.fromLegacyText(legacyContent));
}
/**
* Set a text displayed as a tooltip when the cursor is hover the current component.
* This method is only relevant if this Display is intended to be displayed in the chat or in a book
* @param content the text as a {@link Display} instance.
* @return this
*/
public Display hoverText(Display content) {
return hoverText(content.get());
}
/**
* Allow the player to click on the current component to access to the specified URL.
* This method is only relevant if this Display is intended to be displayed in the chat
* @param url the URL
* @return this
*/
public Display clickURL(String url) {
current.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url));
return this;
}
/**
* Allow the player to click on the current component to copy content to the clipboard.
* @param str the string to copy to clipboard
* @return this
*/
public Display clickClipboard(String str) {
current.setClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, str));
return this;
}
/**
* Allow the player to click on the current component to run the specified command.
* This method is only relevant if this Display is intended to be displayed in the chat, in a book or on a sign.
* On the sign, all the commands are executed in a row when the player click on the sign.
* @param cmd the command, with the "/"
* @return this
*/
public Display clickCommand(String cmd) {
current.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, cmd));
return this;
}
/**
* Allow the player to click on the current component to fill the textfield with the specified command.
* This method is only relevant if this Display is intended to be displayed in the chat.
* @param cmd the command
* @return this
*/
public Display clickSuggest(String cmd) {
current.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, cmd));
return this;
}
/**
* Allow the player to shuft-click on the current component to insert the specified string into the textfield (at the cursor location).
* This method is only relevant if this Display is intended to be displayed in the chat.
* @param str the string
* @return this
*/
public Display clickInsertion(String str) {
current.setInsertion(str);
return this;
}
private void finalizeCurrentComponent() {
if (current != null) root.addExtra(current);
current = null;
}
/**
* Add the current compoment into the root component and return the root component.
* @return
*/
public BaseComponent get() {
finalizeCurrentComponent();
if (!root.hasFormatting() && root.getExtra() != null && root.getExtra().size() == 1)
return root.getExtra().get(0);
return root;
}
/**
* Add the current compoment into the root component and return all the components in an array.
* @return
*/
public BaseComponent[] getArray() {
finalizeCurrentComponent();
return root.getExtra().toArray(new BaseComponent[root.getExtra().size()]);
}
}

View File

@@ -6,7 +6,6 @@ public class TextProgressBar {
private static String pattern_start = "[";
private static String pattern_end = "]";
private static ChatColor color_empty = ChatColor.DARK_GRAY;
private static ChatColor color_decoration = ChatColor.GOLD;
private static ChatColor color_default = ChatColor.RESET;
private static String pattern_empty = ".";
private static String pattern_full = "|";
@@ -35,7 +34,7 @@ public class TextProgressBar {
}
int sum_sizes = 0;
String bar = color_decoration + pattern_start;
String bar = pattern_start;
for (int i = 0; i < sizes.length; i++) {
sum_sizes += sizes[i];
@@ -52,7 +51,7 @@ public class TextProgressBar {
for (int j = 0; j < (max_size - sum_sizes); j++)
bar = bar + pattern_empty;
bar = bar + color_decoration + pattern_end;
bar = bar + ChatColor.RESET + pattern_end;
return bar;
}