Added support for special color code (reset/bold/italic/etc...)

This commit is contained in:
Felix Cravic 2020-07-03 19:53:53 +02:00
parent 87921a8788
commit 2b021e26c1
2 changed files with 133 additions and 17 deletions

View File

@ -7,8 +7,16 @@ import java.util.Map;
public class ChatColor {
// Special
public static final ChatColor NO_COLOR = new ChatColor();
public static final ChatColor RESET = new ChatColor("reset");
public static final ChatColor BOLD = new ChatColor("bold");
public static final ChatColor ITALIC = new ChatColor("italic");
public static final ChatColor UNDERLINED = new ChatColor("underlined");
public static final ChatColor STRIKETHROUGH = new ChatColor("strikethrough");
public static final ChatColor OBFUSCATED = new ChatColor("obfuscated");
// Color
public static final ChatColor BLACK = fromRGB(0, 0, 0, 0);
public static final ChatColor DARK_BLUE = fromRGB(0, 0, 170, 1);
public static final ChatColor DARK_GREEN = fromRGB(0, 170, 0, 2);
@ -29,6 +37,14 @@ public class ChatColor {
private static Map<Character, ChatColor> legacyColorCodesMap = new HashMap<>();
static {
colorCode.put("reset", RESET);
colorCode.put("bold", BOLD);
colorCode.put("italic", ITALIC);
colorCode.put("underlined", UNDERLINED);
colorCode.put("strikethrough", STRIKETHROUGH);
colorCode.put("obfuscated", OBFUSCATED);
colorCode.put("black", BLACK);
colorCode.put("dark_blue", DARK_BLUE);
colorCode.put("dark_green", DARK_GREEN);
@ -46,6 +62,13 @@ public class ChatColor {
colorCode.put("yellow", YELLOW);
colorCode.put("white", WHITE);
legacyColorCodesMap.put('k', OBFUSCATED);
legacyColorCodesMap.put('l', BOLD);
legacyColorCodesMap.put('m', STRIKETHROUGH);
legacyColorCodesMap.put('n', UNDERLINED);
legacyColorCodesMap.put('o', ITALIC);
legacyColorCodesMap.put('r', RESET);
legacyColorCodesMap.put('0', BLACK);
legacyColorCodesMap.put('1', DARK_BLUE);
legacyColorCodesMap.put('2', DARK_GREEN);
@ -68,6 +91,11 @@ public class ChatColor {
private int red, green, blue;
private int id;
// Special
private String codeName;
private boolean special;
private ChatColor(int r, int g, int b, int id) {
this.empty = false;
this.red = r;
@ -76,8 +104,14 @@ public class ChatColor {
this.id = id;
}
private ChatColor(String codeName) {
this.codeName = codeName;
this.special = true;
}
private ChatColor() {
this.empty = true;
this.special = true;
}
public static ChatColor fromRGB(int r, int g, int b) {
@ -112,6 +146,19 @@ public class ChatColor {
return blue;
}
public boolean isSpecial() {
return special;
}
/**
* Get the code name is the color is "special"
*
* @return the special code name
*/
protected String getCodeName() {
return codeName;
}
public int getId() {
Check.stateCondition(id == -1, "Please use one of the ChatColor constant instead");
return id;
@ -122,18 +169,31 @@ public class ChatColor {
if (empty)
return "";
String redH = Integer.toHexString(red);
if (redH.length() == 1)
redH = "0" + redH;
final String header = "{#";
final String footer = "}";
String greenH = Integer.toHexString(green);
if (greenH.length() == 1)
greenH = "0" + greenH;
String code;
String blueH = Integer.toHexString(blue);
if (blueH.length() == 1)
blueH = "0" + blueH;
if (codeName != null) {
// Special color (reset/bold/etc...)
code = codeName;
} else {
// RGB color
String redH = Integer.toHexString(red);
if (redH.length() == 1)
redH = "0" + redH;
return "{#" + redH + greenH + blueH + "}";
String greenH = Integer.toHexString(green);
if (greenH.length() == 1)
greenH = "0" + greenH;
String blueH = Integer.toHexString(blue);
if (blueH.length() == 1)
blueH = "0" + blueH;
code = redH + greenH + blueH;
}
return header + code + footer;
}
}

View File

@ -123,6 +123,7 @@ public class ColoredText {
int formatEnd = 0;
String currentColor = "";
SpecialComponentContainer specialComponentContainer = new SpecialComponentContainer();
for (int i = 0; i < message.length(); i++) {
// Last char or null
@ -134,7 +135,7 @@ public class ColoredText {
formatEnd = formatEnd > 0 ? formatEnd + 1 : formatEnd;
String rawMessage = message.substring(formatEnd, i);
if (!rawMessage.isEmpty()) {
objects.add(getMessagePart(MessageType.RAW, rawMessage, currentColor));
objects.add(getMessagePart(MessageType.RAW, rawMessage, currentColor, specialComponentContainer));
}
inFormat = true;
@ -158,6 +159,23 @@ public class ColoredText {
if (color == ChatColor.NO_COLOR) {
// Use rgb formatting (#ffffff)
currentColor = "#" + colorCode;
} else if (color.isSpecial()) {
// Check for special color (reset/bold/etc...)
if (color == ChatColor.RESET) {
// Remove all additional component
currentColor = "";
specialComponentContainer.reset();
} else if (color == ChatColor.BOLD) {
specialComponentContainer.bold = true;
} else if (color == ChatColor.ITALIC) {
specialComponentContainer.italic = true;
} else if (color == ChatColor.UNDERLINED) {
specialComponentContainer.underlined = true;
} else if (color == ChatColor.STRIKETHROUGH) {
specialComponentContainer.strikethrough = true;
} else if (color == ChatColor.OBFUSCATED) {
specialComponentContainer.obfuscated = true;
}
} else {
// Use color name formatting (white)
currentColor = colorCode;
@ -169,7 +187,7 @@ public class ColoredText {
final String translatableCode = formatString.substring(1);
final boolean hasArgs = translatableCode.contains(",");
if (!hasArgs) {
objects.add(getMessagePart(MessageType.TRANSLATABLE, translatableCode, currentColor));
objects.add(getMessagePart(MessageType.TRANSLATABLE, translatableCode, currentColor, specialComponentContainer));
} else {
// Arguments parsing
// ex: {@translatable.key,arg1,arg2,etc}
@ -177,11 +195,11 @@ public class ColoredText {
final String finalTranslatableCode = split[0];
final String[] arguments = Arrays.copyOfRange(split, 1, split.length);
JsonObject translatableObject = getMessagePart(MessageType.TRANSLATABLE, finalTranslatableCode, currentColor);
JsonObject translatableObject = getMessagePart(MessageType.TRANSLATABLE, finalTranslatableCode, currentColor, specialComponentContainer);
if (arguments.length > 0) {
JsonArray argArray = new JsonArray();
for (String arg : arguments) {
argArray.add(getMessagePart(MessageType.RAW, arg, currentColor));
argArray.add(getMessagePart(MessageType.RAW, arg, currentColor, specialComponentContainer));
}
translatableObject.add("with", argArray);
objects.add(translatableObject);
@ -192,7 +210,7 @@ public class ColoredText {
// Keybind component
if (formatString.startsWith("&")) {
String keybindCode = formatString.substring(1);
objects.add(getMessagePart(MessageType.KEYBIND, keybindCode, currentColor));
objects.add(getMessagePart(MessageType.KEYBIND, keybindCode, currentColor, specialComponentContainer));
continue;
}
}
@ -201,7 +219,7 @@ public class ColoredText {
// Add the remaining of the message as a raw message when any
if (formatEnd < message.length()) {
String lastRawMessage = message.substring(formatEnd + 1);
objects.add(getMessagePart(MessageType.RAW, lastRawMessage, currentColor));
objects.add(getMessagePart(MessageType.RAW, lastRawMessage, currentColor, specialComponentContainer));
}
return objects;
@ -215,7 +233,8 @@ public class ColoredText {
* @param color the last color
* @return a json object representing a message
*/
private JsonObject getMessagePart(MessageType messageType, String message, String color) {
private JsonObject getMessagePart(MessageType messageType, String message, String color,
SpecialComponentContainer specialComponentContainer) {
JsonObject object = new JsonObject();
switch (messageType) {
case RAW:
@ -231,6 +250,27 @@ public class ColoredText {
if (!color.isEmpty()) {
object.addProperty("color", color);
}
if (specialComponentContainer.bold) {
object.addProperty("bold", "true");
}
if (specialComponentContainer.italic) {
object.addProperty("italic", "true");
}
if (specialComponentContainer.underlined) {
object.addProperty("underlined", "true");
}
if (specialComponentContainer.strikethrough) {
object.addProperty("strikethrough", "true");
}
if (specialComponentContainer.obfuscated) {
object.addProperty("obfuscated", "true");
}
return object;
}
@ -243,4 +283,20 @@ public class ColoredText {
return appendFormat(legacy);
}
private static class SpecialComponentContainer {
boolean bold = false;
boolean italic = false;
boolean underlined = false;
boolean strikethrough = false;
boolean obfuscated = false;
private void reset() {
this.bold = false;
this.italic = false;
this.underlined = false;
this.strikethrough = false;
this.obfuscated = false;
}
}
}