From 54d5757d0ab662fcc4e1dc88987e4fde46afa5eb Mon Sep 17 00:00:00 2001 From: Crypto Morin Date: Thu, 16 Jul 2020 09:32:22 -0700 Subject: [PATCH 01/14] Performance Improvements (#340) * Performance Improvements * More Optimizations * Even More Optimizations & Cleanups * Almost a recode I guess --- pom.xml | 36 +-- .../clip/placeholderapi/PlaceholderAPI.java | 229 ++++++++---------- .../placeholderapi/PlaceholderAPIPlugin.java | 166 ++++++------- .../clip/placeholderapi/PlaceholderHook.java | 19 +- .../placeholderapi/PlaceholderReplacer.java | 150 ++++++++++++ .../clip/placeholderapi/commands/Command.java | 49 ++-- .../commands/CommandHandler.java | 69 +++--- .../commands/CompletionHandler.java | 35 +-- .../commands/command/BcParseCommand.java | 26 +- .../commands/command/EcloudCommand.java | 16 +- .../commands/command/HelpCommand.java | 5 +- .../commands/command/InfoCommand.java | 15 +- .../commands/command/ListCommand.java | 7 +- .../commands/command/ParseCommand.java | 44 ++-- .../commands/command/ParseRelCommand.java | 13 +- .../commands/command/RegisterCommand.java | 11 +- .../commands/command/ReloadCommand.java | 5 +- .../commands/command/UnregisterCommand.java | 19 +- .../commands/command/VersionCommand.java | 9 +- .../command/ecloud/EcloudClearCommand.java | 5 +- .../EcloudDisableCommand.java} | 16 +- .../command/ecloud/EcloudDownloadCommand.java | 30 ++- .../EcloudEnableCommand.java} | 14 +- .../command/ecloud/EcloudInfoCommand.java | 17 +- .../command/ecloud/EcloudListCommand.java | 36 ++- .../ecloud/EcloudPlaceholdersCommand.java | 19 +- .../command/ecloud/EcloudRefreshCommand.java | 9 +- .../command/ecloud/EcloudStatusCommand.java | 7 +- .../ecloud/EcloudVersionInfoCommand.java | 18 +- .../exceptions/NoDefaultCommandException.java | 8 - .../placeholderapi/expansion/Cacheable.java | 1 - .../placeholderapi/expansion/Cleanable.java | 5 +- .../expansion/ExpansionManager.java | 92 +++---- .../placeholderapi/expansion/NMSVersion.java | 51 ++-- .../expansion/PlaceholderExpansion.java | 38 ++- .../placeholderapi/expansion/Relational.java | 1 - .../placeholderapi/expansion/Taskable.java | 2 - .../placeholderapi/expansion/Version.java | 2 - .../expansion/VersionSpecific.java | 2 +- .../expansion/cloud/CloudExpansion.java | 25 +- .../cloud/ExpansionCloudManager.java | 50 +--- .../external/EZPlaceholderHook.java | 8 +- .../listeners/ApacheListener.java | 39 +++ .../listeners/PlaceholderListener.java | 64 ++--- .../listeners/ServerLoadEventListener.java | 11 +- .../clip/placeholderapi/util/Constants.java | 9 - .../me/clip/placeholderapi/util/FileUtil.java | 47 ++-- .../java/me/clip/placeholderapi/util/Msg.java | 21 +- .../clip/placeholderapi/util/TimeFormat.java | 28 --- .../me/clip/placeholderapi/util/TimeUtil.java | 8 +- .../UpdateChecker.java | 63 +++-- src/main/resources/plugin.yml | 82 ++++--- 52 files changed, 876 insertions(+), 875 deletions(-) create mode 100644 src/main/java/me/clip/placeholderapi/PlaceholderReplacer.java rename src/main/java/me/clip/placeholderapi/commands/command/{DisableEcloudCommand.java => ecloud/EcloudDisableCommand.java} (53%) rename src/main/java/me/clip/placeholderapi/commands/command/{EnableCloudCommand.java => ecloud/EcloudEnableCommand.java} (54%) delete mode 100644 src/main/java/me/clip/placeholderapi/exceptions/NoDefaultCommandException.java create mode 100644 src/main/java/me/clip/placeholderapi/listeners/ApacheListener.java delete mode 100644 src/main/java/me/clip/placeholderapi/util/Constants.java delete mode 100644 src/main/java/me/clip/placeholderapi/util/TimeFormat.java rename src/main/java/me/clip/placeholderapi/{updatechecker => util}/UpdateChecker.java (66%) diff --git a/pom.xml b/pom.xml index 8f07573..e82f6f8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,8 +5,8 @@ me.clip placeholderapi - 2.10.7-DEV-${BUILD_NUMBER} + PlaceholderAPI An awesome placeholder provider! http://extendedclip.com @@ -33,7 +33,7 @@ org.spigotmc - spigot-api + spigot 1.16.1-R0.1-SNAPSHOT provided @@ -45,7 +45,7 @@ org.bstats bstats-bukkit - 1.5 + 1.7 me.rayzr522 @@ -84,27 +84,27 @@ org.apache.maven.plugins maven-shade-plugin - 3.1.0 + 3.2.4 + + false + false + + + org.bstats + me.clip.placeholderapi.util + + + com.google.code.gson + me.clip.placeholderapi.libs.gson + + + package shade - - false - false - - - org.bstats - me.clip.placeholderapi.metrics - - - com.google.code.gson - me.clip.placeholderapi.libs.gson - - - diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java index 8ce1674..d089aa0 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java @@ -20,14 +20,13 @@ */ package me.clip.placeholderapi; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import me.clip.placeholderapi.events.ExpansionRegisterEvent; import me.clip.placeholderapi.events.ExpansionUnregisterEvent; -import me.clip.placeholderapi.expansion.Cacheable; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.Relational; -import me.clip.placeholderapi.util.Msg; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; @@ -35,18 +34,17 @@ import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.stream.Collectors; import static me.clip.placeholderapi.util.Msg.color; public class PlaceholderAPI { - - private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]"); + protected static final Map PLACEHOLDERS = new ConcurrentHashMap<>(); + private static final Pattern PERCENT_PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]"); private static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]"); private static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern.compile("[%](rel_)([^%]+)[%]"); - private static final Map placeholders = new HashMap<>(); private PlaceholderAPI() { } @@ -58,9 +56,7 @@ public class PlaceholderAPI { * @return true if identifier is already registered */ public static boolean isRegistered(String identifier) { - return getRegisteredIdentifiers().stream() - .filter(id -> id.equalsIgnoreCase(identifier)) - .findFirst().orElse(null) != null; + return PLACEHOLDERS.containsKey(identifier.toLowerCase(Locale.ENGLISH)); } /** @@ -73,15 +69,11 @@ public class PlaceholderAPI { * registered for the specified identifier */ public static boolean registerPlaceholderHook(String identifier, PlaceholderHook placeholderHook) { - Validate.notNull(identifier, "Identifier can not be null"); - Validate.notNull(placeholderHook, "Placeholderhook can not be null"); - - if (isRegistered(identifier)) { - return false; - } - - placeholders.put(identifier.toLowerCase(), placeholderHook); + Validate.notEmpty(identifier, "Placeholder identifier cannot be null or empty"); + Objects.requireNonNull(placeholderHook, "Placeholder hook cannot be null"); + if (isRegistered(identifier)) return false; + PLACEHOLDERS.put(identifier.toLowerCase(Locale.ENGLISH), placeholderHook); return true; } @@ -93,8 +85,8 @@ public class PlaceholderAPI { * placeholder hook registered for the identifier specified */ public static boolean unregisterPlaceholderHook(String identifier) { - Validate.notNull(identifier, "Identifier can not be null"); - return placeholders.remove(identifier.toLowerCase()) != null; + Validate.notEmpty(identifier, "Identifier cannot be null"); + return PLACEHOLDERS.remove(identifier.toLowerCase(Locale.ENGLISH)) != null; } /** @@ -103,7 +95,7 @@ public class PlaceholderAPI { * @return All registered placeholder identifiers */ public static Set getRegisteredIdentifiers() { - return ImmutableSet.copyOf(placeholders.keySet()); + return ImmutableSet.copyOf(PLACEHOLDERS.keySet()); } /** @@ -112,15 +104,16 @@ public class PlaceholderAPI { * @return Copy of the internal placeholder map */ public static Map getPlaceholders() { - return ImmutableMap.copyOf(placeholders); + return ImmutableMap.copyOf(PLACEHOLDERS); } public static Set getExpansions() { - Set set = getPlaceholders().values().stream() - .filter(PlaceholderExpansion.class::isInstance).map(PlaceholderExpansion.class::cast) - .collect(Collectors.toCollection(HashSet::new)); + Set expansions = new HashSet<>(); + for (PlaceholderHook expansion : PLACEHOLDERS.values()) { + if (expansion.isExpansion()) expansions.add((PlaceholderExpansion) expansion); + } - return ImmutableSet.copyOf(set); + return ImmutableSet.copyOf(expansions); } /** @@ -130,7 +123,7 @@ public class PlaceholderAPI { * @return true if String contains any registered placeholder identifiers, false otherwise */ public static boolean containsPlaceholders(String text) { - return text != null && PLACEHOLDER_PATTERN.matcher(text).find(); + return !Strings.isNullOrEmpty(text) && PERCENT_PLACEHOLDER_PATTERN.matcher(text).find(); } /** @@ -140,7 +133,7 @@ public class PlaceholderAPI { * @return true if String contains any registered placeholder identifiers, false otherwise */ public static boolean containsBracketPlaceholders(String text) { - return text != null && BRACKET_PLACEHOLDER_PATTERN.matcher(text).find(); + return !Strings.isNullOrEmpty(text) && BRACKET_PLACEHOLDER_PATTERN.matcher(text).find(); } /** @@ -177,7 +170,7 @@ public class PlaceholderAPI { * @return String containing all translated placeholders */ public static List setPlaceholders(OfflinePlayer player, List text) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true); + return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, true); } /** @@ -190,7 +183,7 @@ public class PlaceholderAPI { * @return String containing all translated placeholders */ public static List setPlaceholders(OfflinePlayer player, List text, boolean colorize) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); + return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize); } /** @@ -219,13 +212,13 @@ public class PlaceholderAPI { * @return String containing all translated placeholders */ public static List setPlaceholders(OfflinePlayer player, List text, Pattern pattern, boolean colorize) { - if (text == null) { - return null; - } + if (text == null) return null; + List lines = new ArrayList<>(); - return text.stream() - .map(line -> setPlaceholders(player, line, pattern, colorize)) - .collect(Collectors.toList()); + for (String line : text) { + lines.add(setPlaceholders(player, line, pattern, colorize)); + } + return lines; } /** @@ -262,7 +255,7 @@ public class PlaceholderAPI { * @return String containing all translated placeholders */ public static String setPlaceholders(OfflinePlayer player, String text) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN); + return PlaceholderReplacer.evaluatePlaceholders(player, text, PlaceholderReplacer.Closure.PERCENT, false); } /** @@ -275,7 +268,7 @@ public class PlaceholderAPI { * @return The text containing the parsed placeholders */ public static String setPlaceholders(OfflinePlayer player, String text, boolean colorize) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); + return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize); } /** @@ -304,43 +297,51 @@ public class PlaceholderAPI { * @return The text containing the parsed placeholders */ public static String setPlaceholders(OfflinePlayer player, String text, Pattern pattern, boolean colorize) { - if (text == null) { - return null; - } - - if (placeholders.isEmpty()) { - return colorize ? color(text) : text; - } - - final Matcher matcher = pattern.matcher(text); - final Map hooks = getPlaceholders(); + if (text == null) return null; + if (PLACEHOLDERS.isEmpty()) return colorize ? color(text) : text; + Matcher matcher = pattern.matcher(text); while (matcher.find()) { - final String format = matcher.group(1); - final int index = format.indexOf("_"); + String format = matcher.group(1); + int index = format.indexOf('_'); + if (index <= 0 || index >= format.length()) continue; - if (index <= 0 || index >= format.length()) { - continue; - } + // We don't need to use getPlaceholders() because we know what we're doing and we won't modify the map. + // And instead of looking for the element twice using contains() and get() we only get it and check if it's null. + String identifier = format.substring(0, index).toLowerCase(Locale.ENGLISH); + PlaceholderHook handler = PLACEHOLDERS.get(identifier); - final String identifier = format.substring(0, index).toLowerCase(); - final String params = format.substring(index + 1); - final PlaceholderHook hook = hooks.get(identifier); + if (handler != null) { + String params = format.substring(index + 1); + String value = handler.onRequest(player, params); - if (hook == null) { - continue; - } - - final String value = hook.onRequest(player, params); - - if (value != null) { - text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value)); + if (value != null) { + text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value)); + } } } return colorize ? color(text) : text; } + /** + * Optimized version of {@link #setPlaceholders(OfflinePlayer, String, Pattern, boolean)} + * + * @param player player to parse the placeholders against. + * @param text the text to translate. + * @param closure the closing points of a placeholder. %, {, [ etc... + * @param colorize if we should colorize this text using the common & symbol. + * @return the translated text. + */ + public static String setPlaceholders(OfflinePlayer player, String text, PlaceholderReplacer.Closure closure, boolean colorize) { + if (text == null) return null; + if (text.isEmpty()) return ""; + if (PLACEHOLDERS.isEmpty()) return colorize ? color(text) : text; + + // We don't want to dirty our class. + return PlaceholderReplacer.evaluatePlaceholders(player, text, closure, colorize); + } + /** * Translate placeholders in the provided List based on the relation of the two provided players. *
The pattern of a valid placeholder is {@literal %rel__%}. @@ -365,13 +366,12 @@ public class PlaceholderAPI { * @return The text containing the parsed relational placeholders */ public static List setRelationalPlaceholders(Player one, Player two, List text, boolean colorize) { - if (text == null) { - return null; + if (text == null) return null; + List lines = new ArrayList<>(); + for (String line : text) { + lines.add(setRelationalPlaceholders(one, two, line, colorize)); } - - return text.stream() - .map(line -> setRelationalPlaceholders(one, two, line, colorize)) - .collect(Collectors.toList()); + return lines; } /** @@ -397,43 +397,31 @@ public class PlaceholderAPI { * @param colorize If color codes (&[0-1a-fk-o]) should be translated * @return The text containing the parsed relational placeholders */ - @SuppressWarnings("DuplicatedCode") public static String setRelationalPlaceholders(Player one, Player two, String text, boolean colorize) { - if (text == null) { - return null; - } - - if (placeholders.isEmpty()) { - return colorize ? Msg.color(text) : text; - } - - final Matcher matcher = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text); - final Map hooks = getPlaceholders(); + if (text == null) return null; + if (PLACEHOLDERS.isEmpty()) return colorize ? color(text) : text; + Matcher matcher = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text); while (matcher.find()) { - final String format = matcher.group(2); - final int index = format.indexOf("_"); + String format = matcher.group(2); + int index = format.indexOf('_'); + if (index <= 0 || index >= format.length()) continue; - if (index <= 0 || index >= format.length()) { - continue; - } + String identifier = format.substring(0, index).toLowerCase(Locale.ENGLISH); + PlaceholderHook handler = PLACEHOLDERS.get(identifier); - String identifier = format.substring(0, index).toLowerCase(); - String params = format.substring(index + 1); - final PlaceholderHook hook = hooks.get(identifier); + if (handler.isRelational()) { + Relational relational = (Relational) handler; + String params = format.substring(index + 1); + String value = relational.onPlaceholderRequest(one, two, params); - if (!(hook instanceof Relational)) { - continue; - } - - final String value = ((Relational) hook).onPlaceholderRequest(one, two, params); - - if (value != null) { - text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value)); + if (value != null) { + text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value)); + } } } - return colorize ? Msg.color(text) : text; + return colorize ? color(text) : text; } /** @@ -441,43 +429,34 @@ public class PlaceholderAPI { */ protected static void unregisterAll() { unregisterAllProvidedExpansions(); - placeholders.clear(); + PLACEHOLDERS.clear(); } /** * Unregister all expansions provided by PlaceholderAPI */ public static void unregisterAllProvidedExpansions() { - final Set set = new HashSet<>(placeholders.values()); + if (PLACEHOLDERS.isEmpty()) return; - for (PlaceholderHook hook : set) { - if (hook instanceof PlaceholderExpansion) { - final PlaceholderExpansion expansion = (PlaceholderExpansion) hook; - - if (!expansion.persist()) { - unregisterExpansion(expansion); - } - } - - if (hook instanceof Cacheable) { - ((Cacheable) hook).clear(); + for (PlaceholderHook handler : PLACEHOLDERS.values()) { + if (handler.isExpansion()) { + PlaceholderExpansion expansion = (PlaceholderExpansion) handler; + if (!expansion.persist()) unregisterExpansion(expansion); } } } - public static boolean registerExpansion(PlaceholderExpansion ex) { - ExpansionRegisterEvent ev = new ExpansionRegisterEvent(ex); - Bukkit.getPluginManager().callEvent(ev); - if (ev.isCancelled()) { - return false; - } + public static boolean registerExpansion(PlaceholderExpansion expansion) { + ExpansionRegisterEvent event = new ExpansionRegisterEvent(expansion); + Bukkit.getPluginManager().callEvent(event); + if (event.isCancelled()) return false; - return registerPlaceholderHook(ex.getIdentifier(), ex); + return registerPlaceholderHook(expansion.getIdentifier(), expansion); } - public static boolean unregisterExpansion(PlaceholderExpansion ex) { - if (unregisterPlaceholderHook(ex.getIdentifier())) { - Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(ex)); + public static boolean unregisterExpansion(PlaceholderExpansion expansion) { + if (unregisterPlaceholderHook(expansion.getIdentifier())) { + Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(expansion)); return true; } @@ -490,7 +469,7 @@ public class PlaceholderAPI { * @return The pattern for {@literal %_%} */ public static Pattern getPlaceholderPattern() { - return PLACEHOLDER_PATTERN; + return PERCENT_PLACEHOLDER_PATTERN; } /** @@ -532,19 +511,19 @@ public class PlaceholderAPI { } public static String setPlaceholders(Player player, String text) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true); + return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, true); } public static String setPlaceholders(Player player, String text, boolean colorize) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); + return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize); } public static List setPlaceholders(Player player, List text) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true); + return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, true); } public static List setPlaceholders(Player player, List text, boolean colorize) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); + return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize); } public static String setBracketPlaceholders(Player player, String text) { diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java index f52e880..60d2e60 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java @@ -21,66 +21,63 @@ package me.clip.placeholderapi; import me.clip.placeholderapi.commands.CommandHandler; +import me.clip.placeholderapi.commands.CompletionHandler; import me.clip.placeholderapi.configuration.PlaceholderAPIConfig; import me.clip.placeholderapi.expansion.ExpansionManager; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.Version; import me.clip.placeholderapi.expansion.cloud.ExpansionCloudManager; import me.clip.placeholderapi.external.EZPlaceholderHook; +import me.clip.placeholderapi.listeners.ApacheListener; import me.clip.placeholderapi.listeners.PlaceholderListener; import me.clip.placeholderapi.listeners.ServerLoadEventListener; -import me.clip.placeholderapi.updatechecker.UpdateChecker; import me.clip.placeholderapi.util.TimeUtil; +import me.clip.placeholderapi.util.UpdateChecker; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; +import org.bukkit.command.PluginCommand; import org.bukkit.plugin.java.JavaPlugin; import java.text.SimpleDateFormat; +import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.Map; -import java.util.Objects; import java.util.concurrent.TimeUnit; - /** * Yes I have a shit load of work to do... * * @author Ryan McCarthy */ public class PlaceholderAPIPlugin extends JavaPlugin { - + private static final Version serverVersion; private static PlaceholderAPIPlugin instance; - private static SimpleDateFormat dateFormat; + private static DateTimeFormatter dateFormat; private static String booleanTrue; private static String booleanFalse; - private static Version serverVersion; + + static { + // It's not possible to be null or throw an index exception unless it's a bug. + String nmsVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + boolean spigot; + + try { + Class.forName("org.spigotmc.SpigotConfig"); + spigot = true; + } catch (ExceptionInInitializerError | ClassNotFoundException ignored) { + spigot = false; + } + + serverVersion = new Version(nmsVersion, spigot); + } + private PlaceholderAPIConfig config; private ExpansionManager expansionManager; private ExpansionCloudManager expansionCloud; private long startTime; - private static Version getVersion() { - String v = "unknown"; - boolean spigot = false; - - try { - v = Bukkit.getServer().getClass().getPackage().getName() - .split("\\.")[3]; - } catch (ArrayIndexOutOfBoundsException ex) { - } - - try { - Class.forName("org.spigotmc.SpigotConfig"); - Class.forName("net.md_5.bungee.api.chat.BaseComponent"); - spigot = true; - } catch (ExceptionInInitializerError | ClassNotFoundException ignored) { - } - - return new Version(v, spigot); - } - /** * Gets the static instance of the main class for PlaceholderAPI. This class is not the actual API * class, this is the main class that extends JavaPlugin. For most API methods, use static methods @@ -98,9 +95,8 @@ public class PlaceholderAPIPlugin extends JavaPlugin { * * @return date format */ - public static SimpleDateFormat getDateFormat() { - return dateFormat != null ? dateFormat : new SimpleDateFormat( - "MM/dd/yy HH:mm:ss"); + public static DateTimeFormatter getDateFormat() { + return dateFormat != null ? dateFormat : DateTimeFormatter.ofPattern("MM/dd/yy HH:mm:ss"); } /** @@ -122,26 +118,26 @@ public class PlaceholderAPIPlugin extends JavaPlugin { } public static Version getServerVersion() { - return serverVersion != null ? serverVersion : getVersion(); - } - - @Override - public void onLoad() { - startTime = System.currentTimeMillis(); - instance = this; - serverVersion = getVersion(); - config = new PlaceholderAPIConfig(this); - expansionManager = new ExpansionManager(this); + return serverVersion; } @Override public void onEnable() { + startTime = System.currentTimeMillis(); + instance = this; + + config = new PlaceholderAPIConfig(this); config.loadDefConfig(); setupOptions(); - Objects.requireNonNull(getCommand("placeholderapi")).setExecutor(new CommandHandler()); + expansionManager = new ExpansionManager(this); new PlaceholderListener(this); + PluginCommand command = getCommand("placeholderapi"); + command.setExecutor(new CommandHandler()); + command.setTabCompleter(new CompletionHandler()); + + new ApacheListener(this); try { Class.forName("org.bukkit.event.server.ServerLoadEvent"); new ServerLoadEventListener(this); @@ -150,7 +146,7 @@ public class PlaceholderAPIPlugin extends JavaPlugin { getLogger().info("Placeholder expansion registration initializing..."); //fetch any hooks that may have registered externally onEnable first otherwise they will be lost - final Map alreadyRegistered = PlaceholderAPI.getPlaceholders(); + Map alreadyRegistered = PlaceholderAPI.PLACEHOLDERS; getExpansionManager().registerAllExpansions(); if (alreadyRegistered != null && !alreadyRegistered.isEmpty()) { @@ -159,13 +155,8 @@ public class PlaceholderAPIPlugin extends JavaPlugin { }, 1); } - if (config.checkUpdates()) { - new UpdateChecker(this).fetch(); - } - - if (config.isCloudEnabled()) { - enableCloud(); - } + if (config.checkUpdates()) new UpdateChecker(this).fetch(); + if (config.isCloudEnabled()) enableCloud(); setupMetrics(); getServer().getScheduler().runTaskLater(this, this::checkHook, 40); @@ -175,14 +166,13 @@ public class PlaceholderAPIPlugin extends JavaPlugin { public void onDisable() { disableCloud(); PlaceholderAPI.unregisterAll(); - expansionManager = null; Bukkit.getScheduler().cancelTasks(this); - serverVersion = null; + + expansionManager = null; instance = null; } public void reloadConf(CommandSender s) { - boolean cloudEnabled = this.expansionCloud != null; PlaceholderAPI.unregisterAllProvidedExpansions(); reloadConfig(); setupOptions(); @@ -190,79 +180,70 @@ public class PlaceholderAPIPlugin extends JavaPlugin { if (!config.isCloudEnabled()) { disableCloud(); - } else if (!cloudEnabled) { + } else if (this.expansionCloud != null) { enableCloud(); } - s.sendMessage(ChatColor.translateAlternateColorCodes('&', - PlaceholderAPI.getRegisteredIdentifiers().size() - + " &aplaceholder hooks successfully registered!")); + s.sendMessage(ChatColor.translateAlternateColorCodes('&', PlaceholderAPI.PLACEHOLDERS.size() + " &aplaceholder hooks successfully registered!")); } + @SuppressWarnings("deprecation") private void checkHook() { - Map loaded = PlaceholderAPI.getPlaceholders(); - - loaded.values().forEach(h -> { - if (h instanceof EZPlaceholderHook) { + for (PlaceholderHook hook : PlaceholderAPI.PLACEHOLDERS.values()) { + if (hook instanceof EZPlaceholderHook) { + String pluginName = ((EZPlaceholderHook) hook).getPluginName(); String author; try { - author = Bukkit.getPluginManager().getPlugin(((EZPlaceholderHook) h).getPluginName()).getDescription().getAuthors().toString(); + author = Bukkit.getPluginManager().getPlugin(pluginName).getDescription().getAuthors().toString(); } catch (Exception ex) { author = "the author of the hook's plugin"; } - getLogger().severe(((EZPlaceholderHook) h).getPluginName() + + getLogger().severe(pluginName + " is currently using a deprecated method to hook into PlaceholderAPI. Placeholders for that plugin no longer work. " + - "Please consult {author} and urge them to update it ASAP.".replace("{author}", author)); + "Please consult " + author + " and urge them to update it ASAP."); // disable the hook on startup - PlaceholderAPI.unregisterPlaceholderHook(((EZPlaceholderHook) h).getPlaceholderName()); + PlaceholderAPI.unregisterPlaceholderHook(((EZPlaceholderHook) hook).getPlaceholderName()); } - }); + } } private void setupOptions() { booleanTrue = config.booleanTrue(); - - if (booleanTrue == null) { - booleanTrue = "true"; - } + if (booleanTrue == null) booleanTrue = "true"; booleanFalse = config.booleanFalse(); - - if (booleanFalse == null) { - booleanFalse = "false"; - } + if (booleanFalse == null) booleanFalse = "false"; try { - dateFormat = new SimpleDateFormat(config.dateFormat()); - } catch (Exception e) { - dateFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss"); + dateFormat = DateTimeFormatter.ofPattern(config.dateFormat()); + } catch (Exception ignored) { + dateFormat = DateTimeFormatter.ofPattern("MM/dd/yy HH:mm:ss"); } } private void setupMetrics() { - Metrics m = new Metrics(this); - m.addCustomChart(new Metrics.SimplePie("using_expansion_cloud", () -> getExpansionCloud() != null ? "yes" : "no")); + // This is NOT the plugin resource ID. it's the bStats ID. + Metrics metrics = new Metrics(this, 438); + metrics.addCustomChart(new Metrics.SimplePie("using_expansion_cloud", + () -> getExpansionCloud() != null ? "yes" : "no")); - m.addCustomChart(new Metrics.SimplePie("using_spigot", () -> getServerVersion().isSpigot() ? "yes" : "no")); + metrics.addCustomChart(new Metrics.SimplePie("using_spigot", + () -> getServerVersion().isSpigot() ? "yes" : "no")); - m.addCustomChart(new Metrics.AdvancedPie("expansions_used", () -> { + metrics.addCustomChart(new Metrics.AdvancedPie("expansions_used", () -> { Map map = new HashMap<>(); - Map hooks = PlaceholderAPI.getPlaceholders(); - - if (!hooks.isEmpty()) { - - for (PlaceholderHook hook : hooks.values()) { - if (hook instanceof PlaceholderExpansion) { - PlaceholderExpansion expansion = (PlaceholderExpansion) hook; - map.put(expansion.getRequiredPlugin() == null ? expansion.getIdentifier() : expansion.getRequiredPlugin(), 1); - } + for (PlaceholderHook hook : PlaceholderAPI.PLACEHOLDERS.values()) { + if (hook.isExpansion()) { + PlaceholderExpansion ex = (PlaceholderExpansion) hook; + map.put(ex.getRequiredPlugin() == null ? ex.getIdentifier() + : ex.getRequiredPlugin(), 1); } } - return map; + return map; })); } @@ -276,10 +257,7 @@ public class PlaceholderAPIPlugin extends JavaPlugin { } public void disableCloud() { - if (expansionCloud != null) { - expansionCloud.clean(); - expansionCloud = null; - } + if (expansionCloud != null) expansionCloud = null; } /** @@ -305,6 +283,6 @@ public class PlaceholderAPIPlugin extends JavaPlugin { } public long getUptimeMillis() { - return (System.currentTimeMillis() - startTime); + return System.currentTimeMillis() - startTime; } } diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderHook.java b/src/main/java/me/clip/placeholderapi/PlaceholderHook.java index e41e68d..c1ea2c5 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderHook.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderHook.java @@ -20,13 +20,14 @@ */ package me.clip.placeholderapi; +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import me.clip.placeholderapi.expansion.Relational; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; public abstract class PlaceholderHook { - /** - * called when a placeholder value is requested from this hook + * Called when a placeholder value is requested from this hook. * * @param player {@link OfflinePlayer} to request the placeholder value for, null if not needed for a * player @@ -41,8 +42,12 @@ public abstract class PlaceholderHook { return onPlaceholderRequest(null, params); } + public PlaceholderAPIPlugin getPlaceholderAPI() { + return PlaceholderAPIPlugin.getInstance(); + } + /** - * called when a placeholder is requested from this hook + * Called when a placeholder is requested from this hook. * * @param player {@link Player} to request the placeholder value for, null if not needed for a player * @param params String passed to the hook to determine what value to return @@ -51,4 +56,12 @@ public abstract class PlaceholderHook { public String onPlaceholderRequest(Player player, String params) { return null; } + + public boolean isExpansion() { + return this instanceof PlaceholderExpansion; + } + + public boolean isRelational() { + return this instanceof Relational; + } } diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderReplacer.java b/src/main/java/me/clip/placeholderapi/PlaceholderReplacer.java new file mode 100644 index 0000000..c29d0e4 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/PlaceholderReplacer.java @@ -0,0 +1,150 @@ +/* + * PlaceholderAPI + * Copyright (C) 2019 Ryan McCarthy + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package me.clip.placeholderapi; + +import com.google.common.collect.ImmutableSet; +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; + +import java.util.Set; + +/** + * This is certainly hard to understand and maintain, but it's fully optimized. + * It's almost x5 times faster than the RegEx method for normal sized strings. This performance gap gets smaller + * for smaller strings. + * + * @author Crypto Morin + */ +public class PlaceholderReplacer { + /** + * Cached available color codes. Technically the uppercase of each letter can be used too, but no one really uses the uppercase ones. + */ + private static final Set COLOR_CODES = ImmutableSet.of('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f', 'k', 'l', 'm', 'o', 'r', 'x'); + + /** + * Translates placeholders for a string using pure character loops. + * Might cause problems in really rare conditions. + * + * @param player the player to translate the string for. + * @param str the string to translate. + * @param closure the type of the placeholder closing points. + * @param colorize if this message should be colorized as well. + * @return a translated string. + */ + public static String evaluatePlaceholders(OfflinePlayer player, String str, Closure closure, boolean colorize) { + char[] chars = str.toCharArray(); + StringBuilder builder = new StringBuilder(chars.length); + + // This won't cause memory leaks. It's inside a method. And we want to use setLength instead of + // creating a new string builder to use the maximum capacity and avoid initializing new objects. + StringBuilder identifier = new StringBuilder(50); + PlaceholderHook handler = null; + + // Stages: + // Stage -1: Look for the color code in the next character. + // Stage 0: No closures detected, or the detected identifier is invalid. We're going forward while appending the characters normally. + // Stage 1: The closure has been detected, looking for the placeholder identifier... + // Stage 2: Detected the identifier and the parameter. Translating the placeholder... + int stage = 0; + + for (char ch : chars) { + if (stage == -1 && COLOR_CODES.contains(ch)) { + builder.append(ChatColor.COLOR_CHAR).append(ch); + stage = 0; + continue; + } + + // Check if the placeholder starts or ends. + if (ch == closure.start || ch == closure.end) { + // If the placeholder ends. + if (stage == 2) { + String parameter = identifier.toString(); + String translated = handler.onRequest(player, parameter); + + if (translated == null) { + String name = handler.isExpansion() ? ((PlaceholderExpansion) handler).getIdentifier() : ""; + builder.append(closure.start).append(name).append('_').append(parameter).append(closure.end); + } else builder.append(translated); + + identifier.setLength(0); + stage = 0; + continue; + } else if (stage == 1) { // If it just started | Double closures | If it's still hasn't detected the indentifier, reset. + builder.append(closure.start).append(identifier); + } + + identifier.setLength(0); + stage = 1; + continue; + } + + // Placeholder identifier started. + if (stage == 1) { + // Compare the current character with the idenfitier's. + // We reached the end of our identifier. + if (ch == '_') { + handler = PlaceholderAPI.PLACEHOLDERS.get(identifier.toString()); + if (handler == null) { + builder.append(closure.start).append(identifier).append('_'); + stage = 0; + } else { + identifier.setLength(0); + stage = 2; + } + continue; + } + + // Keep building the identifier name. + identifier.append(ch); + continue; + } + + // Building the placeholder parameter. + if (stage == 2) { + identifier.append(ch); + continue; + } + + // Nothing placeholder related was found. + if (colorize && ch == '&') { + stage = -1; + continue; + } + builder.append(ch); + } + + if (identifier != null) { + if (stage > 0) builder.append(closure.end); + builder.append(identifier); + } + return builder.toString(); + } + + public enum Closure { + PERCENT('%', '%'), BRACKETS('[', ']'), BRACES('{', '}'); + + public char start, end; + + Closure(char start, char end) { + this.start = start; + this.end = end; + } + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/Command.java b/src/main/java/me/clip/placeholderapi/commands/Command.java index 531c8be..f7310aa 100644 --- a/src/main/java/me/clip/placeholderapi/commands/Command.java +++ b/src/main/java/me/clip/placeholderapi/commands/Command.java @@ -1,52 +1,42 @@ package me.clip.placeholderapi.commands; -import com.google.common.collect.ImmutableSet; import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; -import java.util.Set; public abstract class Command { - private static final Options EMPTY_OPTIONS = new Options(null, 0, null); + private static final Options EMPTY_OPTIONS = new Options(null, 0); private final String match; private final String usage; private final int minimumArguments; - private final Set permissions; + /** + * Commands should not have multiple permissions. This can lead to a lot of confusions. + * This is also a lot more appropriate for maintainability, I saw a lot of commands regitered with wrong permissions. + * We will use the main command name to parse our permission. + */ + private final String permission; - protected Command(@NotNull final String match) { + protected Command(String match) { this(match, EMPTY_OPTIONS); } - protected Command(@NotNull final String match, @NotNull final Options options) { + protected Command(String match, Options options) { this.match = match; this.usage = options.usage == null ? "/papi " + match + " [optional args]" : options.usage; - this.permissions = options.permissions == null ? Collections.emptySet() : ImmutableSet.copyOf(options.permissions); + this.permission = "placeholderapi." + match.replace(' ', '.'); this.minimumArguments = options.minimumArguments; } - protected static Options usage(@NotNull final String usage, final int minimumArguments) { - return new Options(usage, minimumArguments, null); + protected static Options options(String usage, int minimumArguments) { + return new Options(usage, minimumArguments); } - protected static Options permissions(@NotNull final String... permissions) { - return new Options(null, 0, permissions); - } - - protected static Options options(@NotNull final String usage, final int minimumArguments, - @NotNull final String... permissions) { - return new Options(usage, minimumArguments, permissions); - } - - @NotNull public String getMatch() { return match; } - @NotNull public String getUsage() { return usage; } @@ -55,28 +45,23 @@ public abstract class Command { return minimumArguments; } - @NotNull - public Set getPermissions() { - return permissions; + public String getPermission() { + return permission; } - public abstract void execute(@NotNull final CommandSender sender, @NotNull final String[] args); + public abstract void execute(CommandSender sender, String[] args); - @NotNull - public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { + public List handleCompletion(CommandSender sender, String[] args) { return Collections.emptyList(); } private static class Options { private final String usage; private final int minimumArguments; - private final String[] permissions; - private Options(@Nullable final String usage, final int minimumArguments, - @Nullable final String[] permissions) { + private Options(String usage, int minimumArguments) { this.usage = usage; this.minimumArguments = minimumArguments; - this.permissions = permissions; } } } diff --git a/src/main/java/me/clip/placeholderapi/commands/CommandHandler.java b/src/main/java/me/clip/placeholderapi/commands/CommandHandler.java index 12374cd..36c7d87 100644 --- a/src/main/java/me/clip/placeholderapi/commands/CommandHandler.java +++ b/src/main/java/me/clip/placeholderapi/commands/CommandHandler.java @@ -1,25 +1,33 @@ package me.clip.placeholderapi.commands; import com.google.common.collect.Lists; -import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.command.*; -import me.clip.placeholderapi.commands.command.ecloud.EcloudInfoCommand; -import me.clip.placeholderapi.commands.command.ecloud.EcloudListCommand; import me.clip.placeholderapi.commands.command.ecloud.*; import me.clip.placeholderapi.util.Msg; +import org.apache.commons.lang.StringUtils; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import java.util.List; -import java.util.Objects; import java.util.Optional; -import java.util.regex.Pattern; public final class CommandHandler implements CommandExecutor { private static final Command DEFAULT = new VersionCommand(); - private static final List COMMANDS = Lists.newArrayList( + protected static final List COMMANDS = Lists.newArrayList( + DEFAULT, + new HelpCommand(), + new InfoCommand(), + new ListCommand(), + new RegisterCommand(), + new UnregisterCommand(), + new ReloadCommand(), + new BcParseCommand(), + new ParseCommand(), + new ParseRelCommand(), + + new EcloudCommand(), new EcloudClearCommand(), new EcloudDownloadCommand(), new EcloudInfoCommand(), @@ -28,74 +36,57 @@ public final class CommandHandler implements CommandExecutor { new EcloudRefreshCommand(), new EcloudStatusCommand(), new EcloudVersionInfoCommand(), - new EcloudCommand(), - new BcParseCommand(), - new ParseCommand(), - new ParseRelCommand(), - new DisableEcloudCommand(), - new EnableCloudCommand(), - new HelpCommand(), - new InfoCommand(), - new ListCommand(), - new RegisterCommand(), - new ReloadCommand(), - DEFAULT, - new UnregisterCommand() + new EcloudDisableCommand(), + new EcloudEnableCommand() ); static { COMMANDS.sort((command1, command2) -> { - final int comparison = Integer.compare(command1.getMatch().length(), command2.getMatch().length()); + int comparison = Integer.compare(command1.getMatch().length(), command2.getMatch().length()); if (comparison == 1) return -1; if (comparison == -1) return 1; return 0; }); - Objects.requireNonNull(PlaceholderAPIPlugin.getInstance().getCommand("placeholderapi")) - .setTabCompleter(new CompletionHandler(COMMANDS)); } - private static final Pattern SPACE_PATTERN = Pattern.compile(" "); + private static String[] splitArguments(String joinedArguments, String command) { + joinedArguments = StringUtils.remove(joinedArguments, command).trim(); + String[] args = StringUtils.split(joinedArguments); + return args.length == 1 && args[0].isEmpty() ? new String[0] : args; + } @Override - public boolean onCommand(@NotNull final CommandSender sender, @NotNull final org.bukkit.command.Command bukkitCommand, - @NotNull final String name, @NotNull String[] args) { + public boolean onCommand(@NotNull CommandSender sender, @NotNull org.bukkit.command.Command bukkitCommand, @NotNull String name, String[] args) { if (args.length == 0) { DEFAULT.execute(sender, args); return true; } - final String joined = String.join(" ", args).toLowerCase(); - final Optional optional = COMMANDS.stream() + String joined = String.join(" ", args).toLowerCase(); + Optional optional = COMMANDS.stream() .filter(command -> joined.startsWith(command.getMatch())) .findFirst(); if (!optional.isPresent()) { - sender.sendMessage("Specified command is not valid."); + Msg.msg(sender, "&cUnknown command."); return true; } - final Command command = optional.get(); - - if (!command.getPermissions().isEmpty() && command.getPermissions().stream().noneMatch(sender::hasPermission)) { - sender.sendMessage("You do not have the permission to execute specified command."); + Command command = optional.get(); + String permission = command.getPermission(); + if (!sender.hasPermission(permission)) { + Msg.msg(sender, "&cYou do not have the permission to use this command."); return true; } args = splitArguments(joined, command.getMatch()); - if (args.length < command.getMinimumArguments()) { Msg.msg(sender, command.getUsage()); return true; } command.execute(sender, args); - return true; } - - static String[] splitArguments(@NotNull final String joinedArguments, @NotNull final String command) { - final String[] args = SPACE_PATTERN.split(joinedArguments.replace(command, "").trim()); - return args.length == 1 && args[0].isEmpty() ? new String[]{} : args; - } } diff --git a/src/main/java/me/clip/placeholderapi/commands/CompletionHandler.java b/src/main/java/me/clip/placeholderapi/commands/CompletionHandler.java index a48173f..a42177c 100644 --- a/src/main/java/me/clip/placeholderapi/commands/CompletionHandler.java +++ b/src/main/java/me/clip/placeholderapi/commands/CompletionHandler.java @@ -1,32 +1,37 @@ package me.clip.placeholderapi.commands; +import org.apache.commons.lang.StringUtils; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Optional; +import java.util.Locale; +import java.util.stream.Collectors; public final class CompletionHandler implements TabCompleter { - private final List commands; - - CompletionHandler(@NotNull final List commands) { - this.commands = commands; + private static String[] splitArguments(String[] args, String command) { + int skip = StringUtils.split(command).length; + return Arrays.stream(args).skip(skip).toArray(String[]::new); } // it makes me physically cringe trying to understand why bukkit uses a list instead of a set for this - @NotNull + // It's because of the list order. Even if they wanted to change that, they couldn't for the sake of backward compatibility. ~Crypto @Override - public List onTabComplete(@NotNull final CommandSender sender, @NotNull final org.bukkit.command.Command bukkitCommand, - @NotNull final String name, @NotNull final String[] args) { - final String joined = String.join(" ", args).toLowerCase(); - final Optional optional = commands.stream() - .filter(command -> joined.startsWith(command.getMatch())) - .findAny(); + public List onTabComplete(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command bukkitCommand, @NotNull String name, String[] args) { + String joined = String.join(" ", args).toLowerCase(Locale.ENGLISH); - return optional - .map(command -> command.handleCompletion(sender, CommandHandler.splitArguments(joined, command.getMatch()))) - .orElse(Collections.emptyList()); + if (args.length > 1) { + return CommandHandler.COMMANDS.stream() + .filter(command -> sender.hasPermission(command.getPermission()) && joined.startsWith(command.getMatch())) + .findFirst() + .map(command -> command.handleCompletion(sender, splitArguments(args, command.getMatch()))) + .orElse(Collections.emptyList()); + } + return CommandHandler.COMMANDS.stream() + .filter(command -> sender.hasPermission(command.getPermission()) && (args[0].isEmpty() || command.getMatch().startsWith(joined))) + .map(Command::getMatch).collect(Collectors.toList()); } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/BcParseCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/BcParseCommand.java index 8808dc3..e356389 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/BcParseCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/BcParseCommand.java @@ -8,40 +8,34 @@ import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; public final class BcParseCommand extends Command { public BcParseCommand() { - super("bcparse", options("&cYou must specify a player.", 1, "placeholderapi.parse")); + super("bcparse", options("&cYou must specify a player.", 1)); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final OfflinePlayer player; - final String input = args[0]; + public void execute(CommandSender sender, String[] args) { + OfflinePlayer player; + String input = args[0]; if (input.equalsIgnoreCase("me")) { if (sender instanceof Player) { player = (Player) sender; } else { Msg.msg(sender, "&cThis command must target a player when used by console"); - return; } } else { - if (Bukkit.getPlayer(input) != null) { - player = Bukkit.getPlayer(input); - } else { - player = Bukkit.getOfflinePlayer(input); + player = Bukkit.getPlayer(input); + if (player == null) player = Bukkit.getOfflinePlayer(input); + if (player == null || !player.hasPlayedBefore()) { + Msg.msg(sender, "&cCould not find player&8: &f" + input); + return; } } - if (player == null || !player.hasPlayedBefore()) { - Msg.msg(sender, "&cFailed to find player: &f" + input); - return; - } - - final String parse = StringUtils.join(args, " ", 2, args.length); + String parse = StringUtils.join(args, " ", 2, args.length); Msg.broadcast("&r" + PlaceholderAPI.setPlaceholders(player, parse)); } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/EcloudCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/EcloudCommand.java index b37899e..351930d 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/EcloudCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/EcloudCommand.java @@ -6,7 +6,6 @@ import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; import org.bukkit.util.StringUtil; -import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -22,16 +21,18 @@ public final class EcloudCommand extends Command { "placeholders", "refresh", "status", - "versioninfo" + "versioninfo", + "enable", + "disable" ); public EcloudCommand() { - super("ecloud", permissions("placeholderapi.ecloud")); + super("ecloud"); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + public void execute(CommandSender sender, String[] args) { + PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); if (args.length == 0) { Msg.msg(sender, "&bExpansion cloud commands", @@ -57,7 +58,6 @@ public final class EcloudCommand extends Command { if (plugin.getExpansionCloud() == null) { Msg.msg(sender, "&7The expansion cloud is not enabled!"); - return; } @@ -69,9 +69,9 @@ public final class EcloudCommand extends Command { sender.sendMessage("Specified command is not valid."); } - @NotNull + @Override - public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { + public List handleCompletion(CommandSender sender, String[] args) { if (args.length == MAXIMUM_ARGUMENTS) { return StringUtil.copyPartialMatches(args[0], COMPLETIONS, new ArrayList<>(COMPLETIONS.size())); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/HelpCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/HelpCommand.java index 0ef952f..49654f7 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/HelpCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/HelpCommand.java @@ -4,15 +4,14 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; public final class HelpCommand extends Command { public HelpCommand() { - super("help", permissions("placeholderapi.ecloud")); + super("help"); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + public void execute(CommandSender sender, String[] args) { Msg.msg(sender, "PlaceholderAPI &aHelp &e(&f" + PlaceholderAPIPlugin.getInstance().getDescription().getVersion() + "&e)", "&b/papi", "&fView plugin info/version info", diff --git a/src/main/java/me/clip/placeholderapi/commands/command/InfoCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/InfoCommand.java index 8987932..acec7b5 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/InfoCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/InfoCommand.java @@ -7,7 +7,6 @@ import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; import org.bukkit.util.StringUtil; -import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -17,13 +16,13 @@ public final class InfoCommand extends Command { private static final int MINIMUM_ARGUMENTS = 1; public InfoCommand() { - super("info", options("&cIncorrect usage! &7/papi info ", MINIMUM_ARGUMENTS, "placeholderapi.info")); + super("info", options("&cIncorrect usage! &7/papi info ", MINIMUM_ARGUMENTS)); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final String requestedExpansion = args[0]; - final PlaceholderExpansion ex = PlaceholderAPIPlugin.getInstance().getExpansionManager().getRegisteredExpansion(requestedExpansion); + public void execute(CommandSender sender, String[] args) { + String requestedExpansion = args[0]; + PlaceholderExpansion ex = PlaceholderAPIPlugin.getInstance().getExpansionManager().getRegisteredExpansion(requestedExpansion); if (ex == null) { Msg.msg(sender, "&cThere is no expansion loaded with the identifier: &f" + requestedExpansion); @@ -54,11 +53,11 @@ public final class InfoCommand extends Command { } } - @NotNull + @Override - public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { + public List handleCompletion(CommandSender sender, String[] args) { if (args.length == MINIMUM_ARGUMENTS) { - final Set completions = PlaceholderAPI.getRegisteredIdentifiers(); + Set completions = PlaceholderAPI.getRegisteredIdentifiers(); return StringUtil.copyPartialMatches(args[0], completions, new ArrayList<>(completions.size())); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ListCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ListCommand.java index ba8aa66..b9e64aa 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ListCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ListCommand.java @@ -4,19 +4,18 @@ import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; import java.util.Set; import java.util.stream.Collectors; public final class ListCommand extends Command { public ListCommand() { - super("list", permissions("placeholderapi.list")); + super("list"); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final Set registered = PlaceholderAPI.getRegisteredIdentifiers(); + public void execute(CommandSender sender, String[] args) { + Set registered = PlaceholderAPI.getRegisteredIdentifiers(); if (registered.isEmpty()) { Msg.msg(sender, "&7There are no placeholder hooks currently registered!"); return; diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ParseCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ParseCommand.java index 4166a47..fae842c 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ParseCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ParseCommand.java @@ -7,41 +7,53 @@ import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; +import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; public final class ParseCommand extends Command { public ParseCommand() { - super("parse", options("&cYou must specify a player.", 1, "placeholderapi.parse")); + super("parse", options("&cYou must specify a player.", 1)); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final OfflinePlayer player; - final String input = args[0]; + public void execute(CommandSender sender, String[] args) { + OfflinePlayer player; + String input = args[0]; if (input.equalsIgnoreCase("me")) { if (sender instanceof Player) { player = (Player) sender; } else { Msg.msg(sender, "&cThis command must target a player when used by console"); - return; } } else { - if (Bukkit.getPlayer(input) != null) { - player = Bukkit.getPlayer(input); - } else { - player = Bukkit.getOfflinePlayer(input); + player = Bukkit.getPlayer(input); + if (player == null) player = Bukkit.getOfflinePlayer(input); + if (player == null || !player.hasPlayedBefore()) { + Msg.msg(sender, "&cCould not find player&8: &f" + input); + return; } } - if (player == null || !player.hasPlayedBefore()) { - Msg.msg(sender, "&cFailed to find player: &f" + input); - return; - } - - final String parse = StringUtils.join(args, " ", 1, args.length); + String parse = StringUtils.join(args, " ", 1, args.length); Msg.msg(sender, "&r" + PlaceholderAPI.setPlaceholders(player, parse)); } + + @Override + public List handleCompletion(CommandSender sender, String[] args) { + if (args.length == 1) { + List players = Bukkit.getOnlinePlayers().stream().map(HumanEntity::getName).collect(Collectors.toList()); + players.add("me"); + if (args[0].isEmpty()) return players; + else return players.stream().filter(name -> name.startsWith(args[0])).collect(Collectors.toList()); + } + if (args.length == 2) return Collections.singletonList(""); + return new ArrayList<>(); + } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ParseRelCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ParseRelCommand.java index 20afb90..7184edd 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ParseRelCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ParseRelCommand.java @@ -7,30 +7,27 @@ import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; public final class ParseRelCommand extends Command { public ParseRelCommand() { - super("parserel", options("&cYou must specify at least two players.", 2, "placeholderapi.parse")); + super("parserel", options("&cYou must specify at least two players.", 2)); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final Player one = Bukkit.getPlayer(args[0]); + public void execute(CommandSender sender, String[] args) { + Player one = Bukkit.getPlayer(args[0]); if (one == null) { Msg.msg(sender, args[0] + " &cis not online!"); - return; } - final Player two = Bukkit.getPlayer(args[1]); + Player two = Bukkit.getPlayer(args[1]); if (two == null) { Msg.msg(sender, args[1] + " &cis not online!"); - return; } - final String parse = StringUtils.join(args, " ", 1, args.length); + String parse = StringUtils.join(args, " ", 1, args.length); Msg.msg(sender, "&r" + PlaceholderAPI.setRelationalPlaceholders(one, two, parse)); } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/RegisterCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/RegisterCommand.java index 6df7b74..aff9783 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/RegisterCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/RegisterCommand.java @@ -4,22 +4,21 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.util.Msg; +import org.apache.commons.lang.StringUtils; import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; public final class RegisterCommand extends Command { public RegisterCommand() { - super("register", options("&cAn expansion file name must be specified!", 1,"placeholderapi.register")); + super("register", options("&cAn expansion file name must be specified!", 1)); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final String fileName = args[0].replace(".jar", ""); - final PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionManager().registerExpansion(fileName); + public void execute(CommandSender sender, String[] args) { + String fileName = StringUtils.remove(args[0], ".jar"); + PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionManager().registerExpansion(fileName); if (expansion == null) { Msg.msg(sender, "&cFailed to register expansion from " + fileName); - return; } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ReloadCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ReloadCommand.java index cf01301..bed04a1 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ReloadCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ReloadCommand.java @@ -4,15 +4,14 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; public final class ReloadCommand extends Command { public ReloadCommand() { - super("reload", permissions("placeholderapi.reload")); + super("reload"); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + public void execute(CommandSender sender, String[] args) { Msg.msg(sender, "&fPlaceholder&7API &bconfiguration reloaded!"); PlaceholderAPIPlugin.getInstance().reloadConf(sender); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/UnregisterCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/UnregisterCommand.java index b20657e..51c61d4 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/UnregisterCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/UnregisterCommand.java @@ -7,7 +7,6 @@ import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; import org.bukkit.util.StringUtil; -import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -17,18 +16,17 @@ public final class UnregisterCommand extends Command { private static final int MINIMUM_ARGUMENTS = 1; public UnregisterCommand() { - super("unregister", options("&cAn expansion name must be specified!", MINIMUM_ARGUMENTS, "placeholderapi.register")); + super("unregister", options("&cAn expansion name must be specified!", MINIMUM_ARGUMENTS)); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final String requestedExpansion = args[0]; - final PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionManager() + public void execute(CommandSender sender, String[] args) { + String requestedExpansion = args[0]; + PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionManager() .getRegisteredExpansion(requestedExpansion); if (expansion == null) { Msg.msg(sender, "&cFailed to find expansion: &f" + requestedExpansion); - return; } @@ -39,12 +37,11 @@ public final class UnregisterCommand extends Command { } } - @NotNull - @Override - public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { - if (args.length == MINIMUM_ARGUMENTS) { - final Set completions = PlaceholderAPI.getRegisteredIdentifiers(); + @Override + public List handleCompletion(CommandSender sender, String[] args) { + if (args.length == MINIMUM_ARGUMENTS) { + Set completions = PlaceholderAPI.getRegisteredIdentifiers(); return StringUtil.copyPartialMatches(args[0], completions, new ArrayList<>(completions.size())); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/VersionCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/VersionCommand.java index efab041..0f37c52 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/VersionCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/VersionCommand.java @@ -7,7 +7,6 @@ import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.util.StringUtil; -import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -34,8 +33,8 @@ public final class VersionCommand extends Command { } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final PluginDescriptionFile description = PlaceholderAPIPlugin.getInstance().getDescription(); + public void execute(CommandSender sender, String[] args) { + PluginDescriptionFile description = PlaceholderAPIPlugin.getInstance().getDescription(); Msg.msg(sender, "PlaceholderAPI &7version &b&o" + description.getVersion(), "&fCreated by&7: &b" + description.getAuthors(), @@ -43,9 +42,9 @@ public final class VersionCommand extends Command { "&fEcloud commands: &b/papi ecloud"); } - @NotNull + @Override - public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { + public List handleCompletion(CommandSender sender, String[] args) { if (args.length == 1) { return StringUtil.copyPartialMatches(args[0], COMPLETIONS, new ArrayList<>(COMPLETIONS.size())); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudClearCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudClearCommand.java index 3a77d89..6143ff0 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudClearCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudClearCommand.java @@ -4,15 +4,14 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; public final class EcloudClearCommand extends Command { public EcloudClearCommand() { - super("ecloud clear", permissions("placeholderapi.ecloud")); + super("ecloud clear"); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + public void execute(CommandSender sender, String[] args) { PlaceholderAPIPlugin.getInstance().getExpansionCloud().clean(); Msg.msg(sender, "&aThe cache has been cleared!!"); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/DisableEcloudCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDisableCommand.java similarity index 53% rename from src/main/java/me/clip/placeholderapi/commands/command/DisableEcloudCommand.java rename to src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDisableCommand.java index 9e2e841..bc9fcfe 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/DisableEcloudCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDisableCommand.java @@ -1,29 +1,25 @@ -package me.clip.placeholderapi.commands.command; +package me.clip.placeholderapi.commands.command.ecloud; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; -public final class DisableEcloudCommand extends Command { - public DisableEcloudCommand() { - super("disablecloud", permissions("placeholderapi.ecloud")); +public final class EcloudDisableCommand extends Command { + public EcloudDisableCommand() { + super("ecloud disable"); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + public void execute(CommandSender sender, String[] args) { + PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); if (plugin.getExpansionCloud() == null) { Msg.msg(sender, "&7The cloud is already disabled!"); - return; } plugin.disableCloud(); plugin.getPlaceholderAPIConfig().setCloudEnabled(false); Msg.msg(sender, "&aThe cloud has been disabled!"); - - return; } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDownloadCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDownloadCommand.java index d9bac27..ed11e3c 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDownloadCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDownloadCommand.java @@ -9,25 +9,24 @@ import me.clip.placeholderapi.expansion.cloud.ExpansionCloudManager; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; public final class EcloudDownloadCommand extends Command { public EcloudDownloadCommand() { - super("ecloud download", options("&cAn expansion name must be specified!", 1, "placeholderapi.ecloud")); + super("ecloud download", options("&cAn expansion name must be specified!", 1)); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); - final String input = args[0]; - final CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(input); + public void execute(CommandSender sender, String[] args) { + PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + String input = args[0]; + CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(input); if (expansion == null) { Msg.msg(sender, "&cNo expansion found with the name: &f" + input); return; } - final PlaceholderExpansion loaded = plugin.getExpansionManager().getRegisteredExpansion(input); + PlaceholderExpansion loaded = plugin.getExpansionManager().getRegisteredExpansion(input); if (loaded != null && loaded.isRegistered()) { PlaceholderAPI.unregisterPlaceholderHook(loaded.getIdentifier()); } @@ -46,10 +45,23 @@ public final class EcloudDownloadCommand extends Command { } Msg.msg(sender, "&aDownload starting for expansion: &f" + expansion.getName() + " &aversion: &f" + version); - final String player = ((sender instanceof Player) ? sender.getName() : null); - final ExpansionCloudManager cloud = plugin.getExpansionCloud(); + String player = ((sender instanceof Player) ? sender.getName() : null); + ExpansionCloudManager cloud = plugin.getExpansionCloud(); cloud.downloadExpansion(player, expansion, version); cloud.clean(); cloud.fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions()); } + +// @Override +// public List handleCompletion(CommandSender sender, String[] args) { +// List downloads = new ArrayList<>(); +// if (!PlaceholderAPI.isRegistered("player")) downloads.add("player"); +// +// for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { +// String identifier = plugin.getName(); +// if (!PlaceholderAPI.isRegistered(identifier)) downloads.add(identifier); +// } +// +// return downloads; +// } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/EnableCloudCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudEnableCommand.java similarity index 54% rename from src/main/java/me/clip/placeholderapi/commands/command/EnableCloudCommand.java rename to src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudEnableCommand.java index f82ce4e..8c1dd1e 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/EnableCloudCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudEnableCommand.java @@ -1,22 +1,20 @@ -package me.clip.placeholderapi.commands.command; +package me.clip.placeholderapi.commands.command.ecloud; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; -public final class EnableCloudCommand extends Command { - public EnableCloudCommand() { - super("enablecloud", permissions("placeholderapi.ecloud")); +public final class EcloudEnableCommand extends Command { + public EcloudEnableCommand() { + super("ecloud enable"); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + public void execute(CommandSender sender, String[] args) { + PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); if (plugin.getExpansionCloud() != null) { Msg.msg(sender, "&7The cloud is already enabled!"); - return; } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudInfoCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudInfoCommand.java index de40e0b..13c7e7f 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudInfoCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudInfoCommand.java @@ -7,19 +7,18 @@ import me.clip.placeholderapi.util.Msg; import me.rayzr522.jsonmessage.JSONMessage; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; import static me.clip.placeholderapi.util.Msg.color; public final class EcloudInfoCommand extends Command { public EcloudInfoCommand() { - super("ecloud info", options("&cAn expansion name must be specified!", 1, "placeholderapi.ecloud")); + super("ecloud info", options("&cAn expansion name must be specified!", 1)); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final String input = args[0]; - final CloudExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionCloud().getCloudExpansion(input); + public void execute(CommandSender sender, String[] args) { + String input = args[0]; + CloudExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionCloud().getCloudExpansion(input); if (expansion == null) { Msg.msg(sender, "&cNo expansion found by the name: &f" + input); @@ -35,7 +34,7 @@ public final class EcloudInfoCommand extends Command { return; } - final Player p = (Player) sender; + Player p = (Player) sender; Msg.msg(sender, "&bExpansion&7: &f" + expansion.getName(), "&bAuthor: &f" + expansion.getAuthor(), @@ -43,7 +42,7 @@ public final class EcloudInfoCommand extends Command { ); // latest version - final JSONMessage latestVersion = JSONMessage + JSONMessage latestVersion = JSONMessage .create(color("&bLatest version: &f" + expansion.getLatestVersion())); latestVersion.tooltip(color("&bReleased: &f" + expansion.getTimeSinceLastUpdate() + "\n&bUpdate information: &f" + expansion.getVersion().getReleaseNotes() @@ -51,7 +50,7 @@ public final class EcloudInfoCommand extends Command { latestVersion.send(p); // versions - final JSONMessage versions = JSONMessage + JSONMessage versions = JSONMessage .create(color("&bVersions available: &f" + expansion.getVersions().size())); versions.tooltip(color(String.join("&b, &f", expansion.getAvailableVersions()))); versions.suggestCommand( @@ -60,7 +59,7 @@ public final class EcloudInfoCommand extends Command { // placeholders if (expansion.getPlaceholders() != null) { - final JSONMessage placeholders = JSONMessage + JSONMessage placeholders = JSONMessage .create(color("&bPlaceholders: &f" + expansion.getPlaceholders().size())); placeholders.tooltip(color(String.join("&b, &f", expansion.getPlaceholders()))); placeholders.suggestCommand("/papi ecloud placeholders " + expansion.getName()); diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudListCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudListCommand.java index adc545e..f12396d 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudListCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudListCommand.java @@ -9,7 +9,6 @@ import me.rayzr522.jsonmessage.JSONMessage; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.util.StringUtil; -import org.jetbrains.annotations.NotNull; import java.util.*; import java.util.stream.Collectors; @@ -25,13 +24,12 @@ public final class EcloudListCommand extends Command { ); public EcloudListCommand() { - super("ecloud list", options("&cIncorrect usage! &7/papi ecloud list (page)", - MINIMUM_ARGUMENTS, "placeholderapi.ecloud")); + super("ecloud list", options("&cIncorrect usage! &7/papi ecloud list (page)", MINIMUM_ARGUMENTS)); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + public void execute(CommandSender sender, String[] args) { + PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); int page = 1; String author; @@ -103,7 +101,7 @@ public final class EcloudListCommand extends Command { Msg.msg(sender, "&6Gold = Expansions which need updated"); if (!(sender instanceof Player)) { - final Map expansions = new HashMap<>(); + Map expansions = new HashMap<>(); for (CloudExpansion exp : ex.values()) { if (exp == null || exp.getName() == null) { @@ -113,7 +111,7 @@ public final class EcloudListCommand extends Command { expansions.put(exp.getName(), exp); } - final List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); + List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); int i = (int) ex.keySet().toArray()[0]; @@ -122,7 +120,7 @@ public final class EcloudListCommand extends Command { continue; } - final CloudExpansion expansion = expansions.get(name); + CloudExpansion expansion = expansions.get(name); Msg.msg(sender, "&b" + i + "&7: " + (expansion.shouldUpdate() ? "&6" @@ -134,11 +132,11 @@ public final class EcloudListCommand extends Command { return; } - final Player p = (Player) sender; + Player p = (Player) sender; - final Map expansions = new HashMap<>(); + Map expansions = new HashMap<>(); - for (final CloudExpansion exp : ex.values()) { + for (CloudExpansion exp : ex.values()) { if (exp == null || exp.getName() == null) { continue; } @@ -146,7 +144,7 @@ public final class EcloudListCommand extends Command { expansions.put(exp.getName(), exp); } - final List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); + List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); int i = page > 1 ? page * 10 : 0; @@ -155,8 +153,8 @@ public final class EcloudListCommand extends Command { continue; } - final CloudExpansion expansion = expansions.get(name); - final StringBuilder sb = new StringBuilder(); + CloudExpansion expansion = expansions.get(name); + StringBuilder sb = new StringBuilder(); if (expansion.shouldUpdate()) { sb.append("&6Click to update to the latest version of this expansion\n\n"); @@ -172,13 +170,13 @@ public final class EcloudListCommand extends Command { sb.append("&bLast updated&7: &f").append(expansion.getTimeSinceLastUpdate()).append(" ago\n"); sb.append("\n").append(expansion.getDescription()); - final String msg = color( + String msg = color( "&b" + (i + 1) + "&7: " + (expansion.shouldUpdate() ? "&6" : (expansion.hasExpansion() ? "&a" : "")) + expansion.getName()); - final String hover = color(sb.toString()); + String hover = color(sb.toString()); - final JSONMessage line = JSONMessage.create(msg); + JSONMessage line = JSONMessage.create(msg); line.tooltip(hover); if (expansion.shouldUpdate() || !expansion.hasExpansion()) { @@ -192,9 +190,9 @@ public final class EcloudListCommand extends Command { } } - @NotNull + @Override - public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { + public List handleCompletion(CommandSender sender, String[] args) { if (args.length == MINIMUM_ARGUMENTS) { return StringUtil.copyPartialMatches(args[0], COMPLETIONS, new ArrayList<>(COMPLETIONS.size())); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudPlaceholdersCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudPlaceholdersCommand.java index 49ded05..e19f0e3 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudPlaceholdersCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudPlaceholdersCommand.java @@ -8,27 +8,26 @@ import me.clip.placeholderapi.util.Msg; import me.rayzr522.jsonmessage.JSONMessage; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; import java.util.List; public final class EcloudPlaceholdersCommand extends Command { public EcloudPlaceholdersCommand() { - super("ecloud placeholders", options("&cAn expansion name must be specified!", 1, "placeholderapi.ecloud")); + super("ecloud placeholders", options("&cAn expansion name must be specified!", 1)); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); - final String input = args[0]; - final CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(input); + public void execute(CommandSender sender, String[] args) { + PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + String input = args[0]; + CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(input); if (expansion == null) { Msg.msg(sender, "&cNo expansion found by the name: &f" + input); return; } - final List placeholders = expansion.getPlaceholders(); + List placeholders = expansion.getPlaceholders(); if (placeholders == null) { Msg.msg(sender, "&cThe expansion: &f" + expansion.getName() + " &cdoes not have any placeholders listed.", @@ -45,15 +44,15 @@ public final class EcloudPlaceholdersCommand extends Command { return; } - final Player p = (Player) sender; - final JSONMessage message = JSONMessage.create(Msg.color("&bPlaceholders: &f" + placeholders.size())); + Player p = (Player) sender; + JSONMessage message = JSONMessage.create(Msg.color("&bPlaceholders: &f" + placeholders.size())); message.then("\n"); for (int i = 0; i < placeholders.size(); i++) { message.then(i == placeholders.size() - 1 ? placeholders.get(i) : Msg.color(placeholders.get(i) + "&b, &f")); try { message.tooltip(PlaceholderAPI.setPlaceholders(p, placeholders.get(i))); - } catch (final Exception ignored) { + } catch (Exception ignored) { // Ignored exception } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudRefreshCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudRefreshCommand.java index 8e1dd8b..aaf9fd6 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudRefreshCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudRefreshCommand.java @@ -5,17 +5,16 @@ import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.expansion.cloud.ExpansionCloudManager; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; public final class EcloudRefreshCommand extends Command { public EcloudRefreshCommand() { - super("ecloud refresh", permissions("placeholderapi.ecloud")); + super("ecloud refresh"); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); - final ExpansionCloudManager cloud = plugin.getExpansionCloud(); + public void execute(CommandSender sender, String[] args) { + PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + ExpansionCloudManager cloud = plugin.getExpansionCloud(); Msg.msg(sender, "&aRefresh task started. Use &f/papi ecloud list all &ain a few!!"); cloud.clean(); cloud.fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions()); diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudStatusCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudStatusCommand.java index fa5eec6..b505475 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudStatusCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudStatusCommand.java @@ -4,16 +4,15 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; public final class EcloudStatusCommand extends Command { public EcloudStatusCommand() { - super("ecloud status", permissions("placeholderapi.ecloud")); + super("ecloud status"); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + public void execute(CommandSender sender, String[] args) { + PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); Msg.msg(sender, "&bThere are &f" + plugin.getExpansionCloud().getCloudExpansions().size() + " &bexpansions available on the cloud.", "&7A total of &f" + plugin.getExpansionCloud().getCloudAuthorCount() diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudVersionInfoCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudVersionInfoCommand.java index 59637ea..7f2b6c7 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudVersionInfoCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudVersionInfoCommand.java @@ -7,24 +7,22 @@ import me.clip.placeholderapi.util.Msg; import me.rayzr522.jsonmessage.JSONMessage; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; public final class EcloudVersionInfoCommand extends Command { public EcloudVersionInfoCommand() { - super("ecloud versioninfo", options("&cIncorrect usage! &7/papi ecloud versioninfo ", - 2, "placeholderapi.ecloud")); + super("ecloud versioninfo", options("&cIncorrect usage! &7/papi ecloud versioninfo ", 2)); } @Override - public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { - final String input = args[0]; - final CloudExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionCloud().getCloudExpansion(input); + public void execute(CommandSender sender, String[] args) { + String input = args[0]; + CloudExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionCloud().getCloudExpansion(input); if (expansion == null) { Msg.msg(sender, "&cNo expansion found by the name: &f" + input); return; } - final CloudExpansion.Version version = expansion.getVersion(args[1]); + CloudExpansion.Version version = expansion.getVersion(args[1]); if (version == null) { Msg.msg(sender, "&cThe version specified does not exist for expansion: &f" + expansion.getName()); return; @@ -39,10 +37,10 @@ public final class EcloudVersionInfoCommand extends Command { return; } - final Player p = (Player) sender; - final JSONMessage download = JSONMessage.create(Msg.color("&7Click to download this version")); + Player p = (Player) sender; + JSONMessage download = JSONMessage.create(Msg.color("&7Click to download this version")); download.suggestCommand( - "/papi ecloud download " + expansion.getName() + " " + version.getVersion()); + "/papi ecloud download " + expansion.getName() + ' ' + version.getVersion()); download.send(p); } } diff --git a/src/main/java/me/clip/placeholderapi/exceptions/NoDefaultCommandException.java b/src/main/java/me/clip/placeholderapi/exceptions/NoDefaultCommandException.java deleted file mode 100644 index 5e2a047..0000000 --- a/src/main/java/me/clip/placeholderapi/exceptions/NoDefaultCommandException.java +++ /dev/null @@ -1,8 +0,0 @@ -package me.clip.placeholderapi.exceptions; - -public final class NoDefaultCommandException extends RuntimeException { - public NoDefaultCommandException(final String message) { - super(message); - } -} - diff --git a/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java b/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java index a2560dd..b98c93f 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java @@ -28,7 +28,6 @@ package me.clip.placeholderapi.expansion; * @author Ryan McCarthy */ public interface Cacheable { - /** * Called when the implementing class is unregistered from PlaceholderAPI */ diff --git a/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java b/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java index 8bb798f..2616e0f 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java @@ -30,11 +30,10 @@ import org.bukkit.entity.Player; * @author Ryan McCarthy */ public interface Cleanable { - /** * Called when a player leaves the server * - * @param p (@link Player} who left the server + * @param player (@link Player} who left the server */ - void cleanup(Player p); + void cleanup(Player player); } diff --git a/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java b/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java index faa1f68..22fe743 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java @@ -20,6 +20,7 @@ */ package me.clip.placeholderapi.expansion; +import com.google.common.base.Strings; import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderHook; @@ -41,15 +42,13 @@ public final class ExpansionManager { public ExpansionManager(PlaceholderAPIPlugin instance) { plugin = instance; - File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), "expansions"); - if (!f.exists()) { - f.mkdirs(); - } + File f = new File(plugin.getDataFolder(), "expansions"); + if (!f.exists()) f.mkdirs(); } public PlaceholderExpansion getRegisteredExpansion(String name) { for (Entry hook : PlaceholderAPI.getPlaceholders().entrySet()) { - if (hook.getValue() instanceof PlaceholderExpansion) { + if (hook.getValue().isExpansion()) { if (name.equalsIgnoreCase(hook.getKey())) { return (PlaceholderExpansion) hook.getValue(); } @@ -60,31 +59,28 @@ public final class ExpansionManager { } public boolean registerExpansion(PlaceholderExpansion expansion) { - if (expansion == null || expansion.getIdentifier() == null) { - return false; - } + if (expansion == null || expansion.getIdentifier() == null) return false; if (expansion instanceof Configurable) { Map defaults = ((Configurable) expansion).getDefaults(); - String pre = "expansions." + expansion.getIdentifier() + "."; + String pre = expansion.getPathStarter(); FileConfiguration cfg = plugin.getConfig(); boolean save = false; if (defaults != null) { - for (Entry entries : defaults.entrySet()) { - if (entries.getKey() == null || entries.getKey().isEmpty()) { - continue; - } + for (Entry entry : defaults.entrySet()) { + String key = entry.getKey(); + if (Strings.isNullOrEmpty(key)) continue; - if (entries.getValue() == null) { - if (cfg.contains(pre + entries.getKey())) { + if (entry.getValue() == null) { + if (cfg.contains(pre + key)) { save = true; - cfg.set(pre + entries.getKey(), null); + cfg.set(pre + key, null); } } else { - if (!cfg.contains(pre + entries.getKey())) { + if (!cfg.contains(pre + key)) { save = true; - cfg.set(pre + entries.getKey(), entries.getValue()); + cfg.set(pre + key, entry.getValue()); } } } @@ -107,17 +103,11 @@ public final class ExpansionManager { } } - if (!expansion.canRegister()) { - return false; - } - - if (!expansion.register()) { - return false; - } + if (!expansion.canRegister()) return false; + if (!expansion.register()) return false; if (expansion instanceof Listener) { - Listener l = (Listener) expansion; - Bukkit.getPluginManager().registerEvents(l, plugin); + Bukkit.getPluginManager().registerEvents((Listener) expansion, plugin); } plugin.getLogger().info("Successfully registered expansion: " + expansion.getIdentifier()); @@ -143,29 +133,18 @@ public final class ExpansionManager { public PlaceholderExpansion registerExpansion(String fileName) { List> subs = FileUtil.getClasses("expansions", fileName, PlaceholderExpansion.class); - if (subs == null || subs.isEmpty()) { - return null; - } + if (subs == null || subs.isEmpty()) return null; - // only register the first instance found as an expansion jar should only have 1 class + // Only register the first instance found as an expansion JAR should only have 1 class // extending PlaceholderExpansion PlaceholderExpansion ex = createInstance(subs.get(0)); - if (registerExpansion(ex)) { - return ex; - } - + if (registerExpansion(ex)) return ex; return null; } public void registerAllExpansions() { - if (plugin == null) { - return; - } - List> subs = FileUtil.getClasses("expansions", null, PlaceholderExpansion.class); - if (subs == null || subs.isEmpty()) { - return; - } + if (subs == null || subs.isEmpty()) return; for (Class klass : subs) { PlaceholderExpansion ex = createInstance(klass); @@ -180,34 +159,29 @@ public final class ExpansionManager { } } - private PlaceholderExpansion createInstance(Class klass) { - if (klass == null) { - return null; - } - - PlaceholderExpansion ex = null; - if (!PlaceholderExpansion.class.isAssignableFrom(klass)) { - return null; - } + private PlaceholderExpansion createInstance(Class clazz) { + if (clazz == null) return null; + if (!PlaceholderExpansion.class.isAssignableFrom(clazz)) return null; + PlaceholderExpansion expansion = null; try { - Constructor[] c = klass.getConstructors(); - if (c.length == 0) { - ex = (PlaceholderExpansion) klass.newInstance(); + Constructor[] constructors = clazz.getConstructors(); + if (constructors.length == 0) { + expansion = (PlaceholderExpansion) clazz.newInstance(); } else { - for (Constructor con : c) { - if (con.getParameterTypes().length == 0) { - ex = (PlaceholderExpansion) klass.newInstance(); + for (Constructor ctor : constructors) { + if (ctor.getParameterTypes().length == 0) { + expansion = (PlaceholderExpansion) ctor.newInstance(); break; } } } } catch (Throwable t) { plugin.getLogger() - .severe("Failed to init placeholder expansion from class: " + klass.getName()); + .severe("Failed to init placeholder expansion from class: " + clazz.getName()); plugin.getLogger().severe(t.getMessage()); } - return ex; + return expansion; } } diff --git a/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java b/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java index 2f7d89e..a51f708 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java @@ -20,26 +20,28 @@ */ package me.clip.placeholderapi.expansion; -public enum NMSVersion { +import com.google.common.base.Enums; - UNKNOWN("unknown"), - SPIGOT_1_7_R1("v1_7_R1"), - SPIGOT_1_7_R2("v1_7_R2"), - SPIGOT_1_7_R3("v1_7_R3"), - SPIGOT_1_7_R4("v1_7_R4"), - SPIGOT_1_8_R1("v1_8_R1"), - SPIGOT_1_8_R2("v1_8_R2"), - SPIGOT_1_8_R3("v1_8_R3"), - SPIGOT_1_9_R1("v1_9_R1"), - SPIGOT_1_9_R2("v1_9_R2"), - SPIGOT_1_10_R1("v1_10_R1"), - SPIGOT_1_11_R1("v1_11_R1"), - SPIGOT_1_12_R1("v1_12_R1"), - SPIGOT_1_13_R1("v1_13_R1"), - SPIGOT_1_13_R2("v1_13_R2"), - SPIGOT_1_14_R1("v1_14_R1"), - SPIGOT_1_15_R1("v1_15_R1"), - SPIGOT_1_16_R1("v1_16_R1"); +import java.util.Optional; + +public enum NMSVersion { + UNKNOWN("unknown"), + SPIGOT_1_7_R1("v1_7_R1"), + SPIGOT_1_7_R2("v1_7_R2"), + SPIGOT_1_7_R3("v1_7_R3"), + SPIGOT_1_7_R4("v1_7_R4"), + SPIGOT_1_8_R1("v1_8_R1"), + SPIGOT_1_8_R2("v1_8_R2"), + SPIGOT_1_8_R3("v1_8_R3"), + SPIGOT_1_9_R1("v1_9_R1"), + SPIGOT_1_9_R2("v1_9_R2"), + SPIGOT_1_10_R1("v1_10_R1"), + SPIGOT_1_11_R1("v1_11_R1"), + SPIGOT_1_12_R1("v1_12_R1"), + SPIGOT_1_13_R1("v1_13_R1"), + SPIGOT_1_13_R2("v1_13_R2"), + SPIGOT_1_14_R1("v1_14_R1"), + SPIGOT_1_15_R1("v1_15_R1"); private final String version; @@ -48,17 +50,12 @@ public enum NMSVersion { } public static NMSVersion getVersion(String version) { - for (NMSVersion v : values()) { - if (v.getVersion().equalsIgnoreCase(version)) { - return v; - } - } - - return NMSVersion.UNKNOWN; + // Guava caches values() as well. + Optional opt = Enums.getIfPresent(NMSVersion.class, version).toJavaUtil(); + return opt.orElse(NMSVersion.UNKNOWN); } public String getVersion() { return version; } - } diff --git a/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java b/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java index 4ebdb51..f22a900 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java @@ -26,11 +26,11 @@ import me.clip.placeholderapi.PlaceholderHook; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; import java.util.List; public abstract class PlaceholderExpansion extends PlaceholderHook { - /** * The name of this expansion * @@ -123,60 +123,58 @@ public abstract class PlaceholderExpansion extends PlaceholderHook { } /** - * Quick getter for the {@link PlaceholderAPIPlugin} instance + * Quick getter for the {@link PlaceholderAPIPlugin} config. * - * @return {@link PlaceholderAPIPlugin} instance + * @return {@link PlaceholderAPIPlugin} config instance. */ - public PlaceholderAPIPlugin getPlaceholderAPI() { - return PlaceholderAPIPlugin.getInstance(); + public FileConfiguration getConfig() { + return PlaceholderAPIPlugin.getInstance().getConfig(); } public String getString(String path, String def) { - return getPlaceholderAPI().getConfig() - .getString("expansions." + getIdentifier() + "." + path, def); + return getConfig().getString(getPathStarter() + path, def); } public int getInt(String path, int def) { - return getPlaceholderAPI().getConfig() - .getInt("expansions." + getIdentifier() + "." + path, def); + return getConfig().getInt(getPathStarter() + path, def); } public long getLong(String path, long def) { - return getPlaceholderAPI().getConfig() - .getLong("expansions." + getIdentifier() + "." + path, def); + return getConfig().getLong(getPathStarter() + path, def); } public double getDouble(String path, double def) { - return getPlaceholderAPI().getConfig() - .getDouble("expansions." + getIdentifier() + "." + path, def); + return getConfig().getDouble(getPathStarter() + path, def); } public List getStringList(String path) { - return getPlaceholderAPI().getConfig() - .getStringList("expansions." + getIdentifier() + "." + path); + return getConfig().getStringList(getPathStarter() + path); } public Object get(String path, Object def) { - return getPlaceholderAPI().getConfig().get("expansions." + getIdentifier() + "." + path, def); + return getConfig().get(getPathStarter() + path, def); } public ConfigurationSection getConfigSection(String path) { - return getPlaceholderAPI().getConfig() - .getConfigurationSection("expansions." + getIdentifier() + "." + path); + return getConfig().getConfigurationSection(getPathStarter() + path); } public ConfigurationSection getConfigSection() { - return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier()); + return getConfig().getConfigurationSection("expansions." + getIdentifier()); } public boolean configurationContains(String path) { - return getPlaceholderAPI().getConfig().contains("expansions." + getIdentifier() + "." + path); + return getConfig().contains(getPathStarter() + path); } + protected String getPathStarter() { + return "expansions." + getIdentifier() + '.'; + } /** * @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()} */ + @SuppressWarnings("DeprecatedIsStillUsed") @Deprecated public String getPlugin() { return null; diff --git a/src/main/java/me/clip/placeholderapi/expansion/Relational.java b/src/main/java/me/clip/placeholderapi/expansion/Relational.java index d1da242..7414c5f 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Relational.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Relational.java @@ -23,6 +23,5 @@ package me.clip.placeholderapi.expansion; import org.bukkit.entity.Player; public interface Relational { - String onPlaceholderRequest(Player one, Player two, String identifier); } diff --git a/src/main/java/me/clip/placeholderapi/expansion/Taskable.java b/src/main/java/me/clip/placeholderapi/expansion/Taskable.java index b5b2b6f..ca8364f 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Taskable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Taskable.java @@ -20,9 +20,7 @@ */ package me.clip.placeholderapi.expansion; - public interface Taskable { - /** * Called when the implementing class has successfully been registered to the placeholder map * Tasks that need to be performed when this expansion is registered should go here diff --git a/src/main/java/me/clip/placeholderapi/expansion/Version.java b/src/main/java/me/clip/placeholderapi/expansion/Version.java index 95067e4..e9254d6 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Version.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Version.java @@ -21,7 +21,6 @@ package me.clip.placeholderapi.expansion; public final class Version { - private final boolean isSpigot; private final String version; @@ -41,5 +40,4 @@ public final class Version { public boolean compareTo(String version) { return getVersion().equalsIgnoreCase(version); } - } diff --git a/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java b/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java index 766ee51..5d95934 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java +++ b/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java @@ -36,5 +36,5 @@ public interface VersionSpecific { * * @return true if your expansion is compatible with the version the server is running. */ - boolean isCompatibleWith(Version v); + boolean isCompatibleWith(Version version); } diff --git a/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java b/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java index d6c0d7a..41e2273 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java @@ -26,11 +26,8 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; - public class CloudExpansion { - - private String name, - author, + private String name, author, latest_version, description, source_url, @@ -74,14 +71,12 @@ public class CloudExpansion { } public Version getVersion() { - return getLatestVersion() == null ? null : getVersion(getLatestVersion()); + return latest_version == null ? null : getVersion(latest_version); } public Version getVersion(String version) { return versions == null ? null : versions.stream() - .filter(v -> v.getVersion().equals(version)) - .findFirst() - .orElse(null); + .filter(v -> v.getVersion().equals(version)).findFirst().orElse(null); } public List getAvailableVersions() { @@ -140,6 +135,10 @@ public class CloudExpansion { return verified; } + public void setVerified(boolean verified) { + this.verified = verified; + } + public long getLastUpdate() { return last_update; } @@ -156,6 +155,10 @@ public class CloudExpansion { return average_rating; } + public void setAverage_rating(double average_rating) { + this.average_rating = average_rating; + } + public List getPlaceholders() { return placeholders; } @@ -172,7 +175,11 @@ public class CloudExpansion { this.versions = versions; } - public class Version { + public void setRatings_count(long ratings_count) { + this.ratings_count = ratings_count; + } + + public static class Version { private String url, version, release_notes; public String getUrl() { diff --git a/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java b/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java index 78e6cc3..b706f2e 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java @@ -37,37 +37,29 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; public class ExpansionCloudManager { - private static final String API_URL = "http://api.extendedclip.com/v2/"; private static final Gson GSON = new Gson(); - private final PlaceholderAPIPlugin plugin; private final File expansionsDir; - private final List downloading = new ArrayList<>(); + private final Set downloading = new HashSet<>(); private final Map remote = new TreeMap<>(); - public ExpansionCloudManager(PlaceholderAPIPlugin plugin) { this.plugin = plugin; - expansionsDir = new File(plugin.getDataFolder(), "expansions"); - final boolean result = expansionsDir.mkdirs(); - if (result) { + if (expansionsDir.mkdirs()) { plugin.getLogger().info("Created Expansions Directory"); } - } - public void clean() { remote.clear(); downloading.clear(); } - public Map getCloudExpansions() { return remote; } @@ -80,7 +72,6 @@ public class ExpansionCloudManager { .orElse(null); } - public int getCloudAuthorCount() { return remote.values() .stream() @@ -126,14 +117,10 @@ public class ExpansionCloudManager { public int getPagesAvailable(Map map, int amount) { - if (map == null) { - return 0; - } + if (map == null) return 0; int pages = map.size() > 0 ? 1 : 0; - if (pages == 0) { - return pages; - } + if (pages == 0) return 0; if (map.size() > amount) { pages = map.size() / amount; @@ -159,12 +146,11 @@ public class ExpansionCloudManager { return ex; } - public void fetch(boolean allowUnverified) { plugin.getLogger().info("Fetching available expansion information..."); plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> { - final Map data = new HashMap<>(); + Map data = new HashMap<>(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(API_URL).openStream()))) { data.putAll(GSON.fromJson(reader, new TypeToken>() { @@ -173,11 +159,12 @@ public class ExpansionCloudManager { if (plugin.getPlaceholderAPIConfig().isDebugMode()) { ex.printStackTrace(); } else { - plugin.getLogger().warning("Unable to fetch expansions!\nThere was an error with the server host connecting to the PlaceholderAPI eCloud (https://api.extendedclip.com/v2/)"); + plugin.getLogger().warning("Unable to fetch expansions!\nThere was an error with the server host connecting to the PlaceholderAPI eCloud (https://api" + + ".extendedclip.com/v2/)"); } } - final List unsorted = new ArrayList<>(); + List unsorted = new ArrayList<>(); data.forEach((name, cexp) -> { if ((allowUnverified || cexp.isVerified()) && cexp.getLatestVersion() != null && cexp.getVersion(cexp.getLatestVersion()) != null) { @@ -204,7 +191,6 @@ public class ExpansionCloudManager { } plugin.getLogger().info(count + " placeholder expansions are available on the cloud."); - long updates = getToUpdateCount(); if (updates > 0) { @@ -220,19 +206,15 @@ public class ExpansionCloudManager { private void download(URL url, String name) throws IOException { InputStream is = null; - FileOutputStream fos = null; try { URLConnection urlConn = url.openConnection(); - is = urlConn.getInputStream(); - fos = new FileOutputStream( expansionsDir.getAbsolutePath() + File.separator + "Expansion-" + name + ".jar"); byte[] buffer = new byte[is.available()]; - int l; while ((l = is.read(buffer)) > 0) { @@ -252,42 +234,35 @@ public class ExpansionCloudManager { } - public void downloadExpansion(final String player, final CloudExpansion ex) { + public void downloadExpansion(String player, CloudExpansion ex) { downloadExpansion(player, ex, ex.getLatestVersion()); } - public void downloadExpansion(final String player, final CloudExpansion ex, final String version) { + public void downloadExpansion(String player, CloudExpansion ex, String version) { if (downloading.contains(ex.getName())) { return; } - final CloudExpansion.Version ver = ex.getVersions() + CloudExpansion.Version ver = ex.getVersions() .stream() .filter(v -> v.getVersion().equals(version)) .findFirst() .orElse(null); - if (ver == null) { - return; - } + if (ver == null) return; downloading.add(ex.getName()); - plugin.getLogger().info("Attempting download of expansion: " + ex.getName() + (player != null ? " by user: " + player : "") + " from url: " + ver.getUrl()); - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { try { download(new URL(ver.getUrl()), ex.getName()); - plugin.getLogger().info("Download of expansion: " + ex.getName() + " complete!"); - } catch (Exception e) { plugin.getLogger() .warning("Failed to download expansion: " + ex.getName() + " from: " + ver.getUrl()); Bukkit.getScheduler().runTask(plugin, () -> { - downloading.remove(ex.getName()); if (player != null) { @@ -314,7 +289,6 @@ public class ExpansionCloudManager { } } }); - }); } } diff --git a/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java b/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java index a51893d..3eef529 100644 --- a/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java +++ b/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java @@ -25,9 +25,7 @@ import me.clip.placeholderapi.PlaceholderHook; import org.apache.commons.lang.Validate; import org.bukkit.plugin.Plugin; -/** - * Use {@link me.clip.placeholderapi.expansion.PlaceholderExpansion} instead - */ +@SuppressWarnings("DeprecatedIsStillUsed") @Deprecated public abstract class EZPlaceholderHook extends PlaceholderHook { @@ -35,8 +33,8 @@ public abstract class EZPlaceholderHook extends PlaceholderHook { private final String plugin; public EZPlaceholderHook(Plugin plugin, String identifier) { - Validate.notNull(plugin, "Plugin can not be null!"); - Validate.notNull(identifier, "Placeholder name can not be null!"); + Validate.notNull(plugin, "Plugin cannot be null"); + Validate.notNull(identifier, "Placeholder name cannot be null"); this.identifier = identifier; this.plugin = plugin.getName(); } diff --git a/src/main/java/me/clip/placeholderapi/listeners/ApacheListener.java b/src/main/java/me/clip/placeholderapi/listeners/ApacheListener.java new file mode 100644 index 0000000..268e071 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/listeners/ApacheListener.java @@ -0,0 +1,39 @@ +package me.clip.placeholderapi.listeners; + +import me.clip.placeholderapi.PlaceholderAPIPlugin; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.LogEvent; +import org.apache.logging.log4j.core.filter.AbstractFilter; +import org.bukkit.Bukkit; + +/** + * The purpose of this class is to filter the console warning messages when the plugin + * tries to load placeholder expansions from other jars in the plugins folder. + */ +public class ApacheListener extends AbstractFilter { + private boolean cancelled = false; + + public ApacheListener(PlaceholderAPIPlugin plugin) { + org.apache.logging.log4j.core.Logger logger = (org.apache.logging.log4j.core.Logger) LogManager.getRootLogger(); + logger.addFilter(this); + + // 3 second should be more than enough. I have no idea how to unregister a filter. + Bukkit.getScheduler().runTaskLater(plugin, () -> cancelled = true, 3 * 20L); + } + + @Override + public Result filter(LogEvent event) { + if (cancelled) return Result.NEUTRAL; + if (event.getLevel() != Level.WARN) return Result.NEUTRAL; + if (!event.getLoggerName().equals("PlaceholderAPI")) return Result.NEUTRAL; + + // Format: + // Loaded class {CLASS} from {PLUGIN} {VERSION} which is not a depend, softdepend or loadbefore of this plugin. + // E.g. + // Loaded class com.earth2me.essentials.Essentials from PlaceholderAPI v2.10.5-DEV-84 which is not a depend, softdepend or loadbefore of this plugin. + String message = event.getMessage().getFormattedMessage(); + if (message.startsWith("Loaded class") && message.endsWith("which is not a depend, softdepend or loadbefore of this plugin.")) return Result.DENY; + return Result.NEUTRAL; + } +} \ No newline at end of file diff --git a/src/main/java/me/clip/placeholderapi/listeners/PlaceholderListener.java b/src/main/java/me/clip/placeholderapi/listeners/PlaceholderListener.java index c6c06b5..737ebe0 100644 --- a/src/main/java/me/clip/placeholderapi/listeners/PlaceholderListener.java +++ b/src/main/java/me/clip/placeholderapi/listeners/PlaceholderListener.java @@ -37,13 +37,8 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.server.PluginDisableEvent; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - public class PlaceholderListener implements Listener { - private final PlaceholderAPIPlugin plugin; public PlaceholderListener(PlaceholderAPIPlugin instance) { @@ -53,22 +48,23 @@ public class PlaceholderListener implements Listener { @EventHandler public void onExpansionUnregister(ExpansionUnregisterEvent event) { - if (event.getExpansion() instanceof Listener) { - HandlerList.unregisterAll((Listener) event.getExpansion()); + PlaceholderExpansion expansion = event.getExpansion(); + if (expansion instanceof Listener) { + HandlerList.unregisterAll((Listener) expansion); } - if (event.getExpansion() instanceof Taskable) { - ((Taskable) event.getExpansion()).stop(); + if (expansion instanceof Taskable) { + ((Taskable) expansion).stop(); } - if (event.getExpansion() instanceof Cacheable) { - ((Cacheable) event.getExpansion()).clear(); + if (expansion instanceof Cacheable) { + ((Cacheable) expansion).clear(); } if (plugin.getExpansionCloud() != null) { CloudExpansion ex = plugin.getExpansionCloud() - .getCloudExpansion(event.getExpansion().getName()); + .getCloudExpansion(expansion.getName()); if (ex != null) { ex.setHasExpansion(false); @@ -78,28 +74,20 @@ public class PlaceholderListener implements Listener { } @EventHandler(priority = EventPriority.HIGH) - public void onPluginUnload(PluginDisableEvent e) { - String n = e.getPlugin().getName(); + public void onPluginUnload(PluginDisableEvent event) { + // A plugin name cannot be null. + String name = event.getPlugin().getName(); + if (name.equals(plugin.getName())) return; - if (n.equals(plugin.getName())) { - return; - } + for (PlaceholderHook hook : PlaceholderAPI.getPlaceholders().values()) { + if (hook.isExpansion()) { + PlaceholderExpansion ex = (PlaceholderExpansion) hook; - Map hooks = PlaceholderAPI.getPlaceholders(); + if (ex.getRequiredPlugin() == null) continue; - for (Entry entry : hooks.entrySet()) { - PlaceholderHook hook = entry.getValue(); - - if (hook instanceof PlaceholderExpansion) { - PlaceholderExpansion expansion = (PlaceholderExpansion) hook; - - if (expansion.getRequiredPlugin() == null) { - continue; - } - - if (expansion.getRequiredPlugin().equalsIgnoreCase(n)) { - if (PlaceholderAPI.unregisterExpansion(expansion)) { - plugin.getLogger().info("Unregistered placeholder expansion: " + expansion.getIdentifier()); + if (ex.getRequiredPlugin().equalsIgnoreCase(name)) { + if (PlaceholderAPI.unregisterExpansion(ex)) { + plugin.getLogger().info("Unregistered placeholder expansion: " + ex.getIdentifier()); } } } @@ -107,16 +95,10 @@ public class PlaceholderListener implements Listener { } @EventHandler - public void onQuit(PlayerQuitEvent e) { - Set expansions = PlaceholderAPI.getExpansions(); - - if (expansions.isEmpty()) { - return; - } - - for (PlaceholderExpansion ex : expansions) { - if (ex instanceof Cleanable) { - ((Cleanable) ex).cleanup(e.getPlayer()); + public void onQuit(PlayerQuitEvent event) { + for (PlaceholderHook hook : PlaceholderAPI.getPlaceholders().values()) { + if (hook instanceof Cleanable) { + ((Cleanable) hook).cleanup(event.getPlayer()); } } } diff --git a/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java b/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java index b1f38f7..e08da2b 100644 --- a/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java +++ b/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java @@ -31,7 +31,6 @@ import org.bukkit.event.server.ServerLoadEvent; import java.util.Map; public class ServerLoadEventListener implements Listener { - private final PlaceholderAPIPlugin plugin; public ServerLoadEventListener(PlaceholderAPIPlugin instance) { @@ -40,19 +39,19 @@ public class ServerLoadEventListener implements Listener { } /** - * This method will be called when the server is first loaded + * This method will be called when the server is first loaded. *

* The goal of the method is to register all the expansions as soon as possible - * especially before players can join + * especially before players can join. *

* This will ensure no issues with expanions and hooks. * - * @param e the server load event + * @param event the server load event. */ @EventHandler - public void onServerLoad(ServerLoadEvent e) { + public void onServerLoad(ServerLoadEvent event) { plugin.getLogger().info("Placeholder expansion registration initializing..."); - final Map alreadyRegistered = PlaceholderAPI.getPlaceholders(); + Map alreadyRegistered = PlaceholderAPI.getPlaceholders(); plugin.getExpansionManager().registerAllExpansions(); if (alreadyRegistered != null && !alreadyRegistered.isEmpty()) { diff --git a/src/main/java/me/clip/placeholderapi/util/Constants.java b/src/main/java/me/clip/placeholderapi/util/Constants.java deleted file mode 100644 index d911793..0000000 --- a/src/main/java/me/clip/placeholderapi/util/Constants.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.clip.placeholderapi.util; - -public class Constants { - public static final String ADMIN_PERMISSION = "placeholderapi.admin"; - public static final String ECLOUD_PERMISSION = "placeholderapi.ecloud"; - public static final String INFO_PERMISSION = "placeholderapi.info"; - public static final String LIST_PERMISSION = "placeholderapi.list"; - public static final String RELOAD_PERMISSION = "placeholderapi.reload"; -} diff --git a/src/main/java/me/clip/placeholderapi/util/FileUtil.java b/src/main/java/me/clip/placeholderapi/util/FileUtil.java index 84eb613..9466e5b 100644 --- a/src/main/java/me/clip/placeholderapi/util/FileUtil.java +++ b/src/main/java/me/clip/placeholderapi/util/FileUtil.java @@ -42,65 +42,50 @@ public class FileUtil { try { File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), folder); - if (!f.exists()) { - return list; - } + if (!f.exists()) return list; FilenameFilter fileNameFilter = (dir, name) -> { + boolean isJar = name.endsWith(".jar"); if (fileName != null) { - return name.endsWith(".jar") && name.replace(".jar", "") - .equalsIgnoreCase(fileName.replace(".jar", "")); + return isJar && name.substring(0, name.length() - 4) + .equalsIgnoreCase(fileName.substring(0, fileName.length() - 4)); } - return name.endsWith(".jar"); + return isJar; }; File[] jars = f.listFiles(fileNameFilter); - if (jars == null) { - return list; - } + if (jars == null) return list; for (File file : jars) { list = gather(file.toURI().toURL(), list, type); } return list; - } catch (Throwable t) { + } catch (Throwable ignored) { } return null; } private static List> gather(URL jar, List> list, Class clazz) { - if (list == null) { - list = new ArrayList<>(); - } - + // list cannot be null. try (URLClassLoader cl = new URLClassLoader(new URL[]{jar}, clazz.getClassLoader()); JarInputStream jis = new JarInputStream(jar.openStream())) { - while (true) { - JarEntry j = jis.getNextJarEntry(); - if (j == null) { - break; - } - - String name = j.getName(); - if (name == null || name.isEmpty()) { - continue; - } + JarEntry entry; + while ((entry = jis.getNextJarEntry()) != null) { + String name = entry.getName(); + if (name == null || name.isEmpty()) continue; if (name.endsWith(".class")) { - name = name.replace("/", "."); - String cname = name.substring(0, name.lastIndexOf(".class")); + name = name.substring(0, name.length() - 6).replace('/', '.'); - Class c = cl.loadClass(cname); - if (clazz.isAssignableFrom(c)) { - list.add(c); - } + Class loaded = cl.loadClass(name); + if (clazz.isAssignableFrom(loaded)) list.add(loaded); } } - } catch (Throwable t) { + } catch (Throwable ignored) { } return list; diff --git a/src/main/java/me/clip/placeholderapi/util/Msg.java b/src/main/java/me/clip/placeholderapi/util/Msg.java index 3d526e4..e1cdd25 100644 --- a/src/main/java/me/clip/placeholderapi/util/Msg.java +++ b/src/main/java/me/clip/placeholderapi/util/Msg.java @@ -24,17 +24,20 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; -import java.util.Arrays; -import java.util.Objects; -import java.util.stream.Collectors; - -public final class Msg { - public static void msg(CommandSender s, String... msg) { - s.sendMessage(Arrays.stream(msg).filter(Objects::nonNull).map(Msg::color).collect(Collectors.joining("\n"))); +public class Msg { + public static void msg(CommandSender sender, String... messages) { + for (String message : messages) { + String msg = color(message); + sender.sendMessage(msg); + } } - public static void broadcast(String... msg) { - Arrays.stream(msg).filter(Objects::nonNull).map(Msg::color).forEach(Bukkit::broadcastMessage); + public static void broadcast(String... messages) { + CommandSender sender = Bukkit.getConsoleSender(); + for (String message : messages) { + String msg = color(message); + sender.sendMessage(msg); + } } public static String color(String text) { diff --git a/src/main/java/me/clip/placeholderapi/util/TimeFormat.java b/src/main/java/me/clip/placeholderapi/util/TimeFormat.java deleted file mode 100644 index a9c3190..0000000 --- a/src/main/java/me/clip/placeholderapi/util/TimeFormat.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * PlaceholderAPI - * Copyright (C) 2019 Ryan McCarthy - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * - */ -package me.clip.placeholderapi.util; - -public enum TimeFormat { - DAYS, - HOURS, - MINUTES, - SECONDS -} diff --git a/src/main/java/me/clip/placeholderapi/util/TimeUtil.java b/src/main/java/me/clip/placeholderapi/util/TimeUtil.java index b320ecf..8c834ff 100644 --- a/src/main/java/me/clip/placeholderapi/util/TimeUtil.java +++ b/src/main/java/me/clip/placeholderapi/util/TimeUtil.java @@ -22,10 +22,10 @@ package me.clip.placeholderapi.util; import java.time.Duration; import java.time.temporal.ChronoUnit; +import java.util.concurrent.TimeUnit; public class TimeUtil { - - public static String getRemaining(int seconds, TimeFormat type) { + public static String getRemaining(int seconds, TimeUnit type) { if (seconds < 60) { switch (type) { case DAYS: @@ -124,8 +124,8 @@ public class TimeUtil { * @param duration {@link Duration} (eg, Duration.of(20, {@link ChronoUnit#SECONDS}) for 20 seconds) * @return formatted time */ - public static String getTime(final Duration duration) { - final StringBuilder builder = new StringBuilder(); + public static String getTime(Duration duration) { + StringBuilder builder = new StringBuilder(); long seconds = duration.getSeconds(); long minutes = seconds / 60; diff --git a/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java b/src/main/java/me/clip/placeholderapi/util/UpdateChecker.java similarity index 66% rename from src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java rename to src/main/java/me/clip/placeholderapi/util/UpdateChecker.java index afafb0d..03d88e2 100644 --- a/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java +++ b/src/main/java/me/clip/placeholderapi/util/UpdateChecker.java @@ -18,13 +18,13 @@ * * */ -package me.clip.placeholderapi.updatechecker; +package me.clip.placeholderapi.util; import me.clip.placeholderapi.PlaceholderAPIPlugin; -import me.clip.placeholderapi.util.Msg; +import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; @@ -32,10 +32,11 @@ import javax.net.ssl.HttpsURLConnection; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; +import java.nio.charset.StandardCharsets; public class UpdateChecker implements Listener { - - private final int RESOURCE_ID = 6245; + private static final int RESOURCE_ID = 6245; + private static final String SPIGOT_API = "https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID; private final PlaceholderAPIPlugin plugin; private final String pluginVersion; private String spigotVersion; @@ -57,39 +58,35 @@ public class UpdateChecker implements Listener { public void fetch() { Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { try { - HttpsURLConnection con = (HttpsURLConnection) new URL( - "https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection(); + HttpsURLConnection con = (HttpsURLConnection) new URL(SPIGOT_API).openConnection(); + + // Prevents the server from freezing with bad internet connection. con.setRequestMethod("GET"); - spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine(); + con.setConnectTimeout(2000); + con.setReadTimeout(2000); + + spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8)).readLine(); } catch (Exception ex) { - plugin.getLogger().info("Failed to check for updates on spigot."); - return; - } - - if (spigotVersion == null || spigotVersion.isEmpty()) { + plugin.getLogger().warning("Failed to check for updates on spigot."); return; } + if (spigotVersion == null || spigotVersion.isEmpty()) return; updateAvailable = spigotIsNewer(); - - if (!updateAvailable) { - return; - } + if (!updateAvailable) return; Bukkit.getScheduler().runTask(plugin, () -> { plugin.getLogger() - .info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:"); + .info("An update for PlaceholderAPI (v" + spigotVersion + ") is available at:"); plugin.getLogger() - .info("https://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + "/"); + .info("https://www.spigotmc.org/resources/" + RESOURCE_ID + '/'); Bukkit.getPluginManager().registerEvents(this, plugin); }); }); } private boolean spigotIsNewer() { - if (spigotVersion == null || spigotVersion.isEmpty()) { - return false; - } + if (spigotVersion == null || spigotVersion.isEmpty()) return false; String plV = toReadable(pluginVersion); String spV = toReadable(spigotVersion); @@ -97,21 +94,17 @@ public class UpdateChecker implements Listener { } private String toReadable(String version) { - if (version.contains("-DEV-")) { - version = version.split("-DEV-")[0]; - } - - return version.replaceAll("\\.", ""); + if (version.contains("-DEV-")) version = StringUtils.split(version, "-DEV-")[0]; + return StringUtils.remove(version, '.'); } - @EventHandler(priority = EventPriority.MONITOR) - public void onJoin(PlayerJoinEvent e) { - if (e.getPlayer().hasPermission("placeholderapi.updatenotify")) { - Msg.msg(e.getPlayer(), - "&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getSpigotVersion() - + "&e)" - , "&bis available at &ehttps://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID - + "/"); + @EventHandler + public void onJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + if (player.hasPermission("placeholderapi.updatenotify")) { + Msg.msg(player, + "&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getSpigotVersion() + "&e)", + "&bis available at &ehttps://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + '/'); } } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index d4031ef..8b3e5aa 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -4,39 +4,51 @@ version: ${project.version} api-version: '1.13' authors: [extended_clip, Glare] description: ${project.description} -permissions: - placeholderapi.*: - description: ability to use all commands - children: - placeholderapi.admin: true - placeholderapi.admin: - description: ability to use all commands - children: - placeholderapi.list: true - placeholderapi.reload: true - placeholderapi.ecloud: true - placeholderapi.parse: true - placeholderapi.register: true - placeholderapi.updatenotify: true - placeholderapi.list: - description: ability to use the list command - default: op - placeholderapi.reload: - description: ability to use the reload command - default: op - placeholderapi.parse: - description: ability to use parse command - default: op - placeholderapi.register: - description: ability to register or unregister placeholder expansions - default: op - placeholderapi.ecloud: - description: allows the usage of ecloud commands - default: op - placeholderapi.updatenotify: - description: notifies you when there is a PAPI update - default: op + commands: - placeholderapi: - description: PlaceholderAPI command - aliases: [papi] + placeholderapi: + description: PlaceholderAPI command + aliases: [papi] + +permissions: + placeholderapi.*: + description: ability to use all commands + children: + placeholderapi.admin: true + placeholderapi.admin: + description: ability to use all commands + children: + placeholderapi.list: true + placeholderapi.reload: true + placeholderapi.ecloud: true + placeholderapi.parse: true + placeholderapi.register: true + placeholderapi.updatenotify: true + placeholderapi.list: + description: ability to use the list command + default: op + placeholderapi.reload: + description: ability to use the reload command + default: op + placeholderapi.parse: + description: ability to use parse command + default: op + placeholderapi.register: + description: ability to register or unregister placeholder expansions + default: op + placeholderapi.ecloud: + description: allows the usage of ecloud commands + default: op + children: + placeholderapi.ecloud.enable: true + placeholderapi.ecloud.disable: true + placeholderapi.ecloud.list: true + placeholderapi.ecloud.info: true + placeholderapi.ecloud.clear: true + placeholderapi.ecloud.status: true + placeholderapi.ecloud.refresh: true + placeholderapi.ecloud.download: true + placeholderapi.ecloud.versioninfo: true + placeholderapi.updatenotify: + description: notifies you when there is a PAPI update + default: op \ No newline at end of file From b4d6b047af4c580013d7d5949162863dd725d38e Mon Sep 17 00:00:00 2001 From: Sxtanna Date: Sun, 19 Jul 2020 09:12:58 -0400 Subject: [PATCH 02/14] moved compiler source and target to properties --- pom.xml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index e82f6f8..b4cab9e 100644 --- a/pom.xml +++ b/pom.xml @@ -12,6 +12,8 @@ http://extendedclip.com + 1.8 + 1.8 UTF-8 @@ -72,15 +74,6 @@ ${project.name}-${project.version} - - org.apache.maven.plugins - maven-compiler-plugin - 3.7.0 - - 1.8 - 1.8 - - org.apache.maven.plugins maven-shade-plugin From d2223f83b89d099b637530fb2f7f9624ecfadbde Mon Sep 17 00:00:00 2001 From: Sxtanna Date: Sun, 19 Jul 2020 09:16:09 -0400 Subject: [PATCH 03/14] removed server dependency, added provided dependency for log4j-core --- pom.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b4cab9e..5d97f89 100644 --- a/pom.xml +++ b/pom.xml @@ -35,10 +35,16 @@ org.spigotmc - spigot + spigot-api 1.16.1-R0.1-SNAPSHOT provided + + org.apache.logging.log4j + log4j-core + 2.13.3 + provided + com.google.code.gson gson From 4ce0b038525fa49729665dbe0af89988a7ee9cd6 Mon Sep 17 00:00:00 2001 From: extendedclip Date: Mon, 20 Jul 2020 16:57:16 -0400 Subject: [PATCH 04/14] Revert "Performance Improvements (#340)" This reverts commit 54d5757d --- pom.xml | 34 +-- .../clip/placeholderapi/PlaceholderAPI.java | 229 ++++++++++-------- .../placeholderapi/PlaceholderAPIPlugin.java | 166 +++++++------ .../clip/placeholderapi/PlaceholderHook.java | 19 +- .../placeholderapi/PlaceholderReplacer.java | 150 ------------ .../clip/placeholderapi/commands/Command.java | 49 ++-- .../commands/CommandHandler.java | 69 +++--- .../commands/CompletionHandler.java | 35 ++- .../commands/command/BcParseCommand.java | 26 +- ...Command.java => DisableEcloudCommand.java} | 16 +- .../commands/command/EcloudCommand.java | 16 +- ...leCommand.java => EnableCloudCommand.java} | 14 +- .../commands/command/HelpCommand.java | 5 +- .../commands/command/InfoCommand.java | 15 +- .../commands/command/ListCommand.java | 7 +- .../commands/command/ParseCommand.java | 44 ++-- .../commands/command/ParseRelCommand.java | 13 +- .../commands/command/RegisterCommand.java | 11 +- .../commands/command/ReloadCommand.java | 5 +- .../commands/command/UnregisterCommand.java | 17 +- .../commands/command/VersionCommand.java | 9 +- .../command/ecloud/EcloudClearCommand.java | 5 +- .../command/ecloud/EcloudDownloadCommand.java | 30 +-- .../command/ecloud/EcloudInfoCommand.java | 17 +- .../command/ecloud/EcloudListCommand.java | 36 +-- .../ecloud/EcloudPlaceholdersCommand.java | 19 +- .../command/ecloud/EcloudRefreshCommand.java | 9 +- .../command/ecloud/EcloudStatusCommand.java | 7 +- .../ecloud/EcloudVersionInfoCommand.java | 18 +- .../exceptions/NoDefaultCommandException.java | 8 + .../placeholderapi/expansion/Cacheable.java | 1 + .../placeholderapi/expansion/Cleanable.java | 5 +- .../expansion/ExpansionManager.java | 92 ++++--- .../placeholderapi/expansion/NMSVersion.java | 51 ++-- .../expansion/PlaceholderExpansion.java | 38 +-- .../placeholderapi/expansion/Relational.java | 1 + .../placeholderapi/expansion/Taskable.java | 2 + .../placeholderapi/expansion/Version.java | 2 + .../expansion/VersionSpecific.java | 2 +- .../expansion/cloud/CloudExpansion.java | 25 +- .../cloud/ExpansionCloudManager.java | 50 +++- .../external/EZPlaceholderHook.java | 8 +- .../listeners/ApacheListener.java | 39 --- .../listeners/PlaceholderListener.java | 64 +++-- .../listeners/ServerLoadEventListener.java | 11 +- .../UpdateChecker.java | 63 ++--- .../clip/placeholderapi/util/Constants.java | 9 + .../me/clip/placeholderapi/util/FileUtil.java | 47 ++-- .../java/me/clip/placeholderapi/util/Msg.java | 21 +- .../clip/placeholderapi/util/TimeFormat.java | 28 +++ .../me/clip/placeholderapi/util/TimeUtil.java | 8 +- src/main/resources/plugin.yml | 82 +++---- 52 files changed, 873 insertions(+), 874 deletions(-) delete mode 100644 src/main/java/me/clip/placeholderapi/PlaceholderReplacer.java rename src/main/java/me/clip/placeholderapi/commands/command/{ecloud/EcloudDisableCommand.java => DisableEcloudCommand.java} (53%) rename src/main/java/me/clip/placeholderapi/commands/command/{ecloud/EcloudEnableCommand.java => EnableCloudCommand.java} (54%) create mode 100644 src/main/java/me/clip/placeholderapi/exceptions/NoDefaultCommandException.java delete mode 100644 src/main/java/me/clip/placeholderapi/listeners/ApacheListener.java rename src/main/java/me/clip/placeholderapi/{util => updatechecker}/UpdateChecker.java (66%) create mode 100644 src/main/java/me/clip/placeholderapi/util/Constants.java create mode 100644 src/main/java/me/clip/placeholderapi/util/TimeFormat.java diff --git a/pom.xml b/pom.xml index 5d97f89..9ee602b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,8 +5,8 @@ me.clip placeholderapi - 2.10.7-DEV-${BUILD_NUMBER} + 2.10.7-DEV-${BUILD_NUMBER} PlaceholderAPI An awesome placeholder provider! http://extendedclip.com @@ -53,7 +53,7 @@ org.bstats bstats-bukkit - 1.7 + 1.5 me.rayzr522 @@ -83,27 +83,27 @@ org.apache.maven.plugins maven-shade-plugin - 3.2.4 - - false - false - - - org.bstats - me.clip.placeholderapi.util - - - com.google.code.gson - me.clip.placeholderapi.libs.gson - - - + 3.1.0 package shade + + false + false + + + org.bstats + me.clip.placeholderapi.metrics + + + com.google.code.gson + me.clip.placeholderapi.libs.gson + + + diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java index d089aa0..8ce1674 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java @@ -20,13 +20,14 @@ */ package me.clip.placeholderapi; -import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import me.clip.placeholderapi.events.ExpansionRegisterEvent; import me.clip.placeholderapi.events.ExpansionUnregisterEvent; +import me.clip.placeholderapi.expansion.Cacheable; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.Relational; +import me.clip.placeholderapi.util.Msg; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; @@ -34,17 +35,18 @@ import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import static me.clip.placeholderapi.util.Msg.color; public class PlaceholderAPI { - protected static final Map PLACEHOLDERS = new ConcurrentHashMap<>(); - private static final Pattern PERCENT_PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]"); + + private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]"); private static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]"); private static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern.compile("[%](rel_)([^%]+)[%]"); + private static final Map placeholders = new HashMap<>(); private PlaceholderAPI() { } @@ -56,7 +58,9 @@ public class PlaceholderAPI { * @return true if identifier is already registered */ public static boolean isRegistered(String identifier) { - return PLACEHOLDERS.containsKey(identifier.toLowerCase(Locale.ENGLISH)); + return getRegisteredIdentifiers().stream() + .filter(id -> id.equalsIgnoreCase(identifier)) + .findFirst().orElse(null) != null; } /** @@ -69,11 +73,15 @@ public class PlaceholderAPI { * registered for the specified identifier */ public static boolean registerPlaceholderHook(String identifier, PlaceholderHook placeholderHook) { - Validate.notEmpty(identifier, "Placeholder identifier cannot be null or empty"); - Objects.requireNonNull(placeholderHook, "Placeholder hook cannot be null"); + Validate.notNull(identifier, "Identifier can not be null"); + Validate.notNull(placeholderHook, "Placeholderhook can not be null"); + + if (isRegistered(identifier)) { + return false; + } + + placeholders.put(identifier.toLowerCase(), placeholderHook); - if (isRegistered(identifier)) return false; - PLACEHOLDERS.put(identifier.toLowerCase(Locale.ENGLISH), placeholderHook); return true; } @@ -85,8 +93,8 @@ public class PlaceholderAPI { * placeholder hook registered for the identifier specified */ public static boolean unregisterPlaceholderHook(String identifier) { - Validate.notEmpty(identifier, "Identifier cannot be null"); - return PLACEHOLDERS.remove(identifier.toLowerCase(Locale.ENGLISH)) != null; + Validate.notNull(identifier, "Identifier can not be null"); + return placeholders.remove(identifier.toLowerCase()) != null; } /** @@ -95,7 +103,7 @@ public class PlaceholderAPI { * @return All registered placeholder identifiers */ public static Set getRegisteredIdentifiers() { - return ImmutableSet.copyOf(PLACEHOLDERS.keySet()); + return ImmutableSet.copyOf(placeholders.keySet()); } /** @@ -104,16 +112,15 @@ public class PlaceholderAPI { * @return Copy of the internal placeholder map */ public static Map getPlaceholders() { - return ImmutableMap.copyOf(PLACEHOLDERS); + return ImmutableMap.copyOf(placeholders); } public static Set getExpansions() { - Set expansions = new HashSet<>(); - for (PlaceholderHook expansion : PLACEHOLDERS.values()) { - if (expansion.isExpansion()) expansions.add((PlaceholderExpansion) expansion); - } + Set set = getPlaceholders().values().stream() + .filter(PlaceholderExpansion.class::isInstance).map(PlaceholderExpansion.class::cast) + .collect(Collectors.toCollection(HashSet::new)); - return ImmutableSet.copyOf(expansions); + return ImmutableSet.copyOf(set); } /** @@ -123,7 +130,7 @@ public class PlaceholderAPI { * @return true if String contains any registered placeholder identifiers, false otherwise */ public static boolean containsPlaceholders(String text) { - return !Strings.isNullOrEmpty(text) && PERCENT_PLACEHOLDER_PATTERN.matcher(text).find(); + return text != null && PLACEHOLDER_PATTERN.matcher(text).find(); } /** @@ -133,7 +140,7 @@ public class PlaceholderAPI { * @return true if String contains any registered placeholder identifiers, false otherwise */ public static boolean containsBracketPlaceholders(String text) { - return !Strings.isNullOrEmpty(text) && BRACKET_PLACEHOLDER_PATTERN.matcher(text).find(); + return text != null && BRACKET_PLACEHOLDER_PATTERN.matcher(text).find(); } /** @@ -170,7 +177,7 @@ public class PlaceholderAPI { * @return String containing all translated placeholders */ public static List setPlaceholders(OfflinePlayer player, List text) { - return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, true); + return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true); } /** @@ -183,7 +190,7 @@ public class PlaceholderAPI { * @return String containing all translated placeholders */ public static List setPlaceholders(OfflinePlayer player, List text, boolean colorize) { - return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize); + return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); } /** @@ -212,13 +219,13 @@ public class PlaceholderAPI { * @return String containing all translated placeholders */ public static List setPlaceholders(OfflinePlayer player, List text, Pattern pattern, boolean colorize) { - if (text == null) return null; - List lines = new ArrayList<>(); - - for (String line : text) { - lines.add(setPlaceholders(player, line, pattern, colorize)); + if (text == null) { + return null; } - return lines; + + return text.stream() + .map(line -> setPlaceholders(player, line, pattern, colorize)) + .collect(Collectors.toList()); } /** @@ -255,7 +262,7 @@ public class PlaceholderAPI { * @return String containing all translated placeholders */ public static String setPlaceholders(OfflinePlayer player, String text) { - return PlaceholderReplacer.evaluatePlaceholders(player, text, PlaceholderReplacer.Closure.PERCENT, false); + return setPlaceholders(player, text, PLACEHOLDER_PATTERN); } /** @@ -268,7 +275,7 @@ public class PlaceholderAPI { * @return The text containing the parsed placeholders */ public static String setPlaceholders(OfflinePlayer player, String text, boolean colorize) { - return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize); + return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); } /** @@ -297,51 +304,43 @@ public class PlaceholderAPI { * @return The text containing the parsed placeholders */ public static String setPlaceholders(OfflinePlayer player, String text, Pattern pattern, boolean colorize) { - if (text == null) return null; - if (PLACEHOLDERS.isEmpty()) return colorize ? color(text) : text; + if (text == null) { + return null; + } + + if (placeholders.isEmpty()) { + return colorize ? color(text) : text; + } + + final Matcher matcher = pattern.matcher(text); + final Map hooks = getPlaceholders(); - Matcher matcher = pattern.matcher(text); while (matcher.find()) { - String format = matcher.group(1); - int index = format.indexOf('_'); - if (index <= 0 || index >= format.length()) continue; + final String format = matcher.group(1); + final int index = format.indexOf("_"); - // We don't need to use getPlaceholders() because we know what we're doing and we won't modify the map. - // And instead of looking for the element twice using contains() and get() we only get it and check if it's null. - String identifier = format.substring(0, index).toLowerCase(Locale.ENGLISH); - PlaceholderHook handler = PLACEHOLDERS.get(identifier); + if (index <= 0 || index >= format.length()) { + continue; + } - if (handler != null) { - String params = format.substring(index + 1); - String value = handler.onRequest(player, params); + final String identifier = format.substring(0, index).toLowerCase(); + final String params = format.substring(index + 1); + final PlaceholderHook hook = hooks.get(identifier); - if (value != null) { - text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value)); - } + if (hook == null) { + continue; + } + + final String value = hook.onRequest(player, params); + + if (value != null) { + text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value)); } } return colorize ? color(text) : text; } - /** - * Optimized version of {@link #setPlaceholders(OfflinePlayer, String, Pattern, boolean)} - * - * @param player player to parse the placeholders against. - * @param text the text to translate. - * @param closure the closing points of a placeholder. %, {, [ etc... - * @param colorize if we should colorize this text using the common & symbol. - * @return the translated text. - */ - public static String setPlaceholders(OfflinePlayer player, String text, PlaceholderReplacer.Closure closure, boolean colorize) { - if (text == null) return null; - if (text.isEmpty()) return ""; - if (PLACEHOLDERS.isEmpty()) return colorize ? color(text) : text; - - // We don't want to dirty our class. - return PlaceholderReplacer.evaluatePlaceholders(player, text, closure, colorize); - } - /** * Translate placeholders in the provided List based on the relation of the two provided players. *
The pattern of a valid placeholder is {@literal %rel__%}. @@ -366,12 +365,13 @@ public class PlaceholderAPI { * @return The text containing the parsed relational placeholders */ public static List setRelationalPlaceholders(Player one, Player two, List text, boolean colorize) { - if (text == null) return null; - List lines = new ArrayList<>(); - for (String line : text) { - lines.add(setRelationalPlaceholders(one, two, line, colorize)); + if (text == null) { + return null; } - return lines; + + return text.stream() + .map(line -> setRelationalPlaceholders(one, two, line, colorize)) + .collect(Collectors.toList()); } /** @@ -397,31 +397,43 @@ public class PlaceholderAPI { * @param colorize If color codes (&[0-1a-fk-o]) should be translated * @return The text containing the parsed relational placeholders */ + @SuppressWarnings("DuplicatedCode") public static String setRelationalPlaceholders(Player one, Player two, String text, boolean colorize) { - if (text == null) return null; - if (PLACEHOLDERS.isEmpty()) return colorize ? color(text) : text; + if (text == null) { + return null; + } + + if (placeholders.isEmpty()) { + return colorize ? Msg.color(text) : text; + } + + final Matcher matcher = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text); + final Map hooks = getPlaceholders(); - Matcher matcher = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text); while (matcher.find()) { - String format = matcher.group(2); - int index = format.indexOf('_'); - if (index <= 0 || index >= format.length()) continue; + final String format = matcher.group(2); + final int index = format.indexOf("_"); - String identifier = format.substring(0, index).toLowerCase(Locale.ENGLISH); - PlaceholderHook handler = PLACEHOLDERS.get(identifier); + if (index <= 0 || index >= format.length()) { + continue; + } - if (handler.isRelational()) { - Relational relational = (Relational) handler; - String params = format.substring(index + 1); - String value = relational.onPlaceholderRequest(one, two, params); + String identifier = format.substring(0, index).toLowerCase(); + String params = format.substring(index + 1); + final PlaceholderHook hook = hooks.get(identifier); - if (value != null) { - text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value)); - } + if (!(hook instanceof Relational)) { + continue; + } + + final String value = ((Relational) hook).onPlaceholderRequest(one, two, params); + + if (value != null) { + text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value)); } } - return colorize ? color(text) : text; + return colorize ? Msg.color(text) : text; } /** @@ -429,34 +441,43 @@ public class PlaceholderAPI { */ protected static void unregisterAll() { unregisterAllProvidedExpansions(); - PLACEHOLDERS.clear(); + placeholders.clear(); } /** * Unregister all expansions provided by PlaceholderAPI */ public static void unregisterAllProvidedExpansions() { - if (PLACEHOLDERS.isEmpty()) return; + final Set set = new HashSet<>(placeholders.values()); - for (PlaceholderHook handler : PLACEHOLDERS.values()) { - if (handler.isExpansion()) { - PlaceholderExpansion expansion = (PlaceholderExpansion) handler; - if (!expansion.persist()) unregisterExpansion(expansion); + for (PlaceholderHook hook : set) { + if (hook instanceof PlaceholderExpansion) { + final PlaceholderExpansion expansion = (PlaceholderExpansion) hook; + + if (!expansion.persist()) { + unregisterExpansion(expansion); + } + } + + if (hook instanceof Cacheable) { + ((Cacheable) hook).clear(); } } } - public static boolean registerExpansion(PlaceholderExpansion expansion) { - ExpansionRegisterEvent event = new ExpansionRegisterEvent(expansion); - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return false; + public static boolean registerExpansion(PlaceholderExpansion ex) { + ExpansionRegisterEvent ev = new ExpansionRegisterEvent(ex); + Bukkit.getPluginManager().callEvent(ev); + if (ev.isCancelled()) { + return false; + } - return registerPlaceholderHook(expansion.getIdentifier(), expansion); + return registerPlaceholderHook(ex.getIdentifier(), ex); } - public static boolean unregisterExpansion(PlaceholderExpansion expansion) { - if (unregisterPlaceholderHook(expansion.getIdentifier())) { - Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(expansion)); + public static boolean unregisterExpansion(PlaceholderExpansion ex) { + if (unregisterPlaceholderHook(ex.getIdentifier())) { + Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(ex)); return true; } @@ -469,7 +490,7 @@ public class PlaceholderAPI { * @return The pattern for {@literal %_%} */ public static Pattern getPlaceholderPattern() { - return PERCENT_PLACEHOLDER_PATTERN; + return PLACEHOLDER_PATTERN; } /** @@ -511,19 +532,19 @@ public class PlaceholderAPI { } public static String setPlaceholders(Player player, String text) { - return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, true); + return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true); } public static String setPlaceholders(Player player, String text, boolean colorize) { - return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize); + return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); } public static List setPlaceholders(Player player, List text) { - return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, true); + return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true); } public static List setPlaceholders(Player player, List text, boolean colorize) { - return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize); + return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); } public static String setBracketPlaceholders(Player player, String text) { diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java index 60d2e60..f52e880 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java @@ -21,63 +21,66 @@ package me.clip.placeholderapi; import me.clip.placeholderapi.commands.CommandHandler; -import me.clip.placeholderapi.commands.CompletionHandler; import me.clip.placeholderapi.configuration.PlaceholderAPIConfig; import me.clip.placeholderapi.expansion.ExpansionManager; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.Version; import me.clip.placeholderapi.expansion.cloud.ExpansionCloudManager; import me.clip.placeholderapi.external.EZPlaceholderHook; -import me.clip.placeholderapi.listeners.ApacheListener; import me.clip.placeholderapi.listeners.PlaceholderListener; import me.clip.placeholderapi.listeners.ServerLoadEventListener; +import me.clip.placeholderapi.updatechecker.UpdateChecker; import me.clip.placeholderapi.util.TimeUtil; -import me.clip.placeholderapi.util.UpdateChecker; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; -import org.bukkit.command.PluginCommand; import org.bukkit.plugin.java.JavaPlugin; import java.text.SimpleDateFormat; -import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.concurrent.TimeUnit; + /** * Yes I have a shit load of work to do... * * @author Ryan McCarthy */ public class PlaceholderAPIPlugin extends JavaPlugin { - private static final Version serverVersion; + private static PlaceholderAPIPlugin instance; - private static DateTimeFormatter dateFormat; + private static SimpleDateFormat dateFormat; private static String booleanTrue; private static String booleanFalse; - - static { - // It's not possible to be null or throw an index exception unless it's a bug. - String nmsVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; - boolean spigot; - - try { - Class.forName("org.spigotmc.SpigotConfig"); - spigot = true; - } catch (ExceptionInInitializerError | ClassNotFoundException ignored) { - spigot = false; - } - - serverVersion = new Version(nmsVersion, spigot); - } - + private static Version serverVersion; private PlaceholderAPIConfig config; private ExpansionManager expansionManager; private ExpansionCloudManager expansionCloud; private long startTime; + private static Version getVersion() { + String v = "unknown"; + boolean spigot = false; + + try { + v = Bukkit.getServer().getClass().getPackage().getName() + .split("\\.")[3]; + } catch (ArrayIndexOutOfBoundsException ex) { + } + + try { + Class.forName("org.spigotmc.SpigotConfig"); + Class.forName("net.md_5.bungee.api.chat.BaseComponent"); + spigot = true; + } catch (ExceptionInInitializerError | ClassNotFoundException ignored) { + } + + return new Version(v, spigot); + } + /** * Gets the static instance of the main class for PlaceholderAPI. This class is not the actual API * class, this is the main class that extends JavaPlugin. For most API methods, use static methods @@ -95,8 +98,9 @@ public class PlaceholderAPIPlugin extends JavaPlugin { * * @return date format */ - public static DateTimeFormatter getDateFormat() { - return dateFormat != null ? dateFormat : DateTimeFormatter.ofPattern("MM/dd/yy HH:mm:ss"); + public static SimpleDateFormat getDateFormat() { + return dateFormat != null ? dateFormat : new SimpleDateFormat( + "MM/dd/yy HH:mm:ss"); } /** @@ -118,26 +122,26 @@ public class PlaceholderAPIPlugin extends JavaPlugin { } public static Version getServerVersion() { - return serverVersion; + return serverVersion != null ? serverVersion : getVersion(); + } + + @Override + public void onLoad() { + startTime = System.currentTimeMillis(); + instance = this; + serverVersion = getVersion(); + config = new PlaceholderAPIConfig(this); + expansionManager = new ExpansionManager(this); } @Override public void onEnable() { - startTime = System.currentTimeMillis(); - instance = this; - - config = new PlaceholderAPIConfig(this); config.loadDefConfig(); setupOptions(); - expansionManager = new ExpansionManager(this); + Objects.requireNonNull(getCommand("placeholderapi")).setExecutor(new CommandHandler()); new PlaceholderListener(this); - PluginCommand command = getCommand("placeholderapi"); - command.setExecutor(new CommandHandler()); - command.setTabCompleter(new CompletionHandler()); - - new ApacheListener(this); try { Class.forName("org.bukkit.event.server.ServerLoadEvent"); new ServerLoadEventListener(this); @@ -146,7 +150,7 @@ public class PlaceholderAPIPlugin extends JavaPlugin { getLogger().info("Placeholder expansion registration initializing..."); //fetch any hooks that may have registered externally onEnable first otherwise they will be lost - Map alreadyRegistered = PlaceholderAPI.PLACEHOLDERS; + final Map alreadyRegistered = PlaceholderAPI.getPlaceholders(); getExpansionManager().registerAllExpansions(); if (alreadyRegistered != null && !alreadyRegistered.isEmpty()) { @@ -155,8 +159,13 @@ public class PlaceholderAPIPlugin extends JavaPlugin { }, 1); } - if (config.checkUpdates()) new UpdateChecker(this).fetch(); - if (config.isCloudEnabled()) enableCloud(); + if (config.checkUpdates()) { + new UpdateChecker(this).fetch(); + } + + if (config.isCloudEnabled()) { + enableCloud(); + } setupMetrics(); getServer().getScheduler().runTaskLater(this, this::checkHook, 40); @@ -166,13 +175,14 @@ public class PlaceholderAPIPlugin extends JavaPlugin { public void onDisable() { disableCloud(); PlaceholderAPI.unregisterAll(); - Bukkit.getScheduler().cancelTasks(this); - expansionManager = null; + Bukkit.getScheduler().cancelTasks(this); + serverVersion = null; instance = null; } public void reloadConf(CommandSender s) { + boolean cloudEnabled = this.expansionCloud != null; PlaceholderAPI.unregisterAllProvidedExpansions(); reloadConfig(); setupOptions(); @@ -180,70 +190,79 @@ public class PlaceholderAPIPlugin extends JavaPlugin { if (!config.isCloudEnabled()) { disableCloud(); - } else if (this.expansionCloud != null) { + } else if (!cloudEnabled) { enableCloud(); } - s.sendMessage(ChatColor.translateAlternateColorCodes('&', PlaceholderAPI.PLACEHOLDERS.size() + " &aplaceholder hooks successfully registered!")); + s.sendMessage(ChatColor.translateAlternateColorCodes('&', + PlaceholderAPI.getRegisteredIdentifiers().size() + + " &aplaceholder hooks successfully registered!")); } - @SuppressWarnings("deprecation") private void checkHook() { - for (PlaceholderHook hook : PlaceholderAPI.PLACEHOLDERS.values()) { - if (hook instanceof EZPlaceholderHook) { - String pluginName = ((EZPlaceholderHook) hook).getPluginName(); + Map loaded = PlaceholderAPI.getPlaceholders(); + + loaded.values().forEach(h -> { + if (h instanceof EZPlaceholderHook) { String author; try { - author = Bukkit.getPluginManager().getPlugin(pluginName).getDescription().getAuthors().toString(); + author = Bukkit.getPluginManager().getPlugin(((EZPlaceholderHook) h).getPluginName()).getDescription().getAuthors().toString(); } catch (Exception ex) { author = "the author of the hook's plugin"; } - getLogger().severe(pluginName + + getLogger().severe(((EZPlaceholderHook) h).getPluginName() + " is currently using a deprecated method to hook into PlaceholderAPI. Placeholders for that plugin no longer work. " + - "Please consult " + author + " and urge them to update it ASAP."); + "Please consult {author} and urge them to update it ASAP.".replace("{author}", author)); // disable the hook on startup - PlaceholderAPI.unregisterPlaceholderHook(((EZPlaceholderHook) hook).getPlaceholderName()); + PlaceholderAPI.unregisterPlaceholderHook(((EZPlaceholderHook) h).getPlaceholderName()); } - } + }); } private void setupOptions() { booleanTrue = config.booleanTrue(); - if (booleanTrue == null) booleanTrue = "true"; + + if (booleanTrue == null) { + booleanTrue = "true"; + } booleanFalse = config.booleanFalse(); - if (booleanFalse == null) booleanFalse = "false"; + + if (booleanFalse == null) { + booleanFalse = "false"; + } try { - dateFormat = DateTimeFormatter.ofPattern(config.dateFormat()); - } catch (Exception ignored) { - dateFormat = DateTimeFormatter.ofPattern("MM/dd/yy HH:mm:ss"); + dateFormat = new SimpleDateFormat(config.dateFormat()); + } catch (Exception e) { + dateFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss"); } } private void setupMetrics() { - // This is NOT the plugin resource ID. it's the bStats ID. - Metrics metrics = new Metrics(this, 438); - metrics.addCustomChart(new Metrics.SimplePie("using_expansion_cloud", - () -> getExpansionCloud() != null ? "yes" : "no")); + Metrics m = new Metrics(this); + m.addCustomChart(new Metrics.SimplePie("using_expansion_cloud", () -> getExpansionCloud() != null ? "yes" : "no")); - metrics.addCustomChart(new Metrics.SimplePie("using_spigot", - () -> getServerVersion().isSpigot() ? "yes" : "no")); + m.addCustomChart(new Metrics.SimplePie("using_spigot", () -> getServerVersion().isSpigot() ? "yes" : "no")); - metrics.addCustomChart(new Metrics.AdvancedPie("expansions_used", () -> { + m.addCustomChart(new Metrics.AdvancedPie("expansions_used", () -> { Map map = new HashMap<>(); - for (PlaceholderHook hook : PlaceholderAPI.PLACEHOLDERS.values()) { - if (hook.isExpansion()) { - PlaceholderExpansion ex = (PlaceholderExpansion) hook; - map.put(ex.getRequiredPlugin() == null ? ex.getIdentifier() - : ex.getRequiredPlugin(), 1); + Map hooks = PlaceholderAPI.getPlaceholders(); + + if (!hooks.isEmpty()) { + + for (PlaceholderHook hook : hooks.values()) { + if (hook instanceof PlaceholderExpansion) { + PlaceholderExpansion expansion = (PlaceholderExpansion) hook; + map.put(expansion.getRequiredPlugin() == null ? expansion.getIdentifier() : expansion.getRequiredPlugin(), 1); + } } } - return map; + })); } @@ -257,7 +276,10 @@ public class PlaceholderAPIPlugin extends JavaPlugin { } public void disableCloud() { - if (expansionCloud != null) expansionCloud = null; + if (expansionCloud != null) { + expansionCloud.clean(); + expansionCloud = null; + } } /** @@ -283,6 +305,6 @@ public class PlaceholderAPIPlugin extends JavaPlugin { } public long getUptimeMillis() { - return System.currentTimeMillis() - startTime; + return (System.currentTimeMillis() - startTime); } } diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderHook.java b/src/main/java/me/clip/placeholderapi/PlaceholderHook.java index c1ea2c5..e41e68d 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderHook.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderHook.java @@ -20,14 +20,13 @@ */ package me.clip.placeholderapi; -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import me.clip.placeholderapi.expansion.Relational; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; public abstract class PlaceholderHook { + /** - * Called when a placeholder value is requested from this hook. + * called when a placeholder value is requested from this hook * * @param player {@link OfflinePlayer} to request the placeholder value for, null if not needed for a * player @@ -42,12 +41,8 @@ public abstract class PlaceholderHook { return onPlaceholderRequest(null, params); } - public PlaceholderAPIPlugin getPlaceholderAPI() { - return PlaceholderAPIPlugin.getInstance(); - } - /** - * Called when a placeholder is requested from this hook. + * called when a placeholder is requested from this hook * * @param player {@link Player} to request the placeholder value for, null if not needed for a player * @param params String passed to the hook to determine what value to return @@ -56,12 +51,4 @@ public abstract class PlaceholderHook { public String onPlaceholderRequest(Player player, String params) { return null; } - - public boolean isExpansion() { - return this instanceof PlaceholderExpansion; - } - - public boolean isRelational() { - return this instanceof Relational; - } } diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderReplacer.java b/src/main/java/me/clip/placeholderapi/PlaceholderReplacer.java deleted file mode 100644 index c29d0e4..0000000 --- a/src/main/java/me/clip/placeholderapi/PlaceholderReplacer.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * PlaceholderAPI - * Copyright (C) 2019 Ryan McCarthy - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package me.clip.placeholderapi; - -import com.google.common.collect.ImmutableSet; -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import org.bukkit.ChatColor; -import org.bukkit.OfflinePlayer; - -import java.util.Set; - -/** - * This is certainly hard to understand and maintain, but it's fully optimized. - * It's almost x5 times faster than the RegEx method for normal sized strings. This performance gap gets smaller - * for smaller strings. - * - * @author Crypto Morin - */ -public class PlaceholderReplacer { - /** - * Cached available color codes. Technically the uppercase of each letter can be used too, but no one really uses the uppercase ones. - */ - private static final Set COLOR_CODES = ImmutableSet.of('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f', 'k', 'l', 'm', 'o', 'r', 'x'); - - /** - * Translates placeholders for a string using pure character loops. - * Might cause problems in really rare conditions. - * - * @param player the player to translate the string for. - * @param str the string to translate. - * @param closure the type of the placeholder closing points. - * @param colorize if this message should be colorized as well. - * @return a translated string. - */ - public static String evaluatePlaceholders(OfflinePlayer player, String str, Closure closure, boolean colorize) { - char[] chars = str.toCharArray(); - StringBuilder builder = new StringBuilder(chars.length); - - // This won't cause memory leaks. It's inside a method. And we want to use setLength instead of - // creating a new string builder to use the maximum capacity and avoid initializing new objects. - StringBuilder identifier = new StringBuilder(50); - PlaceholderHook handler = null; - - // Stages: - // Stage -1: Look for the color code in the next character. - // Stage 0: No closures detected, or the detected identifier is invalid. We're going forward while appending the characters normally. - // Stage 1: The closure has been detected, looking for the placeholder identifier... - // Stage 2: Detected the identifier and the parameter. Translating the placeholder... - int stage = 0; - - for (char ch : chars) { - if (stage == -1 && COLOR_CODES.contains(ch)) { - builder.append(ChatColor.COLOR_CHAR).append(ch); - stage = 0; - continue; - } - - // Check if the placeholder starts or ends. - if (ch == closure.start || ch == closure.end) { - // If the placeholder ends. - if (stage == 2) { - String parameter = identifier.toString(); - String translated = handler.onRequest(player, parameter); - - if (translated == null) { - String name = handler.isExpansion() ? ((PlaceholderExpansion) handler).getIdentifier() : ""; - builder.append(closure.start).append(name).append('_').append(parameter).append(closure.end); - } else builder.append(translated); - - identifier.setLength(0); - stage = 0; - continue; - } else if (stage == 1) { // If it just started | Double closures | If it's still hasn't detected the indentifier, reset. - builder.append(closure.start).append(identifier); - } - - identifier.setLength(0); - stage = 1; - continue; - } - - // Placeholder identifier started. - if (stage == 1) { - // Compare the current character with the idenfitier's. - // We reached the end of our identifier. - if (ch == '_') { - handler = PlaceholderAPI.PLACEHOLDERS.get(identifier.toString()); - if (handler == null) { - builder.append(closure.start).append(identifier).append('_'); - stage = 0; - } else { - identifier.setLength(0); - stage = 2; - } - continue; - } - - // Keep building the identifier name. - identifier.append(ch); - continue; - } - - // Building the placeholder parameter. - if (stage == 2) { - identifier.append(ch); - continue; - } - - // Nothing placeholder related was found. - if (colorize && ch == '&') { - stage = -1; - continue; - } - builder.append(ch); - } - - if (identifier != null) { - if (stage > 0) builder.append(closure.end); - builder.append(identifier); - } - return builder.toString(); - } - - public enum Closure { - PERCENT('%', '%'), BRACKETS('[', ']'), BRACES('{', '}'); - - public char start, end; - - Closure(char start, char end) { - this.start = start; - this.end = end; - } - } -} diff --git a/src/main/java/me/clip/placeholderapi/commands/Command.java b/src/main/java/me/clip/placeholderapi/commands/Command.java index f7310aa..531c8be 100644 --- a/src/main/java/me/clip/placeholderapi/commands/Command.java +++ b/src/main/java/me/clip/placeholderapi/commands/Command.java @@ -1,42 +1,52 @@ package me.clip.placeholderapi.commands; +import com.google.common.collect.ImmutableSet; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; +import java.util.Set; public abstract class Command { - private static final Options EMPTY_OPTIONS = new Options(null, 0); + private static final Options EMPTY_OPTIONS = new Options(null, 0, null); private final String match; private final String usage; private final int minimumArguments; - /** - * Commands should not have multiple permissions. This can lead to a lot of confusions. - * This is also a lot more appropriate for maintainability, I saw a lot of commands regitered with wrong permissions. - * We will use the main command name to parse our permission. - */ - private final String permission; + private final Set permissions; - protected Command(String match) { + protected Command(@NotNull final String match) { this(match, EMPTY_OPTIONS); } - protected Command(String match, Options options) { + protected Command(@NotNull final String match, @NotNull final Options options) { this.match = match; this.usage = options.usage == null ? "/papi " + match + " [optional args]" : options.usage; - this.permission = "placeholderapi." + match.replace(' ', '.'); + this.permissions = options.permissions == null ? Collections.emptySet() : ImmutableSet.copyOf(options.permissions); this.minimumArguments = options.minimumArguments; } - protected static Options options(String usage, int minimumArguments) { - return new Options(usage, minimumArguments); + protected static Options usage(@NotNull final String usage, final int minimumArguments) { + return new Options(usage, minimumArguments, null); } + protected static Options permissions(@NotNull final String... permissions) { + return new Options(null, 0, permissions); + } + + protected static Options options(@NotNull final String usage, final int minimumArguments, + @NotNull final String... permissions) { + return new Options(usage, minimumArguments, permissions); + } + + @NotNull public String getMatch() { return match; } + @NotNull public String getUsage() { return usage; } @@ -45,23 +55,28 @@ public abstract class Command { return minimumArguments; } - public String getPermission() { - return permission; + @NotNull + public Set getPermissions() { + return permissions; } - public abstract void execute(CommandSender sender, String[] args); + public abstract void execute(@NotNull final CommandSender sender, @NotNull final String[] args); - public List handleCompletion(CommandSender sender, String[] args) { + @NotNull + public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { return Collections.emptyList(); } private static class Options { private final String usage; private final int minimumArguments; + private final String[] permissions; - private Options(String usage, int minimumArguments) { + private Options(@Nullable final String usage, final int minimumArguments, + @Nullable final String[] permissions) { this.usage = usage; this.minimumArguments = minimumArguments; + this.permissions = permissions; } } } diff --git a/src/main/java/me/clip/placeholderapi/commands/CommandHandler.java b/src/main/java/me/clip/placeholderapi/commands/CommandHandler.java index 36c7d87..12374cd 100644 --- a/src/main/java/me/clip/placeholderapi/commands/CommandHandler.java +++ b/src/main/java/me/clip/placeholderapi/commands/CommandHandler.java @@ -1,33 +1,25 @@ package me.clip.placeholderapi.commands; import com.google.common.collect.Lists; +import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.command.*; +import me.clip.placeholderapi.commands.command.ecloud.EcloudInfoCommand; +import me.clip.placeholderapi.commands.command.ecloud.EcloudListCommand; import me.clip.placeholderapi.commands.command.ecloud.*; import me.clip.placeholderapi.util.Msg; -import org.apache.commons.lang.StringUtils; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import java.util.List; +import java.util.Objects; import java.util.Optional; +import java.util.regex.Pattern; public final class CommandHandler implements CommandExecutor { private static final Command DEFAULT = new VersionCommand(); - protected static final List COMMANDS = Lists.newArrayList( - DEFAULT, - new HelpCommand(), - new InfoCommand(), - new ListCommand(), - new RegisterCommand(), - new UnregisterCommand(), - new ReloadCommand(), - new BcParseCommand(), - new ParseCommand(), - new ParseRelCommand(), - - new EcloudCommand(), + private static final List COMMANDS = Lists.newArrayList( new EcloudClearCommand(), new EcloudDownloadCommand(), new EcloudInfoCommand(), @@ -36,57 +28,74 @@ public final class CommandHandler implements CommandExecutor { new EcloudRefreshCommand(), new EcloudStatusCommand(), new EcloudVersionInfoCommand(), - new EcloudDisableCommand(), - new EcloudEnableCommand() + new EcloudCommand(), + new BcParseCommand(), + new ParseCommand(), + new ParseRelCommand(), + new DisableEcloudCommand(), + new EnableCloudCommand(), + new HelpCommand(), + new InfoCommand(), + new ListCommand(), + new RegisterCommand(), + new ReloadCommand(), + DEFAULT, + new UnregisterCommand() ); static { COMMANDS.sort((command1, command2) -> { - int comparison = Integer.compare(command1.getMatch().length(), command2.getMatch().length()); + final int comparison = Integer.compare(command1.getMatch().length(), command2.getMatch().length()); if (comparison == 1) return -1; if (comparison == -1) return 1; return 0; }); + Objects.requireNonNull(PlaceholderAPIPlugin.getInstance().getCommand("placeholderapi")) + .setTabCompleter(new CompletionHandler(COMMANDS)); } - private static String[] splitArguments(String joinedArguments, String command) { - joinedArguments = StringUtils.remove(joinedArguments, command).trim(); - String[] args = StringUtils.split(joinedArguments); - return args.length == 1 && args[0].isEmpty() ? new String[0] : args; - } + private static final Pattern SPACE_PATTERN = Pattern.compile(" "); @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull org.bukkit.command.Command bukkitCommand, @NotNull String name, String[] args) { + public boolean onCommand(@NotNull final CommandSender sender, @NotNull final org.bukkit.command.Command bukkitCommand, + @NotNull final String name, @NotNull String[] args) { if (args.length == 0) { DEFAULT.execute(sender, args); return true; } - String joined = String.join(" ", args).toLowerCase(); - Optional optional = COMMANDS.stream() + final String joined = String.join(" ", args).toLowerCase(); + final Optional optional = COMMANDS.stream() .filter(command -> joined.startsWith(command.getMatch())) .findFirst(); if (!optional.isPresent()) { - Msg.msg(sender, "&cUnknown command."); + sender.sendMessage("Specified command is not valid."); return true; } - Command command = optional.get(); - String permission = command.getPermission(); - if (!sender.hasPermission(permission)) { - Msg.msg(sender, "&cYou do not have the permission to use this command."); + final Command command = optional.get(); + + if (!command.getPermissions().isEmpty() && command.getPermissions().stream().noneMatch(sender::hasPermission)) { + sender.sendMessage("You do not have the permission to execute specified command."); return true; } args = splitArguments(joined, command.getMatch()); + if (args.length < command.getMinimumArguments()) { Msg.msg(sender, command.getUsage()); return true; } command.execute(sender, args); + return true; } + + static String[] splitArguments(@NotNull final String joinedArguments, @NotNull final String command) { + final String[] args = SPACE_PATTERN.split(joinedArguments.replace(command, "").trim()); + return args.length == 1 && args[0].isEmpty() ? new String[]{} : args; + } } diff --git a/src/main/java/me/clip/placeholderapi/commands/CompletionHandler.java b/src/main/java/me/clip/placeholderapi/commands/CompletionHandler.java index a42177c..a48173f 100644 --- a/src/main/java/me/clip/placeholderapi/commands/CompletionHandler.java +++ b/src/main/java/me/clip/placeholderapi/commands/CompletionHandler.java @@ -1,37 +1,32 @@ package me.clip.placeholderapi.commands; -import org.apache.commons.lang.StringUtils; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; import org.jetbrains.annotations.NotNull; -import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.Locale; -import java.util.stream.Collectors; +import java.util.Optional; public final class CompletionHandler implements TabCompleter { - private static String[] splitArguments(String[] args, String command) { - int skip = StringUtils.split(command).length; - return Arrays.stream(args).skip(skip).toArray(String[]::new); + private final List commands; + + CompletionHandler(@NotNull final List commands) { + this.commands = commands; } // it makes me physically cringe trying to understand why bukkit uses a list instead of a set for this - // It's because of the list order. Even if they wanted to change that, they couldn't for the sake of backward compatibility. ~Crypto + @NotNull @Override - public List onTabComplete(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command bukkitCommand, @NotNull String name, String[] args) { - String joined = String.join(" ", args).toLowerCase(Locale.ENGLISH); + public List onTabComplete(@NotNull final CommandSender sender, @NotNull final org.bukkit.command.Command bukkitCommand, + @NotNull final String name, @NotNull final String[] args) { + final String joined = String.join(" ", args).toLowerCase(); + final Optional optional = commands.stream() + .filter(command -> joined.startsWith(command.getMatch())) + .findAny(); - if (args.length > 1) { - return CommandHandler.COMMANDS.stream() - .filter(command -> sender.hasPermission(command.getPermission()) && joined.startsWith(command.getMatch())) - .findFirst() - .map(command -> command.handleCompletion(sender, splitArguments(args, command.getMatch()))) - .orElse(Collections.emptyList()); - } - return CommandHandler.COMMANDS.stream() - .filter(command -> sender.hasPermission(command.getPermission()) && (args[0].isEmpty() || command.getMatch().startsWith(joined))) - .map(Command::getMatch).collect(Collectors.toList()); + return optional + .map(command -> command.handleCompletion(sender, CommandHandler.splitArguments(joined, command.getMatch()))) + .orElse(Collections.emptyList()); } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/BcParseCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/BcParseCommand.java index e356389..8808dc3 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/BcParseCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/BcParseCommand.java @@ -8,34 +8,40 @@ import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; public final class BcParseCommand extends Command { public BcParseCommand() { - super("bcparse", options("&cYou must specify a player.", 1)); + super("bcparse", options("&cYou must specify a player.", 1, "placeholderapi.parse")); } @Override - public void execute(CommandSender sender, String[] args) { - OfflinePlayer player; - String input = args[0]; + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final OfflinePlayer player; + final String input = args[0]; if (input.equalsIgnoreCase("me")) { if (sender instanceof Player) { player = (Player) sender; } else { Msg.msg(sender, "&cThis command must target a player when used by console"); + return; } } else { - player = Bukkit.getPlayer(input); - if (player == null) player = Bukkit.getOfflinePlayer(input); - if (player == null || !player.hasPlayedBefore()) { - Msg.msg(sender, "&cCould not find player&8: &f" + input); - return; + if (Bukkit.getPlayer(input) != null) { + player = Bukkit.getPlayer(input); + } else { + player = Bukkit.getOfflinePlayer(input); } } - String parse = StringUtils.join(args, " ", 2, args.length); + if (player == null || !player.hasPlayedBefore()) { + Msg.msg(sender, "&cFailed to find player: &f" + input); + return; + } + + final String parse = StringUtils.join(args, " ", 2, args.length); Msg.broadcast("&r" + PlaceholderAPI.setPlaceholders(player, parse)); } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDisableCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/DisableEcloudCommand.java similarity index 53% rename from src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDisableCommand.java rename to src/main/java/me/clip/placeholderapi/commands/command/DisableEcloudCommand.java index bc9fcfe..9e2e841 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDisableCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/DisableEcloudCommand.java @@ -1,25 +1,29 @@ -package me.clip.placeholderapi.commands.command.ecloud; +package me.clip.placeholderapi.commands.command; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; -public final class EcloudDisableCommand extends Command { - public EcloudDisableCommand() { - super("ecloud disable"); +public final class DisableEcloudCommand extends Command { + public DisableEcloudCommand() { + super("disablecloud", permissions("placeholderapi.ecloud")); } @Override - public void execute(CommandSender sender, String[] args) { - PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); if (plugin.getExpansionCloud() == null) { Msg.msg(sender, "&7The cloud is already disabled!"); + return; } plugin.disableCloud(); plugin.getPlaceholderAPIConfig().setCloudEnabled(false); Msg.msg(sender, "&aThe cloud has been disabled!"); + + return; } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/EcloudCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/EcloudCommand.java index 351930d..b37899e 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/EcloudCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/EcloudCommand.java @@ -6,6 +6,7 @@ import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; import org.bukkit.util.StringUtil; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -21,18 +22,16 @@ public final class EcloudCommand extends Command { "placeholders", "refresh", "status", - "versioninfo", - "enable", - "disable" + "versioninfo" ); public EcloudCommand() { - super("ecloud"); + super("ecloud", permissions("placeholderapi.ecloud")); } @Override - public void execute(CommandSender sender, String[] args) { - PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); if (args.length == 0) { Msg.msg(sender, "&bExpansion cloud commands", @@ -58,6 +57,7 @@ public final class EcloudCommand extends Command { if (plugin.getExpansionCloud() == null) { Msg.msg(sender, "&7The expansion cloud is not enabled!"); + return; } @@ -69,9 +69,9 @@ public final class EcloudCommand extends Command { sender.sendMessage("Specified command is not valid."); } - + @NotNull @Override - public List handleCompletion(CommandSender sender, String[] args) { + public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { if (args.length == MAXIMUM_ARGUMENTS) { return StringUtil.copyPartialMatches(args[0], COMPLETIONS, new ArrayList<>(COMPLETIONS.size())); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudEnableCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/EnableCloudCommand.java similarity index 54% rename from src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudEnableCommand.java rename to src/main/java/me/clip/placeholderapi/commands/command/EnableCloudCommand.java index 8c1dd1e..f82ce4e 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudEnableCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/EnableCloudCommand.java @@ -1,20 +1,22 @@ -package me.clip.placeholderapi.commands.command.ecloud; +package me.clip.placeholderapi.commands.command; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; -public final class EcloudEnableCommand extends Command { - public EcloudEnableCommand() { - super("ecloud enable"); +public final class EnableCloudCommand extends Command { + public EnableCloudCommand() { + super("enablecloud", permissions("placeholderapi.ecloud")); } @Override - public void execute(CommandSender sender, String[] args) { - PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); if (plugin.getExpansionCloud() != null) { Msg.msg(sender, "&7The cloud is already enabled!"); + return; } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/HelpCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/HelpCommand.java index 49654f7..0ef952f 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/HelpCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/HelpCommand.java @@ -4,14 +4,15 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; public final class HelpCommand extends Command { public HelpCommand() { - super("help"); + super("help", permissions("placeholderapi.ecloud")); } @Override - public void execute(CommandSender sender, String[] args) { + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { Msg.msg(sender, "PlaceholderAPI &aHelp &e(&f" + PlaceholderAPIPlugin.getInstance().getDescription().getVersion() + "&e)", "&b/papi", "&fView plugin info/version info", diff --git a/src/main/java/me/clip/placeholderapi/commands/command/InfoCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/InfoCommand.java index acec7b5..8987932 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/InfoCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/InfoCommand.java @@ -7,6 +7,7 @@ import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; import org.bukkit.util.StringUtil; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -16,13 +17,13 @@ public final class InfoCommand extends Command { private static final int MINIMUM_ARGUMENTS = 1; public InfoCommand() { - super("info", options("&cIncorrect usage! &7/papi info ", MINIMUM_ARGUMENTS)); + super("info", options("&cIncorrect usage! &7/papi info ", MINIMUM_ARGUMENTS, "placeholderapi.info")); } @Override - public void execute(CommandSender sender, String[] args) { - String requestedExpansion = args[0]; - PlaceholderExpansion ex = PlaceholderAPIPlugin.getInstance().getExpansionManager().getRegisteredExpansion(requestedExpansion); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final String requestedExpansion = args[0]; + final PlaceholderExpansion ex = PlaceholderAPIPlugin.getInstance().getExpansionManager().getRegisteredExpansion(requestedExpansion); if (ex == null) { Msg.msg(sender, "&cThere is no expansion loaded with the identifier: &f" + requestedExpansion); @@ -53,11 +54,11 @@ public final class InfoCommand extends Command { } } - + @NotNull @Override - public List handleCompletion(CommandSender sender, String[] args) { + public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { if (args.length == MINIMUM_ARGUMENTS) { - Set completions = PlaceholderAPI.getRegisteredIdentifiers(); + final Set completions = PlaceholderAPI.getRegisteredIdentifiers(); return StringUtil.copyPartialMatches(args[0], completions, new ArrayList<>(completions.size())); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ListCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ListCommand.java index b9e64aa..ba8aa66 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ListCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ListCommand.java @@ -4,18 +4,19 @@ import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; import java.util.Set; import java.util.stream.Collectors; public final class ListCommand extends Command { public ListCommand() { - super("list"); + super("list", permissions("placeholderapi.list")); } @Override - public void execute(CommandSender sender, String[] args) { - Set registered = PlaceholderAPI.getRegisteredIdentifiers(); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final Set registered = PlaceholderAPI.getRegisteredIdentifiers(); if (registered.isEmpty()) { Msg.msg(sender, "&7There are no placeholder hooks currently registered!"); return; diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ParseCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ParseCommand.java index fae842c..4166a47 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ParseCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ParseCommand.java @@ -7,53 +7,41 @@ import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; -import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; +import org.jetbrains.annotations.NotNull; public final class ParseCommand extends Command { public ParseCommand() { - super("parse", options("&cYou must specify a player.", 1)); + super("parse", options("&cYou must specify a player.", 1, "placeholderapi.parse")); } @Override - public void execute(CommandSender sender, String[] args) { - OfflinePlayer player; - String input = args[0]; + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final OfflinePlayer player; + final String input = args[0]; if (input.equalsIgnoreCase("me")) { if (sender instanceof Player) { player = (Player) sender; } else { Msg.msg(sender, "&cThis command must target a player when used by console"); + return; } } else { - player = Bukkit.getPlayer(input); - if (player == null) player = Bukkit.getOfflinePlayer(input); - if (player == null || !player.hasPlayedBefore()) { - Msg.msg(sender, "&cCould not find player&8: &f" + input); - return; + if (Bukkit.getPlayer(input) != null) { + player = Bukkit.getPlayer(input); + } else { + player = Bukkit.getOfflinePlayer(input); } } - String parse = StringUtils.join(args, " ", 1, args.length); + if (player == null || !player.hasPlayedBefore()) { + Msg.msg(sender, "&cFailed to find player: &f" + input); + return; + } + + final String parse = StringUtils.join(args, " ", 1, args.length); Msg.msg(sender, "&r" + PlaceholderAPI.setPlaceholders(player, parse)); } - - @Override - public List handleCompletion(CommandSender sender, String[] args) { - if (args.length == 1) { - List players = Bukkit.getOnlinePlayers().stream().map(HumanEntity::getName).collect(Collectors.toList()); - players.add("me"); - if (args[0].isEmpty()) return players; - else return players.stream().filter(name -> name.startsWith(args[0])).collect(Collectors.toList()); - } - if (args.length == 2) return Collections.singletonList(""); - return new ArrayList<>(); - } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ParseRelCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ParseRelCommand.java index 7184edd..20afb90 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ParseRelCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ParseRelCommand.java @@ -7,27 +7,30 @@ import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; public final class ParseRelCommand extends Command { public ParseRelCommand() { - super("parserel", options("&cYou must specify at least two players.", 2)); + super("parserel", options("&cYou must specify at least two players.", 2, "placeholderapi.parse")); } @Override - public void execute(CommandSender sender, String[] args) { - Player one = Bukkit.getPlayer(args[0]); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final Player one = Bukkit.getPlayer(args[0]); if (one == null) { Msg.msg(sender, args[0] + " &cis not online!"); + return; } - Player two = Bukkit.getPlayer(args[1]); + final Player two = Bukkit.getPlayer(args[1]); if (two == null) { Msg.msg(sender, args[1] + " &cis not online!"); + return; } - String parse = StringUtils.join(args, " ", 1, args.length); + final String parse = StringUtils.join(args, " ", 1, args.length); Msg.msg(sender, "&r" + PlaceholderAPI.setRelationalPlaceholders(one, two, parse)); } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/RegisterCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/RegisterCommand.java index aff9783..6df7b74 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/RegisterCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/RegisterCommand.java @@ -4,21 +4,22 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.util.Msg; -import org.apache.commons.lang.StringUtils; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; public final class RegisterCommand extends Command { public RegisterCommand() { - super("register", options("&cAn expansion file name must be specified!", 1)); + super("register", options("&cAn expansion file name must be specified!", 1,"placeholderapi.register")); } @Override - public void execute(CommandSender sender, String[] args) { - String fileName = StringUtils.remove(args[0], ".jar"); - PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionManager().registerExpansion(fileName); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final String fileName = args[0].replace(".jar", ""); + final PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionManager().registerExpansion(fileName); if (expansion == null) { Msg.msg(sender, "&cFailed to register expansion from " + fileName); + return; } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ReloadCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ReloadCommand.java index bed04a1..cf01301 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ReloadCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ReloadCommand.java @@ -4,14 +4,15 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; public final class ReloadCommand extends Command { public ReloadCommand() { - super("reload"); + super("reload", permissions("placeholderapi.reload")); } @Override - public void execute(CommandSender sender, String[] args) { + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { Msg.msg(sender, "&fPlaceholder&7API &bconfiguration reloaded!"); PlaceholderAPIPlugin.getInstance().reloadConf(sender); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/UnregisterCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/UnregisterCommand.java index 51c61d4..b20657e 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/UnregisterCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/UnregisterCommand.java @@ -7,6 +7,7 @@ import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; import org.bukkit.util.StringUtil; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -16,17 +17,18 @@ public final class UnregisterCommand extends Command { private static final int MINIMUM_ARGUMENTS = 1; public UnregisterCommand() { - super("unregister", options("&cAn expansion name must be specified!", MINIMUM_ARGUMENTS)); + super("unregister", options("&cAn expansion name must be specified!", MINIMUM_ARGUMENTS, "placeholderapi.register")); } @Override - public void execute(CommandSender sender, String[] args) { - String requestedExpansion = args[0]; - PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionManager() + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final String requestedExpansion = args[0]; + final PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionManager() .getRegisteredExpansion(requestedExpansion); if (expansion == null) { Msg.msg(sender, "&cFailed to find expansion: &f" + requestedExpansion); + return; } @@ -37,11 +39,12 @@ public final class UnregisterCommand extends Command { } } - + @NotNull @Override - public List handleCompletion(CommandSender sender, String[] args) { + public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { if (args.length == MINIMUM_ARGUMENTS) { - Set completions = PlaceholderAPI.getRegisteredIdentifiers(); + final Set completions = PlaceholderAPI.getRegisteredIdentifiers(); + return StringUtil.copyPartialMatches(args[0], completions, new ArrayList<>(completions.size())); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/VersionCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/VersionCommand.java index 0f37c52..efab041 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/VersionCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/VersionCommand.java @@ -7,6 +7,7 @@ import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.util.StringUtil; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -33,8 +34,8 @@ public final class VersionCommand extends Command { } @Override - public void execute(CommandSender sender, String[] args) { - PluginDescriptionFile description = PlaceholderAPIPlugin.getInstance().getDescription(); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final PluginDescriptionFile description = PlaceholderAPIPlugin.getInstance().getDescription(); Msg.msg(sender, "PlaceholderAPI &7version &b&o" + description.getVersion(), "&fCreated by&7: &b" + description.getAuthors(), @@ -42,9 +43,9 @@ public final class VersionCommand extends Command { "&fEcloud commands: &b/papi ecloud"); } - + @NotNull @Override - public List handleCompletion(CommandSender sender, String[] args) { + public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { if (args.length == 1) { return StringUtil.copyPartialMatches(args[0], COMPLETIONS, new ArrayList<>(COMPLETIONS.size())); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudClearCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudClearCommand.java index 6143ff0..3a77d89 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudClearCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudClearCommand.java @@ -4,14 +4,15 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; public final class EcloudClearCommand extends Command { public EcloudClearCommand() { - super("ecloud clear"); + super("ecloud clear", permissions("placeholderapi.ecloud")); } @Override - public void execute(CommandSender sender, String[] args) { + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { PlaceholderAPIPlugin.getInstance().getExpansionCloud().clean(); Msg.msg(sender, "&aThe cache has been cleared!!"); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDownloadCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDownloadCommand.java index ed11e3c..d9bac27 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDownloadCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudDownloadCommand.java @@ -9,24 +9,25 @@ import me.clip.placeholderapi.expansion.cloud.ExpansionCloudManager; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; public final class EcloudDownloadCommand extends Command { public EcloudDownloadCommand() { - super("ecloud download", options("&cAn expansion name must be specified!", 1)); + super("ecloud download", options("&cAn expansion name must be specified!", 1, "placeholderapi.ecloud")); } @Override - public void execute(CommandSender sender, String[] args) { - PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); - String input = args[0]; - CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(input); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + final String input = args[0]; + final CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(input); if (expansion == null) { Msg.msg(sender, "&cNo expansion found with the name: &f" + input); return; } - PlaceholderExpansion loaded = plugin.getExpansionManager().getRegisteredExpansion(input); + final PlaceholderExpansion loaded = plugin.getExpansionManager().getRegisteredExpansion(input); if (loaded != null && loaded.isRegistered()) { PlaceholderAPI.unregisterPlaceholderHook(loaded.getIdentifier()); } @@ -45,23 +46,10 @@ public final class EcloudDownloadCommand extends Command { } Msg.msg(sender, "&aDownload starting for expansion: &f" + expansion.getName() + " &aversion: &f" + version); - String player = ((sender instanceof Player) ? sender.getName() : null); - ExpansionCloudManager cloud = plugin.getExpansionCloud(); + final String player = ((sender instanceof Player) ? sender.getName() : null); + final ExpansionCloudManager cloud = plugin.getExpansionCloud(); cloud.downloadExpansion(player, expansion, version); cloud.clean(); cloud.fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions()); } - -// @Override -// public List handleCompletion(CommandSender sender, String[] args) { -// List downloads = new ArrayList<>(); -// if (!PlaceholderAPI.isRegistered("player")) downloads.add("player"); -// -// for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { -// String identifier = plugin.getName(); -// if (!PlaceholderAPI.isRegistered(identifier)) downloads.add(identifier); -// } -// -// return downloads; -// } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudInfoCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudInfoCommand.java index 13c7e7f..de40e0b 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudInfoCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudInfoCommand.java @@ -7,18 +7,19 @@ import me.clip.placeholderapi.util.Msg; import me.rayzr522.jsonmessage.JSONMessage; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; import static me.clip.placeholderapi.util.Msg.color; public final class EcloudInfoCommand extends Command { public EcloudInfoCommand() { - super("ecloud info", options("&cAn expansion name must be specified!", 1)); + super("ecloud info", options("&cAn expansion name must be specified!", 1, "placeholderapi.ecloud")); } @Override - public void execute(CommandSender sender, String[] args) { - String input = args[0]; - CloudExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionCloud().getCloudExpansion(input); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final String input = args[0]; + final CloudExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionCloud().getCloudExpansion(input); if (expansion == null) { Msg.msg(sender, "&cNo expansion found by the name: &f" + input); @@ -34,7 +35,7 @@ public final class EcloudInfoCommand extends Command { return; } - Player p = (Player) sender; + final Player p = (Player) sender; Msg.msg(sender, "&bExpansion&7: &f" + expansion.getName(), "&bAuthor: &f" + expansion.getAuthor(), @@ -42,7 +43,7 @@ public final class EcloudInfoCommand extends Command { ); // latest version - JSONMessage latestVersion = JSONMessage + final JSONMessage latestVersion = JSONMessage .create(color("&bLatest version: &f" + expansion.getLatestVersion())); latestVersion.tooltip(color("&bReleased: &f" + expansion.getTimeSinceLastUpdate() + "\n&bUpdate information: &f" + expansion.getVersion().getReleaseNotes() @@ -50,7 +51,7 @@ public final class EcloudInfoCommand extends Command { latestVersion.send(p); // versions - JSONMessage versions = JSONMessage + final JSONMessage versions = JSONMessage .create(color("&bVersions available: &f" + expansion.getVersions().size())); versions.tooltip(color(String.join("&b, &f", expansion.getAvailableVersions()))); versions.suggestCommand( @@ -59,7 +60,7 @@ public final class EcloudInfoCommand extends Command { // placeholders if (expansion.getPlaceholders() != null) { - JSONMessage placeholders = JSONMessage + final JSONMessage placeholders = JSONMessage .create(color("&bPlaceholders: &f" + expansion.getPlaceholders().size())); placeholders.tooltip(color(String.join("&b, &f", expansion.getPlaceholders()))); placeholders.suggestCommand("/papi ecloud placeholders " + expansion.getName()); diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudListCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudListCommand.java index f12396d..adc545e 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudListCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudListCommand.java @@ -9,6 +9,7 @@ import me.rayzr522.jsonmessage.JSONMessage; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.util.StringUtil; +import org.jetbrains.annotations.NotNull; import java.util.*; import java.util.stream.Collectors; @@ -24,12 +25,13 @@ public final class EcloudListCommand extends Command { ); public EcloudListCommand() { - super("ecloud list", options("&cIncorrect usage! &7/papi ecloud list (page)", MINIMUM_ARGUMENTS)); + super("ecloud list", options("&cIncorrect usage! &7/papi ecloud list (page)", + MINIMUM_ARGUMENTS, "placeholderapi.ecloud")); } @Override - public void execute(CommandSender sender, String[] args) { - PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); int page = 1; String author; @@ -101,7 +103,7 @@ public final class EcloudListCommand extends Command { Msg.msg(sender, "&6Gold = Expansions which need updated"); if (!(sender instanceof Player)) { - Map expansions = new HashMap<>(); + final Map expansions = new HashMap<>(); for (CloudExpansion exp : ex.values()) { if (exp == null || exp.getName() == null) { @@ -111,7 +113,7 @@ public final class EcloudListCommand extends Command { expansions.put(exp.getName(), exp); } - List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); + final List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); int i = (int) ex.keySet().toArray()[0]; @@ -120,7 +122,7 @@ public final class EcloudListCommand extends Command { continue; } - CloudExpansion expansion = expansions.get(name); + final CloudExpansion expansion = expansions.get(name); Msg.msg(sender, "&b" + i + "&7: " + (expansion.shouldUpdate() ? "&6" @@ -132,11 +134,11 @@ public final class EcloudListCommand extends Command { return; } - Player p = (Player) sender; + final Player p = (Player) sender; - Map expansions = new HashMap<>(); + final Map expansions = new HashMap<>(); - for (CloudExpansion exp : ex.values()) { + for (final CloudExpansion exp : ex.values()) { if (exp == null || exp.getName() == null) { continue; } @@ -144,7 +146,7 @@ public final class EcloudListCommand extends Command { expansions.put(exp.getName(), exp); } - List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); + final List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); int i = page > 1 ? page * 10 : 0; @@ -153,8 +155,8 @@ public final class EcloudListCommand extends Command { continue; } - CloudExpansion expansion = expansions.get(name); - StringBuilder sb = new StringBuilder(); + final CloudExpansion expansion = expansions.get(name); + final StringBuilder sb = new StringBuilder(); if (expansion.shouldUpdate()) { sb.append("&6Click to update to the latest version of this expansion\n\n"); @@ -170,13 +172,13 @@ public final class EcloudListCommand extends Command { sb.append("&bLast updated&7: &f").append(expansion.getTimeSinceLastUpdate()).append(" ago\n"); sb.append("\n").append(expansion.getDescription()); - String msg = color( + final String msg = color( "&b" + (i + 1) + "&7: " + (expansion.shouldUpdate() ? "&6" : (expansion.hasExpansion() ? "&a" : "")) + expansion.getName()); - String hover = color(sb.toString()); + final String hover = color(sb.toString()); - JSONMessage line = JSONMessage.create(msg); + final JSONMessage line = JSONMessage.create(msg); line.tooltip(hover); if (expansion.shouldUpdate() || !expansion.hasExpansion()) { @@ -190,9 +192,9 @@ public final class EcloudListCommand extends Command { } } - + @NotNull @Override - public List handleCompletion(CommandSender sender, String[] args) { + public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { if (args.length == MINIMUM_ARGUMENTS) { return StringUtil.copyPartialMatches(args[0], COMPLETIONS, new ArrayList<>(COMPLETIONS.size())); } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudPlaceholdersCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudPlaceholdersCommand.java index e19f0e3..49ded05 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudPlaceholdersCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudPlaceholdersCommand.java @@ -8,26 +8,27 @@ import me.clip.placeholderapi.util.Msg; import me.rayzr522.jsonmessage.JSONMessage; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; import java.util.List; public final class EcloudPlaceholdersCommand extends Command { public EcloudPlaceholdersCommand() { - super("ecloud placeholders", options("&cAn expansion name must be specified!", 1)); + super("ecloud placeholders", options("&cAn expansion name must be specified!", 1, "placeholderapi.ecloud")); } @Override - public void execute(CommandSender sender, String[] args) { - PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); - String input = args[0]; - CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(input); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + final String input = args[0]; + final CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(input); if (expansion == null) { Msg.msg(sender, "&cNo expansion found by the name: &f" + input); return; } - List placeholders = expansion.getPlaceholders(); + final List placeholders = expansion.getPlaceholders(); if (placeholders == null) { Msg.msg(sender, "&cThe expansion: &f" + expansion.getName() + " &cdoes not have any placeholders listed.", @@ -44,15 +45,15 @@ public final class EcloudPlaceholdersCommand extends Command { return; } - Player p = (Player) sender; - JSONMessage message = JSONMessage.create(Msg.color("&bPlaceholders: &f" + placeholders.size())); + final Player p = (Player) sender; + final JSONMessage message = JSONMessage.create(Msg.color("&bPlaceholders: &f" + placeholders.size())); message.then("\n"); for (int i = 0; i < placeholders.size(); i++) { message.then(i == placeholders.size() - 1 ? placeholders.get(i) : Msg.color(placeholders.get(i) + "&b, &f")); try { message.tooltip(PlaceholderAPI.setPlaceholders(p, placeholders.get(i))); - } catch (Exception ignored) { + } catch (final Exception ignored) { // Ignored exception } } diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudRefreshCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudRefreshCommand.java index aaf9fd6..8e1dd8b 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudRefreshCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudRefreshCommand.java @@ -5,16 +5,17 @@ import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.expansion.cloud.ExpansionCloudManager; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; public final class EcloudRefreshCommand extends Command { public EcloudRefreshCommand() { - super("ecloud refresh"); + super("ecloud refresh", permissions("placeholderapi.ecloud")); } @Override - public void execute(CommandSender sender, String[] args) { - PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); - ExpansionCloudManager cloud = plugin.getExpansionCloud(); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + final ExpansionCloudManager cloud = plugin.getExpansionCloud(); Msg.msg(sender, "&aRefresh task started. Use &f/papi ecloud list all &ain a few!!"); cloud.clean(); cloud.fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions()); diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudStatusCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudStatusCommand.java index b505475..fa5eec6 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudStatusCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudStatusCommand.java @@ -4,15 +4,16 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.commands.Command; import me.clip.placeholderapi.util.Msg; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; public final class EcloudStatusCommand extends Command { public EcloudStatusCommand() { - super("ecloud status"); + super("ecloud status", permissions("placeholderapi.ecloud")); } @Override - public void execute(CommandSender sender, String[] args) { - PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); Msg.msg(sender, "&bThere are &f" + plugin.getExpansionCloud().getCloudExpansions().size() + " &bexpansions available on the cloud.", "&7A total of &f" + plugin.getExpansionCloud().getCloudAuthorCount() diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudVersionInfoCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudVersionInfoCommand.java index 7f2b6c7..59637ea 100644 --- a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudVersionInfoCommand.java +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/EcloudVersionInfoCommand.java @@ -7,22 +7,24 @@ import me.clip.placeholderapi.util.Msg; import me.rayzr522.jsonmessage.JSONMessage; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; public final class EcloudVersionInfoCommand extends Command { public EcloudVersionInfoCommand() { - super("ecloud versioninfo", options("&cIncorrect usage! &7/papi ecloud versioninfo ", 2)); + super("ecloud versioninfo", options("&cIncorrect usage! &7/papi ecloud versioninfo ", + 2, "placeholderapi.ecloud")); } @Override - public void execute(CommandSender sender, String[] args) { - String input = args[0]; - CloudExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionCloud().getCloudExpansion(input); + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final String input = args[0]; + final CloudExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionCloud().getCloudExpansion(input); if (expansion == null) { Msg.msg(sender, "&cNo expansion found by the name: &f" + input); return; } - CloudExpansion.Version version = expansion.getVersion(args[1]); + final CloudExpansion.Version version = expansion.getVersion(args[1]); if (version == null) { Msg.msg(sender, "&cThe version specified does not exist for expansion: &f" + expansion.getName()); return; @@ -37,10 +39,10 @@ public final class EcloudVersionInfoCommand extends Command { return; } - Player p = (Player) sender; - JSONMessage download = JSONMessage.create(Msg.color("&7Click to download this version")); + final Player p = (Player) sender; + final JSONMessage download = JSONMessage.create(Msg.color("&7Click to download this version")); download.suggestCommand( - "/papi ecloud download " + expansion.getName() + ' ' + version.getVersion()); + "/papi ecloud download " + expansion.getName() + " " + version.getVersion()); download.send(p); } } diff --git a/src/main/java/me/clip/placeholderapi/exceptions/NoDefaultCommandException.java b/src/main/java/me/clip/placeholderapi/exceptions/NoDefaultCommandException.java new file mode 100644 index 0000000..5e2a047 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/exceptions/NoDefaultCommandException.java @@ -0,0 +1,8 @@ +package me.clip.placeholderapi.exceptions; + +public final class NoDefaultCommandException extends RuntimeException { + public NoDefaultCommandException(final String message) { + super(message); + } +} + diff --git a/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java b/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java index b98c93f..a2560dd 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java @@ -28,6 +28,7 @@ package me.clip.placeholderapi.expansion; * @author Ryan McCarthy */ public interface Cacheable { + /** * Called when the implementing class is unregistered from PlaceholderAPI */ diff --git a/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java b/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java index 2616e0f..8bb798f 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java @@ -30,10 +30,11 @@ import org.bukkit.entity.Player; * @author Ryan McCarthy */ public interface Cleanable { + /** * Called when a player leaves the server * - * @param player (@link Player} who left the server + * @param p (@link Player} who left the server */ - void cleanup(Player player); + void cleanup(Player p); } diff --git a/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java b/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java index 22fe743..faa1f68 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java @@ -20,7 +20,6 @@ */ package me.clip.placeholderapi.expansion; -import com.google.common.base.Strings; import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderHook; @@ -42,13 +41,15 @@ public final class ExpansionManager { public ExpansionManager(PlaceholderAPIPlugin instance) { plugin = instance; - File f = new File(plugin.getDataFolder(), "expansions"); - if (!f.exists()) f.mkdirs(); + File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), "expansions"); + if (!f.exists()) { + f.mkdirs(); + } } public PlaceholderExpansion getRegisteredExpansion(String name) { for (Entry hook : PlaceholderAPI.getPlaceholders().entrySet()) { - if (hook.getValue().isExpansion()) { + if (hook.getValue() instanceof PlaceholderExpansion) { if (name.equalsIgnoreCase(hook.getKey())) { return (PlaceholderExpansion) hook.getValue(); } @@ -59,28 +60,31 @@ public final class ExpansionManager { } public boolean registerExpansion(PlaceholderExpansion expansion) { - if (expansion == null || expansion.getIdentifier() == null) return false; + if (expansion == null || expansion.getIdentifier() == null) { + return false; + } if (expansion instanceof Configurable) { Map defaults = ((Configurable) expansion).getDefaults(); - String pre = expansion.getPathStarter(); + String pre = "expansions." + expansion.getIdentifier() + "."; FileConfiguration cfg = plugin.getConfig(); boolean save = false; if (defaults != null) { - for (Entry entry : defaults.entrySet()) { - String key = entry.getKey(); - if (Strings.isNullOrEmpty(key)) continue; + for (Entry entries : defaults.entrySet()) { + if (entries.getKey() == null || entries.getKey().isEmpty()) { + continue; + } - if (entry.getValue() == null) { - if (cfg.contains(pre + key)) { + if (entries.getValue() == null) { + if (cfg.contains(pre + entries.getKey())) { save = true; - cfg.set(pre + key, null); + cfg.set(pre + entries.getKey(), null); } } else { - if (!cfg.contains(pre + key)) { + if (!cfg.contains(pre + entries.getKey())) { save = true; - cfg.set(pre + key, entry.getValue()); + cfg.set(pre + entries.getKey(), entries.getValue()); } } } @@ -103,11 +107,17 @@ public final class ExpansionManager { } } - if (!expansion.canRegister()) return false; - if (!expansion.register()) return false; + if (!expansion.canRegister()) { + return false; + } + + if (!expansion.register()) { + return false; + } if (expansion instanceof Listener) { - Bukkit.getPluginManager().registerEvents((Listener) expansion, plugin); + Listener l = (Listener) expansion; + Bukkit.getPluginManager().registerEvents(l, plugin); } plugin.getLogger().info("Successfully registered expansion: " + expansion.getIdentifier()); @@ -133,18 +143,29 @@ public final class ExpansionManager { public PlaceholderExpansion registerExpansion(String fileName) { List> subs = FileUtil.getClasses("expansions", fileName, PlaceholderExpansion.class); - if (subs == null || subs.isEmpty()) return null; + if (subs == null || subs.isEmpty()) { + return null; + } - // Only register the first instance found as an expansion JAR should only have 1 class + // only register the first instance found as an expansion jar should only have 1 class // extending PlaceholderExpansion PlaceholderExpansion ex = createInstance(subs.get(0)); - if (registerExpansion(ex)) return ex; + if (registerExpansion(ex)) { + return ex; + } + return null; } public void registerAllExpansions() { + if (plugin == null) { + return; + } + List> subs = FileUtil.getClasses("expansions", null, PlaceholderExpansion.class); - if (subs == null || subs.isEmpty()) return; + if (subs == null || subs.isEmpty()) { + return; + } for (Class klass : subs) { PlaceholderExpansion ex = createInstance(klass); @@ -159,29 +180,34 @@ public final class ExpansionManager { } } - private PlaceholderExpansion createInstance(Class clazz) { - if (clazz == null) return null; - if (!PlaceholderExpansion.class.isAssignableFrom(clazz)) return null; + private PlaceholderExpansion createInstance(Class klass) { + if (klass == null) { + return null; + } + + PlaceholderExpansion ex = null; + if (!PlaceholderExpansion.class.isAssignableFrom(klass)) { + return null; + } - PlaceholderExpansion expansion = null; try { - Constructor[] constructors = clazz.getConstructors(); - if (constructors.length == 0) { - expansion = (PlaceholderExpansion) clazz.newInstance(); + Constructor[] c = klass.getConstructors(); + if (c.length == 0) { + ex = (PlaceholderExpansion) klass.newInstance(); } else { - for (Constructor ctor : constructors) { - if (ctor.getParameterTypes().length == 0) { - expansion = (PlaceholderExpansion) ctor.newInstance(); + for (Constructor con : c) { + if (con.getParameterTypes().length == 0) { + ex = (PlaceholderExpansion) klass.newInstance(); break; } } } } catch (Throwable t) { plugin.getLogger() - .severe("Failed to init placeholder expansion from class: " + clazz.getName()); + .severe("Failed to init placeholder expansion from class: " + klass.getName()); plugin.getLogger().severe(t.getMessage()); } - return expansion; + return ex; } } diff --git a/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java b/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java index a51f708..2f7d89e 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java @@ -20,28 +20,26 @@ */ package me.clip.placeholderapi.expansion; -import com.google.common.base.Enums; - -import java.util.Optional; - public enum NMSVersion { - UNKNOWN("unknown"), - SPIGOT_1_7_R1("v1_7_R1"), - SPIGOT_1_7_R2("v1_7_R2"), - SPIGOT_1_7_R3("v1_7_R3"), - SPIGOT_1_7_R4("v1_7_R4"), - SPIGOT_1_8_R1("v1_8_R1"), - SPIGOT_1_8_R2("v1_8_R2"), - SPIGOT_1_8_R3("v1_8_R3"), - SPIGOT_1_9_R1("v1_9_R1"), - SPIGOT_1_9_R2("v1_9_R2"), - SPIGOT_1_10_R1("v1_10_R1"), - SPIGOT_1_11_R1("v1_11_R1"), - SPIGOT_1_12_R1("v1_12_R1"), - SPIGOT_1_13_R1("v1_13_R1"), - SPIGOT_1_13_R2("v1_13_R2"), - SPIGOT_1_14_R1("v1_14_R1"), - SPIGOT_1_15_R1("v1_15_R1"); + + UNKNOWN("unknown"), + SPIGOT_1_7_R1("v1_7_R1"), + SPIGOT_1_7_R2("v1_7_R2"), + SPIGOT_1_7_R3("v1_7_R3"), + SPIGOT_1_7_R4("v1_7_R4"), + SPIGOT_1_8_R1("v1_8_R1"), + SPIGOT_1_8_R2("v1_8_R2"), + SPIGOT_1_8_R3("v1_8_R3"), + SPIGOT_1_9_R1("v1_9_R1"), + SPIGOT_1_9_R2("v1_9_R2"), + SPIGOT_1_10_R1("v1_10_R1"), + SPIGOT_1_11_R1("v1_11_R1"), + SPIGOT_1_12_R1("v1_12_R1"), + SPIGOT_1_13_R1("v1_13_R1"), + SPIGOT_1_13_R2("v1_13_R2"), + SPIGOT_1_14_R1("v1_14_R1"), + SPIGOT_1_15_R1("v1_15_R1"), + SPIGOT_1_16_R1("v1_16_R1"); private final String version; @@ -50,12 +48,17 @@ public enum NMSVersion { } public static NMSVersion getVersion(String version) { - // Guava caches values() as well. - Optional opt = Enums.getIfPresent(NMSVersion.class, version).toJavaUtil(); - return opt.orElse(NMSVersion.UNKNOWN); + for (NMSVersion v : values()) { + if (v.getVersion().equalsIgnoreCase(version)) { + return v; + } + } + + return NMSVersion.UNKNOWN; } public String getVersion() { return version; } + } diff --git a/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java b/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java index f22a900..4ebdb51 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java @@ -26,11 +26,11 @@ import me.clip.placeholderapi.PlaceholderHook; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; import java.util.List; public abstract class PlaceholderExpansion extends PlaceholderHook { + /** * The name of this expansion * @@ -123,58 +123,60 @@ public abstract class PlaceholderExpansion extends PlaceholderHook { } /** - * Quick getter for the {@link PlaceholderAPIPlugin} config. + * Quick getter for the {@link PlaceholderAPIPlugin} instance * - * @return {@link PlaceholderAPIPlugin} config instance. + * @return {@link PlaceholderAPIPlugin} instance */ - public FileConfiguration getConfig() { - return PlaceholderAPIPlugin.getInstance().getConfig(); + public PlaceholderAPIPlugin getPlaceholderAPI() { + return PlaceholderAPIPlugin.getInstance(); } public String getString(String path, String def) { - return getConfig().getString(getPathStarter() + path, def); + return getPlaceholderAPI().getConfig() + .getString("expansions." + getIdentifier() + "." + path, def); } public int getInt(String path, int def) { - return getConfig().getInt(getPathStarter() + path, def); + return getPlaceholderAPI().getConfig() + .getInt("expansions." + getIdentifier() + "." + path, def); } public long getLong(String path, long def) { - return getConfig().getLong(getPathStarter() + path, def); + return getPlaceholderAPI().getConfig() + .getLong("expansions." + getIdentifier() + "." + path, def); } public double getDouble(String path, double def) { - return getConfig().getDouble(getPathStarter() + path, def); + return getPlaceholderAPI().getConfig() + .getDouble("expansions." + getIdentifier() + "." + path, def); } public List getStringList(String path) { - return getConfig().getStringList(getPathStarter() + path); + return getPlaceholderAPI().getConfig() + .getStringList("expansions." + getIdentifier() + "." + path); } public Object get(String path, Object def) { - return getConfig().get(getPathStarter() + path, def); + return getPlaceholderAPI().getConfig().get("expansions." + getIdentifier() + "." + path, def); } public ConfigurationSection getConfigSection(String path) { - return getConfig().getConfigurationSection(getPathStarter() + path); + return getPlaceholderAPI().getConfig() + .getConfigurationSection("expansions." + getIdentifier() + "." + path); } public ConfigurationSection getConfigSection() { - return getConfig().getConfigurationSection("expansions." + getIdentifier()); + return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier()); } public boolean configurationContains(String path) { - return getConfig().contains(getPathStarter() + path); + return getPlaceholderAPI().getConfig().contains("expansions." + getIdentifier() + "." + path); } - protected String getPathStarter() { - return "expansions." + getIdentifier() + '.'; - } /** * @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()} */ - @SuppressWarnings("DeprecatedIsStillUsed") @Deprecated public String getPlugin() { return null; diff --git a/src/main/java/me/clip/placeholderapi/expansion/Relational.java b/src/main/java/me/clip/placeholderapi/expansion/Relational.java index 7414c5f..d1da242 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Relational.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Relational.java @@ -23,5 +23,6 @@ package me.clip.placeholderapi.expansion; import org.bukkit.entity.Player; public interface Relational { + String onPlaceholderRequest(Player one, Player two, String identifier); } diff --git a/src/main/java/me/clip/placeholderapi/expansion/Taskable.java b/src/main/java/me/clip/placeholderapi/expansion/Taskable.java index ca8364f..b5b2b6f 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Taskable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Taskable.java @@ -20,7 +20,9 @@ */ package me.clip.placeholderapi.expansion; + public interface Taskable { + /** * Called when the implementing class has successfully been registered to the placeholder map * Tasks that need to be performed when this expansion is registered should go here diff --git a/src/main/java/me/clip/placeholderapi/expansion/Version.java b/src/main/java/me/clip/placeholderapi/expansion/Version.java index e9254d6..95067e4 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Version.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Version.java @@ -21,6 +21,7 @@ package me.clip.placeholderapi.expansion; public final class Version { + private final boolean isSpigot; private final String version; @@ -40,4 +41,5 @@ public final class Version { public boolean compareTo(String version) { return getVersion().equalsIgnoreCase(version); } + } diff --git a/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java b/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java index 5d95934..766ee51 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java +++ b/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java @@ -36,5 +36,5 @@ public interface VersionSpecific { * * @return true if your expansion is compatible with the version the server is running. */ - boolean isCompatibleWith(Version version); + boolean isCompatibleWith(Version v); } diff --git a/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java b/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java index 41e2273..d6c0d7a 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java @@ -26,8 +26,11 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; + public class CloudExpansion { - private String name, author, + + private String name, + author, latest_version, description, source_url, @@ -71,12 +74,14 @@ public class CloudExpansion { } public Version getVersion() { - return latest_version == null ? null : getVersion(latest_version); + return getLatestVersion() == null ? null : getVersion(getLatestVersion()); } public Version getVersion(String version) { return versions == null ? null : versions.stream() - .filter(v -> v.getVersion().equals(version)).findFirst().orElse(null); + .filter(v -> v.getVersion().equals(version)) + .findFirst() + .orElse(null); } public List getAvailableVersions() { @@ -135,10 +140,6 @@ public class CloudExpansion { return verified; } - public void setVerified(boolean verified) { - this.verified = verified; - } - public long getLastUpdate() { return last_update; } @@ -155,10 +156,6 @@ public class CloudExpansion { return average_rating; } - public void setAverage_rating(double average_rating) { - this.average_rating = average_rating; - } - public List getPlaceholders() { return placeholders; } @@ -175,11 +172,7 @@ public class CloudExpansion { this.versions = versions; } - public void setRatings_count(long ratings_count) { - this.ratings_count = ratings_count; - } - - public static class Version { + public class Version { private String url, version, release_notes; public String getUrl() { diff --git a/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java b/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java index b706f2e..78e6cc3 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java @@ -37,29 +37,37 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; public class ExpansionCloudManager { + private static final String API_URL = "http://api.extendedclip.com/v2/"; private static final Gson GSON = new Gson(); + private final PlaceholderAPIPlugin plugin; private final File expansionsDir; - private final Set downloading = new HashSet<>(); + private final List downloading = new ArrayList<>(); private final Map remote = new TreeMap<>(); + public ExpansionCloudManager(PlaceholderAPIPlugin plugin) { this.plugin = plugin; + expansionsDir = new File(plugin.getDataFolder(), "expansions"); - if (expansionsDir.mkdirs()) { + final boolean result = expansionsDir.mkdirs(); + if (result) { plugin.getLogger().info("Created Expansions Directory"); } + } + public void clean() { remote.clear(); downloading.clear(); } + public Map getCloudExpansions() { return remote; } @@ -72,6 +80,7 @@ public class ExpansionCloudManager { .orElse(null); } + public int getCloudAuthorCount() { return remote.values() .stream() @@ -117,10 +126,14 @@ public class ExpansionCloudManager { public int getPagesAvailable(Map map, int amount) { - if (map == null) return 0; + if (map == null) { + return 0; + } int pages = map.size() > 0 ? 1 : 0; - if (pages == 0) return 0; + if (pages == 0) { + return pages; + } if (map.size() > amount) { pages = map.size() / amount; @@ -146,11 +159,12 @@ public class ExpansionCloudManager { return ex; } + public void fetch(boolean allowUnverified) { plugin.getLogger().info("Fetching available expansion information..."); plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> { - Map data = new HashMap<>(); + final Map data = new HashMap<>(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(API_URL).openStream()))) { data.putAll(GSON.fromJson(reader, new TypeToken>() { @@ -159,12 +173,11 @@ public class ExpansionCloudManager { if (plugin.getPlaceholderAPIConfig().isDebugMode()) { ex.printStackTrace(); } else { - plugin.getLogger().warning("Unable to fetch expansions!\nThere was an error with the server host connecting to the PlaceholderAPI eCloud (https://api" + - ".extendedclip.com/v2/)"); + plugin.getLogger().warning("Unable to fetch expansions!\nThere was an error with the server host connecting to the PlaceholderAPI eCloud (https://api.extendedclip.com/v2/)"); } } - List unsorted = new ArrayList<>(); + final List unsorted = new ArrayList<>(); data.forEach((name, cexp) -> { if ((allowUnverified || cexp.isVerified()) && cexp.getLatestVersion() != null && cexp.getVersion(cexp.getLatestVersion()) != null) { @@ -191,6 +204,7 @@ public class ExpansionCloudManager { } plugin.getLogger().info(count + " placeholder expansions are available on the cloud."); + long updates = getToUpdateCount(); if (updates > 0) { @@ -206,15 +220,19 @@ public class ExpansionCloudManager { private void download(URL url, String name) throws IOException { InputStream is = null; + FileOutputStream fos = null; try { URLConnection urlConn = url.openConnection(); + is = urlConn.getInputStream(); + fos = new FileOutputStream( expansionsDir.getAbsolutePath() + File.separator + "Expansion-" + name + ".jar"); byte[] buffer = new byte[is.available()]; + int l; while ((l = is.read(buffer)) > 0) { @@ -234,35 +252,42 @@ public class ExpansionCloudManager { } - public void downloadExpansion(String player, CloudExpansion ex) { + public void downloadExpansion(final String player, final CloudExpansion ex) { downloadExpansion(player, ex, ex.getLatestVersion()); } - public void downloadExpansion(String player, CloudExpansion ex, String version) { + public void downloadExpansion(final String player, final CloudExpansion ex, final String version) { if (downloading.contains(ex.getName())) { return; } - CloudExpansion.Version ver = ex.getVersions() + final CloudExpansion.Version ver = ex.getVersions() .stream() .filter(v -> v.getVersion().equals(version)) .findFirst() .orElse(null); - if (ver == null) return; + if (ver == null) { + return; + } downloading.add(ex.getName()); + plugin.getLogger().info("Attempting download of expansion: " + ex.getName() + (player != null ? " by user: " + player : "") + " from url: " + ver.getUrl()); + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { try { download(new URL(ver.getUrl()), ex.getName()); + plugin.getLogger().info("Download of expansion: " + ex.getName() + " complete!"); + } catch (Exception e) { plugin.getLogger() .warning("Failed to download expansion: " + ex.getName() + " from: " + ver.getUrl()); Bukkit.getScheduler().runTask(plugin, () -> { + downloading.remove(ex.getName()); if (player != null) { @@ -289,6 +314,7 @@ public class ExpansionCloudManager { } } }); + }); } } diff --git a/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java b/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java index 3eef529..a51893d 100644 --- a/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java +++ b/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java @@ -25,7 +25,9 @@ import me.clip.placeholderapi.PlaceholderHook; import org.apache.commons.lang.Validate; import org.bukkit.plugin.Plugin; -@SuppressWarnings("DeprecatedIsStillUsed") +/** + * Use {@link me.clip.placeholderapi.expansion.PlaceholderExpansion} instead + */ @Deprecated public abstract class EZPlaceholderHook extends PlaceholderHook { @@ -33,8 +35,8 @@ public abstract class EZPlaceholderHook extends PlaceholderHook { private final String plugin; public EZPlaceholderHook(Plugin plugin, String identifier) { - Validate.notNull(plugin, "Plugin cannot be null"); - Validate.notNull(identifier, "Placeholder name cannot be null"); + Validate.notNull(plugin, "Plugin can not be null!"); + Validate.notNull(identifier, "Placeholder name can not be null!"); this.identifier = identifier; this.plugin = plugin.getName(); } diff --git a/src/main/java/me/clip/placeholderapi/listeners/ApacheListener.java b/src/main/java/me/clip/placeholderapi/listeners/ApacheListener.java deleted file mode 100644 index 268e071..0000000 --- a/src/main/java/me/clip/placeholderapi/listeners/ApacheListener.java +++ /dev/null @@ -1,39 +0,0 @@ -package me.clip.placeholderapi.listeners; - -import me.clip.placeholderapi.PlaceholderAPIPlugin; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.filter.AbstractFilter; -import org.bukkit.Bukkit; - -/** - * The purpose of this class is to filter the console warning messages when the plugin - * tries to load placeholder expansions from other jars in the plugins folder. - */ -public class ApacheListener extends AbstractFilter { - private boolean cancelled = false; - - public ApacheListener(PlaceholderAPIPlugin plugin) { - org.apache.logging.log4j.core.Logger logger = (org.apache.logging.log4j.core.Logger) LogManager.getRootLogger(); - logger.addFilter(this); - - // 3 second should be more than enough. I have no idea how to unregister a filter. - Bukkit.getScheduler().runTaskLater(plugin, () -> cancelled = true, 3 * 20L); - } - - @Override - public Result filter(LogEvent event) { - if (cancelled) return Result.NEUTRAL; - if (event.getLevel() != Level.WARN) return Result.NEUTRAL; - if (!event.getLoggerName().equals("PlaceholderAPI")) return Result.NEUTRAL; - - // Format: - // Loaded class {CLASS} from {PLUGIN} {VERSION} which is not a depend, softdepend or loadbefore of this plugin. - // E.g. - // Loaded class com.earth2me.essentials.Essentials from PlaceholderAPI v2.10.5-DEV-84 which is not a depend, softdepend or loadbefore of this plugin. - String message = event.getMessage().getFormattedMessage(); - if (message.startsWith("Loaded class") && message.endsWith("which is not a depend, softdepend or loadbefore of this plugin.")) return Result.DENY; - return Result.NEUTRAL; - } -} \ No newline at end of file diff --git a/src/main/java/me/clip/placeholderapi/listeners/PlaceholderListener.java b/src/main/java/me/clip/placeholderapi/listeners/PlaceholderListener.java index 737ebe0..c6c06b5 100644 --- a/src/main/java/me/clip/placeholderapi/listeners/PlaceholderListener.java +++ b/src/main/java/me/clip/placeholderapi/listeners/PlaceholderListener.java @@ -37,8 +37,13 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.server.PluginDisableEvent; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + public class PlaceholderListener implements Listener { + private final PlaceholderAPIPlugin plugin; public PlaceholderListener(PlaceholderAPIPlugin instance) { @@ -48,23 +53,22 @@ public class PlaceholderListener implements Listener { @EventHandler public void onExpansionUnregister(ExpansionUnregisterEvent event) { - PlaceholderExpansion expansion = event.getExpansion(); - if (expansion instanceof Listener) { - HandlerList.unregisterAll((Listener) expansion); + if (event.getExpansion() instanceof Listener) { + HandlerList.unregisterAll((Listener) event.getExpansion()); } - if (expansion instanceof Taskable) { - ((Taskable) expansion).stop(); + if (event.getExpansion() instanceof Taskable) { + ((Taskable) event.getExpansion()).stop(); } - if (expansion instanceof Cacheable) { - ((Cacheable) expansion).clear(); + if (event.getExpansion() instanceof Cacheable) { + ((Cacheable) event.getExpansion()).clear(); } if (plugin.getExpansionCloud() != null) { CloudExpansion ex = plugin.getExpansionCloud() - .getCloudExpansion(expansion.getName()); + .getCloudExpansion(event.getExpansion().getName()); if (ex != null) { ex.setHasExpansion(false); @@ -74,20 +78,28 @@ public class PlaceholderListener implements Listener { } @EventHandler(priority = EventPriority.HIGH) - public void onPluginUnload(PluginDisableEvent event) { - // A plugin name cannot be null. - String name = event.getPlugin().getName(); - if (name.equals(plugin.getName())) return; + public void onPluginUnload(PluginDisableEvent e) { + String n = e.getPlugin().getName(); - for (PlaceholderHook hook : PlaceholderAPI.getPlaceholders().values()) { - if (hook.isExpansion()) { - PlaceholderExpansion ex = (PlaceholderExpansion) hook; + if (n.equals(plugin.getName())) { + return; + } - if (ex.getRequiredPlugin() == null) continue; + Map hooks = PlaceholderAPI.getPlaceholders(); - if (ex.getRequiredPlugin().equalsIgnoreCase(name)) { - if (PlaceholderAPI.unregisterExpansion(ex)) { - plugin.getLogger().info("Unregistered placeholder expansion: " + ex.getIdentifier()); + for (Entry entry : hooks.entrySet()) { + PlaceholderHook hook = entry.getValue(); + + if (hook instanceof PlaceholderExpansion) { + PlaceholderExpansion expansion = (PlaceholderExpansion) hook; + + if (expansion.getRequiredPlugin() == null) { + continue; + } + + if (expansion.getRequiredPlugin().equalsIgnoreCase(n)) { + if (PlaceholderAPI.unregisterExpansion(expansion)) { + plugin.getLogger().info("Unregistered placeholder expansion: " + expansion.getIdentifier()); } } } @@ -95,10 +107,16 @@ public class PlaceholderListener implements Listener { } @EventHandler - public void onQuit(PlayerQuitEvent event) { - for (PlaceholderHook hook : PlaceholderAPI.getPlaceholders().values()) { - if (hook instanceof Cleanable) { - ((Cleanable) hook).cleanup(event.getPlayer()); + public void onQuit(PlayerQuitEvent e) { + Set expansions = PlaceholderAPI.getExpansions(); + + if (expansions.isEmpty()) { + return; + } + + for (PlaceholderExpansion ex : expansions) { + if (ex instanceof Cleanable) { + ((Cleanable) ex).cleanup(e.getPlayer()); } } } diff --git a/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java b/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java index e08da2b..b1f38f7 100644 --- a/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java +++ b/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java @@ -31,6 +31,7 @@ import org.bukkit.event.server.ServerLoadEvent; import java.util.Map; public class ServerLoadEventListener implements Listener { + private final PlaceholderAPIPlugin plugin; public ServerLoadEventListener(PlaceholderAPIPlugin instance) { @@ -39,19 +40,19 @@ public class ServerLoadEventListener implements Listener { } /** - * This method will be called when the server is first loaded. + * This method will be called when the server is first loaded *

* The goal of the method is to register all the expansions as soon as possible - * especially before players can join. + * especially before players can join *

* This will ensure no issues with expanions and hooks. * - * @param event the server load event. + * @param e the server load event */ @EventHandler - public void onServerLoad(ServerLoadEvent event) { + public void onServerLoad(ServerLoadEvent e) { plugin.getLogger().info("Placeholder expansion registration initializing..."); - Map alreadyRegistered = PlaceholderAPI.getPlaceholders(); + final Map alreadyRegistered = PlaceholderAPI.getPlaceholders(); plugin.getExpansionManager().registerAllExpansions(); if (alreadyRegistered != null && !alreadyRegistered.isEmpty()) { diff --git a/src/main/java/me/clip/placeholderapi/util/UpdateChecker.java b/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java similarity index 66% rename from src/main/java/me/clip/placeholderapi/util/UpdateChecker.java rename to src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java index 03d88e2..afafb0d 100644 --- a/src/main/java/me/clip/placeholderapi/util/UpdateChecker.java +++ b/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java @@ -18,13 +18,13 @@ * * */ -package me.clip.placeholderapi.util; +package me.clip.placeholderapi.updatechecker; import me.clip.placeholderapi.PlaceholderAPIPlugin; -import org.apache.commons.lang.StringUtils; +import me.clip.placeholderapi.util.Msg; import org.bukkit.Bukkit; -import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; @@ -32,11 +32,10 @@ import javax.net.ssl.HttpsURLConnection; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; -import java.nio.charset.StandardCharsets; public class UpdateChecker implements Listener { - private static final int RESOURCE_ID = 6245; - private static final String SPIGOT_API = "https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID; + + private final int RESOURCE_ID = 6245; private final PlaceholderAPIPlugin plugin; private final String pluginVersion; private String spigotVersion; @@ -58,35 +57,39 @@ public class UpdateChecker implements Listener { public void fetch() { Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { try { - HttpsURLConnection con = (HttpsURLConnection) new URL(SPIGOT_API).openConnection(); - - // Prevents the server from freezing with bad internet connection. + HttpsURLConnection con = (HttpsURLConnection) new URL( + "https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection(); con.setRequestMethod("GET"); - con.setConnectTimeout(2000); - con.setReadTimeout(2000); - - spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8)).readLine(); + spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine(); } catch (Exception ex) { - plugin.getLogger().warning("Failed to check for updates on spigot."); + plugin.getLogger().info("Failed to check for updates on spigot."); + return; + } + + if (spigotVersion == null || spigotVersion.isEmpty()) { return; } - if (spigotVersion == null || spigotVersion.isEmpty()) return; updateAvailable = spigotIsNewer(); - if (!updateAvailable) return; + + if (!updateAvailable) { + return; + } Bukkit.getScheduler().runTask(plugin, () -> { plugin.getLogger() - .info("An update for PlaceholderAPI (v" + spigotVersion + ") is available at:"); + .info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:"); plugin.getLogger() - .info("https://www.spigotmc.org/resources/" + RESOURCE_ID + '/'); + .info("https://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + "/"); Bukkit.getPluginManager().registerEvents(this, plugin); }); }); } private boolean spigotIsNewer() { - if (spigotVersion == null || spigotVersion.isEmpty()) return false; + if (spigotVersion == null || spigotVersion.isEmpty()) { + return false; + } String plV = toReadable(pluginVersion); String spV = toReadable(spigotVersion); @@ -94,17 +97,21 @@ public class UpdateChecker implements Listener { } private String toReadable(String version) { - if (version.contains("-DEV-")) version = StringUtils.split(version, "-DEV-")[0]; - return StringUtils.remove(version, '.'); + if (version.contains("-DEV-")) { + version = version.split("-DEV-")[0]; + } + + return version.replaceAll("\\.", ""); } - @EventHandler - public void onJoin(PlayerJoinEvent event) { - Player player = event.getPlayer(); - if (player.hasPermission("placeholderapi.updatenotify")) { - Msg.msg(player, - "&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getSpigotVersion() + "&e)", - "&bis available at &ehttps://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + '/'); + @EventHandler(priority = EventPriority.MONITOR) + public void onJoin(PlayerJoinEvent e) { + if (e.getPlayer().hasPermission("placeholderapi.updatenotify")) { + Msg.msg(e.getPlayer(), + "&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getSpigotVersion() + + "&e)" + , "&bis available at &ehttps://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + + "/"); } } } diff --git a/src/main/java/me/clip/placeholderapi/util/Constants.java b/src/main/java/me/clip/placeholderapi/util/Constants.java new file mode 100644 index 0000000..d911793 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/util/Constants.java @@ -0,0 +1,9 @@ +package me.clip.placeholderapi.util; + +public class Constants { + public static final String ADMIN_PERMISSION = "placeholderapi.admin"; + public static final String ECLOUD_PERMISSION = "placeholderapi.ecloud"; + public static final String INFO_PERMISSION = "placeholderapi.info"; + public static final String LIST_PERMISSION = "placeholderapi.list"; + public static final String RELOAD_PERMISSION = "placeholderapi.reload"; +} diff --git a/src/main/java/me/clip/placeholderapi/util/FileUtil.java b/src/main/java/me/clip/placeholderapi/util/FileUtil.java index 9466e5b..84eb613 100644 --- a/src/main/java/me/clip/placeholderapi/util/FileUtil.java +++ b/src/main/java/me/clip/placeholderapi/util/FileUtil.java @@ -42,50 +42,65 @@ public class FileUtil { try { File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), folder); - if (!f.exists()) return list; + if (!f.exists()) { + return list; + } FilenameFilter fileNameFilter = (dir, name) -> { - boolean isJar = name.endsWith(".jar"); if (fileName != null) { - return isJar && name.substring(0, name.length() - 4) - .equalsIgnoreCase(fileName.substring(0, fileName.length() - 4)); + return name.endsWith(".jar") && name.replace(".jar", "") + .equalsIgnoreCase(fileName.replace(".jar", "")); } - return isJar; + return name.endsWith(".jar"); }; File[] jars = f.listFiles(fileNameFilter); - if (jars == null) return list; + if (jars == null) { + return list; + } for (File file : jars) { list = gather(file.toURI().toURL(), list, type); } return list; - } catch (Throwable ignored) { + } catch (Throwable t) { } return null; } private static List> gather(URL jar, List> list, Class clazz) { - // list cannot be null. + if (list == null) { + list = new ArrayList<>(); + } + try (URLClassLoader cl = new URLClassLoader(new URL[]{jar}, clazz.getClassLoader()); JarInputStream jis = new JarInputStream(jar.openStream())) { - JarEntry entry; - while ((entry = jis.getNextJarEntry()) != null) { - String name = entry.getName(); - if (name == null || name.isEmpty()) continue; + while (true) { + JarEntry j = jis.getNextJarEntry(); + if (j == null) { + break; + } + + String name = j.getName(); + if (name == null || name.isEmpty()) { + continue; + } if (name.endsWith(".class")) { - name = name.substring(0, name.length() - 6).replace('/', '.'); + name = name.replace("/", "."); + String cname = name.substring(0, name.lastIndexOf(".class")); - Class loaded = cl.loadClass(name); - if (clazz.isAssignableFrom(loaded)) list.add(loaded); + Class c = cl.loadClass(cname); + if (clazz.isAssignableFrom(c)) { + list.add(c); + } } } - } catch (Throwable ignored) { + } catch (Throwable t) { } return list; diff --git a/src/main/java/me/clip/placeholderapi/util/Msg.java b/src/main/java/me/clip/placeholderapi/util/Msg.java index e1cdd25..3d526e4 100644 --- a/src/main/java/me/clip/placeholderapi/util/Msg.java +++ b/src/main/java/me/clip/placeholderapi/util/Msg.java @@ -24,20 +24,17 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; -public class Msg { - public static void msg(CommandSender sender, String... messages) { - for (String message : messages) { - String msg = color(message); - sender.sendMessage(msg); - } +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; + +public final class Msg { + public static void msg(CommandSender s, String... msg) { + s.sendMessage(Arrays.stream(msg).filter(Objects::nonNull).map(Msg::color).collect(Collectors.joining("\n"))); } - public static void broadcast(String... messages) { - CommandSender sender = Bukkit.getConsoleSender(); - for (String message : messages) { - String msg = color(message); - sender.sendMessage(msg); - } + public static void broadcast(String... msg) { + Arrays.stream(msg).filter(Objects::nonNull).map(Msg::color).forEach(Bukkit::broadcastMessage); } public static String color(String text) { diff --git a/src/main/java/me/clip/placeholderapi/util/TimeFormat.java b/src/main/java/me/clip/placeholderapi/util/TimeFormat.java new file mode 100644 index 0000000..a9c3190 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/util/TimeFormat.java @@ -0,0 +1,28 @@ +/* + * + * PlaceholderAPI + * Copyright (C) 2019 Ryan McCarthy + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * + */ +package me.clip.placeholderapi.util; + +public enum TimeFormat { + DAYS, + HOURS, + MINUTES, + SECONDS +} diff --git a/src/main/java/me/clip/placeholderapi/util/TimeUtil.java b/src/main/java/me/clip/placeholderapi/util/TimeUtil.java index 8c834ff..b320ecf 100644 --- a/src/main/java/me/clip/placeholderapi/util/TimeUtil.java +++ b/src/main/java/me/clip/placeholderapi/util/TimeUtil.java @@ -22,10 +22,10 @@ package me.clip.placeholderapi.util; import java.time.Duration; import java.time.temporal.ChronoUnit; -import java.util.concurrent.TimeUnit; public class TimeUtil { - public static String getRemaining(int seconds, TimeUnit type) { + + public static String getRemaining(int seconds, TimeFormat type) { if (seconds < 60) { switch (type) { case DAYS: @@ -124,8 +124,8 @@ public class TimeUtil { * @param duration {@link Duration} (eg, Duration.of(20, {@link ChronoUnit#SECONDS}) for 20 seconds) * @return formatted time */ - public static String getTime(Duration duration) { - StringBuilder builder = new StringBuilder(); + public static String getTime(final Duration duration) { + final StringBuilder builder = new StringBuilder(); long seconds = duration.getSeconds(); long minutes = seconds / 60; diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 8b3e5aa..d4031ef 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -4,51 +4,39 @@ version: ${project.version} api-version: '1.13' authors: [extended_clip, Glare] description: ${project.description} - -commands: - placeholderapi: - description: PlaceholderAPI command - aliases: [papi] - permissions: - placeholderapi.*: - description: ability to use all commands - children: - placeholderapi.admin: true - placeholderapi.admin: - description: ability to use all commands - children: - placeholderapi.list: true - placeholderapi.reload: true - placeholderapi.ecloud: true - placeholderapi.parse: true - placeholderapi.register: true - placeholderapi.updatenotify: true - placeholderapi.list: - description: ability to use the list command - default: op - placeholderapi.reload: - description: ability to use the reload command - default: op - placeholderapi.parse: - description: ability to use parse command - default: op - placeholderapi.register: - description: ability to register or unregister placeholder expansions - default: op - placeholderapi.ecloud: - description: allows the usage of ecloud commands - default: op - children: - placeholderapi.ecloud.enable: true - placeholderapi.ecloud.disable: true - placeholderapi.ecloud.list: true - placeholderapi.ecloud.info: true - placeholderapi.ecloud.clear: true - placeholderapi.ecloud.status: true - placeholderapi.ecloud.refresh: true - placeholderapi.ecloud.download: true - placeholderapi.ecloud.versioninfo: true - placeholderapi.updatenotify: - description: notifies you when there is a PAPI update - default: op \ No newline at end of file + placeholderapi.*: + description: ability to use all commands + children: + placeholderapi.admin: true + placeholderapi.admin: + description: ability to use all commands + children: + placeholderapi.list: true + placeholderapi.reload: true + placeholderapi.ecloud: true + placeholderapi.parse: true + placeholderapi.register: true + placeholderapi.updatenotify: true + placeholderapi.list: + description: ability to use the list command + default: op + placeholderapi.reload: + description: ability to use the reload command + default: op + placeholderapi.parse: + description: ability to use parse command + default: op + placeholderapi.register: + description: ability to register or unregister placeholder expansions + default: op + placeholderapi.ecloud: + description: allows the usage of ecloud commands + default: op + placeholderapi.updatenotify: + description: notifies you when there is a PAPI update + default: op +commands: + placeholderapi: + description: PlaceholderAPI command + aliases: [papi] From 9d73893cc822691d31c91def5e5299a290bb065d Mon Sep 17 00:00:00 2001 From: Sxtanna Date: Mon, 20 Jul 2020 16:59:25 -0400 Subject: [PATCH 05/14] replacer api, unit tests, and benchmarks (#354) * added abstracted replacer api, and both char and regex based implementations * added test dependencies for jmh and junit * added unit tests and benchmarks for the replacer implementations * updated replacers to accept specific closure types, added test to verify malformed placeholder handling * updated jmh to 1.23, updated junit to 5.6.2 --- pom.xml | 18 ++ .../replacer/CharsReplacer.java | 129 ++++++++++++ .../replacer/RegexReplacer.java | 55 +++++ .../placeholderapi/replacer/Replacer.java | 33 +++ .../java/me/clip/placeholderapi/Values.java | 188 ++++++++++++++++++ .../replacer/ReplacerBenchmarks.java | 45 +++++ .../replacer/ReplacerUnitTester.java | 67 +++++++ 7 files changed, 535 insertions(+) create mode 100644 src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java create mode 100644 src/main/java/me/clip/placeholderapi/replacer/RegexReplacer.java create mode 100644 src/main/java/me/clip/placeholderapi/replacer/Replacer.java create mode 100644 src/test/java/me/clip/placeholderapi/Values.java create mode 100644 src/test/java/me/clip/placeholderapi/replacer/ReplacerBenchmarks.java create mode 100644 src/test/java/me/clip/placeholderapi/replacer/ReplacerUnitTester.java diff --git a/pom.xml b/pom.xml index 9ee602b..4bf0934 100644 --- a/pom.xml +++ b/pom.xml @@ -66,6 +66,24 @@ 19.0.0 provided + + org.openjdk.jmh + jmh-core + 1.23 + test + + + org.openjdk.jmh + jmh-generator-annprocess + 1.23 + test + + + org.junit.jupiter + junit-jupiter + 5.6.2 + test + diff --git a/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java b/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java new file mode 100644 index 0000000..731ca9a --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/replacer/CharsReplacer.java @@ -0,0 +1,129 @@ +package me.clip.placeholderapi.replacer; + +import me.clip.placeholderapi.PlaceholderHook; +import org.bukkit.OfflinePlayer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Function; + +public final class CharsReplacer implements Replacer +{ + + @NotNull + private final Closure closure; + + public CharsReplacer(@NotNull final Closure closure) + { + this.closure = closure; + } + + + @Override + public @NotNull String apply(@NotNull final String text, @Nullable final OfflinePlayer player, @NotNull final Function lookup) + { + final char[] chars = text.toCharArray(); + final StringBuilder builder = new StringBuilder(text.length()); + + final StringBuilder identifier = new StringBuilder(); + final StringBuilder parameters = new StringBuilder(); + + for (int i = 0; i < chars.length; i++) + { + final char l = chars[i]; + + if (l == '&' && ++i < chars.length) + { + final char c = chars[i]; + + if (c != '0' && c != '1' && c != '2' && c != '3' && c != '4' && c != '5' && c != '6' && c != '7' && c != '8' && c != '9' && c != 'a' && c != 'b' && c != 'c' && c != 'd' && c != 'e' && c != 'f' && c != 'k' && c != 'l' && c != 'm' && c != 'o' && c != 'r' && c != 'x') + { + builder.append(l).append(c); + } + else + { + builder.append('§').append(c); + } + continue; + } + + if (l != closure.head || i + 1 >= chars.length) + { + builder.append(l); + continue; + } + + boolean identified = false; + boolean oopsitsbad = false; + + while (++i < chars.length) + { + final char p = chars[i]; + + if (p == closure.tail) + { + break; + } + + if (p == ' ') + { + oopsitsbad = true; + break; + } + + if (p == '_' && !identified) + { + identified = true; + continue; + } + + if (identified) + { + parameters.append(p); + } + else + { + identifier.append(p); + } + } + + final String identifierString = identifier.toString(); + final String parametersString = parameters.toString(); + + identifier.setLength(0); + parameters.setLength(0); + + if (oopsitsbad) + { + builder.append(closure.head).append(identifierString); + + if (identified) + { + builder.append('_').append(parametersString); + } + + builder.append(' '); + continue; + } + + final PlaceholderHook placeholder = lookup.apply(identifierString); + if (placeholder == null) + { + builder.append(closure.head).append(identifierString).append('_').append(parametersString).append(closure.tail); + continue; + } + + final String replacement = placeholder.onRequest(player, parametersString); + if (replacement == null) + { + builder.append(closure.head).append(identifierString).append('_').append(parametersString).append(closure.tail); + continue; + } + + builder.append(replacement); + } + + return builder.toString(); + } + +} diff --git a/src/main/java/me/clip/placeholderapi/replacer/RegexReplacer.java b/src/main/java/me/clip/placeholderapi/replacer/RegexReplacer.java new file mode 100644 index 0000000..8218384 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/replacer/RegexReplacer.java @@ -0,0 +1,55 @@ +package me.clip.placeholderapi.replacer; + +import me.clip.placeholderapi.PlaceholderHook; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public final class RegexReplacer implements Replacer +{ + + @NotNull + private final Pattern pattern; + + public RegexReplacer(@NotNull final Closure closure) + { + this.pattern = Pattern.compile(String.format("\\%s((?[a-zA-Z0-9]+)_)(?[^%s%s]+)\\%s", closure.head, closure.head, closure.tail, closure.tail)); + } + + + @Override + public @NotNull String apply(@NotNull final String text, @Nullable final OfflinePlayer player, @NotNull final Function lookup) + { + final Matcher matcher = pattern.matcher(text); + if (!matcher.find()) + { + return text; + } + + final StringBuffer builder = new StringBuffer(); + + do + { + final String identifier = matcher.group("identifier"); + final String parameters = matcher.group("parameters"); + + final PlaceholderHook hook = lookup.apply(identifier); + if (hook == null) + { + continue; + } + + final String requested = hook.onRequest(player, parameters); + matcher.appendReplacement(builder, requested != null ? requested : matcher.group(0)); + } + while (matcher.find()); + + return ChatColor.translateAlternateColorCodes('&', matcher.appendTail(builder).toString()); + } + +} diff --git a/src/main/java/me/clip/placeholderapi/replacer/Replacer.java b/src/main/java/me/clip/placeholderapi/replacer/Replacer.java new file mode 100644 index 0000000..0665442 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/replacer/Replacer.java @@ -0,0 +1,33 @@ +package me.clip.placeholderapi.replacer; + +import me.clip.placeholderapi.PlaceholderHook; +import org.bukkit.OfflinePlayer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Function; + +public interface Replacer +{ + + @NotNull + String apply(@NotNull final String text, @Nullable final OfflinePlayer player, @NotNull final Function lookup); + + + enum Closure + { + BRACES('{', '}'), + BRACKETS('[', ']'), + PERCENT('%', '%'); + + + public final char head, tail; + + Closure(final char head, final char tail) + { + this.head = head; + this.tail = tail; + } + } + +} diff --git a/src/test/java/me/clip/placeholderapi/Values.java b/src/test/java/me/clip/placeholderapi/Values.java new file mode 100644 index 0000000..698157e --- /dev/null +++ b/src/test/java/me/clip/placeholderapi/Values.java @@ -0,0 +1,188 @@ +package me.clip.placeholderapi; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import me.clip.placeholderapi.replacer.CharsReplacer; +import me.clip.placeholderapi.replacer.RegexReplacer; +import me.clip.placeholderapi.replacer.Replacer; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Set; +import java.util.function.Function; + +public interface Values +{ + + String SMALL_TEXT = "My name is %player_name%"; + String LARGE_TEXT = "My name is %player_name% and my location is (%player_x%, %player_y%, %player_z%), this placeholder is invalid %server_name%"; + + ImmutableMap PLACEHOLDERS = ImmutableMap.builder() + .put("player", new MockPlayerPlaceholderHook()) + .build(); + + + Replacer CHARS_REPLACER = new CharsReplacer(Replacer.Closure.PERCENT); + Replacer REGEX_REPLACER = new RegexReplacer(Replacer.Closure.PERCENT); + Replacer TESTS_REPLACER = new Replacer() + { + private final Set COLOR_CODES = ImmutableSet.of('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f', 'k', 'l', 'm', 'o', 'r', 'x'); + + private final boolean colorize = true; + private final PlaceholderReplacer.Closure closure = PlaceholderReplacer.Closure.PERCENT; + + @Override + public @NotNull String apply(final @NotNull String text, final @Nullable OfflinePlayer player, final @NotNull Function lookup) + { + char[] chars = text.toCharArray(); + StringBuilder builder = new StringBuilder(chars.length); + + // This won't cause memory leaks. It's inside a method. And we want to use setLength instead of + // creating a new string builder to use the maximum capacity and avoid initializing new objects. + StringBuilder identifier = new StringBuilder(50); + PlaceholderHook handler = null; + + // Stages: + // Stage -1: Look for the color code in the next character. + // Stage 0: No closures detected, or the detected identifier is invalid. We're going forward while appending the characters normally. + // Stage 1: The closure has been detected, looking for the placeholder identifier... + // Stage 2: Detected the identifier and the parameter. Translating the placeholder... + int stage = 0; + + for (char ch : chars) + { + if (stage == -1 && COLOR_CODES.contains(ch)) + { + builder.append(ChatColor.COLOR_CHAR).append(ch); + stage = 0; + continue; + } + + // Check if the placeholder starts or ends. + if (ch == closure.start || ch == closure.end) + { + // If the placeholder ends. + if (stage == 2) + { + String parameter = identifier.toString(); + String translated = handler.onRequest(player, parameter); + + if (translated == null) + { + String name = handler.isExpansion() ? ((PlaceholderExpansion) handler).getIdentifier() : ""; + builder.append(closure.start).append(name).append('_').append(parameter).append(closure.end); + } + else + { + builder.append(translated); + } + + identifier.setLength(0); + stage = 0; + continue; + } + else if (stage == 1) + { // If it just started | Double closures | If it's still hasn't detected the indentifier, reset. + builder.append(closure.start).append(identifier); + } + + identifier.setLength(0); + stage = 1; + continue; + } + + // Placeholder identifier started. + if (stage == 1) + { + // Compare the current character with the idenfitier's. + // We reached the end of our identifier. + if (ch == '_') + { + handler = lookup.apply(identifier.toString()); + if (handler == null) + { + builder.append(closure.start).append(identifier).append('_'); + stage = 0; + } + else + { + identifier.setLength(0); + stage = 2; + } + continue; + } + + // Keep building the identifier name. + identifier.append(ch); + continue; + } + + // Building the placeholder parameter. + if (stage == 2) + { + identifier.append(ch); + continue; + } + + // Nothing placeholder related was found. + if (colorize && ch == '&') + { + stage = -1; + continue; + } + builder.append(ch); + } + + if (identifier != null) + { + if (stage > 0) + { + builder.append(closure.end); + } + builder.append(identifier); + } + return builder.toString(); + } + }; + + + final class MockPlayerPlaceholderHook extends PlaceholderHook + { + + public static final String PLAYER_X = String.valueOf(10); + public static final String PLAYER_Y = String.valueOf(20); + public static final String PLAYER_Z = String.valueOf(30); + public static final String PLAYER_NAME = "Sxtanna"; + + + @Override + public String onRequest(final OfflinePlayer player, final String params) + { + final String[] parts = params.split("_"); + if (parts.length == 0) + { + return null; + } + + switch (parts[0]) + { + case "name": + return PLAYER_NAME; + case "x": + return PLAYER_X; + case "y": + return PLAYER_Y; + case "z": + return PLAYER_Z; + } + + return null; + } + + } + +} diff --git a/src/test/java/me/clip/placeholderapi/replacer/ReplacerBenchmarks.java b/src/test/java/me/clip/placeholderapi/replacer/ReplacerBenchmarks.java new file mode 100644 index 0000000..cf08ae7 --- /dev/null +++ b/src/test/java/me/clip/placeholderapi/replacer/ReplacerBenchmarks.java @@ -0,0 +1,45 @@ +package me.clip.placeholderapi.replacer; + +import me.clip.placeholderapi.Values; +import org.openjdk.jmh.annotations.Benchmark; + +public class ReplacerBenchmarks +{ + + @Benchmark + public void measureCharsReplacerSmallText() + { + Values.CHARS_REPLACER.apply(Values.SMALL_TEXT, null, Values.PLACEHOLDERS::get); + } + + @Benchmark + public void measureRegexReplacerSmallText() + { + Values.REGEX_REPLACER.apply(Values.SMALL_TEXT, null, Values.PLACEHOLDERS::get); + } + + @Benchmark + public void measureCharsReplacerLargeText() + { + Values.CHARS_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get); + } + + @Benchmark + public void measureRegexReplacerLargeText() + { + Values.REGEX_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get); + } + + @Benchmark + public void measureTestsReplacerSmallText() + { + Values.TESTS_REPLACER.apply(Values.SMALL_TEXT, null, Values.PLACEHOLDERS::get); + } + + @Benchmark + public void measureTestsReplacerLargeText() + { + Values.TESTS_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get); + } + +} \ No newline at end of file diff --git a/src/test/java/me/clip/placeholderapi/replacer/ReplacerUnitTester.java b/src/test/java/me/clip/placeholderapi/replacer/ReplacerUnitTester.java new file mode 100644 index 0000000..03d9408 --- /dev/null +++ b/src/test/java/me/clip/placeholderapi/replacer/ReplacerUnitTester.java @@ -0,0 +1,67 @@ +package me.clip.placeholderapi.replacer; + +import me.clip.placeholderapi.Values; +import org.junit.jupiter.api.Test; + +import static me.clip.placeholderapi.Values.MockPlayerPlaceholderHook.PLAYER_NAME; +import static me.clip.placeholderapi.Values.MockPlayerPlaceholderHook.PLAYER_X; +import static me.clip.placeholderapi.Values.MockPlayerPlaceholderHook.PLAYER_Y; +import static me.clip.placeholderapi.Values.MockPlayerPlaceholderHook.PLAYER_Z; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public final class ReplacerUnitTester +{ + + @Test + void testCharsReplacerProducesExpectedSingleValue() + { + assertEquals(PLAYER_NAME, Values.CHARS_REPLACER.apply("%player_name%", null, Values.PLACEHOLDERS::get)); + } + + @Test + void testRegexReplacerProducesExpectedSingleValue() + { + assertEquals(PLAYER_NAME, Values.REGEX_REPLACER.apply("%player_name%", null, Values.PLACEHOLDERS::get)); + } + + @Test + void testCharsReplacerProducesExpectedSentence() + { + assertEquals(String.format("My name is %s and my location is (%s, %s, %s), this placeholder is invalid %%server_name%%", PLAYER_NAME, PLAYER_X, PLAYER_Y, PLAYER_Z), Values.CHARS_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get)); + } + + @Test + void testRegexReplacerProducesExpectedSentence() + { + assertEquals(String.format("My name is %s and my location is (%s, %s, %s), this placeholder is invalid %%server_name%%", PLAYER_NAME, PLAYER_X, PLAYER_Y, PLAYER_Z), Values.REGEX_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get)); + } + + @Test + void testResultsAreTheSameAsReplacement() + { + final String resultChars = Values.CHARS_REPLACER.apply("%player_name%", null, Values.PLACEHOLDERS::get); + final String resultRegex = Values.REGEX_REPLACER.apply("%player_name%", null, Values.PLACEHOLDERS::get); + + assertEquals(resultChars, resultRegex); + + assertEquals(PLAYER_NAME, resultChars); + } + + @Test + void testResultsAreTheSameNoReplacement() + { + final String resultChars = Values.CHARS_REPLACER.apply("%player_location%", null, Values.PLACEHOLDERS::get); + final String resultRegex = Values.REGEX_REPLACER.apply("%player_location%", null, Values.PLACEHOLDERS::get); + + assertEquals(resultChars, resultRegex); + } + + @Test + void testCharsReplacerIgnoresMalformed() + { + final String text = "10% and %hello world 15%"; + + assertEquals(text, Values.CHARS_REPLACER.apply(text, null, Values.PLACEHOLDERS::get)); + } + +} From 49012dc6b2314eab541d35a806d0fd53ffee4e1f Mon Sep 17 00:00:00 2001 From: extendedclip Date: Mon, 20 Jul 2020 17:23:27 -0400 Subject: [PATCH 06/14] here --- .../clip/placeholderapi/PlaceholderAPI.java | 40 +++---------------- 1 file changed, 5 insertions(+), 35 deletions(-) diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java index 8ce1674..a68b0fa 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java @@ -27,6 +27,9 @@ import me.clip.placeholderapi.events.ExpansionUnregisterEvent; import me.clip.placeholderapi.expansion.Cacheable; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.Relational; +import me.clip.placeholderapi.replacer.CharsReplacer; +import me.clip.placeholderapi.replacer.Replacer; +import me.clip.placeholderapi.replacer.Replacer.Closure; import me.clip.placeholderapi.util.Msg; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; @@ -47,6 +50,7 @@ public class PlaceholderAPI { private static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]"); private static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern.compile("[%](rel_)([^%]+)[%]"); private static final Map placeholders = new HashMap<>(); + private static final Replacer REPLACER = new CharsReplacer(Closure.PERCENT); private PlaceholderAPI() { } @@ -304,41 +308,7 @@ public class PlaceholderAPI { * @return The text containing the parsed placeholders */ public static String setPlaceholders(OfflinePlayer player, String text, Pattern pattern, boolean colorize) { - if (text == null) { - return null; - } - - if (placeholders.isEmpty()) { - return colorize ? color(text) : text; - } - - final Matcher matcher = pattern.matcher(text); - final Map hooks = getPlaceholders(); - - while (matcher.find()) { - final String format = matcher.group(1); - final int index = format.indexOf("_"); - - if (index <= 0 || index >= format.length()) { - continue; - } - - final String identifier = format.substring(0, index).toLowerCase(); - final String params = format.substring(index + 1); - final PlaceholderHook hook = hooks.get(identifier); - - if (hook == null) { - continue; - } - - final String value = hook.onRequest(player, params); - - if (value != null) { - text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value)); - } - } - - return colorize ? color(text) : text; + return REPLACER.apply(text, player, placeholders::get); } /** From 9060ea6bd3d8e25f7ba2e2c4e23710797c476f62 Mon Sep 17 00:00:00 2001 From: Sxtanna Date: Mon, 20 Jul 2020 17:38:18 -0400 Subject: [PATCH 07/14] updated to use new closure --- src/test/java/me/clip/placeholderapi/Values.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/test/java/me/clip/placeholderapi/Values.java b/src/test/java/me/clip/placeholderapi/Values.java index 698157e..37b393c 100644 --- a/src/test/java/me/clip/placeholderapi/Values.java +++ b/src/test/java/me/clip/placeholderapi/Values.java @@ -2,7 +2,6 @@ package me.clip.placeholderapi; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.replacer.CharsReplacer; import me.clip.placeholderapi.replacer.RegexReplacer; import me.clip.placeholderapi.replacer.Replacer; @@ -33,7 +32,7 @@ public interface Values 'a', 'b', 'c', 'd', 'e', 'f', 'k', 'l', 'm', 'o', 'r', 'x'); private final boolean colorize = true; - private final PlaceholderReplacer.Closure closure = PlaceholderReplacer.Closure.PERCENT; + private final Replacer.Closure closure = Replacer.Closure.PERCENT; @Override public @NotNull String apply(final @NotNull String text, final @Nullable OfflinePlayer player, final @NotNull Function lookup) @@ -63,7 +62,7 @@ public interface Values } // Check if the placeholder starts or ends. - if (ch == closure.start || ch == closure.end) + if (ch == closure.head || ch == closure.tail) { // If the placeholder ends. if (stage == 2) @@ -73,8 +72,8 @@ public interface Values if (translated == null) { - String name = handler.isExpansion() ? ((PlaceholderExpansion) handler).getIdentifier() : ""; - builder.append(closure.start).append(name).append('_').append(parameter).append(closure.end); + String name = ""; + builder.append(closure.head).append(name).append('_').append(parameter).append(closure.tail); } else { @@ -87,7 +86,7 @@ public interface Values } else if (stage == 1) { // If it just started | Double closures | If it's still hasn't detected the indentifier, reset. - builder.append(closure.start).append(identifier); + builder.append(closure.head).append(identifier); } identifier.setLength(0); @@ -105,7 +104,7 @@ public interface Values handler = lookup.apply(identifier.toString()); if (handler == null) { - builder.append(closure.start).append(identifier).append('_'); + builder.append(closure.head).append(identifier).append('_'); stage = 0; } else @@ -141,7 +140,7 @@ public interface Values { if (stage > 0) { - builder.append(closure.end); + builder.append(closure.tail); } builder.append(identifier); } From 3b3892e7d6d5471579ed33d408458143c66aaed0 Mon Sep 17 00:00:00 2001 From: Sxtanna Date: Mon, 20 Jul 2020 18:14:13 -0400 Subject: [PATCH 08/14] updated placeholder hook to define immutability and null contracts, deprecated online player function --- .../clip/placeholderapi/PlaceholderHook.java | 60 +++++++++++-------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderHook.java b/src/main/java/me/clip/placeholderapi/PlaceholderHook.java index e41e68d..629143c 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderHook.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderHook.java @@ -22,33 +22,43 @@ package me.clip.placeholderapi; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public abstract class PlaceholderHook { +public abstract class PlaceholderHook +{ - /** - * called when a placeholder value is requested from this hook - * - * @param player {@link OfflinePlayer} to request the placeholder value for, null if not needed for a - * player - * @param params String passed to the hook to determine what value to return - * @return value for the requested player and params - */ - public String onRequest(OfflinePlayer player, String params) { - if (player != null && player.isOnline()) { - return onPlaceholderRequest((Player) player, params); - } + /** + * called when a placeholder value is requested from this hook + * + * @param player {@link OfflinePlayer} to request the placeholder value for, null if not needed for a + * player + * @param params String passed to the hook to determine what value to return + * @return value for the requested player and params + */ + @Nullable + public String onRequest(@Nullable final OfflinePlayer player, @NotNull final String params) + { + if (player != null && player.isOnline()) + { + return onPlaceholderRequest((Player) player, params); + } - return onPlaceholderRequest(null, params); - } + return onPlaceholderRequest(null, params); + } + + /** + * called when a placeholder is requested from this hook + * + * @param player {@link Player} to request the placeholder value for, null if not needed for a player + * @param params String passed to the hook to determine what value to return + * @return value for the requested player and params + */ + @Nullable + @Deprecated + public String onPlaceholderRequest(@Nullable final Player player, @NotNull final String params) + { + return null; + } - /** - * called when a placeholder is requested from this hook - * - * @param player {@link Player} to request the placeholder value for, null if not needed for a player - * @param params String passed to the hook to determine what value to return - * @return value for the requested player and params - */ - public String onPlaceholderRequest(Player player, String params) { - return null; - } } From 45b3ebfbc2262d983233583f77113a5252408418 Mon Sep 17 00:00:00 2001 From: Sxtanna Date: Mon, 20 Jul 2020 18:16:46 -0400 Subject: [PATCH 09/14] updated to use new char replacer, deprecated all older functions, defined null contracts, and immutability. --- .../clip/placeholderapi/PlaceholderAPI.java | 1074 +++++++++-------- 1 file changed, 581 insertions(+), 493 deletions(-) diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java index a68b0fa..caf76ab 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java @@ -31,505 +31,593 @@ import me.clip.placeholderapi.replacer.CharsReplacer; import me.clip.placeholderapi.replacer.Replacer; import me.clip.placeholderapi.replacer.Replacer.Closure; import me.clip.placeholderapi.util.Msg; -import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; -import static me.clip.placeholderapi.util.Msg.color; - -public class PlaceholderAPI { - - private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]"); - private static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]"); - private static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern.compile("[%](rel_)([^%]+)[%]"); - private static final Map placeholders = new HashMap<>(); - private static final Replacer REPLACER = new CharsReplacer(Closure.PERCENT); - - private PlaceholderAPI() { - } - - /** - * Check if a specific placeholder identifier is currently registered - * - * @param identifier The identifier to check - * @return true if identifier is already registered - */ - public static boolean isRegistered(String identifier) { - return getRegisteredIdentifiers().stream() - .filter(id -> id.equalsIgnoreCase(identifier)) - .findFirst().orElse(null) != null; - } - - /** - * Register a new placeholder hook - * - * @param identifier Identifier of the placeholder -> "%(identifier)_(args...)% - * @param placeholderHook Implementing class that contains the onPlaceholderRequest method which - * is called when a value is needed for the specific placeholder - * @return true if the hook was successfully registered, false if there is already a hook - * registered for the specified identifier - */ - public static boolean registerPlaceholderHook(String identifier, PlaceholderHook placeholderHook) { - Validate.notNull(identifier, "Identifier can not be null"); - Validate.notNull(placeholderHook, "Placeholderhook can not be null"); - - if (isRegistered(identifier)) { - return false; - } - - placeholders.put(identifier.toLowerCase(), placeholderHook); - - return true; - } - - /** - * Unregister a placeholder hook by identifier - * - * @param identifier The identifier for the placeholder hook to unregister - * @return true if the placeholder hook was successfully unregistered, false if there was no - * placeholder hook registered for the identifier specified - */ - public static boolean unregisterPlaceholderHook(String identifier) { - Validate.notNull(identifier, "Identifier can not be null"); - return placeholders.remove(identifier.toLowerCase()) != null; - } - - /** - * Get all registered placeholder identifiers - * - * @return All registered placeholder identifiers - */ - public static Set getRegisteredIdentifiers() { - return ImmutableSet.copyOf(placeholders.keySet()); - } - - /** - * Get map of registered placeholders - * - * @return Copy of the internal placeholder map - */ - public static Map getPlaceholders() { - return ImmutableMap.copyOf(placeholders); - } - - public static Set getExpansions() { - Set set = getPlaceholders().values().stream() - .filter(PlaceholderExpansion.class::isInstance).map(PlaceholderExpansion.class::cast) - .collect(Collectors.toCollection(HashSet::new)); - - return ImmutableSet.copyOf(set); - } - - /** - * Check if a String contains any PlaceholderAPI placeholders ({@literal %_%}). - * - * @param text String to check - * @return true if String contains any registered placeholder identifiers, false otherwise - */ - public static boolean containsPlaceholders(String text) { - return text != null && PLACEHOLDER_PATTERN.matcher(text).find(); - } - - /** - * Check if a String contains any PlaceholderAPI bracket placeholders ({@literal {_}}). - * - * @param text String to check - * @return true if String contains any registered placeholder identifiers, false otherwise - */ - public static boolean containsBracketPlaceholders(String text) { - return text != null && BRACKET_PLACEHOLDER_PATTERN.matcher(text).find(); - } - - /** - * Translates all placeholders into their corresponding values. - *
The pattern of a valid placeholder is {@literal {_}}. - * - * @param player Player to parse the placeholders against - * @param text List of Strings to set the placeholder values in - * @return String containing all translated placeholders - */ - public static List setBracketPlaceholders(OfflinePlayer player, List text) { - return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); - } - - /** - * Translates all placeholders into their corresponding values. - *
The pattern of a valid placeholder is {@literal {_}}. - * - * @param player Player to parse the placeholders against - * @param text List of Strings to set the placeholder values in - * @param colorize If color codes (&[0-1a-fk-o]) should be translated - * @return String containing all translated placeholders - */ - public static List setBracketPlaceholders(OfflinePlayer player, List text, boolean colorize) { - return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, colorize); - } - - /** - * Translates all placeholders into their corresponding values. - *
The pattern of a valid placeholder is {@literal %_%}. - * - * @param player Player to parse the placeholders against - * @param text List of Strings to set the placeholder values in - * @return String containing all translated placeholders - */ - public static List setPlaceholders(OfflinePlayer player, List text) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true); - } - - /** - * Translates all placeholders into their corresponding values. - *
The pattern of a valid placeholder is {@literal %_%}. - * - * @param player Player to parse the placeholders against - * @param text List of Strings to set the placeholder values in - * @param colorize If color codes (&[0-1a-fk-o]) should be translated - * @return String containing all translated placeholders - */ - public static List setPlaceholders(OfflinePlayer player, List text, boolean colorize) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); - } - - /** - * Translates all placeholders into their corresponding values. - *
You set the pattern yourself through this method. - * - * @param player Player to parse the placeholders against - * @param text List of Strings to set the placeholder values in - * @param pattern The pattern to match placeholders to. Capture group 1 must contain an underscore separating the - * identifier from the params - * @return String containing all translated placeholders - */ - public static List setPlaceholders(OfflinePlayer player, List text, Pattern pattern) { - return setPlaceholders(player, text, pattern, true); - } - - /** - * Translates all placeholders into their corresponding values. - *
You set the pattern yourself through this method. - * - * @param player Player to parse the placeholders against - * @param text List of Strings to set the placeholder values in - * @param pattern The pattern to match placeholders to. Capture group 1 must contain an underscore separating the - * identifier from the params - * @param colorize If color codes (&[0-1a-fk-o]) should be translated - * @return String containing all translated placeholders - */ - public static List setPlaceholders(OfflinePlayer player, List text, Pattern pattern, boolean colorize) { - if (text == null) { - return null; - } - - return text.stream() - .map(line -> setPlaceholders(player, line, pattern, colorize)) - .collect(Collectors.toList()); - } - - /** - * Translates all placeholders into their corresponding values. - *
The pattern of a valid placeholder is {@literal {_}}. - * - * @param player Player to parse the placeholders against - * @param text Text to set the placeholder values in - * @return String containing all translated placeholders - */ - public static String setBracketPlaceholders(OfflinePlayer player, String text) { - return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); - } - - /** - * Translates all placeholders into their corresponding values. - *
The pattern of a valid placeholder is {@literal {_}} - * - * @param player Player to parse the placeholders against - * @param text Text to set the placeholder values in - * @param colorize If color codes (&[0-1a-fk-o]) should be translated - * @return String containing all translated placeholders - */ - public static String setBracketPlaceholders(OfflinePlayer player, String text, boolean colorize) { - return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, colorize); - } - - /** - * Translates all placeholders into their corresponding values. - *
The pattern of a valid placeholder is {@literal %_%}. - * - * @param player Player to parse the placeholders against - * @param text Text to set the placeholder values in - * @return String containing all translated placeholders - */ - public static String setPlaceholders(OfflinePlayer player, String text) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN); - } - - /** - * Translates all placeholders into their corresponding values. - *
The pattern of a valid placeholder is {@literal %_%}. - * - * @param player Player to parse the placeholder against - * @param text Text to parse the placeholders in - * @param colorize If color codes (&[0-1a-fk-o]) should be translated - * @return The text containing the parsed placeholders - */ - public static String setPlaceholders(OfflinePlayer player, String text, boolean colorize) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); - } - - /** - * Translates all placeholders into their corresponding values. - *
You set the pattern yourself through this method. - * - * @param player Player to parse the placeholders against - * @param text Text to set the placeholder values in - * @param pattern The pattern to match placeholders to. Capture group 1 must contain an underscore separating the - * identifier from the params - * @return The text containing the parsed placeholders - */ - public static String setPlaceholders(OfflinePlayer player, String text, Pattern pattern) { - return setPlaceholders(player, text, pattern, true); - } - - /** - * Translates all placeholders into their corresponding values. - *
You set the pattern yourself through this method. - * - * @param player Player to parse the placeholders against - * @param text Text to set the placeholder values in - * @param pattern The pattern to match placeholders to. Capture group 1 must contain an underscore separating the - * identifier from the params - * @param colorize If color codes (&[0-1a-fk-o]) should be translated - * @return The text containing the parsed placeholders - */ - public static String setPlaceholders(OfflinePlayer player, String text, Pattern pattern, boolean colorize) { - return REPLACER.apply(text, player, placeholders::get); - } - - /** - * Translate placeholders in the provided List based on the relation of the two provided players. - *
The pattern of a valid placeholder is {@literal %rel__%}. - * - * @param one Player to compare - * @param two Player to compare - * @param text text to parse the placeholder values to - * @return The text containing the parsed relational placeholders - */ - public static List setRelationalPlaceholders(Player one, Player two, List text) { - return setRelationalPlaceholders(one, two, text, true); - } - - /** - * Translate placeholders in the provided list based on the relation of the two provided players. - *
The pattern of a valid placeholder is {@literal %rel__%}. - * - * @param one First player to compare - * @param two Second player to compare - * @param text Text to parse the placeholders in - * @param colorize If color codes (&[0-1a-fk-o]) should be translated - * @return The text containing the parsed relational placeholders - */ - public static List setRelationalPlaceholders(Player one, Player two, List text, boolean colorize) { - if (text == null) { - return null; - } - - return text.stream() - .map(line -> setRelationalPlaceholders(one, two, line, colorize)) - .collect(Collectors.toList()); - } - - /** - * set relational placeholders in the text specified placeholders are matched with the pattern - * %% when set with this method - * - * @param one First player to compare - * @param two Second player to compare - * @param text Text to parse the placeholders in - * @return The text containing the parsed relational placeholders - */ - public static String setRelationalPlaceholders(Player one, Player two, String text) { - return setRelationalPlaceholders(one, two, text, true); - } - - /** - * set relational placeholders in the text specified placeholders are matched with the pattern - * %% when set with this method - * - * @param one Player to compare - * @param two Player to compare - * @param text Text to parse the placeholders in - * @param colorize If color codes (&[0-1a-fk-o]) should be translated - * @return The text containing the parsed relational placeholders - */ - @SuppressWarnings("DuplicatedCode") - public static String setRelationalPlaceholders(Player one, Player two, String text, boolean colorize) { - if (text == null) { - return null; - } - - if (placeholders.isEmpty()) { - return colorize ? Msg.color(text) : text; - } - - final Matcher matcher = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text); - final Map hooks = getPlaceholders(); - - while (matcher.find()) { - final String format = matcher.group(2); - final int index = format.indexOf("_"); - - if (index <= 0 || index >= format.length()) { - continue; - } - - String identifier = format.substring(0, index).toLowerCase(); - String params = format.substring(index + 1); - final PlaceholderHook hook = hooks.get(identifier); - - if (!(hook instanceof Relational)) { - continue; - } - - final String value = ((Relational) hook).onPlaceholderRequest(one, two, params); - - if (value != null) { - text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value)); - } - } - - return colorize ? Msg.color(text) : text; - } - - /** - * Unregister ALL placeholder hooks that are currently registered - */ - protected static void unregisterAll() { - unregisterAllProvidedExpansions(); - placeholders.clear(); - } - - /** - * Unregister all expansions provided by PlaceholderAPI - */ - public static void unregisterAllProvidedExpansions() { - final Set set = new HashSet<>(placeholders.values()); - - for (PlaceholderHook hook : set) { - if (hook instanceof PlaceholderExpansion) { - final PlaceholderExpansion expansion = (PlaceholderExpansion) hook; - - if (!expansion.persist()) { - unregisterExpansion(expansion); - } - } - - if (hook instanceof Cacheable) { - ((Cacheable) hook).clear(); - } - } - } - - public static boolean registerExpansion(PlaceholderExpansion ex) { - ExpansionRegisterEvent ev = new ExpansionRegisterEvent(ex); - Bukkit.getPluginManager().callEvent(ev); - if (ev.isCancelled()) { - return false; - } - - return registerPlaceholderHook(ex.getIdentifier(), ex); - } - - public static boolean unregisterExpansion(PlaceholderExpansion ex) { - if (unregisterPlaceholderHook(ex.getIdentifier())) { - Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(ex)); - return true; - } - - return false; - } - - /** - * Gets the placeholder pattern for the default placeholders. - * - * @return The pattern for {@literal %_%} - */ - public static Pattern getPlaceholderPattern() { - return PLACEHOLDER_PATTERN; - } - - /** - * Gets the placeholder pattern for the bracket placeholders. - * - * @return The pattern for {@literal {_}} - */ - public static Pattern getBracketPlaceholderPattern() { - return BRACKET_PLACEHOLDER_PATTERN; - } - - /** - * Gets the placeholder pattern for the relational placeholders. - * - * @return The pattern for {@literal %rel__%} - */ - public static Pattern getRelationalPlaceholderPattern() { - return RELATIONAL_PLACEHOLDER_PATTERN; - } - - @Deprecated - public static Set getRegisteredPlaceholderPlugins() { - return getRegisteredIdentifiers(); - } - - @Deprecated - public static Set getExternalPlaceholderPlugins() { - return null; - } - - @Deprecated - public static boolean registerPlaceholderHook(Plugin plugin, PlaceholderHook placeholderHook) { - return plugin != null && registerPlaceholderHook(plugin.getName(), placeholderHook); - } - - @Deprecated - public static boolean unregisterPlaceholderHook(Plugin plugin) { - return plugin != null && unregisterPlaceholderHook(plugin.getName()); - } - - public static String setPlaceholders(Player player, String text) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true); - } - - public static String setPlaceholders(Player player, String text, boolean colorize) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); - } - - public static List setPlaceholders(Player player, List text) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true); - } - - public static List setPlaceholders(Player player, List text, boolean colorize) { - return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); - } - - public static String setBracketPlaceholders(Player player, String text) { - return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); - } - - public static String setBracketPlaceholders(Player player, String text, boolean colorize) { - return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, colorize); - } - - public static List setBracketPlaceholders(Player player, List text) { - return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); - } - - public static List setBracketPlaceholders(Player player, List text, boolean colorize) { - return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, colorize); - } -} +public final class PlaceholderAPI +{ + + private static final Replacer REPLACER = new CharsReplacer(Closure.PERCENT); + private static final Map PLACEHOLDERS = new HashMap<>(); + + + @Deprecated + private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]"); + @Deprecated + private static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]"); + @Deprecated + private static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern.compile("[%](rel_)([^%]+)[%]"); + + + private PlaceholderAPI() + { + } + + + // === Current API === + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal %_%}. + * + * @param player Player to parse the placeholders against + * @param text Text to set the placeholder values in + * @return String containing all translated placeholders + */ + @NotNull + public static String setPlaceholders(@Nullable final OfflinePlayer player, @NotNull final String text) + { + return REPLACER.apply(text, player, PLACEHOLDERS::get); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal %_%}. + * + * @param player Player to parse the placeholders against + * @param text List of Strings to set the placeholder values in + * @return String containing all translated placeholders + */ + @NotNull + public static List setPlaceholders(@Nullable final OfflinePlayer player, @NotNull List<@NotNull String> text) + { + return text.stream().map(line -> setPlaceholders(player, line)).collect(Collectors.toList()); + } + + /** + * Check if a specific placeholder identifier is currently registered + * + * @param identifier The identifier to check + * @return true if identifier is already registered + */ + public static boolean isRegistered(@NotNull final String identifier) + { + return PLACEHOLDERS.containsKey(identifier.toLowerCase()); + } + + /** + * Register a new placeholder hook + * + * @param identifier Identifier of the placeholder -> "%(identifier)_(args...)% + * @param placeholderHook Implementing class that contains the onPlaceholderRequest method which + * is called when a value is needed for the specific placeholder + * @return true if the hook was successfully registered, false if there is already a hook + * registered for the specified identifier + */ + public static boolean registerPlaceholderHook(@NotNull final String identifier, @NotNull final PlaceholderHook placeholderHook) + { + return PLACEHOLDERS.putIfAbsent(identifier.toLowerCase(), placeholderHook) == null; + } + + public static boolean registerPlaceholderHook(@NotNull final Plugin plugin, @NotNull final PlaceholderHook placeholderHook) + { + return registerPlaceholderHook(plugin.getName(), placeholderHook); + } + + /** + * Unregister a placeholder hook by identifier + * + * @param identifier The identifier for the placeholder hook to unregister + * @return true if the placeholder hook was successfully unregistered, false if there was no + * placeholder hook registered for the identifier specified + */ + public static boolean unregisterPlaceholderHook(@NotNull final String identifier) + { + return PLACEHOLDERS.remove(identifier.toLowerCase()) != null; + } + + public static boolean unregisterPlaceholderHook(@NotNull final Plugin plugin) + { + return unregisterPlaceholderHook(plugin.getName()); + } + + + /** + * Get all registered placeholder identifiers + * + * @return All registered placeholder identifiers + */ + @NotNull + public static Set getRegisteredIdentifiers() + { + return ImmutableSet.copyOf(PLACEHOLDERS.keySet()); + } + + /** + * Get map of registered placeholders + * + * @return Copy of the internal placeholder map + */ + @NotNull + public static Map getPlaceholders() + { + return ImmutableMap.copyOf(PLACEHOLDERS); + } + + + /** + * Unregister ALL placeholder hooks that are currently registered + */ + protected static void unregisterAll() + { + unregisterAllProvidedExpansions(); + PLACEHOLDERS.clear(); + } + + /** + * Unregister all expansions provided by PlaceholderAPI + */ + public static void unregisterAllProvidedExpansions() + { + final Set set = new HashSet<>(PLACEHOLDERS.values()); + + for (PlaceholderHook hook : set) + { + if (hook instanceof PlaceholderExpansion) + { + final PlaceholderExpansion expansion = (PlaceholderExpansion) hook; + + if (!expansion.persist()) + { + unregisterExpansion(expansion); + } + } + + if (hook instanceof Cacheable) + { + ((Cacheable) hook).clear(); + } + } + } + + public static boolean registerExpansion(@NotNull final PlaceholderExpansion expansion) + { + final ExpansionRegisterEvent event = new ExpansionRegisterEvent(expansion); + Bukkit.getPluginManager().callEvent(event); + + if (event.isCancelled()) + { + return false; + } + + return registerPlaceholderHook(expansion.getIdentifier(), expansion); + } + + public static boolean unregisterExpansion(@NotNull final PlaceholderExpansion expansion) + { + if (unregisterPlaceholderHook(expansion.getIdentifier())) + { + Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(expansion)); + return true; + } + + return false; + } + + + // === Deprecated API === (please don't use this, thank you - Sxtanna :P) + + /** + * Translates all placeholders into their corresponding values. + *
You set the pattern yourself through this method. + * + * @param player Player to parse the placeholders against + * @param text Text to set the placeholder values in + * @param pattern The pattern to match placeholders to. Capture group 1 must contain an underscore separating the + * identifier from the params + * @param colorize If color codes (&[0-1a-fk-o]) should be translated + * @return The text containing the parsed placeholders + * @deprecated this will do absolutely nothing different + */ + @NotNull + @Deprecated + public static String setPlaceholders(@Nullable final OfflinePlayer player, @NotNull final String text, @NotNull final Pattern pattern, final boolean colorize) + { + return setPlaceholders(player, text); + } + + /** + * Translates all placeholders into their corresponding values. + *
You set the pattern yourself through this method. + * + * @param player Player to parse the placeholders against + * @param text List of Strings to set the placeholder values in + * @param pattern The pattern to match placeholders to. Capture group 1 must contain an underscore separating the + * identifier from the params + * @param colorize If color codes (&[0-1a-fk-o]) should be translated + * @return String containing all translated placeholders + */ + @NotNull + @Deprecated + public static List setPlaceholders(@Nullable final OfflinePlayer player, @NotNull final List text, @NotNull final Pattern pattern, final boolean colorize) + { + return setPlaceholders(player, text); + } + + @Deprecated + public static Set getExpansions() + { + Set set = getPlaceholders().values().stream() + .filter(PlaceholderExpansion.class::isInstance).map(PlaceholderExpansion.class::cast) + .collect(Collectors.toCollection(HashSet::new)); + + return ImmutableSet.copyOf(set); + } + + /** + * Check if a String contains any PlaceholderAPI placeholders ({@literal %_%}). + * + * @param text String to check + * @return true if String contains any registered placeholder identifiers, false otherwise + */ + @Deprecated + public static boolean containsPlaceholders(String text) + { + return text != null && PLACEHOLDER_PATTERN.matcher(text).find(); + } + + /** + * Check if a String contains any PlaceholderAPI bracket placeholders ({@literal {_}}). + * + * @param text String to check + * @return true if String contains any registered placeholder identifiers, false otherwise + */ + @Deprecated + public static boolean containsBracketPlaceholders(String text) + { + return text != null && BRACKET_PLACEHOLDER_PATTERN.matcher(text).find(); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal {_}}. + * + * @param player Player to parse the placeholders against + * @param text List of Strings to set the placeholder values in + * @return String containing all translated placeholders + */ + @Deprecated + public static List setBracketPlaceholders(OfflinePlayer player, List text) + { + return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal {_}}. + * + * @param player Player to parse the placeholders against + * @param text List of Strings to set the placeholder values in + * @param colorize If color codes (&[0-1a-fk-o]) should be translated + * @return String containing all translated placeholders + */ + @Deprecated + public static List setBracketPlaceholders(OfflinePlayer player, List text, boolean colorize) + { + return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, colorize); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal %_%}. + * + * @param player Player to parse the placeholders against + * @param text List of Strings to set the placeholder values in + * @param colorize If color codes (&[0-1a-fk-o]) should be translated + * @return String containing all translated placeholders + */ + @Deprecated + public static List setPlaceholders(OfflinePlayer player, List text, boolean colorize) + { + return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); + } + + /** + * Translates all placeholders into their corresponding values. + *
You set the pattern yourself through this method. + * + * @param player Player to parse the placeholders against + * @param text List of Strings to set the placeholder values in + * @param pattern The pattern to match placeholders to. Capture group 1 must contain an underscore separating the + * identifier from the params + * @return String containing all translated placeholders + */ + @Deprecated + public static List setPlaceholders(OfflinePlayer player, List text, Pattern pattern) + { + return setPlaceholders(player, text, pattern, true); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal {_}}. + * + * @param player Player to parse the placeholders against + * @param text Text to set the placeholder values in + * @return String containing all translated placeholders + */ + @Deprecated + public static String setBracketPlaceholders(OfflinePlayer player, String text) + { + return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal {_}} + * + * @param player Player to parse the placeholders against + * @param text Text to set the placeholder values in + * @param colorize If color codes (&[0-1a-fk-o]) should be translated + * @return String containing all translated placeholders + */ + @Deprecated + public static String setBracketPlaceholders(OfflinePlayer player, String text, boolean colorize) + { + return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, colorize); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal %_%}. + * + * @param player Player to parse the placeholder against + * @param text Text to parse the placeholders in + * @param colorize If color codes (&[0-1a-fk-o]) should be translated + * @return The text containing the parsed placeholders + */ + @Deprecated + public static String setPlaceholders(OfflinePlayer player, String text, boolean colorize) + { + return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); + } + + /** + * Translates all placeholders into their corresponding values. + *
You set the pattern yourself through this method. + * + * @param player Player to parse the placeholders against + * @param text Text to set the placeholder values in + * @param pattern The pattern to match placeholders to. Capture group 1 must contain an underscore separating the + * identifier from the params + * @return The text containing the parsed placeholders + */ + @Deprecated + public static String setPlaceholders(OfflinePlayer player, String text, Pattern pattern) + { + return setPlaceholders(player, text, pattern, true); + } + + /** + * Translate placeholders in the provided List based on the relation of the two provided players. + *
The pattern of a valid placeholder is {@literal %rel__%}. + * + * @param one Player to compare + * @param two Player to compare + * @param text text to parse the placeholder values to + * @return The text containing the parsed relational placeholders + */ + @Deprecated + public static List setRelationalPlaceholders(Player one, Player two, List text) + { + return setRelationalPlaceholders(one, two, text, true); + } + + /** + * Translate placeholders in the provided list based on the relation of the two provided players. + *
The pattern of a valid placeholder is {@literal %rel__%}. + * + * @param one First player to compare + * @param two Second player to compare + * @param text Text to parse the placeholders in + * @param colorize If color codes (&[0-1a-fk-o]) should be translated + * @return The text containing the parsed relational placeholders + */ + @Deprecated + public static List setRelationalPlaceholders(Player one, Player two, List text, boolean colorize) + { + if (text == null) + { + return null; + } + + return text.stream() + .map(line -> setRelationalPlaceholders(one, two, line, colorize)) + .collect(Collectors.toList()); + } + + /** + * set relational placeholders in the text specified placeholders are matched with the pattern + * %% when set with this method + * + * @param one First player to compare + * @param two Second player to compare + * @param text Text to parse the placeholders in + * @return The text containing the parsed relational placeholders + */ + @Deprecated + public static String setRelationalPlaceholders(Player one, Player two, String text) + { + return setRelationalPlaceholders(one, two, text, true); + } + + /** + * set relational placeholders in the text specified placeholders are matched with the pattern + * %% when set with this method + * + * @param one Player to compare + * @param two Player to compare + * @param text Text to parse the placeholders in + * @param colorize If color codes (&[0-1a-fk-o]) should be translated + * @return The text containing the parsed relational placeholders + */ + @Deprecated + @SuppressWarnings("DuplicatedCode") + public static String setRelationalPlaceholders(Player one, Player two, String text, boolean colorize) + { + if (text == null) + { + return null; + } + + if (PLACEHOLDERS.isEmpty()) + { + return colorize ? Msg.color(text) : text; + } + + final Matcher matcher = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text); + final Map hooks = getPlaceholders(); + + while (matcher.find()) + { + final String format = matcher.group(2); + final int index = format.indexOf("_"); + + if (index <= 0 || index >= format.length()) + { + continue; + } + + String identifier = format.substring(0, index).toLowerCase(); + String params = format.substring(index + 1); + final PlaceholderHook hook = hooks.get(identifier); + + if (!(hook instanceof Relational)) + { + continue; + } + + final String value = ((Relational) hook).onPlaceholderRequest(one, two, params); + + if (value != null) + { + text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value)); + } + } + + return colorize ? Msg.color(text) : text; + } + + /** + * Gets the placeholder pattern for the default placeholders. + * + * @return The pattern for {@literal %_%} + */ + @Deprecated + public static Pattern getPlaceholderPattern() + { + return PLACEHOLDER_PATTERN; + } + + /** + * Gets the placeholder pattern for the bracket placeholders. + * + * @return The pattern for {@literal {_}} + */ + @Deprecated + public static Pattern getBracketPlaceholderPattern() + { + return BRACKET_PLACEHOLDER_PATTERN; + } + + /** + * Gets the placeholder pattern for the relational placeholders. + * + * @return The pattern for {@literal %rel__%} + */ + @Deprecated + public static Pattern getRelationalPlaceholderPattern() + { + return RELATIONAL_PLACEHOLDER_PATTERN; + } + + + @Deprecated + public static Set getRegisteredPlaceholderPlugins() + { + return getRegisteredIdentifiers(); + } + + @Deprecated + public static Set getExternalPlaceholderPlugins() + { + return null; + } + + + @Deprecated + public static String setPlaceholders(Player player, String text, boolean colorize) + { + return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); + } + + @Deprecated + public static List setPlaceholders(Player player, List text) + { + return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true); + } + + @Deprecated + public static List setPlaceholders(Player player, List text, boolean colorize) + { + return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); + } + + @Deprecated + public static String setBracketPlaceholders(Player player, String text) + { + return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); + } + + @Deprecated + public static String setBracketPlaceholders(Player player, String text, boolean colorize) + { + return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, colorize); + } + + @Deprecated + public static List setBracketPlaceholders(Player player, List text) + { + return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); + } + + @Deprecated + public static List setBracketPlaceholders(Player player, List text, boolean colorize) + { + return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, colorize); + } + +} \ No newline at end of file From 42992de312dece7ddd4e65742a7bd4dacdefa5a5 Mon Sep 17 00:00:00 2001 From: Sxtanna Date: Mon, 20 Jul 2020 18:22:08 -0400 Subject: [PATCH 10/14] updated with null contracts, immutability, and early returns. --- .../java/me/clip/placeholderapi/util/Msg.java | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/main/java/me/clip/placeholderapi/util/Msg.java b/src/main/java/me/clip/placeholderapi/util/Msg.java index 3d526e4..022ef5a 100644 --- a/src/main/java/me/clip/placeholderapi/util/Msg.java +++ b/src/main/java/me/clip/placeholderapi/util/Msg.java @@ -23,21 +23,37 @@ package me.clip.placeholderapi.util; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; import java.util.Arrays; -import java.util.Objects; import java.util.stream.Collectors; -public final class Msg { - public static void msg(CommandSender s, String... msg) { - s.sendMessage(Arrays.stream(msg).filter(Objects::nonNull).map(Msg::color).collect(Collectors.joining("\n"))); - } +public final class Msg +{ - public static void broadcast(String... msg) { - Arrays.stream(msg).filter(Objects::nonNull).map(Msg::color).forEach(Bukkit::broadcastMessage); - } + public static void msg(@NotNull final CommandSender sender, @NotNull final String... messages) + { + if (messages.length == 0) + { + return; + } + + sender.sendMessage(Arrays.stream(messages).map(Msg::color).collect(Collectors.joining("\n"))); + } + + public static void broadcast(@NotNull final String... messages) + { + if (messages.length == 0) + { + return; + } + + Bukkit.broadcastMessage(Arrays.stream(messages).map(Msg::color).collect(Collectors.joining("\n"))); + } + + public static String color(@NotNull final String text) + { + return ChatColor.translateAlternateColorCodes('&', text); + } - public static String color(String text) { - return ChatColor.translateAlternateColorCodes('&', text); - } } From e7ce84e7fc8211131fb95226432cdf6de816a8eb Mon Sep 17 00:00:00 2001 From: Sxtanna Date: Mon, 20 Jul 2020 18:55:37 -0400 Subject: [PATCH 11/14] cleaned up fileutil and expansion manager --- .../expansion/ExpansionManager.java | 317 ++++++++++-------- .../me/clip/placeholderapi/util/FileUtil.java | 124 ++++--- 2 files changed, 229 insertions(+), 212 deletions(-) diff --git a/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java b/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java index faa1f68..e1eb341 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java @@ -28,186 +28,207 @@ import me.clip.placeholderapi.util.FileUtil; import org.bukkit.Bukkit; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; -import java.lang.reflect.Constructor; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.logging.Level; -public final class ExpansionManager { - private final PlaceholderAPIPlugin plugin; +public final class ExpansionManager +{ - public ExpansionManager(PlaceholderAPIPlugin instance) { - plugin = instance; + @NotNull + private final File folder; + @NotNull + private final PlaceholderAPIPlugin plugin; - File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), "expansions"); - if (!f.exists()) { - f.mkdirs(); - } - } + public ExpansionManager(@NotNull final PlaceholderAPIPlugin plugin) + { + this.plugin = plugin; + this.folder = new File(plugin.getDataFolder(), "expansions"); - public PlaceholderExpansion getRegisteredExpansion(String name) { - for (Entry hook : PlaceholderAPI.getPlaceholders().entrySet()) { - if (hook.getValue() instanceof PlaceholderExpansion) { - if (name.equalsIgnoreCase(hook.getKey())) { - return (PlaceholderExpansion) hook.getValue(); - } - } - } + if (!this.folder.exists() && !folder.mkdirs()) + { + plugin.getLogger().log(Level.WARNING, "failed to create expansions folder!"); + } + } - return null; - } + public PlaceholderExpansion getRegisteredExpansion(String name) + { + for (Entry hook : PlaceholderAPI.getPlaceholders().entrySet()) + { + if (hook.getValue() instanceof PlaceholderExpansion) + { + if (name.equalsIgnoreCase(hook.getKey())) + { + return (PlaceholderExpansion) hook.getValue(); + } + } + } - public boolean registerExpansion(PlaceholderExpansion expansion) { - if (expansion == null || expansion.getIdentifier() == null) { - return false; - } + return null; + } - if (expansion instanceof Configurable) { - Map defaults = ((Configurable) expansion).getDefaults(); - String pre = "expansions." + expansion.getIdentifier() + "."; - FileConfiguration cfg = plugin.getConfig(); - boolean save = false; + public boolean registerExpansion(@NotNull final PlaceholderExpansion expansion) + { + if (expansion.getIdentifier() == null) + { + return false; + } - if (defaults != null) { - for (Entry entries : defaults.entrySet()) { - if (entries.getKey() == null || entries.getKey().isEmpty()) { - continue; - } + if (expansion instanceof Configurable) + { + Map defaults = ((Configurable) expansion).getDefaults(); + String pre = "expansions." + expansion.getIdentifier() + "."; + FileConfiguration cfg = plugin.getConfig(); + boolean save = false; - if (entries.getValue() == null) { - if (cfg.contains(pre + entries.getKey())) { - save = true; - cfg.set(pre + entries.getKey(), null); - } - } else { - if (!cfg.contains(pre + entries.getKey())) { - save = true; - cfg.set(pre + entries.getKey(), entries.getValue()); - } - } - } - } + if (defaults != null) + { + for (Entry entries : defaults.entrySet()) + { + if (entries.getKey() == null || entries.getKey().isEmpty()) + { + continue; + } - if (save) { - plugin.saveConfig(); - plugin.reloadConfig(); - } - } + if (entries.getValue() == null) + { + if (cfg.contains(pre + entries.getKey())) + { + save = true; + cfg.set(pre + entries.getKey(), null); + } + } + else + { + if (!cfg.contains(pre + entries.getKey())) + { + save = true; + cfg.set(pre + entries.getKey(), entries.getValue()); + } + } + } + } - if (expansion instanceof VersionSpecific) { - VersionSpecific nms = (VersionSpecific) expansion; - if (!nms.isCompatibleWith(PlaceholderAPIPlugin.getServerVersion())) { - plugin.getLogger() - .info( - "Your server version is not compatible with expansion: " + expansion.getIdentifier() - + " version: " + expansion.getVersion()); - return false; - } - } + if (save) + { + plugin.saveConfig(); + plugin.reloadConfig(); + } + } - if (!expansion.canRegister()) { - return false; - } + if (expansion instanceof VersionSpecific) + { + VersionSpecific nms = (VersionSpecific) expansion; + if (!nms.isCompatibleWith(PlaceholderAPIPlugin.getServerVersion())) + { + plugin.getLogger() + .info( + "Your server version is not compatible with expansion: " + expansion.getIdentifier() + + " version: " + expansion.getVersion()); + return false; + } + } - if (!expansion.register()) { - return false; - } + if (!expansion.canRegister() || !expansion.register()) + { + return false; + } - if (expansion instanceof Listener) { - Listener l = (Listener) expansion; - Bukkit.getPluginManager().registerEvents(l, plugin); - } + if (expansion instanceof Listener) + { + Bukkit.getPluginManager().registerEvents(((Listener) expansion), plugin); + } - plugin.getLogger().info("Successfully registered expansion: " + expansion.getIdentifier()); + plugin.getLogger().info("Successfully registered expansion: " + expansion.getIdentifier()); - if (expansion instanceof Taskable) { - ((Taskable) expansion).start(); - } + if (expansion instanceof Taskable) + { + ((Taskable) expansion).start(); + } - if (plugin.getExpansionCloud() != null) { - CloudExpansion ce = plugin.getExpansionCloud().getCloudExpansion(expansion.getIdentifier()); + if (plugin.getExpansionCloud() != null) + { + final CloudExpansion cloudExpansion = plugin.getExpansionCloud().getCloudExpansion(expansion.getIdentifier()); - if (ce != null) { - ce.setHasExpansion(true); - if (!ce.getLatestVersion().equals(expansion.getVersion())) { - ce.setShouldUpdate(true); - } - } - } + if (cloudExpansion != null) + { + cloudExpansion.setHasExpansion(true); + if (!cloudExpansion.getLatestVersion().equals(expansion.getVersion())) + { + cloudExpansion.setShouldUpdate(true); + } + } + } - return true; - } + return true; + } - public PlaceholderExpansion registerExpansion(String fileName) { - List> subs = FileUtil.getClasses("expansions", fileName, PlaceholderExpansion.class); - if (subs == null || subs.isEmpty()) { - return null; - } + @Nullable + public PlaceholderExpansion registerExpansion(@NotNull final String fileName) + { + final List> subs = FileUtil.getClasses(folder, PlaceholderExpansion.class, fileName); + if (subs.isEmpty()) + { + return null; + } - // only register the first instance found as an expansion jar should only have 1 class - // extending PlaceholderExpansion - PlaceholderExpansion ex = createInstance(subs.get(0)); - if (registerExpansion(ex)) { - return ex; - } + // only register the first instance found as an expansion jar should only have 1 class + // extending PlaceholderExpansion + final PlaceholderExpansion expansion = createInstance(subs.get(0)); + if (expansion != null && registerExpansion(expansion)) + { + return expansion; + } - return null; - } + return null; + } - public void registerAllExpansions() { - if (plugin == null) { - return; - } + public void registerAllExpansions() + { + final List<@NotNull Class> subs = FileUtil.getClasses(folder, PlaceholderExpansion.class); + if (subs.isEmpty()) + { + return; + } - List> subs = FileUtil.getClasses("expansions", null, PlaceholderExpansion.class); - if (subs == null || subs.isEmpty()) { - return; - } + for (final Class clazz : subs) + { + final PlaceholderExpansion expansion = createInstance(clazz); + if (expansion == null) + { + continue; + } - for (Class klass : subs) { - PlaceholderExpansion ex = createInstance(klass); - if (ex != null) { - try { - registerExpansion(ex); - } catch (Exception e) { - plugin.getLogger().info("Couldn't register " + ex.getIdentifier() + " expansion"); - e.printStackTrace(); - } - } - } - } + try + { + registerExpansion(expansion); + } + catch (final Exception ex) + { + plugin.getLogger().log(Level.WARNING, "Couldn't register " + expansion.getIdentifier() + " expansion", ex); + } + } + } - private PlaceholderExpansion createInstance(Class klass) { - if (klass == null) { - return null; - } + @Nullable + private PlaceholderExpansion createInstance(@NotNull final Class clazz) + { + try + { + return clazz.getDeclaredConstructor().newInstance(); + } + catch (final Throwable ex) + { + plugin.getLogger().log(Level.SEVERE, "Failed to load placeholder expansion from class: " + clazz.getName(), ex); + } - PlaceholderExpansion ex = null; - if (!PlaceholderExpansion.class.isAssignableFrom(klass)) { - return null; - } + return null; + } - try { - Constructor[] c = klass.getConstructors(); - if (c.length == 0) { - ex = (PlaceholderExpansion) klass.newInstance(); - } else { - for (Constructor con : c) { - if (con.getParameterTypes().length == 0) { - ex = (PlaceholderExpansion) klass.newInstance(); - break; - } - } - } - } catch (Throwable t) { - plugin.getLogger() - .severe("Failed to init placeholder expansion from class: " + klass.getName()); - plugin.getLogger().severe(t.getMessage()); - } - - return ex; - } } diff --git a/src/main/java/me/clip/placeholderapi/util/FileUtil.java b/src/main/java/me/clip/placeholderapi/util/FileUtil.java index 84eb613..0acb44e 100644 --- a/src/main/java/me/clip/placeholderapi/util/FileUtil.java +++ b/src/main/java/me/clip/placeholderapi/util/FileUtil.java @@ -20,89 +20,85 @@ */ package me.clip.placeholderapi.util; -import me.clip.placeholderapi.PlaceholderAPIPlugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.FilenameFilter; +import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; -public class FileUtil { +public class FileUtil +{ - public static List> getClasses(String folder, Class type) { - return getClasses(folder, null, type); - } + @NotNull + public static List<@NotNull Class> getClasses(@NotNull final File folder, @NotNull final Class clazz) + { + return getClasses(folder, clazz, null); + } - public static List> getClasses(String folder, String fileName, Class type) { - List> list = new ArrayList<>(); + @NotNull + public static List<@NotNull Class> getClasses(@NotNull final File folder, @NotNull final Class clazz, @Nullable final String target) + { + if (!folder.exists()) + { + return Collections.emptyList(); + } - try { - File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), folder); - if (!f.exists()) { - return list; - } + try + { + final FilenameFilter filter = + (dir, name) -> name.endsWith(".jar") && (target == null || name.replace(".jar", "").equalsIgnoreCase(target.replace(".jar", ""))); - FilenameFilter fileNameFilter = (dir, name) -> { - if (fileName != null) { - return name.endsWith(".jar") && name.replace(".jar", "") - .equalsIgnoreCase(fileName.replace(".jar", "")); - } + final File[] jars = folder.listFiles(filter); + if (jars == null) + { + return Collections.emptyList(); + } - return name.endsWith(".jar"); - }; + final List<@NotNull Class> list = new ArrayList<>(); - File[] jars = f.listFiles(fileNameFilter); - if (jars == null) { - return list; - } + for (File file : jars) + { + gather(file.toURI().toURL(), clazz, list); + } - for (File file : jars) { - list = gather(file.toURI().toURL(), list, type); - } + return list; + } + catch (Throwable t) + { + // THIS SHOULD NOT BE EATEN LIKE THIS. + } - return list; - } catch (Throwable t) { - } + return Collections.emptyList(); + } - return null; - } + private static void gather(@NotNull final URL jar, @NotNull final Class clazz, @NotNull final List<@NotNull Class> list) throws IOException, ClassNotFoundException + { + try (final URLClassLoader loader = new URLClassLoader(new URL[]{jar}, clazz.getClassLoader()); final JarInputStream stream = new JarInputStream(jar.openStream())) + { + JarEntry entry; + while ((entry = stream.getNextJarEntry()) != null) + { + final String name = entry.getName(); + if (name == null || name.isEmpty() || !name.endsWith(".class")) + { + continue; + } - private static List> gather(URL jar, List> list, Class clazz) { - if (list == null) { - list = new ArrayList<>(); - } + final Class loaded = loader.loadClass(name.substring(0, name.lastIndexOf('.')).replace('/', '.')); + if (clazz.isAssignableFrom(loaded)) + { + list.add(loaded.asSubclass(clazz)); + } + } + } + } - try (URLClassLoader cl = new URLClassLoader(new URL[]{jar}, clazz.getClassLoader()); - JarInputStream jis = new JarInputStream(jar.openStream())) { - - while (true) { - JarEntry j = jis.getNextJarEntry(); - if (j == null) { - break; - } - - String name = j.getName(); - if (name == null || name.isEmpty()) { - continue; - } - - if (name.endsWith(".class")) { - name = name.replace("/", "."); - String cname = name.substring(0, name.lastIndexOf(".class")); - - Class c = cl.loadClass(cname); - if (clazz.isAssignableFrom(c)) { - list.add(c); - } - } - } - } catch (Throwable t) { - } - - return list; - } } From 51f61f61af08c3e539cf5a32cab97fcf1bd0e649 Mon Sep 17 00:00:00 2001 From: Andre_601 <11576465+Andre601@users.noreply.github.com> Date: Tue, 21 Jul 2020 01:06:37 +0200 Subject: [PATCH 12/14] Add missing deprecation notices. --- src/main/java/me/clip/placeholderapi/PlaceholderAPI.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java index caf76ab..7082cb3 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java @@ -240,7 +240,8 @@ public final class PlaceholderAPI * identifier from the params * @param colorize If color codes (&[0-1a-fk-o]) should be translated * @return The text containing the parsed placeholders - * @deprecated this will do absolutely nothing different + * + * @deprecated Please use {@link #setPlaceholders(OfflinePlayer, String)} instead. */ @NotNull @Deprecated @@ -620,4 +621,4 @@ public final class PlaceholderAPI return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, colorize); } -} \ No newline at end of file +} From 75004f08d0740d5bb3d98b87d4931c04b432e99d Mon Sep 17 00:00:00 2001 From: Andre601 <11576465+Andre601@users.noreply.github.com> Date: Tue, 21 Jul 2020 01:20:26 +0200 Subject: [PATCH 13/14] Add deprecation notice to all methods Was it so hard to do a Ctrl+C, Ctrl+V? --- .../clip/placeholderapi/PlaceholderAPI.java | 71 +++++++++++++++---- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java index 7082cb3..19f66d2 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java @@ -228,7 +228,7 @@ public final class PlaceholderAPI } - // === Deprecated API === (please don't use this, thank you - Sxtanna :P) + // === Deprecated API === /** * Translates all placeholders into their corresponding values. @@ -240,8 +240,7 @@ public final class PlaceholderAPI * identifier from the params * @param colorize If color codes (&[0-1a-fk-o]) should be translated * @return The text containing the parsed placeholders - * - * @deprecated Please use {@link #setPlaceholders(OfflinePlayer, String)} instead. + * @deprecated Please use {@link #setPlaceholders(OfflinePlayer, String)} instead */ @NotNull @Deprecated @@ -260,6 +259,7 @@ public final class PlaceholderAPI * identifier from the params * @param colorize If color codes (&[0-1a-fk-o]) should be translated * @return String containing all translated placeholders + * @deprecated Please use {@link #setPlaceholders(OfflinePlayer, List)} instead */ @NotNull @Deprecated @@ -283,6 +283,7 @@ public final class PlaceholderAPI * * @param text String to check * @return true if String contains any registered placeholder identifiers, false otherwise + * @deprecated Will be removed in a future release. */ @Deprecated public static boolean containsPlaceholders(String text) @@ -295,6 +296,7 @@ public final class PlaceholderAPI * * @param text String to check * @return true if String contains any registered placeholder identifiers, false otherwise + * @deprecated Will be removed in a future release. */ @Deprecated public static boolean containsBracketPlaceholders(String text) @@ -309,6 +311,7 @@ public final class PlaceholderAPI * @param player Player to parse the placeholders against * @param text List of Strings to set the placeholder values in * @return String containing all translated placeholders + * @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead. */ @Deprecated public static List setBracketPlaceholders(OfflinePlayer player, List text) @@ -324,6 +327,7 @@ public final class PlaceholderAPI * @param text List of Strings to set the placeholder values in * @param colorize If color codes (&[0-1a-fk-o]) should be translated * @return String containing all translated placeholders + * @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead. */ @Deprecated public static List setBracketPlaceholders(OfflinePlayer player, List text, boolean colorize) @@ -339,6 +343,7 @@ public final class PlaceholderAPI * @param text List of Strings to set the placeholder values in * @param colorize If color codes (&[0-1a-fk-o]) should be translated * @return String containing all translated placeholders + * @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead. */ @Deprecated public static List setPlaceholders(OfflinePlayer player, List text, boolean colorize) @@ -355,6 +360,7 @@ public final class PlaceholderAPI * @param pattern The pattern to match placeholders to. Capture group 1 must contain an underscore separating the * identifier from the params * @return String containing all translated placeholders + * @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead. */ @Deprecated public static List setPlaceholders(OfflinePlayer player, List text, Pattern pattern) @@ -369,6 +375,7 @@ public final class PlaceholderAPI * @param player Player to parse the placeholders against * @param text Text to set the placeholder values in * @return String containing all translated placeholders + * @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead. */ @Deprecated public static String setBracketPlaceholders(OfflinePlayer player, String text) @@ -384,6 +391,7 @@ public final class PlaceholderAPI * @param text Text to set the placeholder values in * @param colorize If color codes (&[0-1a-fk-o]) should be translated * @return String containing all translated placeholders + * @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead. */ @Deprecated public static String setBracketPlaceholders(OfflinePlayer player, String text, boolean colorize) @@ -399,6 +407,7 @@ public final class PlaceholderAPI * @param text Text to parse the placeholders in * @param colorize If color codes (&[0-1a-fk-o]) should be translated * @return The text containing the parsed placeholders + * @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead. */ @Deprecated public static String setPlaceholders(OfflinePlayer player, String text, boolean colorize) @@ -415,6 +424,7 @@ public final class PlaceholderAPI * @param pattern The pattern to match placeholders to. Capture group 1 must contain an underscore separating the * identifier from the params * @return The text containing the parsed placeholders + * @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead. */ @Deprecated public static String setPlaceholders(OfflinePlayer player, String text, Pattern pattern) @@ -430,6 +440,7 @@ public final class PlaceholderAPI * @param two Player to compare * @param text text to parse the placeholder values to * @return The text containing the parsed relational placeholders + * @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead. */ @Deprecated public static List setRelationalPlaceholders(Player one, Player two, List text) @@ -446,6 +457,7 @@ public final class PlaceholderAPI * @param text Text to parse the placeholders in * @param colorize If color codes (&[0-1a-fk-o]) should be translated * @return The text containing the parsed relational placeholders + * @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead. */ @Deprecated public static List setRelationalPlaceholders(Player one, Player two, List text, boolean colorize) @@ -468,6 +480,7 @@ public final class PlaceholderAPI * @param two Second player to compare * @param text Text to parse the placeholders in * @return The text containing the parsed relational placeholders + * @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead. */ @Deprecated public static String setRelationalPlaceholders(Player one, Player two, String text) @@ -484,6 +497,7 @@ public final class PlaceholderAPI * @param text Text to parse the placeholders in * @param colorize If color codes (&[0-1a-fk-o]) should be translated * @return The text containing the parsed relational placeholders + * @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead. */ @Deprecated @SuppressWarnings("DuplicatedCode") @@ -536,6 +550,7 @@ public final class PlaceholderAPI * Gets the placeholder pattern for the default placeholders. * * @return The pattern for {@literal %_%} + * @deprecated Will be removed in a future release. */ @Deprecated public static Pattern getPlaceholderPattern() @@ -547,6 +562,7 @@ public final class PlaceholderAPI * Gets the placeholder pattern for the bracket placeholders. * * @return The pattern for {@literal {_}} + * @deprecated Will be removed in a future release. */ @Deprecated public static Pattern getBracketPlaceholderPattern() @@ -558,63 +574,90 @@ public final class PlaceholderAPI * Gets the placeholder pattern for the relational placeholders. * * @return The pattern for {@literal %rel__%} + * @deprecated Will be removed in a future release. */ @Deprecated public static Pattern getRelationalPlaceholderPattern() { return RELATIONAL_PLACEHOLDER_PATTERN; } - - + + + /** + * @deprecated Will be removed in a future release. + */ @Deprecated public static Set getRegisteredPlaceholderPlugins() { return getRegisteredIdentifiers(); } - + + /** + * @deprecated Will be removed in a future release. + */ @Deprecated public static Set getExternalPlaceholderPlugins() { return null; } - - + + /** + * @deprecated Will be removed in a future release. + */ @Deprecated public static String setPlaceholders(Player player, String text, boolean colorize) { return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); } - + + /** + * @deprecated Will be removed in a future release. + */ @Deprecated public static List setPlaceholders(Player player, List text) { return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true); } - + + /** + * @deprecated Will be removed in a future release. + */ @Deprecated public static List setPlaceholders(Player player, List text, boolean colorize) { return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); } - + + /** + * @deprecated Will be removed in a future release. + */ @Deprecated public static String setBracketPlaceholders(Player player, String text) { return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); } - + + /** + * @deprecated Will be removed in a future release. + */ @Deprecated public static String setBracketPlaceholders(Player player, String text, boolean colorize) { return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, colorize); } - + + /** + * @deprecated Will be removed in a future release. + */ @Deprecated public static List setBracketPlaceholders(Player player, List text) { return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); } - + + /** + * @deprecated Will be removed in a future release. + */ @Deprecated public static List setBracketPlaceholders(Player player, List text, boolean colorize) { From a2a736d9093e9a42c39b8d4e70509ac484f84740 Mon Sep 17 00:00:00 2001 From: Sxtanna Date: Mon, 20 Jul 2020 19:50:36 -0400 Subject: [PATCH 14/14] undeprecated bracket placeholder methods, --- .../clip/placeholderapi/PlaceholderAPI.java | 87 ++++++++++--------- .../placeholderapi/replacer/Replacer.java | 3 +- 2 files changed, 46 insertions(+), 44 deletions(-) diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java index 19f66d2..a990636 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java @@ -50,7 +50,9 @@ import java.util.stream.Collectors; public final class PlaceholderAPI { - private static final Replacer REPLACER = new CharsReplacer(Closure.PERCENT); + private static final Replacer REPLACER_PERCENT = new CharsReplacer(Closure.PERCENT); + private static final Replacer REPLACER_BRACKET = new CharsReplacer(Closure.BRACKET); + private static final Map PLACEHOLDERS = new HashMap<>(); @@ -80,7 +82,7 @@ public final class PlaceholderAPI @NotNull public static String setPlaceholders(@Nullable final OfflinePlayer player, @NotNull final String text) { - return REPLACER.apply(text, player, PLACEHOLDERS::get); + return REPLACER_PERCENT.apply(text, player, PLACEHOLDERS::get); } /** @@ -92,11 +94,42 @@ public final class PlaceholderAPI * @return String containing all translated placeholders */ @NotNull - public static List setPlaceholders(@Nullable final OfflinePlayer player, @NotNull List<@NotNull String> text) + public static List setPlaceholders(@Nullable final OfflinePlayer player, @NotNull final List<@NotNull String> text) { return text.stream().map(line -> setPlaceholders(player, line)).collect(Collectors.toList()); } + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal {_}}. + * + * @param player Player to parse the placeholders against + * @param text Text to set the placeholder values in + * + * @return String containing all translated placeholders + */ + @NotNull + public static String setBracketPlaceholders(@Nullable final OfflinePlayer player, @NotNull final String text) + { + return REPLACER_BRACKET.apply(text, player, PLACEHOLDERS::get); + } + + /** + * Translates all placeholders into their corresponding values. + *
The pattern of a valid placeholder is {@literal {_}}. + * + * @param player Player to parse the placeholders against + * @param text List of Strings to set the placeholder values in + * + * @return String containing all translated placeholders + */ + @NotNull + public static List setBracketPlaceholders(@Nullable final OfflinePlayer player, @NotNull final List<@NotNull String> text) + { + return text.stream().map(line -> setBracketPlaceholders(player, line)).collect(Collectors.toList()); + } + + /** * Check if a specific placeholder identifier is currently registered * @@ -304,21 +337,6 @@ public final class PlaceholderAPI return text != null && BRACKET_PLACEHOLDER_PATTERN.matcher(text).find(); } - /** - * Translates all placeholders into their corresponding values. - *
The pattern of a valid placeholder is {@literal {_}}. - * - * @param player Player to parse the placeholders against - * @param text List of Strings to set the placeholder values in - * @return String containing all translated placeholders - * @deprecated Use {@link #setPlaceholders(OfflinePlayer, List)} instead. - */ - @Deprecated - public static List setBracketPlaceholders(OfflinePlayer player, List text) - { - return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); - } - /** * Translates all placeholders into their corresponding values. *
The pattern of a valid placeholder is {@literal {_}}. @@ -368,20 +386,6 @@ public final class PlaceholderAPI return setPlaceholders(player, text, pattern, true); } - /** - * Translates all placeholders into their corresponding values. - *
The pattern of a valid placeholder is {@literal {_}}. - * - * @param player Player to parse the placeholders against - * @param text Text to set the placeholder values in - * @return String containing all translated placeholders - * @deprecated Use {@link #setPlaceholders(OfflinePlayer, String)} instead. - */ - @Deprecated - public static String setBracketPlaceholders(OfflinePlayer player, String text) - { - return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); - } /** * Translates all placeholders into their corresponding values. @@ -581,8 +585,7 @@ public final class PlaceholderAPI { return RELATIONAL_PLACEHOLDER_PATTERN; } - - + /** * @deprecated Will be removed in a future release. */ @@ -591,7 +594,7 @@ public final class PlaceholderAPI { return getRegisteredIdentifiers(); } - + /** * @deprecated Will be removed in a future release. */ @@ -600,7 +603,7 @@ public final class PlaceholderAPI { return null; } - + /** * @deprecated Will be removed in a future release. */ @@ -609,7 +612,7 @@ public final class PlaceholderAPI { return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); } - + /** * @deprecated Will be removed in a future release. */ @@ -618,7 +621,7 @@ public final class PlaceholderAPI { return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true); } - + /** * @deprecated Will be removed in a future release. */ @@ -627,7 +630,7 @@ public final class PlaceholderAPI { return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize); } - + /** * @deprecated Will be removed in a future release. */ @@ -636,7 +639,7 @@ public final class PlaceholderAPI { return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); } - + /** * @deprecated Will be removed in a future release. */ @@ -645,7 +648,7 @@ public final class PlaceholderAPI { return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, colorize); } - + /** * @deprecated Will be removed in a future release. */ @@ -654,7 +657,7 @@ public final class PlaceholderAPI { return setPlaceholders(player, text, BRACKET_PLACEHOLDER_PATTERN, true); } - + /** * @deprecated Will be removed in a future release. */ diff --git a/src/main/java/me/clip/placeholderapi/replacer/Replacer.java b/src/main/java/me/clip/placeholderapi/replacer/Replacer.java index 0665442..005c0f7 100644 --- a/src/main/java/me/clip/placeholderapi/replacer/Replacer.java +++ b/src/main/java/me/clip/placeholderapi/replacer/Replacer.java @@ -16,8 +16,7 @@ public interface Replacer enum Closure { - BRACES('{', '}'), - BRACKETS('[', ']'), + BRACKET('{', '}'), PERCENT('%', '%');