+ * Hex color codes are in the format of RRGGBB + * Minecraft color codes are in the format of §x§R§R§G§G§B§B + * Where R, G, and B are the red, green, and blue values respectively. + * The §x is a special character that tells Minecraft to use the following color codes as hex values. + * The §R§R is the red value, the §G§G is the green value, and the §B§B is the blue value. + * Example: §x§R§R§G§G§B§B is the equivalent of the hex color code RRGGBB + *
+ * @param messageWithHex The message with hex color codes to translate + * @return The message with the hex color codes translated to Minecraft color codes + */ + public static String translateHexColorCodes(String messageWithHex) { + if(messageWithHex == null) { + return null; + } + + final Matcher matcher = hexPattern.matcher(messageWithHex); + final StringBuilder buffer = new StringBuilder(messageWithHex.length() + 4 * 8); + while (matcher.find()) { + String group = matcher.group(1); + String hexEquivalent = "§x" + + "§" + group.charAt(0) + "§" + group.charAt(1) + + "§" + group.charAt(2) + "§" + group.charAt(3) + + "§" + group.charAt(4) + "§" + group.charAt(5); + matcher.appendReplacement(buffer, hexEquivalent); + } + return matcher.appendTail(buffer).toString(); + } + + // Method to reverse the transformation from Minecraft color codes to hex codes + public static String reverseTranslateHexColorCodes(String minecraftColorString) { + // Matches the Minecraft color pattern: §x§R§R§G§G§B§B + Matcher matcher = minecraftHexPattern.matcher(minecraftColorString); + StringBuilder buffer = new StringBuilder(); + + while (matcher.find()) { + String hexColor = "#" + + matcher.group(1).substring(1) + matcher.group(2).substring(1) + + matcher.group(3).substring(1) + matcher.group(4).substring(1) + + matcher.group(5).substring(1) + matcher.group(6).substring(1); + matcher.appendReplacement(buffer, "&" + hexColor); + } + matcher.appendTail(buffer); + return buffer.toString(); + } } diff --git a/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java b/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java index d272eeb76..0946b4cc5 100644 --- a/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java +++ b/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java @@ -42,8 +42,8 @@ public final class CommandRegistrationManager { command.setDescription(LocaleLoader.getString("Commands.Description.Skill", StringUtils.getCapitalized(localizedName))); command.setPermission("mcmmo.commands." + commandName); command.setPermissionMessage(permissionsMessage); - command.setUsage(LocaleLoader.getString("Commands.Usage.0", localizedName)); - command.setUsage(command.getUsage() + "\n" + LocaleLoader.getString("Commands.Usage.2", localizedName, "?", "[" + LocaleLoader.getString("Commands.Usage.Page") + "]")); + command.setUsage(LocaleLoader.getString("Commands.Usage.0", commandName)); + command.setUsage(command.getUsage() + "\n" + LocaleLoader.getString("Commands.Usage.2", commandName, "?", "[" + LocaleLoader.getString("Commands.Usage.Page") + "]")); switch (skill) { case ACROBATICS: diff --git a/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java b/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java index 3f497af07..39ddfbd24 100644 --- a/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java +++ b/src/main/java/com/gmail/nossr50/util/skills/SkillTools.java @@ -349,8 +349,7 @@ public class SkillTools { * @return the localized name for a {@link PrimarySkillType} */ public String getLocalizedSkillName(PrimarySkillType primarySkillType) { - //TODO: Replace with current impl - return StringUtils.getCapitalized(LocaleLoader.getString(StringUtils.getCapitalized(primarySkillType.toString()) + ".SkillName")); + return LocaleLoader.getString(StringUtils.getCapitalized(primarySkillType.toString()) + ".SkillName"); } public boolean doesPlayerHaveSkillPermission(Player player, PrimarySkillType primarySkillType) { diff --git a/src/main/java/com/gmail/nossr50/util/text/TextComponentFactory.java b/src/main/java/com/gmail/nossr50/util/text/TextComponentFactory.java index debcf685b..89981bb85 100644 --- a/src/main/java/com/gmail/nossr50/util/text/TextComponentFactory.java +++ b/src/main/java/com/gmail/nossr50/util/text/TextComponentFactory.java @@ -19,6 +19,7 @@ import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextDecoration; +import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -235,8 +236,8 @@ public class TextComponentFactory { } private static Component getSubSkillTextComponent(Player player, SubSkillType subSkillType) { - //Get skill name - String skillName = subSkillType.getLocaleName(); + //Get skill name and strip it of color + final String skillName = ChatColor.stripColor(subSkillType.getLocaleName()); boolean skillUnlocked = RankUtils.hasUnlockedSubskill(player, subSkillType); @@ -306,7 +307,7 @@ public class TextComponentFactory { * @return the hover basecomponent object for this subskill */ private static Component getSubSkillHoverEventJSON(AbstractSubSkill abstractSubSkill, Player player) { - String skillName = abstractSubSkill.getNiceName(); + String skillName = ChatColor.stripColor(abstractSubSkill.getNiceName()); /* * Hover Event BaseComponent color table @@ -399,7 +400,8 @@ public class TextComponentFactory { } private static Component getSubSkillHoverEventJSON(SubSkillType subSkillType, Player player) { - String skillName = subSkillType.getLocaleName(); + // Get skill name and strip it of color + String skillName = ChatColor.stripColor(subSkillType.getLocaleName()); /* * Hover Event BaseComponent color table @@ -433,11 +435,9 @@ public class TextComponentFactory { } componentBuilder.append(Component.newline()); - componentBuilder.append(Component.text(LocaleLoader.getString("JSON.DescriptionHeader"))); - componentBuilder.color(ccDescriptionHeader); + componentBuilder.append(Component.text(LocaleLoader.getString("JSON.DescriptionHeader")).color(ccDescriptionHeader)); componentBuilder.append(Component.newline()); - componentBuilder.append(Component.text(subSkillType.getLocaleDescription())); - componentBuilder.color(ccDescription); + componentBuilder.append(Component.text(ChatColor.stripColor(subSkillType.getLocaleDescription())).color(ccDescription)); } return componentBuilder.build(); diff --git a/src/main/resources/locale/locale_en_US.properties b/src/main/resources/locale/locale_en_US.properties index 7da72244d..11e550b20 100644 --- a/src/main/resources/locale/locale_en_US.properties +++ b/src/main/resources/locale/locale_en_US.properties @@ -1,10 +1,5 @@ -#I'm going to try to normalize our locale file, forgive the mess for now. -# TODO: Update JSON to support hex - -#DO NOT USE COLOR CODES IN THE JSON KEYS -#COLORS ARE DEFINED IN advanced.yml IF YOU WISH TO CHANGE THEM JSON.Rank=Rank -JSON.DescriptionHeader=Description +JSON.DescriptionHeader=Description: JSON.JWrapper.Header=Details JSON.Type.Passive=Passive JSON.Type.Active=Active @@ -784,7 +779,7 @@ Commands.XPBar.Reset=&6XP Bar settings for mcMMO have been reset. Commands.XPBar.SettingChanged=&6XP Bar setting for &a{0}&6 is now set to &a{1} Commands.Skill.Invalid=That is not a valid skillname! Commands.Skill.ChildSkill=Child skills are not valid for this command! -Commands.Skill.Leaderboard=--mcMMO &9{0}&e Leaderboard-- +Commands.Skill.Leaderboard=-&e-mcMMO &9{0}&e Leaderboard-- Commands.SkillInfo=&a- View detailed information about a skill Commands.Stats=&a- View your mcMMO stats Commands.ToggleAbility=&a- Toggle ability activation with right click diff --git a/src/test/java/com/gmail/nossr50/locale/LocaleLoaderTest.java b/src/test/java/com/gmail/nossr50/locale/LocaleLoaderTest.java new file mode 100644 index 000000000..d7db4bee3 --- /dev/null +++ b/src/test/java/com/gmail/nossr50/locale/LocaleLoaderTest.java @@ -0,0 +1,76 @@ +package com.gmail.nossr50.locale; + +import org.bukkit.ChatColor; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class LocaleLoaderTest { + + @BeforeEach + void setUp() { + } + + @AfterEach + void tearDown() { + } + + @ParameterizedTest + @ValueSource(strings = {"§cTest", "[[RED]]Test"}) + void addColorsShouldAddColorRed(String testString) { + // When + final String result = LocaleLoader.addColors(testString); + + // Then + assertThat(result).isEqualTo(ChatColor.RED + "Test"); + } + + // hex colors test + @Test + void translateHexColorCodesShouldAddRed() { + // Given + final String testString = "FF0000Test"; + + // When + final String result = LocaleLoader.translateHexColorCodes(testString); + + // Then + final String expectedResult = "§x§F§F§0§0§0§0Test"; + assertThat(result).isEqualTo(expectedResult); + } + + @Test + void reverseTranslateHexColorCodesShouldRemoveRed() { + // Given + final String testString = "§x§F§F§0§0§0§0Test"; + + // When + final String result = LocaleLoader.reverseTranslateHexColorCodes(testString); + + // Then + final String expectedResult = "FF0000Test"; + assertThat(result).isEqualTo(expectedResult); + } + + @ParameterizedTest + @ValueSource(strings = {"FF0000TeFFst", "FF0000Te[[RED]]st", "[[BLUE]]Te[[RED]]st", "§9Te§cst"}) + void addColorsShouldAddRedAndBlue(String testString) { + // When + final String result = LocaleLoader.addColors(testString); + + // TODO: Hacky, clean this up sometime in the future + // Then + // All legal representations of the same string + final List