Skip to content

Commit 6606708

Browse files
committed
(fix) hex color rendering
1 parent b8c2593 commit 6606708

File tree

2 files changed

+45
-105
lines changed

2 files changed

+45
-105
lines changed

src/main/java/cat/nyaa/nyaacore/LanguageRepository.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ public static Set<String> getAllLanguages() {
5252

5353
// helper function to load language map
5454
private static void loadResourceMap(Plugin plugin, String langTag, Map<String, String> targetMap) {
55-
if (plugin == null || langTag == null || targetMap == null) throw new IllegalArgumentException();
55+
if (plugin == null || langTag == null || targetMap == null)
56+
throw new IllegalArgumentException();
5657
InputStream stream = plugin.getResource("lang/" + langTag + ".yml");
5758
if (stream != null) {
5859
YamlConfiguration section = YamlConfiguration.loadConfiguration(new InputStreamReader(stream, StandardCharsets.UTF_8));
@@ -62,7 +63,8 @@ private static void loadResourceMap(Plugin plugin, String langTag, Map<String, S
6263

6364
// helper function to load language map
6465
private static void loadLocalMap(Plugin plugin, String codeName, Map<String, String> targetMap) {
65-
if (plugin == null || codeName == null || targetMap == null) throw new IllegalArgumentException();
66+
if (plugin == null || codeName == null || targetMap == null)
67+
throw new IllegalArgumentException();
6668
File langFile = new File(plugin.getDataFolder(), codeName + ".yml");
6769
if (langFile.exists() && langFile.isFile()) {
6870
YamlConfiguration section = YamlConfiguration.loadConfiguration(langFile);
@@ -83,7 +85,7 @@ private static void loadLanguageSection(Map<String, String> map, ConfigurationSe
8385
for (String key : section.getKeys(false)) {
8486
String path = prefix + key;
8587
if (section.isString(key)) {
86-
map.put(path, HexColorUtils.hexColored(section.getString(key)));
88+
map.put(path, HexColorUtils.extractColorCode(section.getString(key)));
8789
} else if (section.isConfigurationSection(key)) {
8890
loadLanguageSection(map, section.getConfigurationSection(key), path + ".");
8991
}
@@ -181,7 +183,8 @@ public String getFormatted(String key, Object... para) {
181183
* `null` key-value pair will be ignored
182184
*/
183185
public String getSubstituted(String key, Object... param) {
184-
if (key == null || param == null || (param.length % 2) != 0) throw new IllegalArgumentException();
186+
if (key == null || param == null || (param.length % 2) != 0)
187+
throw new IllegalArgumentException();
185188
Map<Object, Object> map = new HashMap<>();
186189
for (int i = 0; i < param.length / 2; i++) {
187190
if (param[i * 2] != null && param[i * 2 + 1] != null) {
@@ -246,7 +249,8 @@ protected String getLanguage() {
246249

247250
@Override
248251
public String getFormatted(String key, Object... para) {
249-
if (!key.startsWith("internal.")) throw new IllegalArgumentException("Not an internal language key");
252+
if (!key.startsWith("internal."))
253+
throw new IllegalArgumentException("Not an internal language key");
250254
return super.getFormatted(key, para);
251255
}
252256

@@ -258,7 +262,8 @@ public boolean hasKey(String key) {
258262

259263
@Override
260264
public String getSubstituted(String key, Map<?, ?> paraMap) {
261-
if (!key.startsWith("internal.")) throw new IllegalArgumentException("Not an internal language key");
265+
if (!key.startsWith("internal."))
266+
throw new IllegalArgumentException("Not an internal language key");
262267
return super.getSubstituted(key, paraMap);
263268
}
264269
}
Lines changed: 34 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,49 @@
11
package cat.nyaa.nyaacore.utils;
22

3-
import org.bukkit.ChatColor;
4-
5-
import java.awt.*;
6-
import java.util.EnumSet;
7-
import java.util.Locale;
8-
import java.util.Set;
9-
import java.util.regex.Matcher;
3+
import java.util.regex.MatchResult;
104
import java.util.regex.Pattern;
115

126
public class HexColorUtils {
13-
//Extracted from EssentialsX
14-
private static final Pattern REPLACE_ALL_RGB_PATTERN = Pattern.compile("(&)?&#([0-9a-fA-F]{6})");
15-
private static final Pattern REPLACE_ALL_PATTERN = Pattern.compile("(&)?&([0-9a-fk-orA-FK-OR])");
16-
private static final Pattern LOGCOLOR_PATTERN = Pattern.compile("\\x1B\\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]");
17-
18-
private static String replaceFormat(final String input) {
19-
if (input == null) {
20-
return null;
21-
}
22-
return replaceColor(input, EnumSet.allOf(ChatColor.class), true);
23-
}
24-
25-
//This method is used to simply strip the & convention colour codes
26-
public static String stripEssentialsFormat(final String input) {
27-
if (input == null) {
28-
return null;
29-
}
30-
return stripColor(stripColor(input, REPLACE_ALL_PATTERN), REPLACE_ALL_RGB_PATTERN);
31-
}
32-
33-
static String stripColor(final String input, final Pattern pattern) {
34-
return pattern.matcher(input).replaceAll("");
35-
}
36-
37-
public static String stripLogColorFormat(final String input) {
38-
if (input == null) {
39-
return null;
40-
}
41-
return stripColor(input, LOGCOLOR_PATTERN);
42-
}
7+
// Extract from SimpleLanguageLoader
438

44-
private static String replaceColor(final String input, final Set<ChatColor> supported, boolean rgb) {
45-
StringBuffer legacyBuilder = new StringBuffer();
46-
Matcher legacyMatcher = REPLACE_ALL_PATTERN.matcher(input);
47-
legacyLoop:
48-
while (legacyMatcher.find()) {
49-
boolean isEscaped = (legacyMatcher.group(1) != null);
50-
if (!isEscaped) {
51-
char code = legacyMatcher.group(2).toLowerCase(Locale.ROOT).charAt(0);
52-
for (ChatColor color : supported) {
53-
if (color.getChar() == code) {
54-
legacyMatcher.appendReplacement(legacyBuilder, "\u00a7$2");
55-
continue legacyLoop;
56-
}
57-
}
58-
}
59-
// Don't change & to section sign (or replace two &'s with one)
60-
legacyMatcher.appendReplacement(legacyBuilder, "&$2");
61-
}
62-
legacyMatcher.appendTail(legacyBuilder);
9+
/**
10+
* hex color pattern looks like <code>&amp;#RRGGBB</code>
11+
*/
12+
public static final Pattern hexColorPattern = Pattern.compile("&#[0-9A-Fa-f]{6}");
6313

64-
if (rgb) {
65-
StringBuffer rgbBuilder = new StringBuffer();
66-
Matcher rgbMatcher = REPLACE_ALL_RGB_PATTERN.matcher(legacyBuilder.toString());
67-
while (rgbMatcher.find()) {
68-
boolean isEscaped = (rgbMatcher.group(1) != null);
69-
if (!isEscaped) {
70-
try {
71-
String hexCode = rgbMatcher.group(2);
72-
rgbMatcher.appendReplacement(rgbBuilder, parseHexColor(hexCode));
73-
continue;
74-
} catch (NumberFormatException ignored) {
75-
}
76-
}
77-
rgbMatcher.appendReplacement(rgbBuilder, "&#$2");
78-
}
79-
rgbMatcher.appendTail(rgbBuilder);
80-
return rgbBuilder.toString();
81-
}
82-
return legacyBuilder.toString();
14+
/**
15+
* Replace the convenient RGB color code with expanded color code in a string.
16+
*
17+
* @param text text to be proceeded
18+
* @return text with expanded color code
19+
*/
20+
public static String extractColorCode(String text) {
21+
var textParts = hexColorPattern.split(text);
22+
if (textParts.length == 0)
23+
textParts = new String[]{"", ""};
24+
var colorCodes = hexColorPattern.matcher(text).results().map(MatchResult::group).toArray(String[]::new);
25+
var textBuilder = new StringBuilder(textParts[0]);
26+
for (int i = 0; i < colorCodes.length; i++) {
27+
textBuilder.append(convertToTraditionalColorCode(colorCodes[i])).append(textParts[i + 1]);
28+
}
29+
return convertToLegacyColorCode(textBuilder.toString());
8330
}
8431

8532
/**
86-
* @throws NumberFormatException If the provided hex color code is invalid or if version is lower than 1.16.
33+
* Expand color code looks like <code>&amp;#RRGGBB</code> to <code>&amp;x&amp;R&amp;R&amp;G&amp;G&amp;B&amp;B</code>.
34+
*
35+
* @param x convenient color code
36+
* @return expanded color code
8737
*/
88-
private static String parseHexColor(String hexColor) throws NumberFormatException {
89-
if (hexColor.startsWith("#")) {
90-
hexColor = hexColor.substring(1); //fuck you im reassigning this.
91-
}
92-
if (hexColor.length() != 6) {
93-
throw new NumberFormatException("Invalid hex length");
94-
}
95-
Color.decode("#" + hexColor);
96-
StringBuilder assembledColorCode = new StringBuilder();
97-
assembledColorCode.append("\u00a7x");
98-
for (char curChar : hexColor.toCharArray()) {
99-
assembledColorCode.append("\u00a7").append(curChar);
100-
}
101-
return assembledColorCode.toString();
38+
private static String convertToTraditionalColorCode(String x) {
39+
var hexColorCode = x.substring(2);
40+
var colorCodeBuilder = new StringBuilder("&x");
41+
hexColorCode.chars().forEach(c -> colorCodeBuilder.append("&").append((char) c));
42+
return colorCodeBuilder.toString();
10243
}
103-
//Extracted from EssentialsX
10444

105-
//actual call
106-
public static String hexColored(String str) {
107-
try {
108-
return replaceFormat(str);
109-
} catch (Exception e) {
110-
//fallback in case an exception thrown.
111-
return ChatColor.translateAlternateColorCodes('&', str);
112-
}
45+
private static String convertToLegacyColorCode(String text) {
46+
return text.replace('&', '§').replace(String.valueOf('&') + '&', "§");
11347
}
48+
11449
}

0 commit comments

Comments
 (0)