diff --git a/build.gradle b/build.gradle index f3f1b60..3c09f94 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,7 @@ dependencies { compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.24' annotationProcessor group: 'org.projectlombok', name: 'lombok', version: '1.18.24' - implementation 'org.spigotmc:spigot-api:1.12-R0.1-SNAPSHOT' + implementation 'org.spigotmc:spigot-api:1.16.1-R0.1-SNAPSHOT' implementation 'commons-io:commons-io:2.11.0' implementation group: 'org.jetbrains', name: 'annotations', version: '21.0.1' @@ -24,8 +24,8 @@ rootProject.tasks.named("processResources") { compileJava { options.encoding = 'UTF-8' - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 } tasks.withType(JavaCompile) { diff --git a/src/main/java/com/demkom58/divinedrop/DivineCommandHandler.java b/src/main/java/com/demkom58/divinedrop/DivineCommandHandler.java index 2f1ff56..162cc5c 100644 --- a/src/main/java/com/demkom58/divinedrop/DivineCommandHandler.java +++ b/src/main/java/com/demkom58/divinedrop/DivineCommandHandler.java @@ -2,6 +2,7 @@ import com.demkom58.divinedrop.config.ConfigData; import com.demkom58.divinedrop.config.StaticData; +import com.demkom58.divinedrop.util.ColorUtil; import com.demkom58.divinedrop.version.SupportedVersion; import com.demkom58.divinedrop.version.VersionManager; import org.bukkit.Material; @@ -82,6 +83,7 @@ private void getName(@NotNull final CommandSender sender) { return; final Player player = (Player) sender; + @SuppressWarnings("deprecation") // Using "player.getItemInHand()" due legacy version support final ItemStack handStack = versionManager.isOlder(SupportedVersion.V9R1) ? player.getItemInHand() : player.getInventory().getItemInMainHand(); @@ -90,7 +92,7 @@ private void getName(@NotNull final CommandSender sender) { if (handStack.getType() != Material.AIR) { final ItemMeta itemMeta = handStack.getItemMeta(); if (itemMeta != null && itemMeta.hasDisplayName()) - name = itemMeta.getDisplayName().replace('§', '&'); + name = ColorUtil.escapeColor(itemMeta.getDisplayName()); else name = "§7"; } else name = "AIR"; diff --git a/src/main/java/com/demkom58/divinedrop/config/ConfigData.java b/src/main/java/com/demkom58/divinedrop/config/ConfigData.java index 8717654..3aae1ce 100644 --- a/src/main/java/com/demkom58/divinedrop/config/ConfigData.java +++ b/src/main/java/com/demkom58/divinedrop/config/ConfigData.java @@ -5,7 +5,6 @@ import lombok.Getter; import lombok.Setter; import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; @@ -15,6 +14,8 @@ import java.util.HashMap; import java.util.Map; +import static com.demkom58.divinedrop.util.ColorUtil.colorize; + @Getter @Setter public final class ConfigData { @@ -72,21 +73,21 @@ public void updateData(@NotNull final FileConfiguration conf) { cleanerCountdowns = null; checkUpdates = conf.getBoolean("check-updates", true); - format = color(conf.getString("format", "&f%name% &7(x%size%)")); + format = colorize(conf.getString("format", "&f%name% &7(x%size%)")); pickupOnShift = conf.getBoolean("pickup-items-on-sneak", false); ignoreNoPickup = conf.getBoolean("ignore-no-pickup-items", true); lang = conf.getString("lang", "en_CA"); final ConfigurationSection msg = getConfigurationSection(conf, "messages"); - prefixMessage = color(msg.getString("prefix", "&5&lDivineDrop &7> &f")); - itemDisplayNameMessage = color(msg.getString("display-name", "Display Name&7: &f%name%")); - noPermissionMessage = color(msg.getString("no-permission", "&cYou do not have permission to run this command.")); - unknownCmdMessage = color(msg.getString("unknown-cmd", "&cYou entered an unknown command.")); - reloadedMessage = color(msg.getString("reloaded", "&aThe configuration is reloaded.")); + prefixMessage = colorize(msg.getString("prefix", "&5&lDivineDrop &7> &f")); + itemDisplayNameMessage = colorize(msg.getString("display-name", "Display Name&7: &f%name%")); + noPermissionMessage = colorize(msg.getString("no-permission", "&cYou do not have permission to run this command.")); + unknownCmdMessage = colorize(msg.getString("unknown-cmd", "&cYou entered an unknown command.")); + reloadedMessage = colorize(msg.getString("reloaded", "&aThe configuration is reloaded.")); final ConfigurationSection cleaner = getConfigurationSection(conf, "drop-cleaner"); cleanerEnabled = cleaner.getBoolean("enabled", false); - cleanerFormat = color(cleaner.getString("format", "&c[&4%countdown%&c] &f%name% &7(x%size%)")); + cleanerFormat = colorize(cleaner.getString("format", "&c[&4%countdown%&c] &f%name% &7(x%size%)")); timerValue = cleaner.getInt("timer", 10); addItemsOnChunkLoad = cleaner.getBoolean("timer-for-loaded-items", true); savePlayerDeathDroppedItems = cleaner.getBoolean("save-player-dropped-items", false); @@ -111,7 +112,7 @@ public void updateData(@NotNull final FileConfiguration conf) { String name = custom.getString(materialName + ".name-filter"); if (name == null) name = "*"; - name = color(name); + name = colorize(name); int timer = custom.getInt(materialName + ".timer"); String format = custom.getString(materialName + ".format"); @@ -119,7 +120,7 @@ public void updateData(@NotNull final FileConfiguration conf) { if (format == null) format = ConfigData.this.cleanerFormat; - format = color(format); + format = colorize(format); Map itemFilter; if (!cleanerCountdowns.containsKey(material)) { @@ -134,10 +135,6 @@ public void updateData(@NotNull final FileConfiguration conf) { } - public static String color(String s) { - return ChatColor.translateAlternateColorCodes('&', s); - } - @NotNull private ConfigurationSection getConfigurationSection(@NotNull final ConfigurationSection config, @NotNull final String name) { diff --git a/src/main/java/com/demkom58/divinedrop/util/ColorUtil.java b/src/main/java/com/demkom58/divinedrop/util/ColorUtil.java new file mode 100644 index 0000000..602bd4f --- /dev/null +++ b/src/main/java/com/demkom58/divinedrop/util/ColorUtil.java @@ -0,0 +1,79 @@ +package com.demkom58.divinedrop.util; + +import com.demkom58.divinedrop.version.SupportedVersion; +import com.demkom58.divinedrop.version.VersionManager; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.util.Vector; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public final class ColorUtil { + private static final Pattern HEX_COLOR_PATTERN = Pattern.compile("&#[a-fA-f0-9]{6}"); + + private static final Map COLOR_MAP = Collections.unmodifiableMap(new HashMap() {{ + put(ChatColor.BLACK, new Vector(0, 0, 0)); + put(ChatColor.DARK_BLUE, new Vector(0, 0, 170)); + put(ChatColor.DARK_GREEN, new Vector(0, 170, 0)); + put(ChatColor.DARK_AQUA, new Vector(0, 170, 170)); + put(ChatColor.DARK_RED, new Vector(170, 0, 0)); + put(ChatColor.DARK_PURPLE, new Vector(170, 0, 170)); + put(ChatColor.GOLD, new Vector(255, 170, 0)); + put(ChatColor.GRAY, new Vector(170, 170, 170)); + put(ChatColor.DARK_GRAY, new Vector(85, 85, 85)); + put(ChatColor.BLUE, new Vector(85, 85, 255)); + put(ChatColor.GREEN, new Vector(85, 255, 85)); + put(ChatColor.AQUA, new Vector(85, 255, 255)); + put(ChatColor.RED, new Vector(255, 85, 85)); + put(ChatColor.LIGHT_PURPLE, new Vector(255, 85, 255)); + put(ChatColor.YELLOW, new Vector(255, 255, 85)); + put(ChatColor.WHITE, new Vector(255, 255, 255)); + }}); + + public static String colorize(String text) { + Matcher matcher = HEX_COLOR_PATTERN.matcher(text); + + // If RGB colors available use them, else choose the closest constant color + if (VersionManager.detectedVersion.isNewer(SupportedVersion.V15R1)) { + while (matcher.find()) { + String color = text.substring(matcher.start(), matcher.end()); + text = text.replace(color, ChatColor.of(color.substring(1)) + ""); + matcher = HEX_COLOR_PATTERN.matcher(text); + } + } else { + while (matcher.find()) { + String color = text.substring(matcher.start(), matcher.end()); + text = text.replace(color, fromHex(Integer.parseInt(color.substring(2), 16)) + ""); + matcher = HEX_COLOR_PATTERN.matcher(text); + } + } + + return ChatColor.translateAlternateColorCodes('&', text); + } + + public static String escapeColor(String text) { + return text.replace('§', '&'); + } + + public static ChatColor fromHex(int hex) { + int r = (hex & 0xFF0000) >> 16; + int g = (hex & 0xFF00) >> 8; + int b = (hex & 0xFF); + return fromRGB(r, g, b); + } + + public static ChatColor fromRGB(int r, int g, int b) { + TreeMap closest = new TreeMap<>(); + COLOR_MAP.forEach((color, set) -> { + int red = Math.abs(r - set.getBlockX()); + int green = Math.abs(g - set.getBlockY()); + int blue = Math.abs(b - set.getBlockZ()); + closest.put(red + green + blue, color); + }); + return closest.firstEntry().getValue(); + } +} diff --git a/src/main/java/com/demkom58/divinedrop/version/VersionManager.java b/src/main/java/com/demkom58/divinedrop/version/VersionManager.java index a101000..2ff3607 100644 --- a/src/main/java/com/demkom58/divinedrop/version/VersionManager.java +++ b/src/main/java/com/demkom58/divinedrop/version/VersionManager.java @@ -8,6 +8,8 @@ import org.jetbrains.annotations.NotNull; public class VersionManager { + public static SupportedVersion detectedVersion = null; + private final DivineDrop plugin; private Version version; @@ -38,6 +40,8 @@ public void setup(@NotNull final ConfigData data, @NotNull final ItemHandler man throw new UnsupportedOperationException("Current version: " + nmsVersion + ". This version is not supported!"); this.version = supportedVersion.create(manager); + + VersionManager.detectedVersion = supportedVersion; } /**