refactor: rewrite ComponentUtilities component parser (still a bit broken but at least a bit better on the codestyle side)
This commit is contained in:
parent
9b675bfed4
commit
052e57a799
6 changed files with 265 additions and 253 deletions
build-number.txt
src/main/java/me/chayapak1/chomens_bot
|
@ -1 +1 @@
|
|||
1303
|
||||
1341
|
|
@ -209,7 +209,7 @@ public class Bot {
|
|||
// we also set other stuffs here
|
||||
session.send(
|
||||
new ServerboundClientInformationPacket(
|
||||
ComponentUtilities.language.getOrDefault("language.code", "en-us"),
|
||||
ComponentUtilities.LANGUAGE.getOrDefault("language.code", "en-us"),
|
||||
16,
|
||||
ChatVisibility.FULL,
|
||||
true,
|
||||
|
|
|
@ -339,7 +339,7 @@ public class ChatPlugin extends Bot.Listener {
|
|||
if (bot.options.useChat) {
|
||||
if (!targets.equals("@a")) return; // worst fix of all time!1!
|
||||
|
||||
final String stringified = ComponentUtilities.stringifyMotd(component).replace("§", "&");
|
||||
final String stringified = ComponentUtilities.stringifySectionSign(component).replace("§", "&");
|
||||
send(stringified);
|
||||
} else {
|
||||
bot.core.run("minecraft:tellraw " + targets + " " + GsonComponentSerializer.gson().serialize(component));
|
||||
|
|
|
@ -98,15 +98,10 @@ public class DiscordPlugin {
|
|||
if (string.length() > 2000 - 12) {
|
||||
sendMessage(CodeBlockUtilities.escape(string), channelId);
|
||||
} else {
|
||||
final String ansi = ComponentUtilities.stringifyAnsi(component, true);
|
||||
final String ansi = ComponentUtilities.stringifyDiscordAnsi(component);
|
||||
|
||||
sendMessage(
|
||||
CodeBlockUtilities.escape(
|
||||
ansi
|
||||
.replace(
|
||||
"\u001b[9", "\u001b[3"
|
||||
)
|
||||
),
|
||||
CodeBlockUtilities.escape(ansi),
|
||||
channelId
|
||||
);
|
||||
}
|
||||
|
|
|
@ -278,7 +278,7 @@ public class NBSConverter implements Converter {
|
|||
private static final Map<String, String> subtitles = new HashMap<>();
|
||||
|
||||
static {
|
||||
for (Map.Entry<String, String> entry : ComponentUtilities.language.entrySet()) {
|
||||
for (Map.Entry<String, String> entry : ComponentUtilities.LANGUAGE.entrySet()) {
|
||||
if (!entry.getKey().startsWith("subtitles.")) continue;
|
||||
|
||||
subtitles.put(entry.getKey(), entry.getValue());
|
||||
|
|
|
@ -20,45 +20,9 @@ import java.util.regex.Pattern;
|
|||
// totallynotskidded™ from chipmunkbot and added colors (ignore the ohio code please,..,.)
|
||||
public class ComponentUtilities {
|
||||
// component parsing
|
||||
public static final Map<String, String> language = loadJsonStringMap("language.json");
|
||||
private static final Map<String, String> voiceChatLanguage = loadJsonStringMap("voiceChatLanguage.json");
|
||||
private static final Map<String, String> keybinds = loadJsonStringMap("keybinds.json");
|
||||
|
||||
public static final Pattern ARG_PATTERN = Pattern.compile("%(?:(\\d+)\\$)?([s%])");
|
||||
|
||||
public static final int MAX_DEPTH = 16;
|
||||
|
||||
public static final Map<String, String> ansiMap = new HashMap<>();
|
||||
static {
|
||||
// map totallynotskidded™ from https://github.com/PrismarineJS/prismarine-chat/blob/master/index.js#L10
|
||||
ansiMap.put("0", "\u001b[30m");
|
||||
ansiMap.put("1", "\u001b[34m");
|
||||
ansiMap.put("2", "\u001b[32m");
|
||||
ansiMap.put("3", "\u001b[36m");
|
||||
ansiMap.put("4", "\u001b[31m");
|
||||
ansiMap.put("5", "\u001b[35m");
|
||||
ansiMap.put("6", "\u001b[33m");
|
||||
ansiMap.put("7", "\u001b[37m");
|
||||
ansiMap.put("8", "\u001b[90m");
|
||||
ansiMap.put("9", "\u001b[94m");
|
||||
ansiMap.put("a", "\u001b[92m");
|
||||
ansiMap.put("b", "\u001b[96m");
|
||||
ansiMap.put("c", "\u001b[91m");
|
||||
ansiMap.put("d", "\u001b[95m");
|
||||
ansiMap.put("e", "\u001b[93m");
|
||||
ansiMap.put("f", "\u001b[97m");
|
||||
ansiMap.put("l", "\u001b[1m");
|
||||
ansiMap.put("o", "\u001b[3m");
|
||||
ansiMap.put("n", "\u001b[4m");
|
||||
ansiMap.put("m", "\u001b[9m");
|
||||
ansiMap.put("k", "\u001b[6m");
|
||||
ansiMap.put("r", "\u001b[0m");
|
||||
}
|
||||
|
||||
public record PartiallyStringified(
|
||||
String output,
|
||||
String lastColor
|
||||
) {}
|
||||
public static final Map<String, String> LANGUAGE = loadJsonStringMap("language.json");
|
||||
public static final Map<String, String> VOICE_CHAT_LANGUAGE = loadJsonStringMap("voiceChatLanguage.json");
|
||||
public static final Map<String, String> KEYBINDINGS = loadJsonStringMap("keybinds.json");
|
||||
|
||||
private static Map<String, String> loadJsonStringMap (String name) {
|
||||
Map<String, String> map = new HashMap<>();
|
||||
|
@ -74,186 +38,226 @@ public class ComponentUtilities {
|
|||
return map;
|
||||
}
|
||||
|
||||
private static String getOrReturnFallback (TranslatableComponent component) {
|
||||
public static String getOrReturnFallback (TranslatableComponent component) {
|
||||
final String key = component.key();
|
||||
|
||||
final String minecraftKey = language.get(key);
|
||||
final String voiceChatKey = voiceChatLanguage.get(key);
|
||||
final String minecraftKey = LANGUAGE.get(key);
|
||||
final String voiceChatKey = VOICE_CHAT_LANGUAGE.get(key);
|
||||
|
||||
if (minecraftKey != null) return minecraftKey;
|
||||
else if (voiceChatKey != null) return voiceChatKey;
|
||||
else return component.fallback() != null ? component.fallback() : key;
|
||||
}
|
||||
|
||||
public static String stringify (Component message) { return stringify(message, null, 0); }
|
||||
private static String stringify (Component message, String lastColor, int depth) {
|
||||
if (depth > MAX_DEPTH) return "";
|
||||
public static String stringify (Component message) { return new ComponentParser().stringify(message, ComponentParser.ParseType.PLAIN); }
|
||||
public static String stringifySectionSign (Component message) { return new ComponentParser().stringify(message, ComponentParser.ParseType.SECTION_SIGNS); }
|
||||
public static String stringifyAnsi (Component message) { return new ComponentParser().stringify(message, ComponentParser.ParseType.ANSI); }
|
||||
public static String stringifyDiscordAnsi (Component message) { return new ComponentParser().stringify(message, ComponentParser.ParseType.DISCORD_ANSI); }
|
||||
|
||||
try {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
private static class ComponentParser {
|
||||
public static final Pattern ARG_PATTERN = Pattern.compile("%(?:(\\d+)\\$)?([s%])");
|
||||
|
||||
final PartiallyStringified output = stringifyPartially(message, false, false, lastColor, false, depth);
|
||||
public static final int MAX_DEPTH = 16;
|
||||
|
||||
builder.append(output.output);
|
||||
|
||||
for (Component child : message.children()) builder.append(stringify(child, lastColor != null ? lastColor : output.lastColor, depth));
|
||||
|
||||
return builder.toString();
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static String stringifyMotd (Component message) { return stringifyMotd(message, null, 0); }
|
||||
private static String stringifyMotd (Component message, String lastColor, int depth) {
|
||||
if (depth > MAX_DEPTH) return "";
|
||||
|
||||
try {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
||||
final PartiallyStringified output = stringifyPartially(message, true, false, lastColor, false, depth);
|
||||
|
||||
builder.append(output.output);
|
||||
|
||||
for (Component child : message.children()) builder.append(stringifyMotd(child, lastColor != null ? lastColor : output.lastColor, depth));
|
||||
|
||||
return builder.toString();
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static String stringifyAnsi (Component message) { return stringifyAnsi(message, null, false, 0); }
|
||||
public static String stringifyAnsi (Component message, boolean noHex) { return stringifyAnsi(message, null, noHex, 0); }
|
||||
private static String stringifyAnsi (Component message, String lastColor, boolean noHex, int depth) {
|
||||
if (depth > MAX_DEPTH) return "";
|
||||
|
||||
try {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
||||
final PartiallyStringified output = stringifyPartially(message, false, true, lastColor, noHex, depth);
|
||||
|
||||
builder.append(output.output);
|
||||
|
||||
for (Component child : message.children()) builder.append(stringifyAnsi(child, lastColor != null ? lastColor : output.lastColor, noHex, depth));
|
||||
|
||||
return builder.toString();
|
||||
} catch (Exception e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static PartiallyStringified stringifyPartially (Component message, boolean motd, boolean ansi, String lastColor, boolean noHex, int depth) {
|
||||
return switch (message) {
|
||||
case TextComponent t_component -> stringifyPartially(t_component, motd, ansi, lastColor, noHex);
|
||||
case TranslatableComponent t_component -> stringifyPartially(t_component, motd, ansi, lastColor, noHex, depth);
|
||||
case SelectorComponent t_component -> stringifyPartially(t_component, motd, ansi, lastColor, noHex);
|
||||
case KeybindComponent t_component -> stringifyPartially(t_component, motd, ansi, lastColor, noHex);
|
||||
default -> new PartiallyStringified("", null);
|
||||
};
|
||||
}
|
||||
|
||||
public static String getStyle (Style textStyle, boolean motd) {
|
||||
if (textStyle == null) return null;
|
||||
|
||||
StringBuilder style = new StringBuilder();
|
||||
|
||||
for (Map.Entry<TextDecoration, TextDecoration.State> decorationEntry : textStyle.decorations().entrySet()) {
|
||||
final TextDecoration decoration = decorationEntry.getKey();
|
||||
final TextDecoration.State state = decorationEntry.getValue();
|
||||
|
||||
if (state == TextDecoration.State.NOT_SET || state == TextDecoration.State.FALSE) continue;
|
||||
|
||||
if (!motd) {
|
||||
switch (decoration) {
|
||||
case BOLD -> style.append(ansiMap.get("l"));
|
||||
case ITALIC -> style.append(ansiMap.get("o"));
|
||||
case OBFUSCATED -> style.append(ansiMap.get("k"));
|
||||
case UNDERLINED -> style.append(ansiMap.get("n"));
|
||||
case STRIKETHROUGH -> style.append(ansiMap.get("m"));
|
||||
}
|
||||
} else {
|
||||
switch (decoration) {
|
||||
case BOLD -> style.append("§l");
|
||||
case ITALIC -> style.append("§o");
|
||||
case OBFUSCATED -> style.append("§k");
|
||||
case UNDERLINED -> style.append("§n");
|
||||
case STRIKETHROUGH -> style.append("§m");
|
||||
}
|
||||
}
|
||||
public static final Map<String, String> ansiMap = new HashMap<>();
|
||||
static {
|
||||
// map totallynotskidded™ from https://github.com/PrismarineJS/prismarine-chat/blob/master/index.js#L10
|
||||
ansiMap.put("0", "\u001b[30m");
|
||||
ansiMap.put("1", "\u001b[34m");
|
||||
ansiMap.put("2", "\u001b[32m");
|
||||
ansiMap.put("3", "\u001b[36m");
|
||||
ansiMap.put("4", "\u001b[31m");
|
||||
ansiMap.put("5", "\u001b[35m");
|
||||
ansiMap.put("6", "\u001b[33m");
|
||||
ansiMap.put("7", "\u001b[37m");
|
||||
ansiMap.put("8", "\u001b[90m");
|
||||
ansiMap.put("9", "\u001b[94m");
|
||||
ansiMap.put("a", "\u001b[92m");
|
||||
ansiMap.put("b", "\u001b[96m");
|
||||
ansiMap.put("c", "\u001b[91m");
|
||||
ansiMap.put("d", "\u001b[95m");
|
||||
ansiMap.put("e", "\u001b[93m");
|
||||
ansiMap.put("f", "\u001b[97m");
|
||||
ansiMap.put("l", "\u001b[1m");
|
||||
ansiMap.put("o", "\u001b[3m");
|
||||
ansiMap.put("n", "\u001b[4m");
|
||||
ansiMap.put("m", "\u001b[9m");
|
||||
ansiMap.put("k", "\u001b[6m");
|
||||
ansiMap.put("r", "\u001b[0m");
|
||||
}
|
||||
|
||||
return style.toString();
|
||||
}
|
||||
private ParseType type;
|
||||
private int formatsPlaceholdersCount = 0;
|
||||
|
||||
public static String getColor (TextColor color, boolean motd, boolean ansi, boolean noHex) {
|
||||
if (color == null) return null;
|
||||
private String lastStyle = "";
|
||||
|
||||
private String stringify (Component message, ParseType type) {
|
||||
this.type = type;
|
||||
|
||||
if (formatsPlaceholdersCount > MAX_DEPTH) return "";
|
||||
|
||||
// map totallynotskidded™ too from https://github.com/PrismarineJS/prismarine-chat/blob/master/index.js#L299
|
||||
String code;
|
||||
if (color == NamedTextColor.BLACK) code = "0";
|
||||
else if (color == NamedTextColor.DARK_BLUE) code = "1";
|
||||
else if (color == NamedTextColor.DARK_GREEN) code = "2";
|
||||
else if (color == NamedTextColor.DARK_AQUA) code = "3";
|
||||
else if (color == NamedTextColor.DARK_RED) code = "4";
|
||||
else if (color == NamedTextColor.DARK_PURPLE) code = "5";
|
||||
else if (color == NamedTextColor.GOLD) code = "6";
|
||||
else if (color == NamedTextColor.GRAY) code = "7";
|
||||
else if (color == NamedTextColor.DARK_GRAY) code = "8";
|
||||
else if (color == NamedTextColor.BLUE) code = "9";
|
||||
else if (color == NamedTextColor.GREEN) code = "a";
|
||||
else if (color == NamedTextColor.AQUA) code = "b";
|
||||
else if (color == NamedTextColor.RED) code = "c";
|
||||
else if (color == NamedTextColor.LIGHT_PURPLE) code = "d";
|
||||
else if (color == NamedTextColor.YELLOW) code = "e";
|
||||
else if (color == NamedTextColor.WHITE) code = "f";
|
||||
else {
|
||||
try {
|
||||
code = color.asHexString();
|
||||
} catch (NullPointerException e) {
|
||||
code = ""; // mabe...,,.,..,
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
||||
final String color = getColor(message.color());
|
||||
final String style = getStyle(message.style());
|
||||
|
||||
final String output = stringifyPartially(message, color, style);
|
||||
|
||||
builder.append(output);
|
||||
|
||||
for (Component child : message.children()) {
|
||||
final ComponentParser parser = new ComponentParser();
|
||||
parser.lastStyle = lastStyle + color + style;
|
||||
parser.formatsPlaceholdersCount = formatsPlaceholdersCount;
|
||||
builder.append(parser.stringify(child, type));
|
||||
}
|
||||
|
||||
if (type == ParseType.DISCORD_ANSI) {
|
||||
// as of the time writing this (2024-12-28) discord doesn't support the bright colors yet
|
||||
return builder.toString().replace("\u001b[9", "\u001b[3");
|
||||
} else {
|
||||
return builder.toString();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
if (motd) {
|
||||
return "§" + code;
|
||||
} else if (ansi) {
|
||||
String ansiCode = ansiMap.get(code);
|
||||
if (ansiCode == null) {
|
||||
if (noHex) {
|
||||
final int rgb = Integer.parseInt(code.substring(1), 16);
|
||||
public String stringifyPartially (Component message, String color, String style) {
|
||||
return switch (message) {
|
||||
case TextComponent t_component -> stringifyPartially(t_component, color, style);
|
||||
case TranslatableComponent t_component -> stringifyPartially(t_component, color, style);
|
||||
case SelectorComponent t_component -> stringifyPartially(t_component, color, style);
|
||||
case KeybindComponent t_component -> stringifyPartially(t_component, color, style);
|
||||
default -> "";
|
||||
};
|
||||
}
|
||||
|
||||
final String chatColor = ColorUtilities.getClosestChatColor(rgb);
|
||||
public String getStyle (Style textStyle) {
|
||||
if (textStyle == null) return "";
|
||||
|
||||
ansiCode = ansiMap.get(chatColor);
|
||||
} else {
|
||||
ansiCode = "\u001b[38;2;" +
|
||||
color.red() +
|
||||
";" +
|
||||
color.green() +
|
||||
";" +
|
||||
color.blue() +
|
||||
"m";
|
||||
StringBuilder style = new StringBuilder();
|
||||
|
||||
for (Map.Entry<TextDecoration, TextDecoration.State> decorationEntry : textStyle.decorations().entrySet()) {
|
||||
final TextDecoration decoration = decorationEntry.getKey();
|
||||
final TextDecoration.State state = decorationEntry.getValue();
|
||||
|
||||
if (state == TextDecoration.State.NOT_SET || state == TextDecoration.State.FALSE) continue;
|
||||
|
||||
if (type == ParseType.ANSI) {
|
||||
switch (decoration) {
|
||||
case BOLD -> style.append(ansiMap.get("l"));
|
||||
case ITALIC -> style.append(ansiMap.get("o"));
|
||||
case OBFUSCATED -> style.append(ansiMap.get("k"));
|
||||
case UNDERLINED -> style.append(ansiMap.get("n"));
|
||||
case STRIKETHROUGH -> style.append(ansiMap.get("m"));
|
||||
}
|
||||
} else if (type == ParseType.SECTION_SIGNS) {
|
||||
switch (decoration) {
|
||||
case BOLD -> style.append("§l");
|
||||
case ITALIC -> style.append("§o");
|
||||
case OBFUSCATED -> style.append("§k");
|
||||
case UNDERLINED -> style.append("§n");
|
||||
case STRIKETHROUGH -> style.append("§m");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ansiCode;
|
||||
} else return null;
|
||||
}
|
||||
return style.toString();
|
||||
}
|
||||
|
||||
public static PartiallyStringified stringifyPartially (TextComponent message, boolean motd, boolean ansi, String lastColor, boolean noHex) {
|
||||
if ((motd || ansi) && /* don't color big messages -> */ message.content().length() < 25_000) {
|
||||
final String color = getColor(message.color(), motd, ansi, noHex);
|
||||
final String style = getStyle(message.style(), motd);
|
||||
public String getColor (TextColor color) {
|
||||
if (color == null) return "";
|
||||
|
||||
String replacedContent = message.content();
|
||||
// seems very mabe mabe
|
||||
if (ansi && replacedContent.contains("§")) {
|
||||
// is try-catch a great idea?
|
||||
// map totallynotskidded™ too from https://github.com/PrismarineJS/prismarine-chat/blob/master/index.js#L299
|
||||
String code;
|
||||
if (color == NamedTextColor.BLACK) code = "0";
|
||||
else if (color == NamedTextColor.DARK_BLUE) code = "1";
|
||||
else if (color == NamedTextColor.DARK_GREEN) code = "2";
|
||||
else if (color == NamedTextColor.DARK_AQUA) code = "3";
|
||||
else if (color == NamedTextColor.DARK_RED) code = "4";
|
||||
else if (color == NamedTextColor.DARK_PURPLE) code = "5";
|
||||
else if (color == NamedTextColor.GOLD) code = "6";
|
||||
else if (color == NamedTextColor.GRAY) code = "7";
|
||||
else if (color == NamedTextColor.DARK_GRAY) code = "8";
|
||||
else if (color == NamedTextColor.BLUE) code = "9";
|
||||
else if (color == NamedTextColor.GREEN) code = "a";
|
||||
else if (color == NamedTextColor.AQUA) code = "b";
|
||||
else if (color == NamedTextColor.RED) code = "c";
|
||||
else if (color == NamedTextColor.LIGHT_PURPLE) code = "d";
|
||||
else if (color == NamedTextColor.YELLOW) code = "e";
|
||||
else if (color == NamedTextColor.WHITE) code = "f";
|
||||
else {
|
||||
try {
|
||||
code = color.asHexString();
|
||||
} catch (NullPointerException e) {
|
||||
code = ""; // mabe...,,.,..,
|
||||
}
|
||||
}
|
||||
|
||||
if (type == ParseType.SECTION_SIGNS) {
|
||||
return "§" + code;
|
||||
} else if (type == ParseType.ANSI || type == ParseType.DISCORD_ANSI) {
|
||||
String ansiCode = ansiMap.get(code);
|
||||
if (ansiCode == null) {
|
||||
if (type == ParseType.DISCORD_ANSI) {
|
||||
// gets the closest color to the hex
|
||||
|
||||
final int rgb = Integer.parseInt(code.substring(1), 16);
|
||||
|
||||
final String chatColor = ColorUtilities.getClosestChatColor(rgb);
|
||||
|
||||
ansiCode = ansiMap.get(chatColor);
|
||||
} else {
|
||||
ansiCode = "\u001b[38;2;" +
|
||||
color.red() +
|
||||
";" +
|
||||
color.green() +
|
||||
";" +
|
||||
color.blue() +
|
||||
"m";
|
||||
}
|
||||
}
|
||||
|
||||
return ansiCode;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private String getPartialResultAndSetLastColor (String originalResult, String color, String style) {
|
||||
if (type == ParseType.PLAIN) return originalResult;
|
||||
|
||||
String resetCode;
|
||||
if (type == ParseType.ANSI || type == ParseType.DISCORD_ANSI) resetCode = ansiMap.get("r");
|
||||
else resetCode = "§r";
|
||||
|
||||
final String result =
|
||||
lastStyle + color + style +
|
||||
originalResult +
|
||||
resetCode;
|
||||
|
||||
lastStyle = color + style;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private String stringifyPartially (String message, String color, String style) {
|
||||
if (type == ParseType.PLAIN) return message;
|
||||
|
||||
final boolean isAllAnsi = type == ParseType.ANSI || type == ParseType.DISCORD_ANSI;
|
||||
|
||||
String replacedContent = message;
|
||||
// processes section signs
|
||||
// not processing invalid codes is INTENTIONAL and it is a FEATURE
|
||||
if (isAllAnsi && replacedContent.contains("§")) {
|
||||
// is try-catch a great idea for these?
|
||||
try {
|
||||
replacedContent = Pattern
|
||||
.compile("(§.)")
|
||||
.matcher(message.content())
|
||||
.matcher(message)
|
||||
.replaceAll(m -> {
|
||||
final String code = m.group(0).substring(1);
|
||||
|
||||
|
@ -263,69 +267,82 @@ public class ComponentUtilities {
|
|||
} catch (Exception ignored) {}
|
||||
}
|
||||
|
||||
// messy af
|
||||
return new PartiallyStringified((lastColor != null ? lastColor : "") + (color != null ? color : "") + (style != null ? style : "") + replacedContent + (ansi ? ansiMap.get("r") : ""), color);
|
||||
return getPartialResultAndSetLastColor(replacedContent, color, style);
|
||||
}
|
||||
|
||||
return new PartiallyStringified(message.content(), null);
|
||||
}
|
||||
private String stringifyPartially (TextComponent message, String color, String style) {
|
||||
return stringifyPartially(message.content(), color, style);
|
||||
}
|
||||
|
||||
public static PartiallyStringified stringifyPartially (TranslatableComponent message, boolean motd, boolean ansi, String lastColor, boolean noHex, int depth) {
|
||||
String format = getOrReturnFallback(message);
|
||||
private String stringifyPartially (TranslatableComponent message, String color, String style) {
|
||||
final String format = getOrReturnFallback(message);
|
||||
|
||||
// totallynotskidded™️ from HBot (and changed a bit)
|
||||
Matcher matcher = ARG_PATTERN.matcher(format);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
// totallynotskidded™️from HBot (and changed a bit)
|
||||
Matcher matcher = ARG_PATTERN.matcher(format);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
final String style = getStyle(message.style(), motd);
|
||||
final String _color = getColor(message.color(), motd, ansi, noHex);
|
||||
String color;
|
||||
if (_color == null) color = "";
|
||||
else color = _color;
|
||||
|
||||
int i = 0;
|
||||
while (matcher.find()) {
|
||||
depth++;
|
||||
if (matcher.group().equals("%%")) {
|
||||
matcher.appendReplacement(sb, "%");
|
||||
} else {
|
||||
String idxStr = matcher.group(1);
|
||||
int idx = idxStr == null ? i++ : (Integer.parseInt(idxStr) - 1);
|
||||
if (idx >= 0 && idx < message.arguments().size()) {
|
||||
matcher.appendReplacement(
|
||||
sb,
|
||||
Matcher.quoteReplacement(
|
||||
motd ?
|
||||
stringifyMotd(message.arguments().get(idx).asComponent(), lastColor, depth + 1) + color :
|
||||
(
|
||||
ansi ?
|
||||
stringifyAnsi(message.arguments().get(idx).asComponent(), lastColor, noHex, depth + 1) + color :
|
||||
stringify(message.arguments().get(idx).asComponent(), lastColor, depth + 1)
|
||||
)
|
||||
)
|
||||
);
|
||||
// not checking if arguments length equals input format length
|
||||
// is INTENTIONAL and is a FEATURE
|
||||
int i = 0;
|
||||
while (matcher.find()) {
|
||||
formatsPlaceholdersCount++;
|
||||
if (matcher.group().equals("%%")) {
|
||||
matcher.appendReplacement(sb, "%");
|
||||
} else {
|
||||
matcher.appendReplacement(sb, "");
|
||||
final String idxStr = matcher.group(1);
|
||||
|
||||
int idx = idxStr == null ? i++ : (Integer.parseInt(idxStr) - 1);
|
||||
|
||||
if (idx >= 0 && idx < message.arguments().size()) {
|
||||
final ComponentParser parser = new ComponentParser();
|
||||
|
||||
parser.lastStyle = lastStyle + color + style;
|
||||
parser.formatsPlaceholdersCount = formatsPlaceholdersCount;
|
||||
|
||||
matcher.appendReplacement(
|
||||
sb,
|
||||
Matcher.quoteReplacement(
|
||||
parser.stringify(
|
||||
message.arguments()
|
||||
.get(idx)
|
||||
.asComponent(),
|
||||
type
|
||||
) + color // + color IMPORTANT!!!!
|
||||
)
|
||||
);
|
||||
} else {
|
||||
matcher.appendReplacement(sb, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
matcher.appendTail(sb);
|
||||
|
||||
return getPartialResultAndSetLastColor(sb.toString(), color, style);
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
|
||||
return new PartiallyStringified((lastColor != null ? lastColor : "") + color + (style != null && ansi ? style : "") + sb + (ansi ? ansiMap.get("r") : ""), _color);
|
||||
}
|
||||
// on the client side, this acts just like TextComponent
|
||||
// and does NOT process any players stuff
|
||||
private String stringifyPartially (SelectorComponent message, String color, String style) {
|
||||
return stringifyPartially(message.pattern(), style, color);
|
||||
}
|
||||
|
||||
public static PartiallyStringified stringifyPartially (SelectorComponent message, boolean motd, boolean ansi, String lastColor, boolean noHex) {
|
||||
final String style = getStyle(message.style(), motd);
|
||||
final String _color = getColor(message.color(), motd, ansi, noHex);
|
||||
String color;
|
||||
if (_color == null) color = "";
|
||||
else color = _color;
|
||||
return new PartiallyStringified((lastColor != null ? lastColor : "") + color + (style != null && ansi ? style : "") + message.pattern(), _color); // * Client-side selector components are equivalent to text ones, and do NOT list entities.
|
||||
}
|
||||
public String stringifyPartially (KeybindComponent message, String color, String style) {
|
||||
final String keybind = message.keybind();
|
||||
|
||||
public static PartiallyStringified stringifyPartially (KeybindComponent message, boolean motd, boolean ansi, String lastColor, boolean noHex) {
|
||||
String keybind = message.keybind();
|
||||
Component component = keybinds.containsKey(keybind) ? Component.translatable(keybinds.get(keybind)) : Component.text(keybind);
|
||||
return stringifyPartially(component, motd, ansi, lastColor, noHex, 0);
|
||||
// FIXME: this isn't the correct way to parse keybinds
|
||||
final Component component = KEYBINDINGS.containsKey(keybind) ?
|
||||
Component.translatable(KEYBINDINGS.get(keybind)) :
|
||||
Component.text(keybind);
|
||||
|
||||
return stringifyPartially(component, color, style);
|
||||
}
|
||||
|
||||
public enum ParseType {
|
||||
PLAIN,
|
||||
SECTION_SIGNS,
|
||||
ANSI,
|
||||
DISCORD_ANSI
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue