Commands classes refactoring + Display API is more clear

This commit is contained in:
Marc Baloup 2017-07-06 04:02:03 +02:00
parent 1098897955
commit a2b3e15e65
8 changed files with 695 additions and 451 deletions

View File

@ -1,161 +0,0 @@
package fr.pandacube.java.util.chat_display;
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 first = new TextComponent("");
private BaseComponent current = null;
public Display() {}
/**
* Après l'appel de ce contructeur, vous devez appeler nextComponent() pour
* initialiser la composante suivante
*/
public Display(String legacyText) {
convertAndAddLegacy(legacyText);
}
/**
* Construit un message en mettant à la ligne après chaque chaine passé en
* paramètre.<br/>
* Après l'appel de ce contructeur, vous devez appeler nextComponent() pour
* initialiser la composante suivante
*/
public Display(String[] legacyText) {
boolean f = true;
for (String s : legacyText) {
if (s == null) s = "";
if (!f) first.addExtra("\n");
f = false;
convertAndAddLegacy(s);
}
}
/**
* Construit un message en mettant à la ligne après chaque chaine passé en
* paramètre.<br/>
* Après l'appel de ce contructeur, vous devez appeler nextComponent() pour
* initialiser la composante suivante
*/
public Display(List<String> legacyText) {
this(legacyText.toArray(new String[legacyText.size()]));
}
/**
* Après l'appel de ce contructeur, vous devez appeler nextComponent() pour
* initialiser la composante suivante
*/
public Display(BaseComponent firstComponent) {
if (firstComponent == null) throw new IllegalArgumentException("le paramètre ne doit pas être null");
first.addExtra(firstComponent);
}
/**
* Après l'appel de cette méthode, vous devez appeler nextComponent() pour
* initialiser la composante suivante
*/
public Display convertAndAddLegacy(String legacyText) {
finalizeCurrentComponent();
if (legacyText == null) return this;
BaseComponent[] compo = TextComponent.fromLegacyText(legacyText);
for (BaseComponent c : compo)
first.addExtra(c);
return this;
}
public Display nextComponent(String str) {
finalizeCurrentComponent();
if (str == null) str = "";
current = new TextComponent(str);
return this;
}
public Display addComponent(BaseComponent cmp) {
if (cmp == null) throw new IllegalArgumentException("le paramètre ne doit pas être null");
finalizeCurrentComponent();
first.addExtra(cmp);
return this;
}
/**
* Équivalent à <code>nextComponent("\n")</code>, sauf qu'un nouvel appel à
* nextComponent() est nécessaire après.
*/
public Display nextLine() {
finalizeCurrentComponent();
first.addExtra(new TextComponent("\n"));
return this;
}
public Display setColor(ChatColor color) {
current.setColor(color);
return this;
}
public Display setBold(boolean b) {
current.setBold(b);
return this;
}
public Display setItalic(boolean i) {
current.setItalic(i);
return this;
}
public Display setUnderlined(boolean u) {
current.setUnderlined(u);
return this;
}
public Display setObfuscated(boolean o) {
current.setObfuscated(o);
return this;
}
public Display setStrikethrough(boolean s) {
current.setStrikethrough(s);
return this;
}
public Display setHoverText(Display content) {
current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new BaseComponent[] { content.get() }));
return this;
}
public Display setClickURL(String url) {
current.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url));
return this;
}
public Display setClickCommand(String cmd) {
current.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, cmd));
return this;
}
public Display setClickSuggest(String cmd) {
current.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, cmd));
return this;
}
private void finalizeCurrentComponent() {
if (current != null) first.addExtra(current);
current = null;
}
public BaseComponent get() {
finalizeCurrentComponent();
return first;
}
}

View File

