Created
March 24, 2019 14:14
-
-
Save Joo200/6e08dcd1e945496cb47aef393528fc56 to your computer and use it in GitHub Desktop.
Parse bb-coded strings to TextComponents.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package de.baba43.lib.helper.textcomponents; | |
| import net.md_5.bungee.api.chat.BaseComponent; | |
| import net.md_5.bungee.api.chat.TextComponent; | |
| import net.md_5.bungee.api.chat.TranslatableComponent; | |
| import java.text.MessageFormat; | |
| import java.util.HashMap; | |
| import java.util.regex.Matcher; | |
| import java.util.regex.Pattern; | |
| @SuppressWarnings("unused") | |
| public class TextComponentBuilder { | |
| private static String availibleClickEvents = "cmd|link|tic|suggest"; | |
| private static String availibleHover = "hover|hoverItem|hoverAchievement|hoverEntity"; | |
| private static String translateable = "translate"; | |
| private static String availibleHighlight = "h"; | |
| // private static Pattern stripRegex = Pattern.compile("\\[/?(hover|cmd)=?[a-z]*]", Pattern.CASE_INSENSITIVE); | |
| private static Pattern tagPattern = Pattern.compile("\\[(?:/" + | |
| "(" + availibleClickEvents + "|" + availibleHover + "|" + translateable + "|" + availibleHighlight + ")" | |
| + "|(" + translateable + "|" + availibleHighlight + ")" | |
| + "|(" + availibleClickEvents + "|" + availibleHover + ")=([^]]+))]" + | |
| "|(?:(&[0-9a-fklmnor]))"); | |
| public static String stripFormatsString(String input) { | |
| return tagPattern.matcher(input).replaceAll(""); | |
| } | |
| public static TextComponent parse(String toConvert) { | |
| return parse(toConvert, null, null); | |
| } | |
| public static TextComponent parse(String toConvert, TextFormat defaultFormat, TextFormat highlight) { | |
| return parse(toConvert, defaultFormat, highlight, new Object[0]); | |
| } | |
| public static TextComponent parse(String toConvert, TextFormat defaultFormat, TextFormat highlight, Object... args) { | |
| TextComponent finished_message = new TextComponent(""); | |
| if(defaultFormat == null) defaultFormat = new TextFormat(); | |
| if(highlight == null) highlight = defaultFormat; | |
| TextComponentFormat format = new TextComponentFormat(defaultFormat); | |
| TextFormat currentTextFormat = format.getFormat(); | |
| Matcher matcher = tagPattern.matcher(toConvert); | |
| HashMap<String, String> activeAttributes = new HashMap<>(); | |
| int prevEnd = 0; | |
| boolean isTranslateable = false; | |
| while (matcher.find()) { | |
| String inBetween = toConvert.substring(prevEnd, matcher.start()); | |
| inBetween = MessageFormat.format(inBetween, args); | |
| BaseComponent message; | |
| if(isTranslateable) { | |
| message = format.setBaseComponentFormat(new TranslatableComponent(inBetween)); | |
| } else { | |
| message = format.setTextComponentFormat(new TextComponent(inBetween)); | |
| } | |
| finished_message.addExtra(message); | |
| String attribute; | |
| String endTag = matcher.group(1); | |
| if (endTag != null && !endTag.isEmpty()) { | |
| // [/<endTag>] | |
| if (endTag.matches(availibleClickEvents)) { | |
| format.removeClickEvent(); | |
| } | |
| if (endTag.matches(availibleHover)) { | |
| format.removeHoverEvent(); | |
| } | |
| if (endTag.matches(translateable)) { | |
| isTranslateable = false; | |
| } | |
| if(endTag.matches(availibleHighlight)) { | |
| format.setFormat(currentTextFormat); | |
| } | |
| } else if (matcher.group(2) != null) { | |
| if(matcher.group(2).matches(translateable)) { | |
| isTranslateable = true; | |
| } | |
| if(matcher.group(2).matches(availibleHighlight)) { | |
| currentTextFormat = format.getFormat(); | |
| format.setFormat(highlight); | |
| } | |
| } else if (matcher.group(3) != null && matcher.group(4) != null) { | |
| String startTag = matcher.group(3); | |
| attribute = MessageFormat.format(matcher.group(4), args); | |
| // [<startTag>=<attribute>] | |
| if (startTag.matches(availibleClickEvents)) { | |
| format.setClickEvent(startTag, attribute); | |
| } | |
| if (startTag.matches(availibleHover)) { | |
| format.setHoverEvent(startTag, generateHoverText(attribute)); | |
| } | |
| } | |
| if (matcher.group(5) != null) { | |
| String formatTag = matcher.group(5); | |
| format.setFormat(formatTag); | |
| } | |
| prevEnd = matcher.end(); | |
| } | |
| // Nicht vergessen: | |
| finished_message.addExtra(format.setTextComponentFormat(new TextComponent( | |
| MessageFormat.format(toConvert.substring(prevEnd), args)))); | |
| return finished_message; | |
| } | |
| private static BaseComponent[] generateHoverText(String attribute) { | |
| Matcher matcher_hover = Pattern.compile("(?:(&[0-9a-fklmnor]))").matcher(attribute); | |
| int count = 0; | |
| while (matcher_hover.find()) { | |
| count++; | |
| } | |
| matcher_hover = Pattern.compile("(?:(&[0-9a-fklmnor]))").matcher(attribute); | |
| int prevHoverEnd = 0; | |
| int i = 0; | |
| BaseComponent[] hover = new BaseComponent[count + 1]; | |
| TextComponentFormat format = new TextComponentFormat(); | |
| format.resetFormats(); | |
| while (matcher_hover.find()) { | |
| String hover_inBetween = attribute.substring(prevHoverEnd, matcher_hover.start()); | |
| hover[i] = new TextComponent(hover_inBetween); | |
| hover[i] = format.setBaseComponentFormat(hover[i]); | |
| if (matcher_hover.group(1) != null) { | |
| String formatTag = matcher_hover.group(1); | |
| format.setFormat(formatTag); | |
| } | |
| i++; | |
| prevHoverEnd = matcher_hover.end(); | |
| } | |
| hover[i] = new TextComponent(attribute.substring(prevHoverEnd)); | |
| hover[i] = format.setBaseComponentFormat(hover[i]); | |
| return hover; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package de.baba43.lib.helper.textcomponents; | |
| 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; | |
| import java.util.regex.Pattern; | |
| @SuppressWarnings("unused") | |
| public class TextComponentFormat { | |
| private TextFormat format; | |
| private HoverEvent hoverEvent; | |
| private ClickEvent clickEvent; | |
| public TextComponentFormat(TextFormat format) { | |
| this.format = format; | |
| } | |
| public TextComponentFormat() { | |
| this.format = new TextFormat(); | |
| } | |
| public BaseComponent setBaseComponentFormat(BaseComponent toFormat) { | |
| toFormat.setBold(this.format.isBold()); | |
| toFormat.setItalic(this.format.isItalic()); | |
| toFormat.setUnderlined(this.format.isUnderline()); | |
| toFormat.setObfuscated(this.format.isObfuscate()); | |
| toFormat.setStrikethrough(this.format.isStrikethrough()); | |
| toFormat.setColor(this.format.getColor()); | |
| return toFormat; | |
| } | |
| public TextComponent setTextComponentFormat(TextComponent toFormat) { | |
| toFormat.setBold(this.format.isBold()); | |
| toFormat.setItalic(this.format.isItalic()); | |
| toFormat.setUnderlined(this.format.isUnderline()); | |
| toFormat.setObfuscated(this.format.isObfuscate()); | |
| toFormat.setStrikethrough(this.format.isStrikethrough()); | |
| toFormat.setColor(this.format.getColor()); | |
| if (clickEvent != null) toFormat.setClickEvent(this.clickEvent); | |
| if (hoverEvent != null) toFormat.setHoverEvent(this.hoverEvent); | |
| return toFormat; | |
| } | |
| public void setHoverEvent(String formatTag, BaseComponent[] hoverText) { | |
| HoverEvent.Action action; | |
| if (formatTag.equalsIgnoreCase("hover")) { | |
| action = HoverEvent.Action.SHOW_TEXT; | |
| } else if (formatTag.equalsIgnoreCase("hoverItem")) { | |
| action = HoverEvent.Action.SHOW_ITEM; | |
| } else if (formatTag.equalsIgnoreCase("hoverAchievement")) { | |
| action = HoverEvent.Action.SHOW_ACHIEVEMENT; | |
| } else action = HoverEvent.Action.SHOW_TEXT; | |
| this.hoverEvent = new HoverEvent(action, hoverText); | |
| } | |
| public void setClickEvent(String formatTag, String attribute) { | |
| ClickEvent.Action action; | |
| if (formatTag.equalsIgnoreCase("link")) { | |
| action = ClickEvent.Action.OPEN_URL; | |
| } else if (formatTag.equalsIgnoreCase("cmd")) { | |
| action = ClickEvent.Action.RUN_COMMAND; | |
| } else if(formatTag.equalsIgnoreCase("tic") || | |
| formatTag.equalsIgnoreCase("suggest")) { | |
| action = ClickEvent.Action.SUGGEST_COMMAND; | |
| } else { | |
| return; | |
| } | |
| clickEvent = new ClickEvent(action, attribute); | |
| } | |
| public void removeHoverEvent() { | |
| this.hoverEvent = null; | |
| } | |
| public void removeClickEvent() { | |
| this.clickEvent = null; | |
| } | |
| public void setFormat(String formatTag) { | |
| if (Pattern.compile("(?:(&[0-9a-f]))").matcher(formatTag).find()) { // Colorcodes(&0-&f) | |
| this.format = this.format.setColor(ChatColor.getByChar(formatTag.charAt(1))); | |
| } else if (formatTag.equals("&k")) { // obfuscated (wrabbel) | |
| this.format = this.format.setObfuscate(true); | |
| } else if (formatTag.equals("&l")) { | |
| this.format = this.format.setBold(true); | |
| } else if (formatTag.equals("&m")) { | |
| this.format = this.format.setStrikethrough(true); | |
| } else if (formatTag.equals("&n")) { | |
| this.format = this.format.setUnderline(true); | |
| } else if (formatTag.equals("&o")) { | |
| this.format = this.format.setItalic(true); | |
| } else { | |
| resetFormats(); | |
| } | |
| } | |
| public TextFormat getFormat() { | |
| return format; | |
| } | |
| public void setFormat(TextFormat format) { | |
| this.format = format; | |
| } | |
| public void resetFormats() { | |
| this.format = new TextFormat(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package de.baba43.lib.helper.textcomponents; | |
| import net.md_5.bungee.api.ChatColor; | |
| import java.util.Objects; | |
| public final class TextFormat { | |
| private final ChatColor color; | |
| private final boolean obfuscate; | |
| private final boolean underline; | |
| private final boolean bold; | |
| private final boolean strikethrough; | |
| private final boolean italic; | |
| public TextFormat() { | |
| this.color = ChatColor.WHITE; | |
| this.obfuscate = false; | |
| this.underline = false; | |
| this.bold = false; | |
| this.strikethrough = false; | |
| this.italic = false; | |
| } | |
| public TextFormat(ChatColor color) { | |
| this.color = color; | |
| this.obfuscate = false; | |
| this.underline = false; | |
| this.bold = false; | |
| this.strikethrough = false; | |
| this.italic = false; | |
| } | |
| public TextFormat(ChatColor color, boolean obfuscate, boolean underline, boolean bold, boolean strikethrough, boolean italic) { | |
| this.color = color; | |
| this.obfuscate = obfuscate; | |
| this.underline = underline; | |
| this.bold = bold; | |
| this.strikethrough = strikethrough; | |
| this.italic = italic; | |
| } | |
| public ChatColor getColor() { | |
| return color; | |
| } | |
| public boolean isObfuscate() { | |
| return obfuscate; | |
| } | |
| public boolean isUnderline() { | |
| return underline; | |
| } | |
| public boolean isBold() { | |
| return bold; | |
| } | |
| public boolean isStrikethrough() { | |
| return strikethrough; | |
| } | |
| public boolean isItalic() { | |
| return italic; | |
| } | |
| public TextFormat setColor(ChatColor color) { | |
| return new TextFormat(color, this.obfuscate, this.underline, this.bold, this.strikethrough, this.italic); | |
| } | |
| public TextFormat setObfuscate(boolean obfuscate) { | |
| return new TextFormat(this.color, obfuscate, this.underline, this.bold, this.strikethrough, this.italic); | |
| } | |
| public TextFormat setUnderline(boolean underline) { | |
| return new TextFormat(this.color, this.obfuscate, underline, this.bold, this.strikethrough, this.italic); | |
| } | |
| public TextFormat setBold(boolean bold) { | |
| return new TextFormat(this.color, this.obfuscate, this.underline, bold, this.strikethrough, this.italic); | |
| } | |
| public TextFormat setStrikethrough(boolean strikethrough) { | |
| return new TextFormat(this.color, this.obfuscate, this.underline, this.bold, strikethrough, this.italic); | |
| } | |
| public TextFormat setItalic(boolean italic) { | |
| return new TextFormat(this.color, this.obfuscate, this.underline, this.bold, this.strikethrough, italic); | |
| } | |
| @Override | |
| public boolean equals(Object o) { | |
| if (this == o) return true; | |
| if (o == null || getClass() != o.getClass()) return false; | |
| TextFormat that = (TextFormat) o; | |
| return obfuscate == that.obfuscate && | |
| underline == that.underline && | |
| bold == that.bold && | |
| strikethrough == that.strikethrough && | |
| italic == that.italic && | |
| color == that.color; | |
| } | |
| @Override | |
| public int hashCode() { | |
| return Objects.hash(color, obfuscate, underline, bold, strikethrough, italic); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment