Hex pr 1820 (#1822)

This commit is contained in:
tastybento 2021-08-19 12:09:23 -07:00 committed by GitHub
parent e0d6e4df30
commit b906f5561a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 105 additions and 34 deletions

View File

@ -3,13 +3,14 @@ package world.bentobox.bentobox.api.panels.builders;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import org.bukkit.ChatColor;
import org.bukkit.World; import org.bukkit.World;
import world.bentobox.bentobox.api.panels.Panel; import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.PanelListener; import world.bentobox.bentobox.api.panels.PanelListener;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.util.Util;
/** /**
* Builds panels * Builds panels
@ -26,7 +27,7 @@ public class PanelBuilder {
private World world; private World world;
public PanelBuilder name(String name) { public PanelBuilder name(String name) {
this.name = ChatColor.translateAlternateColorCodes('&', name); this.name = Util.translateColorCodes(name);
return this; return this;
} }

View File

@ -5,13 +5,14 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.panels.PanelItem; import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.PanelItem.ClickHandler; import world.bentobox.bentobox.api.panels.PanelItem.ClickHandler;
import world.bentobox.bentobox.util.Util;
public class PanelItemBuilder { public class PanelItemBuilder {
private ItemStack icon = new ItemStack(Material.AIR); private ItemStack icon = new ItemStack(Material.AIR);
@ -59,7 +60,7 @@ public class PanelItemBuilder {
} }
public PanelItemBuilder name(@Nullable String name) { public PanelItemBuilder name(@Nullable String name) {
this.name = name != null ? ChatColor.translateAlternateColorCodes('&', name) : null; this.name = name != null ? Util.translateColorCodes(name) : null;
return this; return this;
} }

View File

@ -410,7 +410,7 @@ public class User implements MetaDataAble {
translation = plugin.getPlaceholdersManager().replacePlaceholders(player, translation); translation = plugin.getPlaceholdersManager().replacePlaceholders(player, translation);
} }
return Util.stripSpaceAfterColorCodes(ChatColor.translateAlternateColorCodes('&', translation)); return Util.translateColorCodes(translation);
} }
} }

View File

@ -13,7 +13,6 @@ import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
@ -414,7 +413,7 @@ public class BlueprintPaster {
// Get the addon that is operating in this world // Get the addon that is operating in this world
String addonName = plugin.getIWM().getAddon(island.getWorld()).map(addon -> addon.getDescription().getName().toLowerCase(Locale.ENGLISH)).orElse(""); String addonName = plugin.getIWM().getAddon(island.getWorld()).map(addon -> addon.getDescription().getName().toLowerCase(Locale.ENGLISH)).orElse("");
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
s.setLine(i, ChatColor.translateAlternateColorCodes('&', plugin.getLocalesManager().getOrDefault(User.getInstance(island.getOwner()), s.setLine(i, Util.translateColorCodes(plugin.getLocalesManager().getOrDefault(User.getInstance(island.getOwner()),
addonName + ".sign.line" + i,"").replace(TextVariables.NAME, name))); addonName + ".sign.line" + i,"").replace(TextVariables.NAME, name)));
} }
} else { } else {

View File

@ -3,7 +3,6 @@ package world.bentobox.bentobox.blueprints.conversation;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.conversations.ConversationContext; import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt; import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt; import org.bukkit.conversations.StringPrompt;
@ -13,6 +12,8 @@ import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle; import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
import world.bentobox.bentobox.util.Util;
/** /**
* Collects a description * Collects a description
@ -57,7 +58,7 @@ public class DescriptionPrompt extends StringPrompt {
if (context.getSessionData(DESCRIPTION) != null) { if (context.getSessionData(DESCRIPTION) != null) {
desc = ((List<String>) context.getSessionData(DESCRIPTION)); desc = ((List<String>) context.getSessionData(DESCRIPTION));
} }
desc.add(ChatColor.translateAlternateColorCodes('&', input)); desc.add(Util.translateColorCodes(input));
context.setSessionData(DESCRIPTION, desc); context.setSessionData(DESCRIPTION, desc);
return this; return this;
} }

View File

@ -15,6 +15,8 @@ import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.blueprints.Blueprint; import world.bentobox.bentobox.blueprints.Blueprint;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle; import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
import world.bentobox.bentobox.managers.BlueprintsManager; import world.bentobox.bentobox.managers.BlueprintsManager;
import world.bentobox.bentobox.util.Util;
public class NamePrompt extends StringPrompt { public class NamePrompt extends StringPrompt {
@ -45,7 +47,7 @@ public class NamePrompt extends StringPrompt {
public Prompt acceptInput(ConversationContext context, String input) { public Prompt acceptInput(ConversationContext context, String input) {
User user = User.getInstance((Player)context.getForWhom()); User user = User.getInstance((Player)context.getForWhom());
// Convert color codes // Convert color codes
input = ChatColor.translateAlternateColorCodes('&', input); input = Util.translateColorCodes(input);
if (ChatColor.stripColor(input).length() > 32) { if (ChatColor.stripColor(input).length() > 32) {
context.getForWhom().sendRawMessage("Too long"); context.getForWhom().sendRawMessage("Too long");
return this; return this;

View File

@ -9,7 +9,6 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.World; import org.bukkit.World;
@ -242,7 +241,7 @@ public class BlueprintManagementPanel {
protected PanelItem getBundleIcon(BlueprintBundle bb) { protected PanelItem getBundleIcon(BlueprintBundle bb) {
return new PanelItemBuilder() return new PanelItemBuilder()
.name(t("edit-description")) .name(t("edit-description"))
.description(bb.getDescription().stream().map(l -> ChatColor.translateAlternateColorCodes('&', l)).collect(Collectors.toList())) .description(bb.getDescription().stream().map(Util::translateColorCodes).collect(Collectors.toList()))
.icon(bb.getIcon()) .icon(bb.getIcon())
.clickHandler((panel, u, clickType, slot) -> { .clickHandler((panel, u, clickType, slot) -> {
u.closeInventory(); u.closeInventory();
@ -340,7 +339,7 @@ public class BlueprintManagementPanel {
protected PanelItem getBlueprintItem(GameModeAddon addon, int pos, BlueprintBundle bb, Blueprint blueprint) { protected PanelItem getBlueprintItem(GameModeAddon addon, int pos, BlueprintBundle bb, Blueprint blueprint) {
// Create description // Create description
List<String> desc = blueprint.getDescription() == null ? new ArrayList<>() : blueprint.getDescription(); List<String> desc = blueprint.getDescription() == null ? new ArrayList<>() : blueprint.getDescription();
desc = desc.stream().map(l -> ChatColor.translateAlternateColorCodes('&', l)).collect(Collectors.toList()); desc = desc.stream().map(Util::translateColorCodes).collect(Collectors.toList());
if ((!blueprint.equals(endBlueprint) && !blueprint.equals(normalBlueprint) && !blueprint.equals(netherBlueprint))) { if ((!blueprint.equals(endBlueprint) && !blueprint.equals(normalBlueprint) && !blueprint.equals(netherBlueprint))) {
if ((pos > MIN_WORLD_SLOT && pos < MAX_WORLD_SLOT)) { if ((pos > MIN_WORLD_SLOT && pos < MAX_WORLD_SLOT)) {
desc.add(t("remove")); desc.add(t("remove"));

View File

@ -5,7 +5,6 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.bukkit.ChatColor;
import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNull;
import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.BentoBox;
@ -16,6 +15,8 @@ import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle; import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
import world.bentobox.bentobox.managers.BlueprintsManager; import world.bentobox.bentobox.managers.BlueprintsManager;
import world.bentobox.bentobox.util.Util;
/** /**
* Displays the available BlueprintBundles to pick up as the island. * Displays the available BlueprintBundles to pick up as the island.
@ -49,7 +50,7 @@ public class IslandCreationPanel {
// Add an item // Add an item
PanelItem item = new PanelItemBuilder() PanelItem item = new PanelItemBuilder()
.name(bb.getDisplayName()) .name(bb.getDisplayName())
.description(bb.getDescription().stream().map(l -> ChatColor.translateAlternateColorCodes('&', l)).collect(Collectors.toList())) .description(bb.getDescription().stream().map(Util::translateColorCodes).collect(Collectors.toList()))
.icon(bb.getIcon()).clickHandler((panel, user1, clickType, slot1) -> { .icon(bb.getIcon()).clickHandler((panel, user1, clickType, slot1) -> {
user1.closeInventory(); user1.closeInventory();
command.execute(user1, label, Collections.singletonList(bb.getUniqueId())); command.execute(user1, label, Collections.singletonList(bb.getUniqueId()));

View File

@ -11,6 +11,8 @@ import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
@ -55,7 +57,10 @@ import world.bentobox.bentobox.nms.NMSAbstraction;
* @author Poslovitch * @author Poslovitch
*/ */
public class Util { public class Util {
/**
* Use standard color code definition: &<hex>.
*/
private static final Pattern HEX_PATTERN = Pattern.compile("&#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})");
private static final String NETHER = "_nether"; private static final String NETHER = "_nether";
private static final String THE_END = "_the_end"; private static final String THE_END = "_the_end";
private static String serverVersion = null; private static String serverVersion = null;
@ -523,6 +528,44 @@ public class Util {
return false; return false;
} }
/**
* This method translates color codes in given string and strips whitespace after them.
* This code parses both: hex and old color codes.
* @param textToColor Text which color codes must be parsed.
* @return String text with parsed colors and stripped whitespaces after them.
*/
@NonNull
public static String translateColorCodes(@NonNull String textToColor) {
// Use matcher to find hex patterns in given text.
Matcher matcher = HEX_PATTERN.matcher(textToColor);
// Increase buffer size by 32 like it is in bungee cord api. Use buffer because it is sync.
StringBuffer buffer = new StringBuffer(textToColor.length() + 32);
while (matcher.find()) {
String group = matcher.group(1);
if (group.length() == 6) {
// Parses #ffffff to a color text.
matcher.appendReplacement(buffer, ChatColor.COLOR_CHAR + "x"
+ ChatColor.COLOR_CHAR + group.charAt(0) + ChatColor.COLOR_CHAR + group.charAt(1)
+ ChatColor.COLOR_CHAR + group.charAt(2) + ChatColor.COLOR_CHAR + group.charAt(3)
+ ChatColor.COLOR_CHAR + group.charAt(4) + ChatColor.COLOR_CHAR + group.charAt(5));
} else {
// Parses #fff to a color text.
matcher.appendReplacement(buffer, ChatColor.COLOR_CHAR + "x"
+ ChatColor.COLOR_CHAR + group.charAt(0) + ChatColor.COLOR_CHAR + group.charAt(0)
+ ChatColor.COLOR_CHAR + group.charAt(1) + ChatColor.COLOR_CHAR + group.charAt(1)
+ ChatColor.COLOR_CHAR + group.charAt(2) + ChatColor.COLOR_CHAR + group.charAt(2));
}
}
// transform normal codes and strip spaces after color code.
return Util.stripSpaceAfterColorCodes(
ChatColor.translateAlternateColorCodes('&', matcher.appendTail(buffer).toString()));
}
/** /**
* Strips spaces immediately after color codes. Used by {@link User#getTranslation(String, String...)}. * Strips spaces immediately after color codes. Used by {@link User#getTranslation(String, String...)}.
* @param textToStrip - text to strip * @param textToStrip - text to strip

View File

@ -162,7 +162,7 @@ public class IslandGoCommandTest {
// Locales // Locales
LocalesManager lm = mock(LocalesManager.class); LocalesManager lm = mock(LocalesManager.class);
when(lm.get(Mockito.any(), Mockito.any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(1, String.class)); when(lm.get(any(), any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(1, String.class));
when(plugin.getLocalesManager()).thenReturn(lm); when(plugin.getLocalesManager()).thenReturn(lm);
// Return the same string // Return the same string
PlaceholdersManager phm = mock(PlaceholdersManager.class); PlaceholdersManager phm = mock(PlaceholdersManager.class);
@ -172,8 +172,8 @@ public class IslandGoCommandTest {
// Notifier // Notifier
when(plugin.getNotifier()).thenReturn(notifier); when(plugin.getNotifier()).thenReturn(notifier);
// Util strip spaces // Util translate color codes (used in user translate methods)
when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); when(Util.translateColorCodes(anyString())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
// Command // Command
igc = new IslandGoCommand(ic); igc = new IslandGoCommand(ic);

View File

@ -194,10 +194,10 @@ public class JoinLeaveListenerTest {
// Util // Util
PowerMockito.mockStatic(Util.class); PowerMockito.mockStatic(Util.class);
when(Util.getWorld(any())).thenReturn(world); when(Util.getWorld(any())).thenReturn(world);
when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); // Util translate color codes (used in user translate methods)
when(Util.translateColorCodes(anyString())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
// user text // user text
LocalesManager lm = mock(LocalesManager.class); LocalesManager lm = mock(LocalesManager.class);
when(plugin.getLocalesManager()).thenReturn(lm); when(plugin.getLocalesManager()).thenReturn(lm);
when(lm.get(any(), anyString())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(1, String.class)); when(lm.get(any(), anyString())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(1, String.class));

View File

@ -129,8 +129,8 @@ public class StandardSpawnProtectionListenerTest {
// Block // Block
when(block.getLocation()).thenReturn(location); when(block.getLocation()).thenReturn(location);
// Util strip spaces // Util translate color codes (used in user translate methods)
when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); when(Util.translateColorCodes(anyString())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
// Set up class // Set up class
ssp = new StandardSpawnProtectionListener(plugin); ssp = new StandardSpawnProtectionListener(plugin);

View File

@ -161,9 +161,8 @@ public abstract class AbstractCommonSetup {
PowerMockito.mockStatic(Util.class); PowerMockito.mockStatic(Util.class);
when(Util.getWorld(any())).thenReturn(mock(World.class)); when(Util.getWorld(any())).thenReturn(mock(World.class));
// Util strip spaces // Util translate color codes (used in user translate methods)
when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); when(Util.translateColorCodes(anyString())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
} }

View File

@ -230,8 +230,8 @@ public class PVPListenerTest {
// Addon // Addon
when(iwm.getAddon(any())).thenReturn(Optional.empty()); when(iwm.getAddon(any())).thenReturn(Optional.empty());
// Util strip spaces // Util translate color codes (used in user translate methods)
when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); when(Util.translateColorCodes(anyString())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
} }

View File

@ -204,8 +204,8 @@ public class EnterExitListenerTest {
// Flags // Flags
Flags.ENTER_EXIT_MESSAGES.setSetting(world, true); Flags.ENTER_EXIT_MESSAGES.setSetting(world, true);
// Util strip spaces // Util translate color codes (used in user translate methods)
when(Util.stripSpaceAfterColorCodes(anyString())).thenCallRealMethod(); when(Util.translateColorCodes(anyString())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
} }
@After @After

View File

@ -43,6 +43,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito; import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.modules.junit4.PowerMockRunner;
@ -127,6 +128,8 @@ public class InvincibleVisitorsListenerTest {
PowerMockito.mockStatic(Util.class); PowerMockito.mockStatic(Util.class);
when(Util.getWorld(any())).thenReturn(mock(World.class)); when(Util.getWorld(any())).thenReturn(mock(World.class));
when(Util.prettifyText(anyString())).thenCallRealMethod(); when(Util.prettifyText(anyString())).thenCallRealMethod();
// Util translate color codes (used in user translate methods)
when(Util.translateColorCodes(anyString())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(0, String.class));
FlagsManager fm = mock(FlagsManager.class); FlagsManager fm = mock(FlagsManager.class);
Flag flag = mock(Flag.class); Flag flag = mock(Flag.class);
when(flag.isSetForWorld(any())).thenReturn(false); when(flag.isSetForWorld(any())).thenReturn(false);

View File

@ -125,7 +125,7 @@ public class UtilTest {
when(phm.replacePlaceholders(any(), any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(1, String.class)); when(phm.replacePlaceholders(any(), any())).thenAnswer((Answer<String>) invocation -> invocation.getArgument(1, String.class));
when(plugin.getLocalesManager()).thenReturn(lm); when(plugin.getLocalesManager()).thenReturn(lm);
} }
@After @After
@ -458,7 +458,7 @@ public class UtilTest {
Bukkit.dispatchCommand(sender, "replace tastybento"); Bukkit.dispatchCommand(sender, "replace tastybento");
verify(plugin).logError("Could not execute test command as console: replace tastybento"); verify(plugin).logError("Could not execute test command as console: replace tastybento");
} }
/** /**
* Test for {@link Util#broadcast(String, String...)} * Test for {@link Util#broadcast(String, String...)}
*/ */
@ -468,7 +468,7 @@ public class UtilTest {
int result = Util.broadcast("test.key", TextVariables.DESCRIPTION, "hello"); int result = Util.broadcast("test.key", TextVariables.DESCRIPTION, "hello");
assertEquals(0, result); assertEquals(0, result);
} }
/** /**
* Test for {@link Util#broadcast(String, String...)} * Test for {@link Util#broadcast(String, String...)}
*/ */
@ -476,6 +476,28 @@ public class UtilTest {
public void testBroadcastStringStringHasPerm() { public void testBroadcastStringStringHasPerm() {
int result = Util.broadcast("test.key", TextVariables.DESCRIPTION, "hello"); int result = Util.broadcast("test.key", TextVariables.DESCRIPTION, "hello");
assertEquals(11, result); assertEquals(11, result);
}
/**
* Test for {@link Util#translateColorCodes(String)}
*/
@Test
public void testTranslateColorCodesAmpersand() {
assertEquals("", Util.translateColorCodes(""));
assertEquals("abcdef ABCDEF", Util.translateColorCodes("abcdef ABCDEF"));
assertEquals("white space after ", Util.translateColorCodes("white space after "));
assertEquals("§ared color", Util.translateColorCodes("&a red color"));
assertEquals("§a big space", Util.translateColorCodes("&a big space"));
assertEquals("§ared color", Util.translateColorCodes("&ared color"));
assertEquals("§ared §bcolor §cgreen §fheheh", Util.translateColorCodes("&ared &bcolor &c green &f heheh"));
}
/**
* Test for {@link Util#translateColorCodes(String)}
*/
@Test
public void testTranslateColorCodesHex() {
assertEquals("§ared color", Util.translateColorCodes("&#ff0000 red color"));
} }
} }