@ -1,201 +0,0 @@
package fr.pandacube.java.util.chat_display;
import java.util.HashMap;
import java.util.Map;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
public class DisplayUtil {
private static Map<Integer, String> charList = new HashMap<Integer, String>() {
private static final long serialVersionUID = 1L;
{
put(-6, "§");
put(2, "!.,:;i|¡");
put(3, "'`lìí");
put(4, " I[]tï×");
put(5, "\"()*<>fk{}");
put(7, "@~®");
}
};
private static final int defaultChatMaxWidth = 320;
private static int chatMaxWidth = defaultChatMaxWidth;
private static final int defaultNbCharPerLineForConsole = 50;
private static int nbCharPerLineForConsole = defaultNbCharPerLineForConsole;
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 textLink, String url, String hoverText) {
String dispURL = (url.length() > 50) ? (url.substring(0, 48) + "...") : url;
return new Display().nextComponent(textLink).setClickURL(url)
.setHoverText(new Display(
ChatColor.GRAY + ((hoverText == null) ? "Cliquez pour accéder au site :" : hoverText) + "\n"
+ ChatColor.GRAY + dispURL))
.setColor(COLOR_LINK).get();
}
public static BaseComponent createCommandLink(String textLink, String commandWithSlash, String hoverText) {
Display d = new Display().nextComponent(textLink).setClickCommand(commandWithSlash).setColor(COLOR_COMMAND);
if (hoverText != null) d.setHoverText(new Display(hoverText));
return d.get();
}
public static BaseComponent createCommandSuggest(String textLink, String commandWithSlash, String hoverText) {
Display d = new Display().nextComponent(textLink).setClickSuggest(commandWithSlash).setColor(COLOR_COMMAND);
if (hoverText != null) d.setHoverText(new Display(hoverText));
return d.get();
}
public static BaseComponent centerText(BaseComponent text, char repeatedChar, ChatColor decorationColor,
boolean console) {
int textWidth = strWidth(text.toPlainText(), console);
if (textWidth > ((console) ? nbCharPerLineForConsole : chatMaxWidth)) return text;
String current = text.toPlainText();
int count = 0;
do {
count++;
current = repeatedChar + current + repeatedChar;
} while (strWidth(current, console) <= ((console) ? nbCharPerLineForConsole : chatMaxWidth));
count--;
String finalLeftOrRight = "";
for (int i = 0; i < count; i++)
finalLeftOrRight += repeatedChar;
Display d = new Display().nextComponent(finalLeftOrRight).setColor(decorationColor).addComponent(text);
if (repeatedChar != ' ') d.nextComponent(finalLeftOrRight).setColor(decorationColor);
return d.get();
}
public static BaseComponent leftText(BaseComponent text, char repeatedChar, ChatColor decorationColor, int nbLeft,
boolean console) {
int textWidth = strWidth(text.toPlainText(), console);
if (textWidth > ((console) ? nbCharPerLineForConsole : chatMaxWidth) || textWidth
+ nbLeft * charW(repeatedChar, console) > ((console) ? nbCharPerLineForConsole : chatMaxWidth))
return text;
Display d = new Display();
String finalLeft = "";
if (nbLeft > 0) {
for (int i = 0; i < nbLeft; i++)
finalLeft += repeatedChar;
d.nextComponent(finalLeft).setColor(decorationColor);
}
d.addComponent(text);
int count = 0;
String current = finalLeft + text.toPlainText();
do {
count++;
current += repeatedChar;
} while (strWidth(current, console) <= ((console) ? nbCharPerLineForConsole : chatMaxWidth));
count--;
if (repeatedChar != ' ') {
String finalRight = "";
for (int i = 0; i < count; i++)
finalRight += repeatedChar;
d.nextComponent(finalRight).setColor(decorationColor);
}
return d.get();
}
public static BaseComponent rightText(BaseComponent text, char repeatedChar, ChatColor decorationColor, int nbRight,
boolean console) {
int textWidth = strWidth(text.toPlainText(), console);
if (textWidth > ((console) ? nbCharPerLineForConsole : chatMaxWidth) || textWidth
+ nbRight * charW(repeatedChar, console) > ((console) ? nbCharPerLineForConsole : chatMaxWidth))
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) <= ((console) ? nbCharPerLineForConsole : chatMaxWidth));
count--;
String finalLeft = "";
for (int i = 0; i < count; i++)
finalLeft += repeatedChar;
Display d = new Display().nextComponent(finalLeft).setColor(decorationColor).addComponent(text);
if (repeatedChar != ' ') {
String finalRight = "";
for (int i = 0; i < nbRight; i++)
finalRight += repeatedChar;
d.nextComponent(finalRight).setColor(decorationColor);
}
return d.get();
}
public static BaseComponent emptyLine(char repeatedChar, ChatColor decorationColor, boolean console) {
int count = ((console) ? nbCharPerLineForConsole : chatMaxWidth) / charW(repeatedChar, console);
String finalLine = "";
for (int i = 0; i < count; i++)
finalLine += repeatedChar;
return new Display().nextComponent(finalLine).setColor(decorationColor).get();
}
public static int strWidth(String str, boolean console) {
int count = 0;
for (char c : str.toCharArray())
count += charW(c, console);
return (count < 0) ? 0 : count;
}
private static int charW(char c, boolean console) {
if (console) return (c == '§') ? -1 : 1;
for (int px : charList.keySet())
if (charList.get(px).indexOf(c) >= 0) return px;
return 6;
}
public static void setNbCharPerLineForConsole(int nb) {
if (nb < 0) nb = 0;
nbCharPerLineForConsole = nb;
}
public static void resetNbCharPerLineForConsole() {
nbCharPerLineForConsole = defaultNbCharPerLineForConsole;
}
public static void setChatMaxWidth(int px) {
if (px < 0) px = 0;
chatMaxWidth = px;
}
public static void resetChatMaxWidth() {
chatMaxWidth = defaultChatMaxWidth;
}
}

View File

@ -1,11 +1,9 @@
package fr.pandacube.java.util.commands;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import java.util.stream.Collectors;
public class AbstractCommand {
@ -50,91 +48,10 @@ public class AbstractCommand {
* @return
*/
public static List<String> getTabProposalFromToken(String token, Collection<String> allProposal) {
List<String> ret = new ArrayList<>();
for (String s : allProposal)
if (s != null && s.toLowerCase().startsWith(token.toLowerCase())) ret.add(s);
if (ret.isEmpty()) ret.addAll(allProposal);
ret.removeIf(s -> s == null);
ret.sort(null); // String implents Comparable
return ret;
}
public static final TabProposal TAB_NO_PROPOSAL = () -> Collections.emptyList();
public static TabProposal TAB_PROPOSAL(Collection<String> proposals) {
return () -> proposals;
}
public static TabProposal TAB_INTEGERS(int startIncluded, int endIncluded) {
List<String> proposals = new ArrayList<>(endIncluded - startIncluded + 1);
for (int i = startIncluded; i <= endIncluded; i++) {
proposals.add(Integer.toString(i));
}
return () -> proposals;
}
public static TabProposal TAB_PROPOSAL_LAST_PARAMS(String[] args, int index, Collection<String> proposals) {
String lastParamToken = getLastParams(args, index);
String[] splittedToken = lastParamToken.split(" ", -1);
int currentTokenPosition = splittedToken.length - 1;
String[] previousTokens = Arrays.copyOf(splittedToken, currentTokenPosition);
List<String> currentTokenProposal = new ArrayList<>();
for (String p : proposals) {
String[] splittedProposal = p.split(" ", -1);
if (splittedProposal.length <= currentTokenPosition)
continue;
if (!Arrays.equals(Arrays.copyOf(splittedToken, currentTokenPosition), previousTokens))
continue;
if (splittedProposal[currentTokenPosition].isEmpty())
continue;
currentTokenProposal.add(splittedProposal[currentTokenPosition]);
}
return () -> currentTokenProposal;
}
@FunctionalInterface
public interface TabProposal {
public abstract Collection<String> getProposal();
}
/**
* Throw an instance of this exception to indicate to the plugin command handler
* that the user has missused the command. The message, if provided, must indicate
* the reason of the mussusage of the command. It will be displayed on the screen
* with eventually indication of how to use the command (help command for example).
* If a {@link Throwable} cause is provided, it will be relayed to the plugin {@link Logger}.
*
*/
public static class BadCommandUsage extends RuntimeException {
private static final long serialVersionUID = 1L;
public BadCommandUsage() {
super();
}
public BadCommandUsage(Throwable cause) {
super(cause);
}
public BadCommandUsage(String message) {
super(message);
}
public BadCommandUsage(String message, Throwable cause) {
super(message, cause);
}
return allProposal.stream()
.filter(s -> s != null && s.toLowerCase().startsWith(token.toLowerCase()))
.sorted()
.collect(Collectors.toList());
}

View File

@ -0,0 +1,31 @@
package fr.pandacube.java.util.commands;
import java.util.logging.Logger;
/**
* Throw an instance of this exception to indicate to the plugin command handler
* that the user has missused the command. The message, if provided, must indicate
* the reason of the mussusage of the command. It will be displayed on the screen
* with eventually indication of how to use the command (help command for example).
* If a {@link Throwable} cause is provided, it will be relayed to the plugin {@link Logger}.
*
*/
public class BadCommandUsage extends RuntimeException {
private static final long serialVersionUID = 1L;
public BadCommandUsage() {
super();
}
public BadCommandUsage(Throwable cause) {
super(cause);
}
public BadCommandUsage(String message) {
super(message);
}
public BadCommandUsage(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,66 @@
package fr.pandacube.java.util.commands;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@FunctionalInterface
public interface TabProposal {
public abstract Collection<String> getProposal();
public static TabProposal empty() { return Collections::emptyList; }
public static TabProposal fromCollection(Collection<String> proposals) {
return () -> proposals;
}
public static TabProposal fromIntRange(int startIncluded, int endIncluded) {
return () -> IntStream.rangeClosed(startIncluded, endIncluded)
.mapToObj(v -> Integer.toString(v))
.collect(Collectors.toList());
}
/**
* Allow tab completion to supply proposal from multi-args (arguments with space,
* generally the last argument of a command) parameters
* @param args all the arguments currently in the buffer
* @param index the index of the first argument of the multi-args parameter
* @param proposals all possible proposals for the multi-args parameter
* @return
*/
public static TabProposal withMultiArgsLastParam(String[] args, int index, Collection<String> proposals) {
String lastParamToken = AbstractCommand.getLastParams(args, index);
String[] splittedToken = lastParamToken.split(" ", -1);
int currentTokenPosition = splittedToken.length - 1;
String[] previousTokens = Arrays.copyOf(splittedToken, currentTokenPosition);
List<String> currentTokenProposal = new ArrayList<>();
for (String p : proposals) {
String[] splittedProposal = p.split(" ", -1);
if (splittedProposal.length <= currentTokenPosition)
continue;
if (!Arrays.equals(Arrays.copyOf(splittedToken, currentTokenPosition), previousTokens))
continue;
if (splittedProposal[currentTokenPosition].isEmpty())
continue;
currentTokenProposal.add(splittedProposal[currentTokenPosition]);
}
return () -> currentTokenProposal;
}
}

View File

@ -0,0 +1,316 @@
package fr.pandacube.java.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) {
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 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();
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

@ -0,0 +1,276 @@
package fr.pandacube.java.util.text_display;
import java.util.Arrays;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
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 static final int DEFAULT_CHAR_SIZE = 6;
public static final Map<Integer, String> CHARS_SIZE = new ImmutableMap.Builder<Integer, String>()
.put(-6, "§")
.put(2, "!.,:;i|¡")
.put(3, "'`lìí")
.put(4, " I[]tï×")
.put(5, "\"()*<>fk{}")
.put(7, "@~®")
.build();
public static final int DEFAULT_CHAT_WIDTH = 320;
public static final int SIGN_WIDTH = 90;
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, 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);
}
private static BaseComponent _createURLLink(Display d, String url, String hoverText) {
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();
}
public static BaseComponent createCommandLink(String text, String commandWithSlash, String hoverText) {
return createCommandLink(text, commandWithSlash, hoverText == null ? null : TextComponent.fromLegacyText(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);
}
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();
}
public static BaseComponent createCommandSuggest(String text, String commandWithSlash, String hoverText) {
return createCommandSuggest(text, commandWithSlash, hoverText == null ? null : TextComponent.fromLegacyText(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);
}
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();
}
// 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;
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);
return d.get();
}
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))
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--;
if (repeatedChar != ' ') {
String finalRight = "";
for (int i = 0; i < count; i++)
finalRight += repeatedChar;
d.next(finalRight).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))
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);
if (repeatedChar != ' ') {
String finalRight = "";
for (int i = 0; i < nbRight; i++)
finalRight += repeatedChar;
d.next(finalRight).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();
}
public static int componentWidth(BaseComponent[] components, boolean console) {
return Arrays.stream(components).mapToInt(c -> componentWidth(c, console)).sum();
}
public static int componentWidth(BaseComponent component, boolean console) {
int count = 0;
for (BaseComponent c : component.getExtra())
count += componentWidth(c, console);
if (component instanceof TextComponent) {
count += strWidth(((TextComponent)component).getText(), console, component.isBold());
}
else if (component instanceof TranslatableComponent) {
for (BaseComponent c : ((TranslatableComponent)component).getWith())
count += componentWidth(c, console);
}
return count;
}
public static int strWidth(String str, boolean console, boolean bold) {
int count = 0;
for (char c : str.toCharArray())
count += charW(c, console, bold);
return (count < 0) ? 0 : count;
}
private static int charW(char c, boolean console, boolean bold) {
if (console) return (c == '§') ? -1 : 1;
for (int px : CHARS_SIZE.keySet())
if (CHARS_SIZE.get(px).indexOf(c) >= 0) return px + (bold ? 1 : 0);
return 6 + (bold ? 1 : 0);
}
}

View File

@ -1,4 +1,4 @@
package fr.pandacube.java.util.chat_display;
package fr.pandacube.java.util.text_display;
import net.md_5.bungee.api.ChatColor;