PlaceHolderUtil.java
package dev.aura.bungeechat.message;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.typesafe.config.Config;
import dev.aura.bungeechat.BungeeChat;
import dev.aura.bungeechat.api.account.AccountManager;
import dev.aura.bungeechat.api.account.BungeeChatAccount;
import dev.aura.bungeechat.api.placeholder.BungeeChatContext;
import dev.aura.bungeechat.api.placeholder.PlaceHolderManager;
import dev.aura.bungeechat.config.Configuration;
import dev.aura.bungeechat.permission.Permission;
import dev.aura.bungeechat.permission.PermissionManager;
import dev.aura.lib.messagestranslator.MessagesTranslator;
import dev.aura.lib.messagestranslator.PluginMessagesTranslator;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import lombok.experimental.UtilityClass;
import net.md_5.bungee.api.ChatColor;
@UtilityClass
public class PlaceHolderUtil {
private static final String FORMATS = "Formats";
private static final String LANGUAGE = "Language";
private static Config formatsBase;
private static MessagesTranslator messageBase;
private static final char altColorChar = '&';
private static final String altColorString = String.valueOf(altColorChar);
private static final String colorCodeReplacement = ChatColor.COLOR_CHAR + "$1";
private static final Pattern duplicateDetection =
Pattern.compile(altColorString + altColorString);
private static final String baseRgbPattern = "[0-9a-f]";
private static final String rgbStartPattern = "[x#]";
private static final Pattern rgbDetection =
Pattern.compile(
ChatColor.COLOR_CHAR + rgbStartPattern + Strings.repeat('(' + baseRgbPattern + ')', 6),
Pattern.CASE_INSENSITIVE);
private static final String rgbReplacement =
ChatColor.COLOR_CHAR
+ "x"
+ ChatColor.COLOR_CHAR
+ "$1"
+ ChatColor.COLOR_CHAR
+ "$2"
+ ChatColor.COLOR_CHAR
+ "$3"
+ ChatColor.COLOR_CHAR
+ "$4"
+ ChatColor.COLOR_CHAR
+ "$5"
+ ChatColor.COLOR_CHAR
+ "$6";
private static final ImmutableMap<Permission, String> colorCodeMap =
ImmutableMap.<Permission, String>builder()
.put(Permission.USE_CHAT_COLOR_RGB, rgbStartPattern + baseRgbPattern + "{6}")
.put(Permission.USE_CHAT_COLOR_BLACK, "0")
.put(Permission.USE_CHAT_COLOR_DARK_BLUE, "1")
.put(Permission.USE_CHAT_COLOR_DARK_GREEN, "2")
.put(Permission.USE_CHAT_COLOR_DARK_AQUA, "3")
.put(Permission.USE_CHAT_COLOR_DARK_RED, "4")
.put(Permission.USE_CHAT_COLOR_DARK_PURPLE, "5")
.put(Permission.USE_CHAT_COLOR_GOLD, "6")
.put(Permission.USE_CHAT_COLOR_GRAY, "7")
.put(Permission.USE_CHAT_COLOR_DARK_GRAY, "8")
.put(Permission.USE_CHAT_COLOR_BLUE, "9")
.put(Permission.USE_CHAT_COLOR_GREEN, "a")
.put(Permission.USE_CHAT_COLOR_AQUA, "b")
.put(Permission.USE_CHAT_COLOR_RED, "c")
.put(Permission.USE_CHAT_COLOR_LIGHT_PURPLE, "d")
.put(Permission.USE_CHAT_COLOR_YELLOW, "e")
.put(Permission.USE_CHAT_COLOR_WHITE, "f")
.put(Permission.USE_CHAT_FORMAT_OBFUSCATED, "k")
.put(Permission.USE_CHAT_FORMAT_BOLD, "l")
.put(Permission.USE_CHAT_FORMAT_STRIKETHROUGH, "m")
.put(Permission.USE_CHAT_FORMAT_UNDERLINE, "n")
.put(Permission.USE_CHAT_FORMAT_ITALIC, "o")
.put(Permission.USE_CHAT_FORMAT_RESET, "r")
.build();
private static final Map<Integer, Optional<Pattern>> patternCache = new HashMap<>();
private static final char placeholderChar = PlaceHolderManager.placeholderChar;
private static final String placeholderString = String.valueOf(placeholderChar);
public static void clearConfigSections() {
formatsBase = null;
messageBase = null;
}
public static void loadConfigSections() {
loadFormatsBase();
loadMessageBase();
}
public static void loadFormatsBase() {
formatsBase = Configuration.get().getConfig(FORMATS);
}
public static void loadMessageBase() {
File dir = BungeeChat.getInstance().getLangFolder();
String language = Configuration.get().getString(LANGUAGE);
messageBase =
new PluginMessagesTranslator(dir, language, BungeeChat.getInstance(), BungeeChat.ID);
}
public static String getFormat(Format format) {
try {
if (formatsBase == null) {
loadFormatsBase();
}
return formatsBase.getString(format.getStringPath());
} catch (RuntimeException e) {
return format.getStringPath();
}
}
public static String getMessage(Messages message) {
try {
if (messageBase == null) {
loadMessageBase();
}
return messageBase.translateWithFallback(message);
} catch (RuntimeException e) {
return message.getStringPath();
}
}
public static String getFullFormatMessage(Format format, BungeeChatContext context) {
return formatMessage(getFormat(format), context);
}
public static String getFullMessage(Messages message) {
return formatMessage(getMessage(message), new BungeeChatContext());
}
public static String getFullMessage(Messages message, BungeeChatContext context) {
return formatMessage(getMessage(message), context);
}
public static String formatMessage(String message, BungeeChatContext context) {
return transformAltColorCodes(PlaceHolderManager.processMessage(message, context));
}
public static String transformAltColorCodes(String message) {
return transformAltColorCodes(message, Optional.empty());
}
public static String transformAltColorCodes(String message, Optional<BungeeChatAccount> account) {
BungeeChatAccount permsAccount = account.orElseGet(AccountManager::getConsoleAccount);
Integer key =
colorCodeMap.keySet().stream()
.map(perm -> PermissionManager.hasPermission(permsAccount, perm))
.reduce(0, (in, bool) -> (in << 1) | (bool ? 1 : 0), (a, b) -> b);
if (!patternCache.containsKey(key)) {
if (key == 0) {
patternCache.put(key, Optional.empty());
} else {
Pattern pattern =
Pattern.compile(
colorCodeMap.entrySet().stream()
.filter(entry -> PermissionManager.hasPermission(permsAccount, entry.getKey()))
.map(Map.Entry::getValue)
.collect(
Collectors.joining(
"|", "(?<!" + altColorChar + ')' + altColorChar + "(", ")")),
Pattern.CASE_INSENSITIVE);
patternCache.put(key, Optional.of(pattern));
}
}
Optional<Pattern> pattern = patternCache.get(key);
if (pattern.isPresent()) {
message = pattern.get().matcher(message).replaceAll(colorCodeReplacement);
message = rgbDetection.matcher(message).replaceAll(rgbReplacement);
}
message = duplicateDetection.matcher(message).replaceAll(altColorString);
return message;
}
public static String escapeAltColorCodes(String message) {
return message.replace(altColorString, altColorString + altColorString);
}
public static String escapePlaceholders(String message) {
return message.replace(placeholderString, placeholderString + placeholderString);
}
public static String escape(String message) {
return escapeAltColorCodes(escapePlaceholders(message));
}
}