cn.nukkit.utils.TextFormat Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of powernukkit Show documentation
Show all versions of powernukkit Show documentation
A Minecraft Bedrock Edition server software implementation made in Java from scratch which supports all new features.
package cn.nukkit.utils;
import com.google.common.collect.Maps;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* All supported formatting values for chat and console.
*/
public enum TextFormat {
/**
* Represents black.
*/
BLACK('0', 0x00),
/**
* Represents dark blue.
*/
DARK_BLUE('1', 0x1),
/**
* Represents dark green.
*/
DARK_GREEN('2', 0x2),
/**
* Represents dark blue (aqua).
*/
DARK_AQUA('3', 0x3),
/**
* Represents dark red.
*/
DARK_RED('4', 0x4),
/**
* Represents dark purple.
*/
DARK_PURPLE('5', 0x5),
/**
* Represents gold.
*/
GOLD('6', 0x6),
/**
* Represents gray.
*/
GRAY('7', 0x7),
/**
* Represents dark gray.
*/
DARK_GRAY('8', 0x8),
/**
* Represents blue.
*/
BLUE('9', 0x9),
/**
* Represents green.
*/
GREEN('a', 0xA),
/**
* Represents aqua.
*/
AQUA('b', 0xB),
/**
* Represents red.
*/
RED('c', 0xC),
/**
* Represents light purple.
*/
LIGHT_PURPLE('d', 0xD),
/**
* Represents yellow.
*/
YELLOW('e', 0xE),
/**
* Represents white.
*/
WHITE('f', 0xF),
/**
* Represents minecoins gold.
*/
MINECOIN_GOLD('g', 0x16),
/**
* Makes the text obfuscated.
*/
OBFUSCATED('k', 0x10, true),
/**
* Makes the text bold.
*/
BOLD('l', 0x11, true),
/**
* Makes a line appear through the text.
*/
STRIKETHROUGH('m', 0x12, true),
/**
* Makes the text appear underlined.
*/
UNDERLINE('n', 0x13, true),
/**
* Makes the text italic.
*/
ITALIC('o', 0x14, true),
/**
* Resets all previous chat colors or formats.
*/
RESET('r', 0x15);
/**
* The special character which prefixes all format codes. Use this if
* you need to dynamically convert format codes from your custom format.
*/
public static final char ESCAPE = '\u00A7';
private static final Pattern CLEAN_PATTERN = Pattern.compile("(?i)" + ESCAPE + "[0-9A-GK-OR]");
private final static Map BY_ID = Maps.newTreeMap();
private final static Map BY_CHAR = new HashMap<>();
static {
for (TextFormat color : values()) {
BY_ID.put(color.intCode, color);
BY_CHAR.put(color.code, color);
}
}
private final int intCode;
private final char code;
private final boolean isFormat;
private final String toString;
TextFormat(char code, int intCode) {
this(code, intCode, false);
}
TextFormat(char code, int intCode, boolean isFormat) {
this.code = code;
this.intCode = intCode;
this.isFormat = isFormat;
this.toString = new String(new char[]{ESCAPE, code});
}
/**
* Gets the TextFormat represented by the specified format code.
*
* @param code Code to check
* @return Associative {@link TextFormat} with the given code,
* or null if it doesn't exist
*/
public static TextFormat getByChar(char code) {
return BY_CHAR.get(code);
}
/**
* Gets the TextFormat represented by the specified format code.
*
* @param code Code to check
* @return Associative {@link TextFormat} with the given code,
* or null if it doesn't exist
*/
public static TextFormat getByChar(String code) {
if (code == null || code.length() <= 1) {
return null;
}
return BY_CHAR.get(code.charAt(0));
}
/**
* Cleans the given message of all format codes.
*
* @param input String to clean.
* @return A copy of the input string, without any formatting.
*/
public static String clean(final String input) {
return clean(input, false);
}
public static String clean(final String input, final boolean recursive) {
if (input == null) {
return null;
}
String result = CLEAN_PATTERN.matcher(input).replaceAll("");
if (recursive && CLEAN_PATTERN.matcher(result).find()) {
return clean(result, true);
}
return result;
}
/**
* Translates a string using an alternate format code character into a
* string that uses the internal TextFormat.ESCAPE format code
* character. The alternate format code character will only be replaced if
* it is immediately followed by 0-9, A-G, a-g, K-O, k-o, R or r.
*
* @param altFormatChar The alternate format code character to replace. Ex: &
* @param textToTranslate Text containing the alternate format code character.
* @return Text containing the TextFormat.ESCAPE format code character.
*/
public static String colorize(char altFormatChar, String textToTranslate) {
char[] b = textToTranslate.toCharArray();
for (int i = 0; i < b.length - 1; i++) {
if (b[i] == altFormatChar && "0123456789AaBbCcDdEeFfGgKkLlMmNnOoRr".indexOf(b[i + 1]) > -1) {
b[i] = TextFormat.ESCAPE;
b[i + 1] = Character.toLowerCase(b[i + 1]);
}
}
return new String(b);
}
/**
* Translates a string, using an ampersand (&) as an alternate format code
* character, into a string that uses the internal TextFormat.ESCAPE format
* code character. The alternate format code character will only be replaced if
* it is immediately followed by 0-9, A-G, a-g, K-O, k-o, R or r.
*
* @param textToTranslate Text containing the alternate format code character.
* @return Text containing the TextFormat.ESCAPE format code character.
*/
public static String colorize(String textToTranslate) {
return colorize('&', textToTranslate);
}
/**
* Gets the chat color used at the end of the given input string.
*
* @param input Input string to retrieve the colors from.
* @return Any remaining chat color to pass onto the next line.
*/
public static String getLastColors(String input) {
StringBuilder result = new StringBuilder();
int length = input.length();
// Search backwards from the end as it is faster
for (int index = length - 1; index > -1; index--) {
char section = input.charAt(index);
if (section == ESCAPE && index < length - 1) {
char c = input.charAt(index + 1);
TextFormat color = getByChar(c);
if (color != null) {
result.insert(0, color.toString());
// Once we find a color or reset we can stop searching
if (color.isColor() || color.equals(RESET)) {
break;
}
}
}
}
return result.toString();
}
/**
* Gets the char value associated with this color
*
* @return A char value of this color code
*/
public char getChar() {
return code;
}
@Override
public String toString() {
return toString;
}
/**
* Checks if this code is a format code as opposed to a color code.
*/
public boolean isFormat() {
return isFormat;
}
/**
* Checks if this code is a color code as opposed to a format code.
*/
public boolean isColor() {
return !isFormat && this != RESET;
}
}