From 3e396a97b05265d261cda94a7f1f5e11cf7112d4 Mon Sep 17 00:00:00 2001 From: Frcsty <50297792+Frcsty@users.noreply.github.com> Date: Mon, 13 Jul 2020 21:27:59 +0200 Subject: [PATCH] Changed command system (#304) * Save Cacheable expansions data on shutdown * Prepare for 1.16 * 1.16.1 is out apparently * Further fixes, still not done * Inline JSONMessages & fix for 1.16 * Done :O * Done for real now, (hopefully) * Changed to static instead of DI for plugin instance * Cleanup * Modified tab completions. Removed extra command. * Apparently this is needed * Started cleaning stuff up basically just pushing so I can continue on laptop * did more cleaning, probs like half way done * more cleaning. reverted back to a min arg system somewhat similar to what frosty had, but less boilerplate. * Started debugging and fixing runtime/compile errors * Fixed bugs, still needs thorough testing * Re-enable metrics * relocated stuff again * - Remove json message relocation - uncomment other relocations - reformat pom - remove useless scope declaration - Fix metrics constructor - Switch commands to use inline json message Co-authored-by: iGabyTM Co-authored-by: darbyjack Co-authored-by: PiggyPiglet --- .gitignore | 3 + pom.xml | 211 ++-- .../clip/placeholderapi/PlaceholderAPI.java | 1010 +++++++++-------- .../placeholderapi/PlaceholderAPIPlugin.java | 491 ++++---- .../clip/placeholderapi/PlaceholderHook.java | 48 +- .../placeholderapi/PlaceholderListener.java | 124 -- .../clip/placeholderapi/commands/Command.java | 82 ++ .../commands/CommandHandler.java | 104 ++ .../commands/CompletionHandler.java | 32 + .../commands/ExpansionCloudCommands.java | 469 -------- .../commands/PlaceholderAPICommands.java | 330 ------ .../commands/command/BcParseCommand.java | 47 + .../command/DisableEcloudCommand.java | 29 + .../commands/command/EcloudCommand.java | 81 ++ .../commands/command/EnableCloudCommand.java | 27 + .../commands/command/HelpCommand.java | 46 + .../commands/command/InfoCommand.java | 68 ++ .../commands/command/ListCommand.java | 28 + .../commands/command/ParseCommand.java | 47 + .../commands/command/ParseRelCommand.java | 36 + .../commands/command/RegisterCommand.java | 28 + .../commands/command/ReloadCommand.java | 19 + .../commands/command/UnregisterCommand.java | 53 + .../commands/command/VersionCommand.java | 55 + .../commands/command/ecloud/ClearCommand.java | 19 + .../command/ecloud/DownloadCommand.java | 55 + .../commands/command/ecloud/InfoCommand.java | 70 ++ .../commands/command/ecloud/ListCommand.java | 208 ++++ .../command/ecloud/PlaceholdersCommand.java | 63 + .../command/ecloud/RefreshCommand.java | 23 + .../command/ecloud/StatusCommand.java | 26 + .../command/ecloud/VersionInfoCommand.java | 48 + .../configuration/PlaceholderAPIConfig.java | 66 +- .../events/ExpansionRegisterEvent.java | 48 +- .../events/ExpansionUnregisterEvent.java | 30 +- .../events/PlaceholderHookUnloadEvent.java | 40 +- .../exceptions/NoDefaultCommandException.java | 8 + .../placeholderapi/expansion/Cacheable.java | 8 +- .../placeholderapi/expansion/Cleanable.java | 12 +- .../expansion/Configurable.java | 20 +- .../expansion/ExpansionManager.java | 300 ++--- .../placeholderapi/expansion/NMSVersion.java | 33 +- .../expansion/PlaceholderExpansion.java | 286 ++--- .../placeholderapi/expansion/Relational.java | 2 +- .../placeholderapi/expansion/Taskable.java | 20 +- .../placeholderapi/expansion/Version.java | 30 +- .../expansion/VersionSpecific.java | 14 +- .../expansion/cloud/CloudExpansion.java | 306 ++--- .../cloud/ExpansionCloudManager.java | 36 +- .../external/EZPlaceholderHook.java | 43 +- .../listeners/PlaceholderListener.java | 123 ++ .../ServerLoadEventListener.java | 10 +- .../updatechecker/UpdateChecker.java | 146 +-- .../clip/placeholderapi/util/Constants.java | 9 + .../me/clip/placeholderapi/util/FileUtil.java | 136 +-- .../clip/placeholderapi/util/JSONMessage.java | 985 ++++++++++++++++ .../java/me/clip/placeholderapi/util/Msg.java | 23 +- .../clip/placeholderapi/util/TimeFormat.java | 8 +- .../me/clip/placeholderapi/util/TimeUtil.java | 279 +++-- src/main/resources/plugin.yml | 2 +- 60 files changed, 4253 insertions(+), 2750 deletions(-) delete mode 100644 src/main/java/me/clip/placeholderapi/PlaceholderListener.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/Command.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/CommandHandler.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/CompletionHandler.java delete mode 100644 src/main/java/me/clip/placeholderapi/commands/ExpansionCloudCommands.java delete mode 100644 src/main/java/me/clip/placeholderapi/commands/PlaceholderAPICommands.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/BcParseCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/DisableEcloudCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/EcloudCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/EnableCloudCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/HelpCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/InfoCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/ListCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/ParseCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/ParseRelCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/RegisterCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/ReloadCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/UnregisterCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/VersionCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/ecloud/ClearCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/ecloud/DownloadCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/ecloud/InfoCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/ecloud/ListCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/ecloud/PlaceholdersCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/ecloud/RefreshCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/ecloud/StatusCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/commands/command/ecloud/VersionInfoCommand.java create mode 100644 src/main/java/me/clip/placeholderapi/exceptions/NoDefaultCommandException.java create mode 100644 src/main/java/me/clip/placeholderapi/listeners/PlaceholderListener.java rename src/main/java/me/clip/placeholderapi/{ => listeners}/ServerLoadEventListener.java (90%) create mode 100644 src/main/java/me/clip/placeholderapi/util/Constants.java create mode 100644 src/main/java/me/clip/placeholderapi/util/JSONMessage.java diff --git a/.gitignore b/.gitignore index 4192205..7d9cce2 100644 --- a/.gitignore +++ b/.gitignore @@ -146,3 +146,6 @@ dist/ nbdist/ .nb-gradle/ nbactions.xml + +### Piggy's Debugging Shit ### +server/ \ No newline at end of file diff --git a/pom.xml b/pom.xml index 75b556d..0389e3d 100644 --- a/pom.xml +++ b/pom.xml @@ -1,119 +1,110 @@ - 4.0.0 + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 - me.clip - placeholderapi + me.clip + placeholderapi - 2.10.7-DEV-${BUILD_NUMBER} - PlaceholderAPI - An awesome placeholder provider! - http://extendedclip.com + 2.10.7-DEV-${BUILD_NUMBER} + PlaceholderAPI + An awesome placeholder provider! + http://extendedclip.com - - UTF-8 - + + UTF-8 + - - - spigot-repo - https://hub.spigotmc.org/nexus/content/repositories/snapshots/ - - - CodeMC - https://repo.codemc.org/repository/maven-public - - - rayzr-repo - https://cdn.rawgit.com/Rayzr522/maven-repo/master/ - - + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + CodeMC + https://repo.codemc.org/repository/maven-public + + - - - org.spigotmc - spigot-api - 1.15.2-R0.1-SNAPSHOT - provided - - - com.google.code.gson - gson - 2.8.5 - - - org.bstats - bstats-bukkit - 1.5 - compile - - - me.rayzr522 - jsonmessage - 1.0.0 - compile - - + + + org.spigotmc + spigot-api + 1.16.1-R0.1-SNAPSHOT + provided + + + com.google.code.gson + gson + 2.8.5 + + + org.bstats + bstats-bukkit + 1.5 + + + org.jetbrains + annotations + 19.0.0 + provided + + - - clean package + + clean package - - - org.apache.maven.plugins - maven-jar-plugin - 2.3.2 - - ${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 - 3.1.0 - - - package - - shade - - - false - false - - - org.bstats - me.clip.placeholderapi.metrics - - - me.rayzr522 - me.clip.placeholderapi.util - - - com.google.code.gson - me.clip.placeholderapi.libs.gson - - - - - - - - - - src/main/resources - true - - - + + + org.apache.maven.plugins + maven-jar-plugin + 2.3.2 + + ${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 + 3.1.0 + + + package + + shade + + + false + false + + + org.bstats + me.clip.placeholderapi.metrics + + + com.google.code.gson + me.clip.placeholderapi.libs.gson + + + + + + + + + + src/main/resources + true + + + diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java index aac83e2..8ce1674 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPI.java @@ -24,8 +24,10 @@ 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; @@ -40,516 +42,524 @@ 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 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; + + 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() { } - - 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; + + /** + * 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; } - - 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) { - if (text == null) { - return null; - } - - if (placeholders.isEmpty()) { - return colorize ? color(text) : text; - } - - Matcher m = pattern.matcher(text); - Map hooks = getPlaceholders(); - - while (m.find()) { - String format = m.group(1); - int index = format.indexOf("_"); - - if (index <= 0 || index >= format.length()) { - continue; - } - - String identifier = format.substring(0, index).toLowerCase(); - String params = format.substring(index + 1); - - if (hooks.containsKey(identifier)) { - String value = hooks.get(identifier).onRequest(player, params); - if (value != null) { - text = text.replaceAll(Pattern.quote(m.group()), Matcher.quoteReplacement(value)); + + /** + * 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; } - - return colorize ? color(text) : text; - } - - /** - * 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; + + /** + * 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; } - - 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 - */ - public static String setRelationalPlaceholders(Player one, Player two, String text, boolean colorize) { - if (text == null) { - return null; + + /** + * Get all registered placeholder identifiers + * + * @return All registered placeholder identifiers + */ + public static Set getRegisteredIdentifiers() { + return ImmutableSet.copyOf(placeholders.keySet()); } - - if (placeholders.isEmpty()) { - return colorize ? color(text) : text; + + /** + * Get map of registered placeholders + * + * @return Copy of the internal placeholder map + */ + public static Map getPlaceholders() { + return ImmutableMap.copyOf(placeholders); } - - Matcher m = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text); - Map hooks = getPlaceholders(); - - while (m.find()) { - String format = m.group(2); - int index = format.indexOf("_"); - - if (index <= 0 || index >= format.length()) { - continue; - } - - String identifier = format.substring(0, index).toLowerCase(); - String params = format.substring(index + 1); - - if (hooks.containsKey(identifier)) { - if (!(hooks.get(identifier) instanceof Relational)) { - continue; + + 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; } - - Relational rel = (Relational) hooks.get(identifier); - String value = rel.onPlaceholderRequest(one, two, params); - - if (value != null) { - text = text.replaceAll(Pattern.quote(m.group()), Matcher.quoteReplacement(value)); + + 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) { + if (text == null) { + return null; } - } - } - - return colorize ? 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() { - if (placeholders.isEmpty()) { - return; - } - - getPlaceholders().forEach((key, value) -> { - if (value instanceof PlaceholderExpansion) { - PlaceholderExpansion ex = (PlaceholderExpansion) value; - - if (!ex.persist()) { - unregisterExpansion(ex); + + if (placeholders.isEmpty()) { + return colorize ? color(text) : text; } - } - }); - } - - public static boolean registerExpansion(PlaceholderExpansion ex) { - ExpansionRegisterEvent ev = new ExpansionRegisterEvent(ex); - Bukkit.getPluginManager().callEvent(ev); - if (ev.isCancelled()) { - return false; + + 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 registerPlaceholderHook(ex.getIdentifier(), ex); - } - - public static boolean unregisterExpansion(PlaceholderExpansion ex) { - if (unregisterPlaceholderHook(ex.getIdentifier())) { - Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(ex)); - return 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 + */ + 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); } - - 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); - } } diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java b/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java index 076d35a..f52e880 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderAPIPlugin.java @@ -20,13 +20,15 @@ */ package me.clip.placeholderapi; -import me.clip.placeholderapi.commands.PlaceholderAPICommands; +import me.clip.placeholderapi.commands.CommandHandler; 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.PlaceholderListener; +import me.clip.placeholderapi.listeners.ServerLoadEventListener; import me.clip.placeholderapi.updatechecker.UpdateChecker; import me.clip.placeholderapi.util.TimeUtil; import org.bstats.bukkit.Metrics; @@ -38,6 +40,7 @@ import org.bukkit.plugin.java.JavaPlugin; import java.text.SimpleDateFormat; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.concurrent.TimeUnit; @@ -48,264 +51,260 @@ import java.util.concurrent.TimeUnit; */ public class PlaceholderAPIPlugin extends JavaPlugin { - private static PlaceholderAPIPlugin instance; - private static SimpleDateFormat dateFormat; - private static String booleanTrue; - private static String booleanFalse; - private static Version serverVersion; - private PlaceholderAPIConfig config; - private ExpansionManager expansionManager; - private ExpansionCloudManager expansionCloud; - private long startTime; + private static PlaceholderAPIPlugin instance; + private static SimpleDateFormat dateFormat; + private static String booleanTrue; + private static String booleanFalse; + 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 - * available from the class: {@link PlaceholderAPI} - * - * @return PlaceholderAPIPlugin instance - */ - public static PlaceholderAPIPlugin getInstance() { - return instance; - } - - /** - * Get the configurable {@linkplain SimpleDateFormat} object that is used to parse time for - * generic time based placeholders - * - * @return date format - */ - public static SimpleDateFormat getDateFormat() { - return dateFormat != null ? dateFormat : new SimpleDateFormat( - "MM/dd/yy HH:mm:ss"); - } - - /** - * Get the configurable {@linkplain String} value that should be returned when a boolean is true - * - * @return string value of true - */ - public static String booleanTrue() { - return booleanTrue != null ? booleanTrue : "true"; - } - - /** - * Get the configurable {@linkplain String} value that should be returned when a boolean is false - * - * @return string value of false - */ - public static String booleanFalse() { - return booleanFalse != null ? booleanFalse : "false"; - } - - 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); - } - - @Override - public void onEnable() { - config.loadDefConfig(); - setupOptions(); - - getCommand("placeholderapi").setExecutor(new PlaceholderAPICommands(this)); - new PlaceholderListener(this); - - try { - Class.forName("org.bukkit.event.server.ServerLoadEvent"); - new ServerLoadEventListener(this); - } catch (ExceptionInInitializerError | ClassNotFoundException exception) { - Bukkit.getScheduler().runTaskLater(this, () -> { - 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(); - getExpansionManager().registerAllExpansions(); - - if (alreadyRegistered != null && !alreadyRegistered.isEmpty()) { - alreadyRegistered.forEach(PlaceholderAPI::registerPlaceholderHook); - } - }, 1); - } - - if (config.checkUpdates()) { - new UpdateChecker(this).fetch(); - } - - if (config.isCloudEnabled()) { - enableCloud(); - } - - setupMetrics(); - getServer().getScheduler().runTaskLater(this, this::checkHook, 40); - } - - @Override - public void onDisable() { - disableCloud(); - PlaceholderAPI.unregisterAll(); - expansionManager = null; - Bukkit.getScheduler().cancelTasks(this); - serverVersion = null; - instance = null; - } - - public void reloadConf(CommandSender s) { - boolean cloudEnabled = this.expansionCloud != null; - PlaceholderAPI.unregisterAllProvidedExpansions(); - reloadConfig(); - setupOptions(); - expansionManager.registerAllExpansions(); - - if (!config.isCloudEnabled()) { - disableCloud(); - } else if (!cloudEnabled) { - enableCloud(); - } - - s.sendMessage(ChatColor.translateAlternateColorCodes('&', - PlaceholderAPI.getRegisteredIdentifiers().size() - + " &aplaceholder hooks successfully registered!")); - } - - private void checkHook() { - Map loaded = PlaceholderAPI.getPlaceholders(); - - loaded.values().forEach(h -> { - if (h instanceof EZPlaceholderHook) { - String author; + private static Version getVersion() { + String v = "unknown"; + boolean spigot = false; try { - author = Bukkit.getPluginManager().getPlugin(((EZPlaceholderHook) h).getPluginName()).getDescription().getAuthors().toString(); - } catch (Exception ex) { - author = "the author of the hook's plugin"; + v = Bukkit.getServer().getClass().getPackage().getName() + .split("\\.")[3]; + } catch (ArrayIndexOutOfBoundsException ex) { } - 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.".replace("{author}", author)); - - // disable the hook on startup - PlaceholderAPI.unregisterPlaceholderHook(((EZPlaceholderHook) h).getPlaceholderName()); - } - }); - } - - private void setupOptions() { - booleanTrue = config.booleanTrue(); - - if (booleanTrue == null) { - booleanTrue = "true"; - } - - booleanFalse = config.booleanFalse(); - - if (booleanFalse == null) { - booleanFalse = "false"; - } - - try { - dateFormat = new SimpleDateFormat(config.dateFormat()); - } catch (Exception e) { - dateFormat = new SimpleDateFormat("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")); - - m.addCustomChart( - new Metrics.SimplePie("using_spigot", () -> getServerVersion().isSpigot() ? "yes" : "no")); - - m.addCustomChart(new Metrics.AdvancedPie("expansions_used", () -> { - Map map = new HashMap<>(); - Map p = PlaceholderAPI.getPlaceholders(); - - if (!p.isEmpty()) { - - for (PlaceholderHook hook : p.values()) { - if (hook instanceof PlaceholderExpansion) { - PlaceholderExpansion ex = (PlaceholderExpansion) hook; - map.put(ex.getRequiredPlugin() == null ? ex.getIdentifier() - : ex.getRequiredPlugin(), 1); - } + try { + Class.forName("org.spigotmc.SpigotConfig"); + Class.forName("net.md_5.bungee.api.chat.BaseComponent"); + spigot = true; + } catch (ExceptionInInitializerError | ClassNotFoundException ignored) { } - } - return map; - })); - - } - - public void enableCloud() { - if (expansionCloud == null) { - expansionCloud = new ExpansionCloudManager(this); - } else { - expansionCloud.clean(); + return new Version(v, spigot); } - expansionCloud.fetch(config.cloudAllowUnverifiedExpansions()); - } - public void disableCloud() { - if (expansionCloud != null) { - expansionCloud.clean(); - expansionCloud = null; + /** + * 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 + * available from the class: {@link PlaceholderAPI} + * + * @return PlaceholderAPIPlugin instance + */ + public static PlaceholderAPIPlugin getInstance() { + return instance; } - } - /** - * Obtain the configuration class for PlaceholderAPI. - * - * @return PlaceholderAPIConfig instance - */ - public PlaceholderAPIConfig getPlaceholderAPIConfig() { - return config; - } + /** + * Get the configurable {@linkplain SimpleDateFormat} object that is used to parse time for + * generic time based placeholders + * + * @return date format + */ + public static SimpleDateFormat getDateFormat() { + return dateFormat != null ? dateFormat : new SimpleDateFormat( + "MM/dd/yy HH:mm:ss"); + } - public ExpansionManager getExpansionManager() { - return expansionManager; - } + /** + * Get the configurable {@linkplain String} value that should be returned when a boolean is true + * + * @return string value of true + */ + public static String booleanTrue() { + return booleanTrue != null ? booleanTrue : "true"; + } - public ExpansionCloudManager getExpansionCloud() { - return expansionCloud; - } + /** + * Get the configurable {@linkplain String} value that should be returned when a boolean is false + * + * @return string value of false + */ + public static String booleanFalse() { + return booleanFalse != null ? booleanFalse : "false"; + } - public String getUptime() { - return TimeUtil - .getTime((int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - startTime)); - } + public static Version getServerVersion() { + return serverVersion != null ? serverVersion : getVersion(); + } - public long getUptimeMillis() { - return (System.currentTimeMillis() - startTime); - } + @Override + public void onLoad() { + startTime = System.currentTimeMillis(); + instance = this; + serverVersion = getVersion(); + config = new PlaceholderAPIConfig(this); + expansionManager = new ExpansionManager(this); + } + + @Override + public void onEnable() { + config.loadDefConfig(); + setupOptions(); + + Objects.requireNonNull(getCommand("placeholderapi")).setExecutor(new CommandHandler()); + new PlaceholderListener(this); + + try { + Class.forName("org.bukkit.event.server.ServerLoadEvent"); + new ServerLoadEventListener(this); + } catch (ExceptionInInitializerError | ClassNotFoundException exception) { + Bukkit.getScheduler().runTaskLater(this, () -> { + 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(); + getExpansionManager().registerAllExpansions(); + + if (alreadyRegistered != null && !alreadyRegistered.isEmpty()) { + alreadyRegistered.forEach(PlaceholderAPI::registerPlaceholderHook); + } + }, 1); + } + + if (config.checkUpdates()) { + new UpdateChecker(this).fetch(); + } + + if (config.isCloudEnabled()) { + enableCloud(); + } + + setupMetrics(); + getServer().getScheduler().runTaskLater(this, this::checkHook, 40); + } + + @Override + public void onDisable() { + disableCloud(); + PlaceholderAPI.unregisterAll(); + expansionManager = null; + Bukkit.getScheduler().cancelTasks(this); + serverVersion = null; + instance = null; + } + + public void reloadConf(CommandSender s) { + boolean cloudEnabled = this.expansionCloud != null; + PlaceholderAPI.unregisterAllProvidedExpansions(); + reloadConfig(); + setupOptions(); + expansionManager.registerAllExpansions(); + + if (!config.isCloudEnabled()) { + disableCloud(); + } else if (!cloudEnabled) { + enableCloud(); + } + + s.sendMessage(ChatColor.translateAlternateColorCodes('&', + PlaceholderAPI.getRegisteredIdentifiers().size() + + " &aplaceholder hooks successfully registered!")); + } + + private void checkHook() { + Map loaded = PlaceholderAPI.getPlaceholders(); + + loaded.values().forEach(h -> { + if (h instanceof EZPlaceholderHook) { + String author; + + try { + author = Bukkit.getPluginManager().getPlugin(((EZPlaceholderHook) h).getPluginName()).getDescription().getAuthors().toString(); + } catch (Exception ex) { + author = "the author of the hook's plugin"; + } + + 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.".replace("{author}", author)); + + // disable the hook on startup + PlaceholderAPI.unregisterPlaceholderHook(((EZPlaceholderHook) h).getPlaceholderName()); + } + }); + } + + private void setupOptions() { + booleanTrue = config.booleanTrue(); + + if (booleanTrue == null) { + booleanTrue = "true"; + } + + booleanFalse = config.booleanFalse(); + + if (booleanFalse == null) { + booleanFalse = "false"; + } + + try { + dateFormat = new SimpleDateFormat(config.dateFormat()); + } catch (Exception e) { + dateFormat = new SimpleDateFormat("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")); + + m.addCustomChart(new Metrics.SimplePie("using_spigot", () -> getServerVersion().isSpigot() ? "yes" : "no")); + + m.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); + } + } + } + return map; + + })); + } + + public void enableCloud() { + if (expansionCloud == null) { + expansionCloud = new ExpansionCloudManager(this); + } else { + expansionCloud.clean(); + } + expansionCloud.fetch(config.cloudAllowUnverifiedExpansions()); + } + + public void disableCloud() { + if (expansionCloud != null) { + expansionCloud.clean(); + expansionCloud = null; + } + } + + /** + * Obtain the configuration class for PlaceholderAPI. + * + * @return PlaceholderAPIConfig instance + */ + public PlaceholderAPIConfig getPlaceholderAPIConfig() { + return config; + } + + public ExpansionManager getExpansionManager() { + return expansionManager; + } + + public ExpansionCloudManager getExpansionCloud() { + return expansionCloud; + } + + public String getUptime() { + return TimeUtil + .getTime((int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - startTime)); + } + + public long getUptimeMillis() { + 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 c70c386..e41e68d 100644 --- a/src/main/java/me/clip/placeholderapi/PlaceholderHook.java +++ b/src/main/java/me/clip/placeholderapi/PlaceholderHook.java @@ -25,30 +25,30 @@ import org.bukkit.entity.Player; public abstract class PlaceholderHook { - /** - * called when a placeholder value is requested from this hook - * - * @param p {@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 p, String params) { - if (p != null && p.isOnline()) { - return onPlaceholderRequest((Player) p, 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 + */ + public String onRequest(OfflinePlayer player, 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 p {@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 p, 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; + } } diff --git a/src/main/java/me/clip/placeholderapi/PlaceholderListener.java b/src/main/java/me/clip/placeholderapi/PlaceholderListener.java deleted file mode 100644 index d2685cb..0000000 --- a/src/main/java/me/clip/placeholderapi/PlaceholderListener.java +++ /dev/null @@ -1,124 +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 me.clip.placeholderapi.events.ExpansionUnregisterEvent; -import me.clip.placeholderapi.expansion.Cacheable; -import me.clip.placeholderapi.expansion.Cleanable; -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import me.clip.placeholderapi.expansion.Taskable; -import me.clip.placeholderapi.expansion.cloud.CloudExpansion; -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.HandlerList; -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) { - plugin = instance; - Bukkit.getPluginManager().registerEvents(this, instance); - } - - @EventHandler - public void onExpansionUnregister(ExpansionUnregisterEvent event) { - if (event.getExpansion() instanceof Listener) { - HandlerList.unregisterAll((Listener) event.getExpansion()); - } - - if (event.getExpansion() instanceof Taskable) { - ((Taskable) event.getExpansion()).stop(); - } - - if (event.getExpansion() instanceof Cacheable) { - ((Cacheable) event.getExpansion()).clear(); - } - - if (plugin.getExpansionCloud() != null) { - - CloudExpansion ex = plugin.getExpansionCloud() - .getCloudExpansion(event.getExpansion().getName()); - - if (ex != null) { - ex.setHasExpansion(false); - ex.setShouldUpdate(false); - } - } - } - - @EventHandler(priority = EventPriority.HIGH) - public void onPluginUnload(PluginDisableEvent e) { - String n = e.getPlugin().getName(); - - if (n == null) { - return; - } - - if (n.equals(plugin.getName())) { - return; - } - - Map hooks = PlaceholderAPI.getPlaceholders(); - - for (Entry hook : hooks.entrySet()) { - PlaceholderHook i = hook.getValue(); - - if (i instanceof PlaceholderExpansion) { - PlaceholderExpansion ex = (PlaceholderExpansion) i; - - if (ex.getRequiredPlugin() == null) { - continue; - } - - if (ex.getRequiredPlugin().equalsIgnoreCase(n)) { - if (PlaceholderAPI.unregisterExpansion(ex)) { - plugin.getLogger().info("Unregistered placeholder expansion: " + ex.getIdentifier()); - } - } - } - } - } - - @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()); - } - } - } -} diff --git a/src/main/java/me/clip/placeholderapi/commands/Command.java b/src/main/java/me/clip/placeholderapi/commands/Command.java new file mode 100644 index 0000000..531c8be --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/Command.java @@ -0,0 +1,82 @@ +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 final String match; + private final String usage; + private final int minimumArguments; + private final Set permissions; + + protected Command(@NotNull final String match) { + this(match, EMPTY_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.permissions = options.permissions == null ? Collections.emptySet() : ImmutableSet.copyOf(options.permissions); + this.minimumArguments = options.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; + } + + public int getMinimumArguments() { + return minimumArguments; + } + + @NotNull + public Set getPermissions() { + return permissions; + } + + public abstract void execute(@NotNull final CommandSender sender, @NotNull final 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(@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 new file mode 100644 index 0000000..932f307 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/CommandHandler.java @@ -0,0 +1,104 @@ +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.InfoCommand; +import me.clip.placeholderapi.commands.command.ecloud.ListCommand; +import me.clip.placeholderapi.commands.command.ecloud.*; +import me.clip.placeholderapi.util.Msg; +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( + new ClearCommand(), + new DownloadCommand(), + new InfoCommand(), + new ListCommand(), + new PlaceholdersCommand(), + new RefreshCommand(), + new StatusCommand(), + new VersionInfoCommand(), + new EcloudCommand(), + new BcParseCommand(), + new ParseCommand(), + new ParseRelCommand(), + new DisableEcloudCommand(), + new EnableCloudCommand(), + new HelpCommand(), + new me.clip.placeholderapi.commands.command.InfoCommand(), + new me.clip.placeholderapi.commands.command.ListCommand(), + new RegisterCommand(), + new ReloadCommand(), + DEFAULT, + new UnregisterCommand() + ); + + static { + COMMANDS.sort((command1, command2) -> { + final int comparison = Integer.compare(command1.getMatch().length(), command2.getMatch().length()); + + if (comparison == 1) return -1; + if (comparison == -1) return 1; + return 0; + }); + } + + private static final Pattern SPACE_PATTERN = Pattern.compile(" "); + + static { + Objects.requireNonNull(PlaceholderAPIPlugin.getInstance().getCommand("placeholderapi")) + .setTabCompleter(new CompletionHandler(COMMANDS)); + } + + @Override + 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; + } + + final String joined = String.join(" ", args).toLowerCase(); + final Optional optional = COMMANDS.stream() + .filter(command -> joined.startsWith(command.getMatch())) + .findFirst(); + + if (!optional.isPresent()) { + sender.sendMessage("Specified command is not valid."); + 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."); + 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 new file mode 100644 index 0000000..a48173f --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/CompletionHandler.java @@ -0,0 +1,32 @@ +package me.clip.placeholderapi.commands; + +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +public final class CompletionHandler implements TabCompleter { + 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 + @NotNull + @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(); + + 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/ExpansionCloudCommands.java b/src/main/java/me/clip/placeholderapi/commands/ExpansionCloudCommands.java deleted file mode 100644 index a10e8fa..0000000 --- a/src/main/java/me/clip/placeholderapi/commands/ExpansionCloudCommands.java +++ /dev/null @@ -1,469 +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.commands; - -import me.clip.placeholderapi.PlaceholderAPI; -import me.clip.placeholderapi.PlaceholderAPIPlugin; -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import me.clip.placeholderapi.expansion.cloud.CloudExpansion; -import me.rayzr522.jsonmessage.JSONMessage; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import static me.clip.placeholderapi.util.Msg.color; -import static me.clip.placeholderapi.util.Msg.msg; - -public class ExpansionCloudCommands implements CommandExecutor { - - private final PlaceholderAPIPlugin plugin; - - public ExpansionCloudCommands(PlaceholderAPIPlugin instance) { - plugin = instance; - } - - @Override - public boolean onCommand(CommandSender s, Command c, String label, String[] args) { - - if (args.length == 1) { - msg(s, "&bExpansion cloud commands", - " ", - "&b/papi ecloud status", - "&fView status of the ecloud", - "&b/papi ecloud list (page)", - "&fList all/author specific available expansions", - "&b/papi ecloud info ", - "&fView information about a specific expansion available on the cloud", - "&b/papi ecloud versioninfo ", - "&fView information about a specific version of an expansion", - "&b/papi ecloud placeholders ", - "&fView placeholders for an expansion", - "&b/papi ecloud download (version)", - "&fDownload an expansion from the ecloud", - "&b/papi ecloud refresh", - "&fFetch the most up to date list of expansions available.", - "&b/papi ecloud clear", - "&fClear the expansion cloud cache."); - return true; - } - - if (args[1].equalsIgnoreCase("refresh") || args[1].equalsIgnoreCase("update") || args[1] - .equalsIgnoreCase("fetch")) { - msg(s, "&aRefresh task started. Use &f/papi ecloud list all &ain a few!!"); - plugin.getExpansionCloud().clean(); - plugin.getExpansionCloud().fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions()); - - return true; - } - - if (plugin.getExpansionCloud().getCloudExpansions().isEmpty()) { - msg(s, "&7No cloud expansions are available at this time."); - - return true; - } - - if (args[1].equalsIgnoreCase("clear")) { - msg(s, "&aThe cache has been cleared!!"); - plugin.getExpansionCloud().clean(); - - return true; - } - - if (args[1].equalsIgnoreCase("status")) { - msg(s, "&bThere are &f" + plugin.getExpansionCloud().getCloudExpansions().size() - + " &bexpansions available on the cloud.", - "&7A total of &f" + plugin.getExpansionCloud().getCloudAuthorCount() - + " &7authors have contributed to the expansion cloud."); - if (plugin.getExpansionCloud().getToUpdateCount() > 0) { - msg(s, "&eYou have &f" + plugin.getExpansionCloud().getToUpdateCount() - + " &eexpansions installed that have updates available."); - } - - return true; - } - - if (args[1].equalsIgnoreCase("info")) { - if (args.length < 3) { - msg(s, "&cAn expansion name must be specified!"); - - return true; - } - - CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(args[2]); - - if (expansion == null) { - msg(s, "&cNo expansion found by the name: &f" + args[2]); - - return true; - } - - if (!(s instanceof Player)) { - msg(s, - (expansion.shouldUpdate() ? "&e" : "") + expansion.getName() + " &8&m-- &r" + expansion - .getVersion().getUrl()); - - return true; - } - - Player p = (Player) s; - - msg(s, "&bExpansion&7: &f" + expansion.getName(), - "&bAuthor: &f" + expansion.getAuthor(), - "&bVerified: &f" + expansion.isVerified() - ); - - // latest version - JSONMessage latestVersion = JSONMessage - .create(color("&bLatest version: &f" + expansion.getLatestVersion())); - latestVersion.tooltip(color("&bReleased: &f" + expansion.getTimeSinceLastUpdate() - + "\n&bUpdate information: &f" + expansion.getVersion().getReleaseNotes() - )); - latestVersion.send(p); - - // versions - JSONMessage versions = JSONMessage - .create(color("&bVersions available: &f" + expansion.getVersions().size())); - versions.tooltip(color(String.join("&b, &f", expansion.getAvailableVersions()))); - versions.suggestCommand( - "/papi ecloud versioninfo " + expansion.getName() + " " + expansion.getLatestVersion()); - versions.send(p); - - // placeholders - if (expansion.getPlaceholders() != null) { - 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()); - placeholders.send(p); - } - return true; - } - - if (args[1].equalsIgnoreCase("versioninfo")) { - if (args.length < 4) { - msg(s, "&cAn expansion name and version must be specified!"); - return true; - } - - CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(args[2]); - if (expansion == null) { - msg(s, "&cNo expansion found by the name: &f" + args[2]); - return true; - } - - CloudExpansion.Version version = expansion.getVersion(args[3]); - if (version == null) { - msg(s, "&cThe version specified does not exist for expansion: &f" + expansion.getName()); - return true; - } - - msg(s, "&bExpansion: " + (expansion.shouldUpdate() ? "&e" : "&f") + expansion.getName(), - "&bVersion: &f" + version.getVersion(), - "&bVersion info: &f" + version.getReleaseNotes()); - - if (!(s instanceof Player)) { - msg(s, "&bDownload url: " + version.getUrl()); - return true; - } - - Player p = (Player) s; - - JSONMessage download = JSONMessage.create(color("&7Click to download this version")); - download.suggestCommand( - "/papi ecloud download " + expansion.getName() + " " + version.getVersion()); - download.send(p); - - return true; - } - - if (args[1].equalsIgnoreCase("placeholders")) { - if (args.length < 3) { - msg(s, "&cAn expansion name must be specified!"); - - return true; - } - - CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(args[2]); - if (expansion == null) { - msg(s, "&cNo expansion found by the name: &f" + args[2]); - - return true; - } - - List placeholders = expansion.getPlaceholders(); - if (placeholders == null) { - msg(s, "&cThe expansion: &f" + expansion.getName() - + " &cdoes not have any placeholders listed.", - "&7You should contact &f" + expansion.getAuthor() + " &7and ask for them to be added."); - - return true; - } - - if (!(s instanceof Player) - || plugin.getExpansionManager().getRegisteredExpansion(expansion.getName()) == null) { - msg(s, "&bPlaceholders: &f" + placeholders.size(), - String.join("&a, &f", placeholders)); - - return true; - } - - Player p = (Player) s; - JSONMessage message = JSONMessage.create(color("&bPlaceholders: &f" + placeholders.size())); - message.then("\n"); - - for (int i = 0; i < placeholders.size(); i++) { - if (i == placeholders.size() - 1) { - message.then(placeholders.get(i)); - } else { - message.then(color(placeholders.get(i) + "&b, &f")); - } - try { - message.tooltip(PlaceholderAPI.setPlaceholders(p, placeholders.get(i))); - } catch (Exception e) { - - } - } - - message.send(p); - - return true; - } - - if (args[1].equalsIgnoreCase("list")) { - int page = 1; - - String author; - boolean installed = false; - - if (args.length < 3) { - msg(s, "&cIncorrect usage! &7/papi ecloud list (page)"); - return true; - } - - author = args[2]; - - if (author.equalsIgnoreCase("all")) { - author = null; - } else if (author.equalsIgnoreCase("installed")) { - author = null; - installed = true; - } - - if (args.length >= 4) { - try { - page = Integer.parseInt(args[3]); - } catch (NumberFormatException ex) { - msg(s, "&cPage number must be an integer!"); - - return true; - } - } - - if (page < 1) { - msg(s, "&cPage must be greater than or equal to 1!"); - - return true; - } - - int avail; - Map ex; - - if (installed) { - ex = plugin.getExpansionCloud().getAllInstalled(); - } else if (author == null) { - ex = plugin.getExpansionCloud().getCloudExpansions(); - } else { - ex = plugin.getExpansionCloud().getAllByAuthor(author); - } - - if (ex == null || ex.isEmpty()) { - msg(s, "&cNo expansions available" + (author != null ? " for author &f" + author : "")); - - return true; - } - - avail = plugin.getExpansionCloud().getPagesAvailable(ex, 10); - if (page > avail) { - msg(s, "&cThere " + ((avail == 1) ? " is only &f" + avail + " &cpage available!" - : "are only &f" + avail + " &cpages available!")); - - return true; - } - - msg(s, "&bShowing expansions for&7: &f" + (author != null ? author - : (installed ? "all installed" : "all available")) + " &8&m--&r &bamount&7: &f" + ex - .size() + " &bpage&7: &f" + page + "&7/&f" + avail); - - ex = plugin.getExpansionCloud().getPage(ex, page, 10); - - if (ex == null) { - msg(s, "&cThere was a problem getting the requested page..."); - - return true; - } - - msg(s, "&aGreen = Expansions you have"); - msg(s, "&6Gold = Expansions which need updated"); - - if (!(s instanceof Player)) { - Map expansions = new HashMap<>(); - - for (CloudExpansion exp : ex.values()) { - if (exp == null || exp.getName() == null) { - continue; - } - - expansions.put(exp.getName(), exp); - } - - List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); - - int i = (int) ex.keySet().toArray()[0]; - - for (String name : ce) { - if (expansions.get(name) == null) { - continue; - } - - CloudExpansion expansion = expansions.get(name); - - msg(s, - "&b" + i + "&7: " + (expansion.shouldUpdate() ? "&6" - : (expansion.hasExpansion() ? "&a" : "&7")) + expansion - .getName() + " &8&m-- &r" + expansion.getVersion().getUrl()); - i++; - } - - return true; - } - - Player p = (Player) s; - - Map expansions = new HashMap<>(); - - for (CloudExpansion exp : ex.values()) { - if (exp == null || exp.getName() == null) { - continue; - } - - expansions.put(exp.getName(), exp); - } - - List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); - - int i = page > 1 ? page * 10 : 0; - - for (String name : ce) { - if (expansions.get(name) == null) { - continue; - } - - 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"); - } else if (!expansion.hasExpansion()) { - sb.append("&bClick to download this expansion\n\n"); - } else { - sb.append("&aYou have the latest version of this expansion\n\n"); - } - - sb.append("&bAuthor&7: &f").append(expansion.getAuthor()).append("\n"); - sb.append("&bVerified&7: &f").append(expansion.isVerified()).append("\n"); - sb.append("&bLatest version&7: &f").append(expansion.getVersion().getVersion()).append("\n"); - sb.append("&bLast updated&7: &f").append(expansion.getTimeSinceLastUpdate()).append(" ago\n"); - sb.append("\n").append(expansion.getDescription()); - - String msg = color( - "&b" + (i + 1) + "&7: " + (expansion.shouldUpdate() ? "&6" - : (expansion.hasExpansion() ? "&a" : "")) + expansion.getName()); - - String hover = color(sb.toString()); - - JSONMessage line = JSONMessage.create(msg); - line.tooltip(hover); - - if (expansion.shouldUpdate() || !expansion.hasExpansion()) { - line.suggestCommand("/papi ecloud download " + expansion.getName()); - } else { - line.suggestCommand("/papi ecloud info " + expansion.getName()); - } - - line.send(p); - i++; - } - - return true; - } - - if (args[1].equalsIgnoreCase("download")) { - if (args.length < 3) { - msg(s, "&cAn expansion name must be specified!"); - return true; - } - - CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(args[2]); - if (expansion == null) { - msg(s, "&cNo expansion found with the name: &f" + args[2]); - return true; - } - - PlaceholderExpansion loaded = plugin.getExpansionManager().getRegisteredExpansion(args[2]); - if (loaded != null && loaded.isRegistered()) { - PlaceholderAPI.unregisterPlaceholderHook(loaded.getIdentifier()); - } - - String version = expansion.getLatestVersion(); - - if (args.length == 4) { - version = args[3]; - if (expansion.getVersion(version) == null) { - msg(s, "&cThe version you specified does not exist for &f" + expansion.getName()); - msg(s, "&7Available versions: &f" + expansion.getVersions().size()); - msg(s, String.join("&a, &f", expansion.getAvailableVersions())); - - return true; - } - } - - msg(s, "&aDownload starting for expansion: &f" + expansion.getName() + " &aversion: &f" + version); - String player = ((s instanceof Player) ? s.getName() : null); - plugin.getExpansionCloud().downloadExpansion(player, expansion, version); - plugin.getExpansionCloud().clean(); - plugin.getExpansionCloud().fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions()); - - return true; - } - - msg(s, "&cIncorrect usage! &b/papi ecloud"); - - return true; - } - - -} diff --git a/src/main/java/me/clip/placeholderapi/commands/PlaceholderAPICommands.java b/src/main/java/me/clip/placeholderapi/commands/PlaceholderAPICommands.java deleted file mode 100644 index 9145f59..0000000 --- a/src/main/java/me/clip/placeholderapi/commands/PlaceholderAPICommands.java +++ /dev/null @@ -1,330 +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.commands; - -import me.clip.placeholderapi.PlaceholderAPI; -import me.clip.placeholderapi.PlaceholderAPIPlugin; -import me.clip.placeholderapi.expansion.PlaceholderExpansion; -import me.clip.placeholderapi.util.Msg; -import org.apache.commons.lang.StringUtils; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import java.util.Set; -import java.util.stream.Collectors; - -public class PlaceholderAPICommands implements CommandExecutor { - - private final PlaceholderAPIPlugin plugin; - private final CommandExecutor eCloud; - - public PlaceholderAPICommands(PlaceholderAPIPlugin i) { - plugin = i; - eCloud = new ExpansionCloudCommands(i); - } - - @Override - public boolean onCommand(CommandSender s, Command c, String label, String[] args) { - if (args.length == 0) { - - Msg.msg(s, "PlaceholderAPI &7version &b&o" + plugin.getDescription().getVersion(), - "&fCreated by&7: &b" + plugin.getDescription().getAuthors(), - "&fPapi commands: &b/papi help", - "&fEcloud commands: &b/papi ecloud"); - - return true; - } else { - if (args[0].equalsIgnoreCase("help")) { - - Msg.msg(s, "PlaceholderAPI &aHelp &e(&f" + plugin.getDescription().getVersion() + "&e)", - "&b/papi", - "&fView plugin info/version info", - "&b/papi list", - "&fList all placeholder expansions that are currently active", - "&b/papi info ", - "&fView information for a specific expansion", - "&b/papi parse <(playername)/me> <...args>", - "&fParse a String with placeholders", - "&b/papi bcparse <(playername)/me> <...args>", - "&fParse a String with placeholders and broadcast the message", - "&b/papi parserel <...args>", - "&fParse a String with relational placeholders", - "&b/papi register ", - "&fRegister an expansion by the name of the file", - "&b/papi unregister ", - "&fUnregister an expansion by name", - "&b/papi reload", - "&fReload the config settings"); - - if (s.hasPermission("placeholderapi.ecloud")) { - Msg.msg(s, "&b/papi disablecloud", - "&fDisable the expansion cloud", - "&b/papi ecloud", - "&fView ecloud command usage"); - - Msg.msg(s, "&b/papi enablecloud", - "&fEnable the expansion cloud"); - } - - return true; - } else if (args[0].equalsIgnoreCase("ecloud")) { - if (!s.hasPermission("placeholderapi.ecloud")) { - Msg.msg(s, "&cYou don't have permission to do that!"); - - return true; - } - - if (plugin.getExpansionCloud() == null) { - Msg.msg(s, "&7The expansion cloud is not enabled!"); - - return true; - } - - return eCloud.onCommand(s, c, label, args); - } else if (args[0].equalsIgnoreCase("enablecloud")) { - if (!s.hasPermission("placeholderapi.ecloud")) { - Msg.msg(s, "&cYou don't have permission to do that!"); - - return true; - } - - if (plugin.getExpansionCloud() != null) { - Msg.msg(s, "&7The cloud is already enabled!"); - - return true; - } - - plugin.enableCloud(); - plugin.getPlaceholderAPIConfig().setCloudEnabled(true); - Msg.msg(s, "&aThe cloud has been enabled!"); - - return true; - } else if (args[0].equalsIgnoreCase("disablecloud")) { - if (!s.hasPermission("placeholderapi.ecloud")) { - Msg.msg(s, "&cYou don't have permission to do that!"); - - return true; - } - - if (plugin.getExpansionCloud() == null) { - Msg.msg(s, "&7The cloud is already disabled!"); - - return true; - } - - plugin.disableCloud(); - plugin.getPlaceholderAPIConfig().setCloudEnabled(false); - Msg.msg(s, "&aThe cloud has been disabled!"); - - return true; - } else if (args.length > 1 && args[0].equalsIgnoreCase("info")) { - if (!s.hasPermission("placeholderapi.info")) { - Msg.msg(s, "&cYou don't have permission to do that!"); - - return true; - } - - PlaceholderExpansion ex = plugin.getExpansionManager().getRegisteredExpansion(args[1]); - if (ex == null) { - Msg.msg(s, "&cThere is no expansion loaded with the identifier: &f" + args[1]); - - return true; - } - - Msg.msg(s, "&7Placeholder expansion info for: &f" + ex.getName()); - Msg.msg(s, "&7Status: " + (ex.isRegistered() ? "&aRegistered" : "&cNot registered")); - - if (ex.getAuthor() != null) { - Msg.msg(s, "&7Created by: &f" + ex.getAuthor()); - } - - if (ex.getVersion() != null) { - Msg.msg(s, "&7Version: &f" + ex.getVersion()); - } - - if (ex.getRequiredPlugin() != null) { - Msg.msg(s, "&7Requires plugin: &f" + ex.getRequiredPlugin()); - } - - if (ex.getPlaceholders() != null) { - Msg.msg(s, "&8&m-- &r&7Placeholders &8&m--"); - - for (String placeholder : ex.getPlaceholders()) { - Msg.msg(s, placeholder); - } - } - - return true; - } else if (args.length > 2 && args[0].equalsIgnoreCase("parse") - || args.length > 2 && args[0].equalsIgnoreCase("bcparse")) { - - if (!s.hasPermission("placeholderapi.parse")) { - Msg.msg(s, "&cYou don't have permission to do that!"); - - return true; - } - - OfflinePlayer pl; - - if (args[1].equalsIgnoreCase("me")) { - if (s instanceof Player) { - pl = (Player) s; - } else { - Msg.msg(s, "&cThis command must target a player when used by console"); - - return true; - } - } else { - if (Bukkit.getPlayer(args[1]) != null) { - pl = Bukkit.getPlayer(args[1]); - } else { - pl = Bukkit.getOfflinePlayer(args[1]); - } - } - - if (pl == null || (!pl.hasPlayedBefore() && !pl.isOnline())) { - Msg.msg(s, "&cFailed to find player: &f" + args[1]); - return true; - } - - String parse = StringUtils.join(args, " ", 2, args.length); - - if (args[0].equalsIgnoreCase("bcparse")) { - Msg.broadcast("&r" + PlaceholderAPI.setPlaceholders(pl, parse)); - } else { - Msg.msg(s, "&r" + PlaceholderAPI.setPlaceholders(pl, parse)); - } - - return true; - } else if (args.length > 3 && args[0].equalsIgnoreCase("parserel")) { - if (!(s instanceof Player)) { - Msg.msg(s, "&cThis command can only be used in game!"); - - return true; - } else { - if (!s.hasPermission("placeholderapi.parse")) { - Msg.msg(s, "&cYou don't have permission to do that!"); - - return true; - } - } - Player one = Bukkit.getPlayer(args[1]); - if (one == null) { - Msg.msg(s, args[1] + " &cis not online!"); - - return true; - } - - Player two = Bukkit.getPlayer(args[2]); - if (two == null) { - Msg.msg(s, args[2] + " &cis not online!"); - - return true; - } - - String parse = StringUtils.join(args, " ", 3, args.length); - Msg.msg(s, "&r" + PlaceholderAPI.setRelationalPlaceholders(one, two, parse)); - - return true; - } else if (args[0].equalsIgnoreCase("reload")) { - if (s instanceof Player) { - if (!s.hasPermission("placeholderapi.reload")) { - Msg.msg(s, "&cYou don't have permission to do that!"); - - return true; - } - } - - Msg.msg(s, "&fPlaceholder&7API &bconfiguration reloaded!"); - plugin.reloadConf(s); - } else if (args[0].equalsIgnoreCase("list")) { - if (s instanceof Player) { - if (!s.hasPermission("placeholderapi.list")) { - Msg.msg(s, "&cYou don't have permission to do that!"); - - return true; - } - } - - Set registered = PlaceholderAPI.getRegisteredIdentifiers(); - if (registered.isEmpty()) { - Msg.msg(s, "&7There are no placeholder hooks currently registered!"); - - return true; - } - - Msg.msg(s, registered.size() + " &7Placeholder hooks registered:"); - Msg.msg(s, registered.stream().sorted().collect(Collectors.joining(", "))); - } else if (args.length > 1 && args[0].equalsIgnoreCase("register")) { - if (s instanceof Player) { - if (!s.hasPermission("placeholderapi.register")) { - Msg.msg(s, "&cYou don't have permission to do that!"); - - return true; - } - } - - String fileName = args[1].replace(".jar", ""); - PlaceholderExpansion ex = plugin.getExpansionManager().registerExpansion(fileName); - - if (ex == null) { - Msg.msg(s, "&cFailed to register expansion from " + fileName); - - return true; - } - - Msg.msg(s, "&aSuccessfully registered expansion: &f" + ex.getName()); - } else if (args.length > 1 && args[0].equalsIgnoreCase("unregister")) { - - if (s instanceof Player) { - if (!s.hasPermission("placeholderapi.register")) { - Msg.msg(s, "&cYou don't have permission to do that!"); - - return true; - } - } - - PlaceholderExpansion ex = plugin.getExpansionManager().getRegisteredExpansion(args[1]); - if (ex == null) { - Msg.msg(s, "&cFailed to find expansion: &f" + args[1]); - - return true; - } - - if (PlaceholderAPI.unregisterExpansion(ex)) { - Msg.msg(s, "&aSuccessfully unregistered expansion: &f" + ex.getName()); - } else { - Msg.msg(s, "&cFailed to unregister expansion: &f" + ex.getName()); - } - - } else { - Msg.msg(s, "&cIncorrect usage! &7/papi help"); - } - } - - return true; - } - -} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/BcParseCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/BcParseCommand.java new file mode 100644 index 0000000..8808dc3 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/BcParseCommand.java @@ -0,0 +1,47 @@ +package me.clip.placeholderapi.commands.command; + +import me.clip.placeholderapi.PlaceholderAPI; +import me.clip.placeholderapi.commands.Command; +import me.clip.placeholderapi.util.Msg; +import org.apache.commons.lang.StringUtils; +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")); + } + + @Override + 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 { + if (Bukkit.getPlayer(input) != null) { + player = Bukkit.getPlayer(input); + } else { + player = Bukkit.getOfflinePlayer(input); + } + } + + 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/DisableEcloudCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/DisableEcloudCommand.java new file mode 100644 index 0000000..9e2e841 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/DisableEcloudCommand.java @@ -0,0 +1,29 @@ +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 DisableEcloudCommand extends Command { + public DisableEcloudCommand() { + super("disablecloud", permissions("placeholderapi.ecloud")); + } + + @Override + 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 new file mode 100644 index 0000000..b37899e --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/EcloudCommand.java @@ -0,0 +1,81 @@ +package me.clip.placeholderapi.commands.command; + +import com.google.common.collect.Sets; +import me.clip.placeholderapi.PlaceholderAPIPlugin; +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; +import java.util.Set; + +public final class EcloudCommand extends Command { + private static final int MAXIMUM_ARGUMENTS = 1; + private static final Set COMPLETIONS = Sets.newHashSet( + "clear", + "download", + "info", + "list", + "placeholders", + "refresh", + "status", + "versioninfo" + ); + + public EcloudCommand() { + super("ecloud", permissions("placeholderapi.ecloud")); + } + + @Override + 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", + " ", + "&b/papi ecloud status", + "&fView status of the ecloud", + "&b/papi ecloud list (page)", + "&fList all/author specific available expansions", + "&b/papi ecloud info ", + "&fView information about a specific expansion available on the cloud", + "&b/papi ecloud versioninfo ", + "&fView information about a specific version of an expansion", + "&b/papi ecloud placeholders ", + "&fView placeholders for an expansion", + "&b/papi ecloud download (version)", + "&fDownload an expansion from the ecloud", + "&b/papi ecloud refresh", + "&fFetch the most up to date list of expansions available.", + "&b/papi ecloud clear", + "&fClear the expansion cloud cache."); + return; + } + + if (plugin.getExpansionCloud() == null) { + Msg.msg(sender, "&7The expansion cloud is not enabled!"); + + return; + } + + if (plugin.getExpansionCloud().getCloudExpansions().isEmpty()) { + Msg.msg(sender, "&7No cloud expansions are available at this time."); + return; + } + + sender.sendMessage("Specified command is not valid."); + } + + @NotNull + @Override + 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())); + } + + return super.handleCompletion(sender, args); + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/EnableCloudCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/EnableCloudCommand.java new file mode 100644 index 0000000..f82ce4e --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/EnableCloudCommand.java @@ -0,0 +1,27 @@ +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 EnableCloudCommand extends Command { + public EnableCloudCommand() { + super("enablecloud", permissions("placeholderapi.ecloud")); + } + + @Override + 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; + } + + plugin.enableCloud(); + plugin.getPlaceholderAPIConfig().setCloudEnabled(true); + Msg.msg(sender, "&aThe cloud has been enabled!"); + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/HelpCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/HelpCommand.java new file mode 100644 index 0000000..0ef952f --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/HelpCommand.java @@ -0,0 +1,46 @@ +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 HelpCommand extends Command { + public HelpCommand() { + super("help", permissions("placeholderapi.ecloud")); + } + + @Override + 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", + "&b/papi list", + "&fList all placeholder expansions that are currently active", + "&b/papi info ", + "&fView information for a specific expansion", + "&b/papi parse <(playername)/me> <...args>", + "&fParse a String with placeholders", + "&b/papi bcparse <(playername)/me> <...args>", + "&fParse a String with placeholders and broadcast the message", + "&b/papi parserel <...args>", + "&fParse a String with relational placeholders", + "&b/papi register ", + "&fRegister an expansion by the name of the file", + "&b/papi unregister ", + "&fUnregister an expansion by name", + "&b/papi reload", + "&fReload the config settings"); + + if (sender.hasPermission("placeholderapi.ecloud")) { + Msg.msg(sender, "&b/papi disablecloud", + "&fDisable the expansion cloud", + "&b/papi ecloud", + "&fView ecloud command usage", + "&b/papi enablecloud", + "&fEnable the expansion cloud"); + + } + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/InfoCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/InfoCommand.java new file mode 100644 index 0000000..8987932 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/InfoCommand.java @@ -0,0 +1,68 @@ +package me.clip.placeholderapi.commands.command; + +import me.clip.placeholderapi.PlaceholderAPI; +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.bukkit.command.CommandSender; +import org.bukkit.util.StringUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +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")); + } + + @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); + if (ex == null) { + Msg.msg(sender, "&cThere is no expansion loaded with the identifier: &f" + requestedExpansion); + + return; + } + + Msg.msg(sender, "&7Placeholder expansion info for: &f" + ex.getName()); + Msg.msg(sender, "&7Status: " + (ex.isRegistered() ? "&aRegistered" : "&cNot registered")); + + if (ex.getAuthor() != null) { + Msg.msg(sender, "&7Created by: &f" + ex.getAuthor()); + } + + if (ex.getVersion() != null) { + Msg.msg(sender, "&7Version: &f" + ex.getVersion()); + } + + if (ex.getRequiredPlugin() != null) { + Msg.msg(sender, "&7Requires plugin: &f" + ex.getRequiredPlugin()); + } + + if (ex.getPlaceholders() != null) { + Msg.msg(sender, "&8&m-- &r&7Placeholders &8&m--"); + + for (String placeholder : ex.getPlaceholders()) { + Msg.msg(sender, placeholder); + } + } + } + + @NotNull + @Override + public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { + if (args.length == MINIMUM_ARGUMENTS) { + final Set completions = PlaceholderAPI.getRegisteredIdentifiers(); + + return StringUtil.copyPartialMatches(args[0], completions, new ArrayList<>(completions.size())); + } + + return super.handleCompletion(sender, args); + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ListCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ListCommand.java new file mode 100644 index 0000000..ba8aa66 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/ListCommand.java @@ -0,0 +1,28 @@ +package me.clip.placeholderapi.commands.command; + +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")); + } + + @Override + 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; + } + + Msg.msg(sender, registered.size() + " &7Placeholder hooks registered:", + registered.stream().sorted().collect(Collectors.joining(", "))); + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ParseCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ParseCommand.java new file mode 100644 index 0000000..4166a47 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/ParseCommand.java @@ -0,0 +1,47 @@ +package me.clip.placeholderapi.commands.command; + +import me.clip.placeholderapi.PlaceholderAPI; +import me.clip.placeholderapi.commands.Command; +import me.clip.placeholderapi.util.Msg; +import org.apache.commons.lang.StringUtils; +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 ParseCommand extends Command { + public ParseCommand() { + super("parse", options("&cYou must specify a player.", 1, "placeholderapi.parse")); + } + + @Override + 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 { + if (Bukkit.getPlayer(input) != null) { + player = Bukkit.getPlayer(input); + } else { + player = Bukkit.getOfflinePlayer(input); + } + } + + 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)); + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ParseRelCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ParseRelCommand.java new file mode 100644 index 0000000..20afb90 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/ParseRelCommand.java @@ -0,0 +1,36 @@ +package me.clip.placeholderapi.commands.command; + +import me.clip.placeholderapi.PlaceholderAPI; +import me.clip.placeholderapi.commands.Command; +import me.clip.placeholderapi.util.Msg; +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")); + } + + @Override + 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; + } + + final 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); + 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 new file mode 100644 index 0000000..6df7b74 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/RegisterCommand.java @@ -0,0 +1,28 @@ +package me.clip.placeholderapi.commands.command; + +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.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")); + } + + @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); + + if (expansion == null) { + Msg.msg(sender, "&cFailed to register expansion from " + fileName); + + return; + } + + Msg.msg(sender, "&aSuccessfully registered expansion: &f" + expansion.getName()); + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ReloadCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ReloadCommand.java new file mode 100644 index 0000000..cf01301 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/ReloadCommand.java @@ -0,0 +1,19 @@ +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 ReloadCommand extends Command { + public ReloadCommand() { + super("reload", permissions("placeholderapi.reload")); + } + + @Override + 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 new file mode 100644 index 0000000..b20657e --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/UnregisterCommand.java @@ -0,0 +1,53 @@ +package me.clip.placeholderapi.commands.command; + +import me.clip.placeholderapi.PlaceholderAPI; +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.bukkit.command.CommandSender; +import org.bukkit.util.StringUtil; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +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")); + } + + @Override + 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; + } + + if (PlaceholderAPI.unregisterExpansion(expansion)) { + Msg.msg(sender, "&aSuccessfully unregistered expansion: &f" + expansion.getName()); + } else { + Msg.msg(sender, "&cFailed to unregister expansion: &f" + expansion.getName()); + } + } + + @NotNull + @Override + public List handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) { + if (args.length == MINIMUM_ARGUMENTS) { + final Set completions = PlaceholderAPI.getRegisteredIdentifiers(); + + return StringUtil.copyPartialMatches(args[0], completions, new ArrayList<>(completions.size())); + } + + return super.handleCompletion(sender, args); + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/VersionCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/VersionCommand.java new file mode 100644 index 0000000..efab041 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/VersionCommand.java @@ -0,0 +1,55 @@ +package me.clip.placeholderapi.commands.command; + +import com.google.common.collect.Sets; +import me.clip.placeholderapi.PlaceholderAPIPlugin; +import me.clip.placeholderapi.commands.Command; +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; +import java.util.Set; + +public final class VersionCommand extends Command { + private static final Set COMPLETIONS = Sets.newHashSet( + "unregister", + "reload", + "register", + "parserel", + "parse", + "list", + "info", + "help", + "ecloud", + "enablecloud", + "disablecloud", + "bcparse" + ); + + public VersionCommand() { + super("version"); + } + + @Override + 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(), + "&fPapi commands: &b/papi help", + "&fEcloud commands: &b/papi ecloud"); + } + + @NotNull + @Override + 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())); + } + + return super.handleCompletion(sender, args); + } +} \ No newline at end of file diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/ClearCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/ClearCommand.java new file mode 100644 index 0000000..db6a3c3 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/ClearCommand.java @@ -0,0 +1,19 @@ +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 ClearCommand extends Command { + public ClearCommand() { + super("ecloud clear", permissions("placeholderapi.ecloud")); + } + + @Override + 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/DownloadCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/DownloadCommand.java new file mode 100644 index 0000000..7402104 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/DownloadCommand.java @@ -0,0 +1,55 @@ +package me.clip.placeholderapi.commands.command.ecloud; + +import me.clip.placeholderapi.PlaceholderAPI; +import me.clip.placeholderapi.PlaceholderAPIPlugin; +import me.clip.placeholderapi.commands.Command; +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import me.clip.placeholderapi.expansion.cloud.CloudExpansion; +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 DownloadCommand extends Command { + public DownloadCommand() { + super("ecloud download", options("&cAn expansion name must be specified!", 1, "placeholderapi.ecloud")); + } + + @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); + + if (expansion == null) { + Msg.msg(sender, "&cNo expansion found with the name: &f" + input); + return; + } + + final PlaceholderExpansion loaded = plugin.getExpansionManager().getRegisteredExpansion(input); + if (loaded != null && loaded.isRegistered()) { + PlaceholderAPI.unregisterPlaceholderHook(loaded.getIdentifier()); + } + + String version = expansion.getLatestVersion(); + + if (args.length == 2) { + version = args[1]; + if (expansion.getVersion(version) == null) { + Msg.msg(sender, "&cThe version you specified does not exist for &f" + expansion.getName()); + Msg.msg(sender, "&7Available versions: &f" + expansion.getVersions().size()); + Msg.msg(sender, String.join("&a, &f", expansion.getAvailableVersions())); + + return; + } + } + + 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(); + cloud.downloadExpansion(player, expansion, version); + cloud.clean(); + cloud.fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions()); + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/InfoCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/InfoCommand.java new file mode 100644 index 0000000..0d06da4 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/InfoCommand.java @@ -0,0 +1,70 @@ +package me.clip.placeholderapi.commands.command.ecloud; + +import me.clip.placeholderapi.PlaceholderAPIPlugin; +import me.clip.placeholderapi.commands.Command; +import me.clip.placeholderapi.expansion.cloud.CloudExpansion; +import me.clip.placeholderapi.util.JSONMessage; +import me.clip.placeholderapi.util.Msg; +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 InfoCommand extends Command { + public InfoCommand() { + super("ecloud info", options("&cAn expansion name must be specified!", 1, "placeholderapi.ecloud")); + } + + @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); + + if (expansion == null) { + Msg.msg(sender, "&cNo expansion found by the name: &f" + input); + + return; + } + + if (!(sender instanceof Player)) { + Msg.msg(sender, + (expansion.shouldUpdate() ? "&e" : "") + expansion.getName() + " &8&m-- &r" + expansion + .getVersion().getUrl()); + + return; + } + + final Player p = (Player) sender; + + Msg.msg(sender, "&bExpansion&7: &f" + expansion.getName(), + "&bAuthor: &f" + expansion.getAuthor(), + "&bVerified: &f" + expansion.isVerified() + ); + + // latest version + 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() + )); + latestVersion.send(p); + + // versions + final JSONMessage versions = JSONMessage + .create(color("&bVersions available: &f" + expansion.getVersions().size())); + versions.tooltip(color(String.join("&b, &f", expansion.getAvailableVersions()))); + versions.suggestCommand( + "/papi ecloud versioninfo " + expansion.getName() + " " + expansion.getLatestVersion()); + versions.send(p); + + // placeholders + if (expansion.getPlaceholders() != null) { + 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()); + placeholders.send(p); + } + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/ListCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/ListCommand.java new file mode 100644 index 0000000..a3680fc --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/ListCommand.java @@ -0,0 +1,208 @@ +package me.clip.placeholderapi.commands.command.ecloud; + +import com.google.common.collect.Sets; +import me.clip.placeholderapi.PlaceholderAPIPlugin; +import me.clip.placeholderapi.commands.Command; +import me.clip.placeholderapi.expansion.cloud.CloudExpansion; +import me.clip.placeholderapi.util.JSONMessage; +import me.clip.placeholderapi.util.Msg; +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; + +import static me.clip.placeholderapi.util.Msg.color; + +public final class ListCommand extends Command { + private static final int MINIMUM_ARGUMENTS = 1; + private static final Set COMPLETIONS = Sets.newHashSet( + "all", + "author", + "installed" + ); + + public ListCommand() { + super("ecloud list", options("&cIncorrect usage! &7/papi ecloud list (page)", + MINIMUM_ARGUMENTS, "placeholderapi.ecloud")); + } + + @Override + public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) { + final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance(); + int page = 1; + + String author; + boolean installed = false; + + author = args[0]; + + if (author.equalsIgnoreCase("all")) { + author = null; + } else if (author.equalsIgnoreCase("installed")) { + author = null; + installed = true; + } + + if (args.length >= 2) { + try { + page = Integer.parseInt(args[1]); + } catch (NumberFormatException ex) { + Msg.msg(sender, "&cPage number must be an integer!"); + + return; + } + } + + if (page < 1) { + Msg.msg(sender, "&cPage must be greater than or equal to 1!"); + + return; + } + + int avail; + Map ex; + + if (installed) { + ex = plugin.getExpansionCloud().getAllInstalled(); + } else if (author == null) { + ex = plugin.getExpansionCloud().getCloudExpansions(); + } else { + ex = plugin.getExpansionCloud().getAllByAuthor(author); + } + + if (ex == null || ex.isEmpty()) { + Msg.msg(sender, "&cNo expansions available" + (author != null ? " for author &f" + author : "")); + + return; + } + + avail = plugin.getExpansionCloud().getPagesAvailable(ex, 10); + if (page > avail) { + Msg.msg(sender, "&cThere " + ((avail == 1) ? " is only &f" + avail + " &cpage available!" + : "are only &f" + avail + " &cpages available!")); + + return; + } + + Msg.msg(sender, "&bShowing expansions for&7: &f" + (author != null ? author + : (installed ? "all installed" : "all available")) + " &8&m--&r &bamount&7: &f" + ex + .size() + " &bpage&7: &f" + page + "&7/&f" + avail); + + ex = plugin.getExpansionCloud().getPage(ex, page, 10); + + if (ex == null) { + Msg.msg(sender, "&cThere was a problem getting the requested page..."); + + return; + } + + Msg.msg(sender, "&aGreen = Expansions you have"); + Msg.msg(sender, "&6Gold = Expansions which need updated"); + + if (!(sender instanceof Player)) { + final Map expansions = new HashMap<>(); + + for (CloudExpansion exp : ex.values()) { + if (exp == null || exp.getName() == null) { + continue; + } + + expansions.put(exp.getName(), exp); + } + + final List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); + + int i = (int) ex.keySet().toArray()[0]; + + for (String name : ce) { + if (expansions.get(name) == null) { + continue; + } + + final CloudExpansion expansion = expansions.get(name); + + Msg.msg(sender, + "&b" + i + "&7: " + (expansion.shouldUpdate() ? "&6" + : (expansion.hasExpansion() ? "&a" : "&7")) + expansion + .getName() + " &8&m-- &r" + expansion.getVersion().getUrl()); + i++; + } + + return; + } + + final Player p = (Player) sender; + + final Map expansions = new HashMap<>(); + + for (final CloudExpansion exp : ex.values()) { + if (exp == null || exp.getName() == null) { + continue; + } + + expansions.put(exp.getName(), exp); + } + + final List ce = expansions.keySet().stream().sorted().collect(Collectors.toList()); + + int i = page > 1 ? page * 10 : 0; + + for (String name : ce) { + if (expansions.get(name) == null) { + continue; + } + + 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"); + } else if (!expansion.hasExpansion()) { + sb.append("&bClick to download this expansion\n\n"); + } else { + sb.append("&aYou have the latest version of this expansion\n\n"); + } + + sb.append("&bAuthor&7: &f").append(expansion.getAuthor()).append("\n"); + sb.append("&bVerified&7: &f").append(expansion.isVerified()).append("\n"); + sb.append("&bLatest version&7: &f").append(expansion.getVersion().getVersion()).append("\n"); + sb.append("&bLast updated&7: &f").append(expansion.getTimeSinceLastUpdate()).append(" ago\n"); + sb.append("\n").append(expansion.getDescription()); + + final String msg = color( + "&b" + (i + 1) + "&7: " + (expansion.shouldUpdate() ? "&6" + : (expansion.hasExpansion() ? "&a" : "")) + expansion.getName()); + + final String hover = color(sb.toString()); + + final JSONMessage line = JSONMessage.create(msg); + line.tooltip(hover); + + if (expansion.shouldUpdate() || !expansion.hasExpansion()) { + line.suggestCommand("/papi ecloud download " + expansion.getName()); + } else { + line.suggestCommand("/papi ecloud info " + expansion.getName()); + } + + line.send(p); + i++; + } + } + + @NotNull + @Override + 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())); + } + + if (args.length == MINIMUM_ARGUMENTS + 1) { + return Collections.singletonList("Pages"); + } + + return super.handleCompletion(sender, args); + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/PlaceholdersCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/PlaceholdersCommand.java new file mode 100644 index 0000000..47919ce --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/PlaceholdersCommand.java @@ -0,0 +1,63 @@ +package me.clip.placeholderapi.commands.command.ecloud; + +import me.clip.placeholderapi.PlaceholderAPI; +import me.clip.placeholderapi.PlaceholderAPIPlugin; +import me.clip.placeholderapi.commands.Command; +import me.clip.placeholderapi.expansion.cloud.CloudExpansion; +import me.clip.placeholderapi.util.JSONMessage; +import me.clip.placeholderapi.util.Msg; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public final class PlaceholdersCommand extends Command { + public PlaceholdersCommand() { + super("ecloud placeholders", options("&cAn expansion name must be specified!", 1, "placeholderapi.ecloud")); + } + + @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); + if (expansion == null) { + Msg.msg(sender, "&cNo expansion found by the name: &f" + input); + + return; + } + + final List placeholders = expansion.getPlaceholders(); + if (placeholders == null) { + Msg.msg(sender, "&cThe expansion: &f" + expansion.getName() + + " &cdoes not have any placeholders listed.", + "&7You should contact &f" + expansion.getAuthor() + " &7and ask for them to be added."); + + return; + } + + if (!(sender instanceof Player) + || plugin.getExpansionManager().getRegisteredExpansion(expansion.getName()) == null) { + Msg.msg(sender, "&bPlaceholders: &f" + placeholders.size(), + String.join("&a, &f", placeholders)); + + return; + } + + 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 (final Exception ignored) { + // Ignored exception + } + } + + message.send(p); + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/RefreshCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/RefreshCommand.java new file mode 100644 index 0000000..e9ec785 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/RefreshCommand.java @@ -0,0 +1,23 @@ +package me.clip.placeholderapi.commands.command.ecloud; + +import me.clip.placeholderapi.PlaceholderAPIPlugin; +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 RefreshCommand extends Command { + public RefreshCommand() { + super("ecloud refresh", permissions("placeholderapi.ecloud")); + } + + @Override + 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/StatusCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/StatusCommand.java new file mode 100644 index 0000000..2bbf8ad --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/StatusCommand.java @@ -0,0 +1,26 @@ +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 StatusCommand extends Command { + public StatusCommand() { + super("ecloud status", permissions("placeholderapi.ecloud")); + } + + @Override + 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() + + " &7authors have contributed to the expansion cloud."); + if (plugin.getExpansionCloud().getToUpdateCount() > 0) { + Msg.msg(sender, "&eYou have &f" + plugin.getExpansionCloud().getToUpdateCount() + + " &eexpansions installed that have updates available."); + } + } +} diff --git a/src/main/java/me/clip/placeholderapi/commands/command/ecloud/VersionInfoCommand.java b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/VersionInfoCommand.java new file mode 100644 index 0000000..2b64115 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/commands/command/ecloud/VersionInfoCommand.java @@ -0,0 +1,48 @@ +package me.clip.placeholderapi.commands.command.ecloud; + +import me.clip.placeholderapi.PlaceholderAPIPlugin; +import me.clip.placeholderapi.commands.Command; +import me.clip.placeholderapi.expansion.cloud.CloudExpansion; +import me.clip.placeholderapi.util.JSONMessage; +import me.clip.placeholderapi.util.Msg; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +public final class VersionInfoCommand extends Command { + public VersionInfoCommand() { + super("ecloud versioninfo", options("&cIncorrect usage! &7/papi ecloud versioninfo ", + 2, "placeholderapi.ecloud")); + } + + @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); + if (expansion == null) { + Msg.msg(sender, "&cNo expansion found by the name: &f" + input); + return; + } + + 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; + } + + Msg.msg(sender, "&bExpansion: " + (expansion.shouldUpdate() ? "&e" : "&f") + expansion.getName(), + "&bVersion: &f" + version.getVersion(), + "&bVersion info: &f" + version.getReleaseNotes()); + + if (!(sender instanceof Player)) { + Msg.msg(sender, "&bDownload url: " + version.getUrl()); + return; + } + + 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()); + download.send(p); + } +} diff --git a/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java b/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java index cf76252..b2824ca 100644 --- a/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java +++ b/src/main/java/me/clip/placeholderapi/configuration/PlaceholderAPIConfig.java @@ -24,47 +24,47 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin; public class PlaceholderAPIConfig { - private final PlaceholderAPIPlugin plugin; + private final PlaceholderAPIPlugin plugin; - public PlaceholderAPIConfig(PlaceholderAPIPlugin i) { - plugin = i; - } + public PlaceholderAPIConfig(PlaceholderAPIPlugin i) { + plugin = i; + } - public void loadDefConfig() { - plugin.saveDefaultConfig(); - plugin.reloadConfig(); - } + public void loadDefConfig() { + plugin.saveDefaultConfig(); + plugin.reloadConfig(); + } - public boolean checkUpdates() { - return plugin.getConfig().getBoolean("check_updates"); - } + public boolean checkUpdates() { + return plugin.getConfig().getBoolean("check_updates"); + } - public boolean cloudAllowUnverifiedExpansions() { - return plugin.getConfig().getBoolean("cloud_allow_unverified_expansions"); - } + public boolean cloudAllowUnverifiedExpansions() { + return plugin.getConfig().getBoolean("cloud_allow_unverified_expansions"); + } - public boolean isCloudEnabled() { - return plugin.getConfig().getBoolean("cloud_enabled"); - } + public boolean isCloudEnabled() { + return plugin.getConfig().getBoolean("cloud_enabled"); + } - public boolean isDebugMode() { - return plugin.getConfig().getBoolean("debug", false); - } + public void setCloudEnabled(boolean b) { + plugin.getConfig().set("cloud_enabled", b); + plugin.reloadConfig(); + } - public void setCloudEnabled(boolean b) { - plugin.getConfig().set("cloud_enabled", b); - plugin.reloadConfig(); - } + public boolean isDebugMode() { + return plugin.getConfig().getBoolean("debug", false); + } - public String booleanTrue() { - return plugin.getConfig().getString("boolean.true"); - } + public String booleanTrue() { + return plugin.getConfig().getString("boolean.true"); + } - public String booleanFalse() { - return plugin.getConfig().getString("boolean.false"); - } + public String booleanFalse() { + return plugin.getConfig().getString("boolean.false"); + } - public String dateFormat() { - return plugin.getConfig().getString("date_format"); - } + public String dateFormat() { + return plugin.getConfig().getString("date_format"); + } } diff --git a/src/main/java/me/clip/placeholderapi/events/ExpansionRegisterEvent.java b/src/main/java/me/clip/placeholderapi/events/ExpansionRegisterEvent.java index f493bd6..f589074 100644 --- a/src/main/java/me/clip/placeholderapi/events/ExpansionRegisterEvent.java +++ b/src/main/java/me/clip/placeholderapi/events/ExpansionRegisterEvent.java @@ -27,35 +27,35 @@ import org.bukkit.event.HandlerList; public class ExpansionRegisterEvent extends Event implements Cancellable { - private static final HandlerList HANDLERS = new HandlerList(); - private final PlaceholderExpansion expansion; - private boolean isCancelled; + private static final HandlerList HANDLERS = new HandlerList(); + private final PlaceholderExpansion expansion; + private boolean isCancelled; - public ExpansionRegisterEvent(PlaceholderExpansion expansion) { - this.expansion = expansion; - } + public ExpansionRegisterEvent(PlaceholderExpansion expansion) { + this.expansion = expansion; + } - public static HandlerList getHandlerList() { - return HANDLERS; - } + public static HandlerList getHandlerList() { + return HANDLERS; + } - @Override - public HandlerList getHandlers() { - return HANDLERS; - } + @Override + public HandlerList getHandlers() { + return HANDLERS; + } - public PlaceholderExpansion getExpansion() { - return expansion; - } + public PlaceholderExpansion getExpansion() { + return expansion; + } - @Override - public boolean isCancelled() { - return isCancelled; - } + @Override + public boolean isCancelled() { + return isCancelled; + } - @Override - public void setCancelled(boolean b) { - this.isCancelled = b; - } + @Override + public void setCancelled(boolean b) { + this.isCancelled = b; + } } diff --git a/src/main/java/me/clip/placeholderapi/events/ExpansionUnregisterEvent.java b/src/main/java/me/clip/placeholderapi/events/ExpansionUnregisterEvent.java index de33feb..5db1bb8 100644 --- a/src/main/java/me/clip/placeholderapi/events/ExpansionUnregisterEvent.java +++ b/src/main/java/me/clip/placeholderapi/events/ExpansionUnregisterEvent.java @@ -26,23 +26,23 @@ import org.bukkit.event.HandlerList; public class ExpansionUnregisterEvent extends Event { - private static final HandlerList HANDLERS = new HandlerList(); - private final PlaceholderExpansion expansion; + private static final HandlerList HANDLERS = new HandlerList(); + private final PlaceholderExpansion expansion; - public ExpansionUnregisterEvent(PlaceholderExpansion expansion) { - this.expansion = expansion; - } + public ExpansionUnregisterEvent(PlaceholderExpansion expansion) { + this.expansion = expansion; + } - public static HandlerList getHandlerList() { - return HANDLERS; - } + public static HandlerList getHandlerList() { + return HANDLERS; + } - @Override - public HandlerList getHandlers() { - return HANDLERS; - } + @Override + public HandlerList getHandlers() { + return HANDLERS; + } - public PlaceholderExpansion getExpansion() { - return expansion; - } + public PlaceholderExpansion getExpansion() { + return expansion; + } } diff --git a/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java b/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java index a75941b..307a103 100644 --- a/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java +++ b/src/main/java/me/clip/placeholderapi/events/PlaceholderHookUnloadEvent.java @@ -27,29 +27,29 @@ import org.bukkit.event.HandlerList; @Deprecated public class PlaceholderHookUnloadEvent extends Event { - private static final HandlerList HANDLERS = new HandlerList(); - private final String plugin; - private final PlaceholderHook hook; + private static final HandlerList HANDLERS = new HandlerList(); + private final String plugin; + private final PlaceholderHook hook; - public PlaceholderHookUnloadEvent(String plugin, PlaceholderHook placeholderHook) { - this.plugin = plugin; - this.hook = placeholderHook; - } + public PlaceholderHookUnloadEvent(String plugin, PlaceholderHook placeholderHook) { + this.plugin = plugin; + this.hook = placeholderHook; + } - public static HandlerList getHandlerList() { - return HANDLERS; - } + public static HandlerList getHandlerList() { + return HANDLERS; + } - @Override - public HandlerList getHandlers() { - return HANDLERS; - } + @Override + public HandlerList getHandlers() { + return HANDLERS; + } - public String getHookName() { - return plugin; - } + public String getHookName() { + return plugin; + } - public PlaceholderHook getHook() { - return hook; - } + public PlaceholderHook getHook() { + return hook; + } } 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 caf4e5d..a2560dd 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Cacheable.java @@ -29,8 +29,8 @@ package me.clip.placeholderapi.expansion; */ public interface Cacheable { - /** - * Called when the implementing class is unregistered from PlaceholderAPI - */ - void clear(); + /** + * Called when the implementing class is unregistered from PlaceholderAPI + */ + void clear(); } diff --git a/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java b/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java index bd6e8f0..8bb798f 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Cleanable.java @@ -31,10 +31,10 @@ import org.bukkit.entity.Player; */ public interface Cleanable { - /** - * Called when a player leaves the server - * - * @param p (@link Player} who left the server - */ - void cleanup(Player p); + /** + * Called when a player leaves the server + * + * @param p (@link Player} who left the server + */ + void cleanup(Player p); } diff --git a/src/main/java/me/clip/placeholderapi/expansion/Configurable.java b/src/main/java/me/clip/placeholderapi/expansion/Configurable.java index 488c08d..ae9f81e 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Configurable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Configurable.java @@ -30,14 +30,14 @@ import java.util.Map; */ public interface Configurable { - /** - * This method will be called before the implementing class is registered to obtain a map of - * configuration options that the implementing class needs These paths and values will be added to - * the PlaceholderAPI config.yml in the configuration section expansions.(placeholder - * identifier).(your key): (your value) - * - * @return Map of config path / values which need to be added / removed from the PlaceholderAPI - * config.yml file - */ - Map getDefaults(); + /** + * This method will be called before the implementing class is registered to obtain a map of + * configuration options that the implementing class needs These paths and values will be added to + * the PlaceholderAPI config.yml in the configuration section expansions.(placeholder + * identifier).(your key): (your value) + * + * @return Map of config path / values which need to be added / removed from the PlaceholderAPI + * config.yml file + */ + Map getDefaults(); } diff --git a/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java b/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java index b679c83..faa1f68 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/ExpansionManager.java @@ -36,178 +36,178 @@ import java.util.Map; import java.util.Map.Entry; public final class ExpansionManager { - private final PlaceholderAPIPlugin plugin; + private final PlaceholderAPIPlugin plugin; - public ExpansionManager(PlaceholderAPIPlugin instance) { - plugin = instance; + public ExpansionManager(PlaceholderAPIPlugin instance) { + plugin = instance; - 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() instanceof PlaceholderExpansion) { - if (name.equalsIgnoreCase(hook.getKey())) { - return (PlaceholderExpansion) hook.getValue(); + File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), "expansions"); + if (!f.exists()) { + f.mkdirs(); } - } } - return null; - } - - public boolean registerExpansion(PlaceholderExpansion expansion) { - if (expansion == null || expansion.getIdentifier() == null) { - return false; - } - - if (expansion instanceof Configurable) { - Map defaults = ((Configurable) expansion).getDefaults(); - String pre = "expansions." + expansion.getIdentifier() + "."; - FileConfiguration cfg = plugin.getConfig(); - boolean save = false; - - if (defaults != null) { - for (Entry entries : defaults.entrySet()) { - if (entries.getKey() == null || entries.getKey().isEmpty()) { - continue; - } - - if (entries.getValue() == null) { - if (cfg.contains(pre + entries.getKey())) { - save = true; - cfg.set(pre + entries.getKey(), 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(); + } } - } else { - if (!cfg.contains(pre + entries.getKey())) { - save = true; - cfg.set(pre + entries.getKey(), entries.getValue()); + } + + return null; + } + + public boolean registerExpansion(PlaceholderExpansion expansion) { + if (expansion == null || expansion.getIdentifier() == null) { + return false; + } + + if (expansion instanceof Configurable) { + Map defaults = ((Configurable) expansion).getDefaults(); + String pre = "expansions." + expansion.getIdentifier() + "."; + FileConfiguration cfg = plugin.getConfig(); + boolean save = false; + + if (defaults != null) { + for (Entry entries : defaults.entrySet()) { + if (entries.getKey() == null || entries.getKey().isEmpty()) { + continue; + } + + 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 (save) { + plugin.saveConfig(); + plugin.reloadConfig(); } - } } - } - if (save) { - plugin.saveConfig(); - plugin.reloadConfig(); - } - } - - 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.canRegister()) { - return false; - } - - if (!expansion.register()) { - return false; - } - - if (expansion instanceof Listener) { - Listener l = (Listener) expansion; - Bukkit.getPluginManager().registerEvents(l, plugin); - } - - plugin.getLogger().info("Successfully registered expansion: " + expansion.getIdentifier()); - - if (expansion instanceof Taskable) { - ((Taskable) expansion).start(); - } - - if (plugin.getExpansionCloud() != null) { - CloudExpansion ce = plugin.getExpansionCloud().getCloudExpansion(expansion.getIdentifier()); - - if (ce != null) { - ce.setHasExpansion(true); - if (!ce.getLatestVersion().equals(expansion.getVersion())) { - ce.setShouldUpdate(true); + 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.canRegister()) { + return false; + } + + if (!expansion.register()) { + return false; + } + + if (expansion instanceof Listener) { + Listener l = (Listener) expansion; + Bukkit.getPluginManager().registerEvents(l, plugin); + } + + plugin.getLogger().info("Successfully registered expansion: " + expansion.getIdentifier()); + + if (expansion instanceof Taskable) { + ((Taskable) expansion).start(); + } + + if (plugin.getExpansionCloud() != null) { + CloudExpansion ce = plugin.getExpansionCloud().getCloudExpansion(expansion.getIdentifier()); + + if (ce != null) { + ce.setHasExpansion(true); + if (!ce.getLatestVersion().equals(expansion.getVersion())) { + ce.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; + } - public PlaceholderExpansion registerExpansion(String fileName) { - List> subs = FileUtil.getClasses("expansions", fileName, PlaceholderExpansion.class); - if (subs == null || 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; + } + + 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; + public void registerAllExpansions() { + if (plugin == null) { + return; + } + + List> subs = FileUtil.getClasses("expansions", null, PlaceholderExpansion.class); + if (subs == null || subs.isEmpty()) { + return; + } + + 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(); + } + } + } } - return null; - } + private PlaceholderExpansion createInstance(Class klass) { + if (klass == null) { + return null; + } - public void registerAllExpansions() { - if (plugin == null) { - return; - } + PlaceholderExpansion ex = null; + if (!PlaceholderExpansion.class.isAssignableFrom(klass)) { + return null; + } - List> subs = FileUtil.getClasses("expansions", null, PlaceholderExpansion.class); - if (subs == null || subs.isEmpty()) { - return; - } - - 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(); + 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()); } - } - } - } - private PlaceholderExpansion createInstance(Class klass) { - if (klass == null) { - return null; + return ex; } - - PlaceholderExpansion ex = null; - if (!PlaceholderExpansion.class.isAssignableFrom(klass)) { - 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/expansion/NMSVersion.java b/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java index 44a6d6b..2f7d89e 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/NMSVersion.java @@ -38,26 +38,27 @@ public enum NMSVersion { 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_15_R1("v1_15_R1"), + SPIGOT_1_16_R1("v1_16_R1"); - private final String version; + private final String version; - NMSVersion(String version) { - this.version = version; - } - - public static NMSVersion getVersion(String version) { - for (NMSVersion v : values()) { - if (v.getVersion().equalsIgnoreCase(version)) { - return v; - } + NMSVersion(String version) { + this.version = version; } - return NMSVersion.UNKNOWN; - } + public static NMSVersion getVersion(String version) { + for (NMSVersion v : values()) { + if (v.getVersion().equalsIgnoreCase(version)) { + return v; + } + } - public String getVersion() { - return version; - } + 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 23a974a..4ebdb51 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/PlaceholderExpansion.java @@ -31,170 +31,170 @@ import java.util.List; public abstract class PlaceholderExpansion extends PlaceholderHook { - /** - * The name of this expansion - * - * @return {@link #getIdentifier()} by default, name of this expansion if specified - */ - public String getName() { - return getIdentifier(); - } + /** + * The name of this expansion + * + * @return {@link #getIdentifier()} by default, name of this expansion if specified + */ + public String getName() { + return getIdentifier(); + } - /** - * The placeholder identifier of this expansion - * - * @return placeholder identifier that is associated with this expansion - */ - public abstract String getIdentifier(); + /** + * The placeholder identifier of this expansion + * + * @return placeholder identifier that is associated with this expansion + */ + public abstract String getIdentifier(); - /** - * The author of this expansion - * - * @return name of the author for this expansion - */ - public abstract String getAuthor(); + /** + * The author of this expansion + * + * @return name of the author for this expansion + */ + public abstract String getAuthor(); - /** - * The version of this expansion - * - * @return current version of this expansion - */ - public abstract String getVersion(); + /** + * The version of this expansion + * + * @return current version of this expansion + */ + public abstract String getVersion(); - /** - * The name of the plugin that this expansion hooks into. by default will return the deprecated - * {@link #getPlugin()} method - * - * @return plugin name that this expansion requires to function - */ - public String getRequiredPlugin() { - return getPlugin(); - } + /** + * The name of the plugin that this expansion hooks into. by default will return the deprecated + * {@link #getPlugin()} method + * + * @return plugin name that this expansion requires to function + */ + public String getRequiredPlugin() { + return getPlugin(); + } - /** - * The placeholders associated with this expansion - * - * @return placeholder list that this expansion provides - */ - public List getPlaceholders() { - return null; - } + /** + * The placeholders associated with this expansion + * + * @return placeholder list that this expansion provides + */ + public List getPlaceholders() { + return null; + } - /** - * Expansions that do not use the ecloud and instead register from the dependency should set this - * to true to ensure that your placeholder expansion is not unregistered when the papi reload - * command is used - * - * @return if this expansion should persist through placeholder reloads - */ - public boolean persist() { - return false; - } + /** + * Expansions that do not use the ecloud and instead register from the dependency should set this + * to true to ensure that your placeholder expansion is not unregistered when the papi reload + * command is used + * + * @return if this expansion should persist through placeholder reloads + */ + public boolean persist() { + return false; + } - /** - * Check if this placeholder identifier has already been registered - * - * @return true if the identifier for this expansion is already registered - */ - public boolean isRegistered() { - Validate.notNull(getIdentifier(), "Placeholder identifier can not be null!"); - return PlaceholderAPI.isRegistered(getIdentifier()); - } + /** + * Check if this placeholder identifier has already been registered + * + * @return true if the identifier for this expansion is already registered + */ + public boolean isRegistered() { + Validate.notNull(getIdentifier(), "Placeholder identifier can not be null!"); + return PlaceholderAPI.isRegistered(getIdentifier()); + } - /** - * If any requirements need to be checked before this expansion should register, you can check - * them here - * - * @return true if this hook meets all the requirements to register - */ - public boolean canRegister() { - return getRequiredPlugin() == null - || Bukkit.getPluginManager().getPlugin(getRequiredPlugin()) != null; - } + /** + * If any requirements need to be checked before this expansion should register, you can check + * them here + * + * @return true if this hook meets all the requirements to register + */ + public boolean canRegister() { + return getRequiredPlugin() == null + || Bukkit.getPluginManager().getPlugin(getRequiredPlugin()) != null; + } - /** - * Attempt to register this PlaceholderExpansion - * - * @return true if this expansion is now registered with PlaceholderAPI - */ - public boolean register() { - Validate.notNull(getIdentifier(), "Placeholder identifier can not be null!"); - return PlaceholderAPI.registerExpansion(this); - } + /** + * Attempt to register this PlaceholderExpansion + * + * @return true if this expansion is now registered with PlaceholderAPI + */ + public boolean register() { + Validate.notNull(getIdentifier(), "Placeholder identifier can not be null!"); + return PlaceholderAPI.registerExpansion(this); + } - /** - * Quick getter for the {@link PlaceholderAPIPlugin} instance - * - * @return {@link PlaceholderAPIPlugin} instance - */ - public PlaceholderAPIPlugin getPlaceholderAPI() { - return PlaceholderAPIPlugin.getInstance(); - } + /** + * Quick getter for the {@link PlaceholderAPIPlugin} instance + * + * @return {@link PlaceholderAPIPlugin} instance + */ + public PlaceholderAPIPlugin getPlaceholderAPI() { + return PlaceholderAPIPlugin.getInstance(); + } - public String getString(String path, String def) { - return getPlaceholderAPI().getConfig() - .getString("expansions." + getIdentifier() + "." + path, def); - } + public String getString(String path, String def) { + return getPlaceholderAPI().getConfig() + .getString("expansions." + getIdentifier() + "." + path, def); + } - public int getInt(String path, int def) { - return getPlaceholderAPI().getConfig() - .getInt("expansions." + getIdentifier() + "." + path, def); - } + public int getInt(String path, int def) { + return getPlaceholderAPI().getConfig() + .getInt("expansions." + getIdentifier() + "." + path, def); + } - public long getLong(String path, long def) { - return getPlaceholderAPI().getConfig() - .getLong("expansions." + getIdentifier() + "." + path, def); - } + public long getLong(String path, long def) { + return getPlaceholderAPI().getConfig() + .getLong("expansions." + getIdentifier() + "." + path, def); + } - public double getDouble(String path, double def) { - return getPlaceholderAPI().getConfig() - .getDouble("expansions." + getIdentifier() + "." + path, def); - } + public double getDouble(String path, double def) { + return getPlaceholderAPI().getConfig() + .getDouble("expansions." + getIdentifier() + "." + path, def); + } - public List getStringList(String path) { - return getPlaceholderAPI().getConfig() - .getStringList("expansions." + getIdentifier() + "." + path); - } + public List getStringList(String path) { + return getPlaceholderAPI().getConfig() + .getStringList("expansions." + getIdentifier() + "." + path); + } - public Object get(String path, Object def) { - return getPlaceholderAPI().getConfig().get("expansions." + getIdentifier() + "." + path, def); - } + public Object get(String path, Object def) { + return getPlaceholderAPI().getConfig().get("expansions." + getIdentifier() + "." + path, def); + } - public ConfigurationSection getConfigSection(String path) { - return getPlaceholderAPI().getConfig() - .getConfigurationSection("expansions." + getIdentifier() + "." + path); - } + public ConfigurationSection getConfigSection(String path) { + return getPlaceholderAPI().getConfig() + .getConfigurationSection("expansions." + getIdentifier() + "." + path); + } - public ConfigurationSection getConfigSection() { - return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier()); - } + public ConfigurationSection getConfigSection() { + return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier()); + } - public boolean configurationContains(String path) { - return getPlaceholderAPI().getConfig().contains("expansions." + getIdentifier() + "." + path); - } + public boolean configurationContains(String path) { + return getPlaceholderAPI().getConfig().contains("expansions." + getIdentifier() + "." + path); + } - /** - * @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()} - */ - @Deprecated - public String getPlugin() { - return null; - } + /** + * @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()} + */ + @Deprecated + public String getPlugin() { + return null; + } - /** - * @deprecated As of versions greater than 2.8.7, use the expansion cloud to show a description - */ - @Deprecated - public String getDescription() { - return null; - } + /** + * @deprecated As of versions greater than 2.8.7, use the expansion cloud to show a description + */ + @Deprecated + public String getDescription() { + return null; + } - /** - * @deprecated As of versions greater than 2.8.7, use the expansion cloud to display a link - */ - @Deprecated - public String getLink() { - return null; - } + /** + * @deprecated As of versions greater than 2.8.7, use the expansion cloud to display a link + */ + @Deprecated + public String getLink() { + 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 e7708cb..d1da242 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Relational.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Relational.java @@ -24,5 +24,5 @@ import org.bukkit.entity.Player; public interface Relational { - String onPlaceholderRequest(Player one, Player two, String identifier); + 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 19cd639..b5b2b6f 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Taskable.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Taskable.java @@ -23,15 +23,15 @@ 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 - */ - void start(); + /** + * 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 + */ + void start(); - /** - * Called when the implementing class has been unregistered from PlaceholderAPI Tasks that need to - * be performed when this expansion has unregistered should go here - */ - void stop(); + /** + * Called when the implementing class has been unregistered from PlaceholderAPI Tasks that need to + * be performed when this expansion has unregistered should go here + */ + void stop(); } diff --git a/src/main/java/me/clip/placeholderapi/expansion/Version.java b/src/main/java/me/clip/placeholderapi/expansion/Version.java index a27345f..95067e4 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/Version.java +++ b/src/main/java/me/clip/placeholderapi/expansion/Version.java @@ -22,24 +22,24 @@ package me.clip.placeholderapi.expansion; public final class Version { - private final boolean isSpigot; - private final String version; + private final boolean isSpigot; + private final String version; - public Version(String version, boolean isSpigot) { - this.version = version; - this.isSpigot = isSpigot; - } + public Version(String version, boolean isSpigot) { + this.version = version; + this.isSpigot = isSpigot; + } - public String getVersion() { - return version == null ? "unknown" : version; - } + public String getVersion() { + return version == null ? "unknown" : version; + } - public boolean isSpigot() { - return isSpigot; - } + public boolean isSpigot() { + return isSpigot; + } - public boolean compareTo(String version) { - return getVersion().equalsIgnoreCase(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 31d956f..766ee51 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java +++ b/src/main/java/me/clip/placeholderapi/expansion/VersionSpecific.java @@ -30,11 +30,11 @@ package me.clip.placeholderapi.expansion; */ public interface VersionSpecific { - /** - * This method is called before the expansion is attempted to be registered The server version - * will be passed to this method so you know what version the server is currently running. - * - * @return true if your expansion is compatible with the version the server is running. - */ - boolean isCompatibleWith(Version v); + /** + * This method is called before the expansion is attempted to be registered The server version + * will be passed to this method so you know what version the server is currently running. + * + * @return true if your expansion is compatible with the version the server is running. + */ + 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 4e2ee0a..d6c0d7a 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java +++ b/src/main/java/me/clip/placeholderapi/expansion/cloud/CloudExpansion.java @@ -29,174 +29,174 @@ import java.util.stream.Collectors; public class CloudExpansion { - private String name, - author, - latest_version, - description, - source_url, - dependency_url; + private String name, + author, + latest_version, + description, + source_url, + dependency_url; - private boolean hasExpansion, - shouldUpdate, - verified; + private boolean hasExpansion, + shouldUpdate, + verified; - private long last_update, - ratings_count; + private long last_update, + ratings_count; - private double average_rating; + private double average_rating; - private List placeholders; + private List placeholders; - private List versions; + private List versions; - public CloudExpansion() { - } - - public String getTimeSinceLastUpdate() { - int time = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - getLastUpdate()); - return TimeUtil.getTime(time); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getAuthor() { - return author; - } - - public void setAuthor(String author) { - this.author = author; - } - - public Version getVersion() { - 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); - } - - public List getAvailableVersions() { - return versions.stream().map(Version::getVersion).collect(Collectors.toList()); - } - - public String getLatestVersion() { - return latest_version; - } - - public void setLatestVersion(String latest_version) { - this.latest_version = latest_version; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getSourceUrl() { - return source_url; - } - - public void setSourceUrl(String source_url) { - this.source_url = source_url; - } - - public String getDependencyUrl() { - return dependency_url; - } - - public void setDependencyUrl(String dependency_url) { - this.dependency_url = dependency_url; - } - - public boolean hasExpansion() { - return hasExpansion; - } - - public void setHasExpansion(boolean hasExpansion) { - this.hasExpansion = hasExpansion; - } - - public boolean shouldUpdate() { - return shouldUpdate; - } - - public void setShouldUpdate(boolean shouldUpdate) { - this.shouldUpdate = shouldUpdate; - } - - public boolean isVerified() { - return verified; - } - - public long getLastUpdate() { - return last_update; - } - - public void setLastUpdate(long last_update) { - this.last_update = last_update; - } - - public long getRatingsCount() { - return ratings_count; - } - - public double getAverage_rating() { - return average_rating; - } - - public List getPlaceholders() { - return placeholders; - } - - public void setPlaceholders(List placeholders) { - this.placeholders = placeholders; - } - - public List getVersions() { - return versions; - } - - public void setVersions(List versions) { - this.versions = versions; - } - - public class Version { - private String url, version, release_notes; - - public String getUrl() { - return url; + public CloudExpansion() { } - public void setUrl(String url) { - this.url = url; + public String getTimeSinceLastUpdate() { + int time = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - getLastUpdate()); + return TimeUtil.getTime(time); } - public String getVersion() { - return version; + public String getName() { + return name; } - public void setVersion(String version) { - this.version = version; + public void setName(String name) { + this.name = name; } - public String getReleaseNotes() { - return release_notes; + public String getAuthor() { + return author; } - public void setReleaseNotes(String release_notes) { - this.release_notes = release_notes; + public void setAuthor(String author) { + this.author = author; + } + + public Version getVersion() { + 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); + } + + public List getAvailableVersions() { + return versions.stream().map(Version::getVersion).collect(Collectors.toList()); + } + + public String getLatestVersion() { + return latest_version; + } + + public void setLatestVersion(String latest_version) { + this.latest_version = latest_version; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getSourceUrl() { + return source_url; + } + + public void setSourceUrl(String source_url) { + this.source_url = source_url; + } + + public String getDependencyUrl() { + return dependency_url; + } + + public void setDependencyUrl(String dependency_url) { + this.dependency_url = dependency_url; + } + + public boolean hasExpansion() { + return hasExpansion; + } + + public void setHasExpansion(boolean hasExpansion) { + this.hasExpansion = hasExpansion; + } + + public boolean shouldUpdate() { + return shouldUpdate; + } + + public void setShouldUpdate(boolean shouldUpdate) { + this.shouldUpdate = shouldUpdate; + } + + public boolean isVerified() { + return verified; + } + + public long getLastUpdate() { + return last_update; + } + + public void setLastUpdate(long last_update) { + this.last_update = last_update; + } + + public long getRatingsCount() { + return ratings_count; + } + + public double getAverage_rating() { + return average_rating; + } + + public List getPlaceholders() { + return placeholders; + } + + public void setPlaceholders(List placeholders) { + this.placeholders = placeholders; + } + + public List getVersions() { + return versions; + } + + public void setVersions(List versions) { + this.versions = versions; + } + + public class Version { + private String url, version, release_notes; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getReleaseNotes() { + return release_notes; + } + + public void setReleaseNotes(String release_notes) { + this.release_notes = release_notes; + } } - } } 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 d8c2af3..78e6cc3 100644 --- a/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java +++ b/src/main/java/me/clip/placeholderapi/expansion/cloud/ExpansionCloudManager.java @@ -74,25 +74,25 @@ public class ExpansionCloudManager { public CloudExpansion getCloudExpansion(String name) { return remote.values() - .stream() - .filter(ex -> ex.getName().equalsIgnoreCase(name)) - .findFirst() - .orElse(null); + .stream() + .filter(ex -> ex.getName().equalsIgnoreCase(name)) + .findFirst() + .orElse(null); } public int getCloudAuthorCount() { return remote.values() - .stream() - .collect(Collectors.groupingBy(CloudExpansion::getAuthor, Collectors.counting())) - .size(); + .stream() + .collect(Collectors.groupingBy(CloudExpansion::getAuthor, Collectors.counting())) + .size(); } public int getToUpdateCount() { return ((int) PlaceholderAPI.getExpansions() - .stream() - .filter(ex -> getCloudExpansion(ex.getName()) != null && getCloudExpansion(ex.getName()).shouldUpdate()) - .count()); + .stream() + .filter(ex -> getCloudExpansion(ex.getName()) != null && getCloudExpansion(ex.getName()).shouldUpdate()) + .count()); } @@ -167,12 +167,12 @@ public class ExpansionCloudManager { final Map data = new HashMap<>(); try (BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(API_URL).openStream()))) { - data.putAll(GSON.fromJson(reader, new TypeToken>() {}.getType())); + data.putAll(GSON.fromJson(reader, new TypeToken>() { + }.getType())); } catch (Exception ex) { if (plugin.getPlaceholderAPIConfig().isDebugMode()) { ex.printStackTrace(); - } - else { + } 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/)"); } } @@ -262,10 +262,10 @@ public class ExpansionCloudManager { } final CloudExpansion.Version ver = ex.getVersions() - .stream() - .filter(v -> v.getVersion().equals(version)) - .findFirst() - .orElse(null); + .stream() + .filter(v -> v.getVersion().equals(version)) + .findFirst() + .orElse(null); if (ver == null) { return; @@ -284,7 +284,7 @@ public class ExpansionCloudManager { } catch (Exception e) { plugin.getLogger() - .warning("Failed to download expansion: " + ex.getName() + " from: " + ver.getUrl()); + .warning("Failed to download expansion: " + ex.getName() + " from: " + ver.getUrl()); Bukkit.getScheduler().runTask(plugin, () -> { diff --git a/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java b/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java index b02fbbb..a51893d 100644 --- a/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java +++ b/src/main/java/me/clip/placeholderapi/external/EZPlaceholderHook.java @@ -25,32 +25,35 @@ import me.clip.placeholderapi.PlaceholderHook; import org.apache.commons.lang.Validate; import org.bukkit.plugin.Plugin; +/** + * Use {@link me.clip.placeholderapi.expansion.PlaceholderExpansion} instead + */ @Deprecated public abstract class EZPlaceholderHook extends PlaceholderHook { - private final String identifier; - private final String plugin; + private final String identifier; + 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!"); - this.identifier = identifier; - this.plugin = plugin.getName(); - } + public EZPlaceholderHook(Plugin plugin, String identifier) { + Validate.notNull(plugin, "Plugin can not be null!"); + Validate.notNull(identifier, "Placeholder name can not be null!"); + this.identifier = identifier; + this.plugin = plugin.getName(); + } - public boolean isHooked() { - return PlaceholderAPI.getRegisteredPlaceholderPlugins().contains(identifier); - } + public boolean isHooked() { + return PlaceholderAPI.getRegisteredPlaceholderPlugins().contains(identifier); + } - public boolean hook() { - return PlaceholderAPI.registerPlaceholderHook(identifier, this); - } + public boolean hook() { + return PlaceholderAPI.registerPlaceholderHook(identifier, this); + } - public String getPlaceholderName() { - return identifier; - } + public String getPlaceholderName() { + return identifier; + } - public String getPluginName() { - return plugin; - } + public String getPluginName() { + return plugin; + } } diff --git a/src/main/java/me/clip/placeholderapi/listeners/PlaceholderListener.java b/src/main/java/me/clip/placeholderapi/listeners/PlaceholderListener.java new file mode 100644 index 0000000..c6c06b5 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/listeners/PlaceholderListener.java @@ -0,0 +1,123 @@ +/* + * + * 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.listeners; + +import me.clip.placeholderapi.PlaceholderAPI; +import me.clip.placeholderapi.PlaceholderAPIPlugin; +import me.clip.placeholderapi.PlaceholderHook; +import me.clip.placeholderapi.events.ExpansionUnregisterEvent; +import me.clip.placeholderapi.expansion.Cacheable; +import me.clip.placeholderapi.expansion.Cleanable; +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import me.clip.placeholderapi.expansion.Taskable; +import me.clip.placeholderapi.expansion.cloud.CloudExpansion; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.HandlerList; +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) { + plugin = instance; + Bukkit.getPluginManager().registerEvents(this, instance); + } + + @EventHandler + public void onExpansionUnregister(ExpansionUnregisterEvent event) { + if (event.getExpansion() instanceof Listener) { + HandlerList.unregisterAll((Listener) event.getExpansion()); + } + + if (event.getExpansion() instanceof Taskable) { + ((Taskable) event.getExpansion()).stop(); + } + + if (event.getExpansion() instanceof Cacheable) { + ((Cacheable) event.getExpansion()).clear(); + } + + if (plugin.getExpansionCloud() != null) { + + CloudExpansion ex = plugin.getExpansionCloud() + .getCloudExpansion(event.getExpansion().getName()); + + if (ex != null) { + ex.setHasExpansion(false); + ex.setShouldUpdate(false); + } + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onPluginUnload(PluginDisableEvent e) { + String n = e.getPlugin().getName(); + + if (n.equals(plugin.getName())) { + return; + } + + Map hooks = PlaceholderAPI.getPlaceholders(); + + 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()); + } + } + } + } + } + + @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()); + } + } + } +} diff --git a/src/main/java/me/clip/placeholderapi/ServerLoadEventListener.java b/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java similarity index 90% rename from src/main/java/me/clip/placeholderapi/ServerLoadEventListener.java rename to src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java index 0ad80cc..b1f38f7 100644 --- a/src/main/java/me/clip/placeholderapi/ServerLoadEventListener.java +++ b/src/main/java/me/clip/placeholderapi/listeners/ServerLoadEventListener.java @@ -18,8 +18,11 @@ * * */ -package me.clip.placeholderapi; +package me.clip.placeholderapi.listeners; +import me.clip.placeholderapi.PlaceholderAPI; +import me.clip.placeholderapi.PlaceholderAPIPlugin; +import me.clip.placeholderapi.PlaceholderHook; import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -38,11 +41,12 @@ public class ServerLoadEventListener implements Listener { /** * 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 - * + *

* This will ensure no issues with expanions and hooks. + * * @param e the server load event */ @EventHandler diff --git a/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java b/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java index f3f56af..afafb0d 100644 --- a/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java +++ b/src/main/java/me/clip/placeholderapi/updatechecker/UpdateChecker.java @@ -35,83 +35,83 @@ import java.net.URL; public class UpdateChecker implements Listener { - private final int RESOURCE_ID = 6245; - private final PlaceholderAPIPlugin plugin; - private String spigotVersion; - private final String pluginVersion; - private boolean updateAvailable; + private final int RESOURCE_ID = 6245; + private final PlaceholderAPIPlugin plugin; + private final String pluginVersion; + private String spigotVersion; + private boolean updateAvailable; - public UpdateChecker(PlaceholderAPIPlugin i) { - plugin = i; - pluginVersion = i.getDescription().getVersion(); - } - - public boolean hasUpdateAvailable() { - return updateAvailable; - } - - public String getSpigotVersion() { - return spigotVersion; - } - - public void fetch() { - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - try { - HttpsURLConnection con = (HttpsURLConnection) new URL( - "https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection(); - con.setRequestMethod("GET"); - spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine(); - } catch (Exception ex) { - plugin.getLogger().info("Failed to check for updates on spigot."); - return; - } - - if (spigotVersion == null || spigotVersion.isEmpty()) { - return; - } - - updateAvailable = spigotIsNewer(); - - if (!updateAvailable) { - return; - } - - Bukkit.getScheduler().runTask(plugin, () -> { - plugin.getLogger() - .info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:"); - plugin.getLogger() - .info("https://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + "/"); - Bukkit.getPluginManager().registerEvents(this, plugin); - }); - }); - } - - private boolean spigotIsNewer() { - if (spigotVersion == null || spigotVersion.isEmpty()) { - return false; + public UpdateChecker(PlaceholderAPIPlugin i) { + plugin = i; + pluginVersion = i.getDescription().getVersion(); } - String plV = toReadable(pluginVersion); - String spV = toReadable(spigotVersion); - return plV.compareTo(spV) < 0; - } - - private String toReadable(String version) { - if (version.contains("-DEV-")) { - version = version.split("-DEV-")[0]; + public boolean hasUpdateAvailable() { + return updateAvailable; } - return version.replaceAll("\\.", ""); - } - - @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 - + "/"); + public String getSpigotVersion() { + return spigotVersion; + } + + public void fetch() { + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + try { + HttpsURLConnection con = (HttpsURLConnection) new URL( + "https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection(); + con.setRequestMethod("GET"); + spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine(); + } catch (Exception ex) { + plugin.getLogger().info("Failed to check for updates on spigot."); + return; + } + + if (spigotVersion == null || spigotVersion.isEmpty()) { + return; + } + + updateAvailable = spigotIsNewer(); + + if (!updateAvailable) { + return; + } + + Bukkit.getScheduler().runTask(plugin, () -> { + plugin.getLogger() + .info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:"); + plugin.getLogger() + .info("https://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + "/"); + Bukkit.getPluginManager().registerEvents(this, plugin); + }); + }); + } + + private boolean spigotIsNewer() { + if (spigotVersion == null || spigotVersion.isEmpty()) { + return false; + } + + String plV = toReadable(pluginVersion); + String spV = toReadable(spigotVersion); + return plV.compareTo(spV) < 0; + } + + private String toReadable(String version) { + if (version.contains("-DEV-")) { + version = version.split("-DEV-")[0]; + } + + return version.replaceAll("\\.", ""); + } + + @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 0660337..84eb613 100644 --- a/src/main/java/me/clip/placeholderapi/util/FileUtil.java +++ b/src/main/java/me/clip/placeholderapi/util/FileUtil.java @@ -33,76 +33,76 @@ import java.util.jar.JarInputStream; public class FileUtil { - public static List> getClasses(String folder, Class type) { - return getClasses(folder, null, type); - } + public static List> getClasses(String folder, Class type) { + return getClasses(folder, null, type); + } - public static List> getClasses(String folder, String fileName, Class type) { - List> list = new ArrayList<>(); + public static List> getClasses(String folder, String fileName, Class type) { + List> list = new ArrayList<>(); + + try { + File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), folder); + if (!f.exists()) { + return list; + } + + FilenameFilter fileNameFilter = (dir, name) -> { + if (fileName != null) { + return name.endsWith(".jar") && name.replace(".jar", "") + .equalsIgnoreCase(fileName.replace(".jar", "")); + } + + return name.endsWith(".jar"); + }; + + File[] jars = f.listFiles(fileNameFilter); + if (jars == null) { + return list; + } + + for (File file : jars) { + list = gather(file.toURI().toURL(), list, type); + } + + return list; + } catch (Throwable t) { + } + + return null; + } + + private static List> gather(URL jar, List> list, Class clazz) { + if (list == null) { + list = new ArrayList<>(); + } + + 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) { + } - try { - File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), folder); - if (!f.exists()) { return list; - } - - FilenameFilter fileNameFilter = (dir, name) -> { - if (fileName != null) { - return name.endsWith(".jar") && name.replace(".jar", "") - .equalsIgnoreCase(fileName.replace(".jar", "")); - } - - return name.endsWith(".jar"); - }; - - File[] jars = f.listFiles(fileNameFilter); - if (jars == null) { - return list; - } - - for (File file : jars) { - list = gather(file.toURI().toURL(), list, type); - } - - return list; - } catch (Throwable t) { } - - return null; - } - - private static List> gather(URL jar, List> list, Class clazz) { - if (list == null) { - list = new ArrayList<>(); - } - - 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; - } } diff --git a/src/main/java/me/clip/placeholderapi/util/JSONMessage.java b/src/main/java/me/clip/placeholderapi/util/JSONMessage.java new file mode 100644 index 0000000..cf62c34 --- /dev/null +++ b/src/main/java/me/clip/placeholderapi/util/JSONMessage.java @@ -0,0 +1,985 @@ +package me.clip.placeholderapi.util; + +import com.google.common.base.Strings; +import com.google.common.collect.BiMap; +import com.google.common.collect.ImmutableBiMap; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.Vector; + +/** + * This is a complete JSON message builder class. To create a new JSONMessage do + * {@link #create(String)} + * + * @author Rayzr + */ +@SuppressWarnings({"WeakerAccess", "unused"}) +public class JSONMessage { + private static final BiMap stylesToNames; + + static { + ImmutableBiMap.Builder builder = ImmutableBiMap.builder(); + for (final ChatColor style : ChatColor.values()) { + if (!style.isFormat()) { + continue; + } + + String styleName; + switch (style) { + case MAGIC: + styleName = "obfuscated"; + break; + case UNDERLINE: + styleName = "underlined"; + break; + default: + styleName = style.name().toLowerCase(); + break; + } + + builder.put(style, styleName); + } + stylesToNames = builder.build(); + } + + + private final List parts = new ArrayList<>(); + private int centeringStartIndex = -1; + + /** + * Creates a new {@link JSONMessage} object + * + * @param text The text to start with + */ + private JSONMessage(String text) { + parts.add(new MessagePart(text)); + } + + /** + * Creates a new {@link JSONMessage} object + * + * @param text The text to start with + * @return A new {@link JSONMessage} object + */ + public static JSONMessage create(String text) { + return new JSONMessage(text); + } + + /** + * Creates a new {@link JSONMessage} object + * + * @return A new {@link JSONMessage} object + */ + public static JSONMessage create() { + return create(""); + } + + /** + * Sends an action bar message + * + * @param message The message to send + * @param players The players you want to send it to + */ + public static void actionbar(String message, Player... players) { + ReflectionHelper.sendPacket(ReflectionHelper.createActionbarPacket(ChatColor.translateAlternateColorCodes('&', message)), players); + } + + /** + * @return The latest {@link MessagePart} + * @throws ArrayIndexOutOfBoundsException If {@code parts.size() <= 0}. + */ + public MessagePart last() { + if (parts.size() <= 0) { + throw new ArrayIndexOutOfBoundsException("No MessageParts exist!"); + } + return parts.get(parts.size() - 1); + } + + /** + * Converts this {@link JSONMessage} instance to actual JSON + * + * @return The JSON representation of this {@link JSONMessage} + */ + public JsonObject toJSON() { + JsonObject obj = new JsonObject(); + + obj.addProperty("text", ""); + + JsonArray array = new JsonArray(); + + parts.stream() + .map(MessagePart::toJSON) + .forEach(array::add); + + obj.add("extra", array); + + return obj; + } + + /** + * Converts this {@link JSONMessage} object to a String representation of the JSON. + * This is an alias of {@code toJSON().toString()}. + */ + @Override + public String toString() { + return toJSON().toString(); + } + + /** + * Converts this {@link JSONMessage} object to the legacy formatting system, which + * uses formatting codes (like &6, &l, &4, etc.) + * + * @return This {@link JSONMessage} instance {@link JSONMessage} in legacy format + */ + public String toLegacy() { + StringBuilder output = new StringBuilder(); + + parts.stream() + .map(MessagePart::toLegacy) + .forEach(output::append); + + return output.toString(); + } + + /** + * Sends this {@link JSONMessage} to all the players specified + * + * @param players The players you want to send this to + */ + public void send(Player... players) { + if (ReflectionHelper.getStringVersion().equalsIgnoreCase("v1_16_R1")) { + ReflectionHelper.sendTextPacket(toString(), players); + return; + } + + ReflectionHelper.sendPacket(ReflectionHelper.createTextPacket(toString()), players); + } + + /** + * Sends this as a title to all the players specified + * + * @param fadeIn How many ticks to fade in + * @param stay How many ticks to stay + * @param fadeOut How many ticks to fade out + * @param players The players to send this to + */ + public void title(int fadeIn, int stay, int fadeOut, Player... players) { + ReflectionHelper.sendPacket(ReflectionHelper.createTitleTimesPacket(fadeIn, stay, fadeOut), players); + ReflectionHelper.sendPacket(ReflectionHelper.createTitlePacket(toString()), players); + } + + /** + * Sends this as a subtitle to all the players specified. Must be used after sending a {@link #title(int, int, int, Player...) title}. + * + * @param players The players to send this to + */ + public void subtitle(Player... players) { + ReflectionHelper.sendPacket(ReflectionHelper.createSubtitlePacket(toString()), players); + } + + /** + * Sends an action bar message + * + * @param players The players you want to send this to + */ + public void actionbar(Player... players) { + actionbar(toLegacy(), players); + } + + /** + * Sets the color of the current message part. + * + * @param color The color to set + * @return This {@link JSONMessage} instance + */ + public JSONMessage color(ChatColor color) { + last().setColor(color); + return this; + } + + /** + * Adds a style to the current message part. + * + * @param style The style to add + * @return This {@link JSONMessage} instance + */ + public JSONMessage style(ChatColor style) { + last().addStyle(style); + return this; + } + + /** + * Makes the text run a command. + * + * @param command The command to run + * @return This {@link JSONMessage} instance + */ + public JSONMessage runCommand(String command) { + last().setOnClick(ClickEvent.runCommand(command)); + return this; + } + + /** + * Makes the text suggest a command. + * + * @param command The command to suggest + * @return This {@link JSONMessage} instance + */ + public JSONMessage suggestCommand(String command) { + last().setOnClick(ClickEvent.suggestCommand(command)); + return this; + } + + /** + * Opens a URL. + * + * @param url The url to open + * @return This {@link JSONMessage} instance + */ + public JSONMessage openURL(String url) { + last().setOnClick(ClickEvent.openURL(url)); + return this; + } + + /** + * Changes the page of a book. Using this in a non-book context is useless + * and will probably error. + * + * @param page The page to change to + * @return This {@link JSONMessage} instance + */ + public JSONMessage changePage(int page) { + last().setOnClick(ClickEvent.changePage(page)); + return this; + } + + /** + * Shows text when you hover over it + * + * @param text The text to show + * @return This {@link JSONMessage} instance + */ + public JSONMessage tooltip(String text) { + last().setOnHover(HoverEvent.showText(text)); + return this; + } + + /** + * Shows text when you hover over it + * + * @param message The text to show + * @return This {@link JSONMessage} instance + */ + public JSONMessage tooltip(JSONMessage message) { + last().setOnHover(HoverEvent.showText(message)); + return this; + } + + /** + * Shows an achievement when you hover over it + * + * @param id The id of the achievement + * @return This {@link JSONMessage} instance + */ + public JSONMessage achievement(String id) { + last().setOnHover(HoverEvent.showAchievement(id)); + return this; + } + + /** + * Adds another part to this {@link JSONMessage} + * + * @param text The text to start the next {@link MessagePart} with + * @return This {@link JSONMessage} instance + */ + public JSONMessage then(String text) { + return then(new MessagePart(text)); + } + + /** + * Adds another part to this {@link JSONMessage} + * + * @param nextPart The next {@link MessagePart} + * @return This {@link JSONMessage} instance + */ + public JSONMessage then(MessagePart nextPart) { + parts.add(nextPart); + return this; + } + + /** + * Adds a horizontal bar to the message of the given length + * + * @param length The length of the horizontal bar + * @return This {@link JSONMessage} instance + */ + public JSONMessage bar(int length) { + return then(Strings.repeat("-", length)).color(ChatColor.DARK_GRAY).style(ChatColor.STRIKETHROUGH); + } + + /** + * Adds a horizontal bar to the message that's 53 characters long. This is + * the default width of the player's chat window. + * + * @return This {@link JSONMessage} instance + */ + public JSONMessage bar() { + return bar(53); + } + + /** + * Adds a blank line to the message + * + * @return This {@link JSONMessage} instance + */ + public JSONMessage newline() { + return then("\n"); + } + + /** + * Sets the starting point to begin centering JSONMessages. + * + * @return This {@link JSONMessage} instance + */ + public JSONMessage beginCenter() { + // Start with the NEXT message part. + centeringStartIndex = parts.size(); + return this; + } + + /** + * Ends the centering of the JSONMessage text. + * + * @return This {@link JSONMessage} instance + */ + public JSONMessage endCenter() { + int current = centeringStartIndex; + + while (current < parts.size()) { + Vector currentLine = new Vector<>(); + int totalLineLength = 0; + + for (; ; current++) { + MessagePart part = current < parts.size() ? parts.get(current) : null; + String raw = part == null ? null : ChatColor.stripColor(part.toLegacy()); + + if (current >= parts.size() || totalLineLength + raw.length() >= 53) { + int padding = Math.max(0, (53 - totalLineLength) / 2); + currentLine.firstElement().setText(Strings.repeat(" ", padding) + currentLine.firstElement().getText()); + currentLine.lastElement().setText(currentLine.lastElement().getText() + "\n"); + currentLine.clear(); + break; + } + + totalLineLength += raw.length(); + currentLine.add(part); + } + } + + MessagePart last = parts.get(parts.size() - 1); + last.setText(last.getText().substring(0, last.getText().length() - 1)); + + centeringStartIndex = -1; + + return this; + } + + /////////////////////////// + // BEGIN UTILITY CLASSES // + /////////////////////////// + + /** + * Represents the JSON format that all click/hover events in JSON messages must follow. + *
+ *
+ * Reference + * + * @author Rayzr + */ + public static class MessageEvent { + + private String action; + private Object value; + + public MessageEvent(String action, Object value) { + this.action = action; + this.value = value; + } + + /** + * @return A {@link JsonObject} representing the properties of this {@link MessageEvent} + */ + public JsonObject toJSON() { + JsonObject obj = new JsonObject(); + obj.addProperty("action", action); + if (value instanceof JsonElement) { + obj.add("value", (JsonElement) value); + } else { + obj.addProperty("value", value.toString()); + } + return obj; + } + + /** + * @return The action + */ + public String getAction() { + return action; + } + + /** + * @param action The action to set + */ + public void setAction(String action) { + this.action = action; + } + + /** + * @return The value + */ + public Object getValue() { + return value; + } + + /** + * @param value The value to set + */ + public void setValue(Object value) { + this.value = value; + } + + } + + public static class ClickEvent { + + /** + * Runs a command. + * + * @param command The command to run + * @return The {@link MessageEvent} + */ + public static MessageEvent runCommand(String command) { + return new MessageEvent("run_command", command); + } + + /** + * Suggests a command by putting inserting it in chat. + * + * @param command The command to suggest + * @return The {@link MessageEvent} + */ + public static MessageEvent suggestCommand(String command) { + return new MessageEvent("suggest_command", command); + } + + /** + * Requires web links to be enabled on the client. + * + * @param url The url to open + * @return The {@link MessageEvent} + */ + public static MessageEvent openURL(String url) { + return new MessageEvent("open_url", url); + } + + /** + * Only used with written books. + * + * @param page The page to switch to + * @return The {@link MessageEvent} + */ + public static MessageEvent changePage(int page) { + return new MessageEvent("change_page", page); + } + + } + + public static class HoverEvent { + + /** + * Shows text when you hover over it + * + * @param text The text to show + * @return The {@link MessageEvent} + */ + public static MessageEvent showText(String text) { + return new MessageEvent("show_text", text); + } + + /** + * Shows text when you hover over it + * + * @param message The {@link JSONMessage} to show + * @return The {@link MessageEvent} + */ + public static MessageEvent showText(JSONMessage message) { + JsonArray arr = new JsonArray(); + arr.add(new JsonPrimitive("")); + arr.add(message.toJSON()); + return new MessageEvent("show_text", arr); + } + + /** + * Shows an achievement when you hover over it + * + * @param id The id of the achievement + * @return The {@link MessageEvent} + */ + public static MessageEvent showAchievement(String id) { + return new MessageEvent("show_achievement", id); + } + + } + + private static class ReflectionHelper { + + private static final String version; + private static Class craftPlayer; + private static Constructor chatComponentText; + private static Class packetPlayOutChat; + private static Class packetPlayOutTitle; + private static Class iChatBaseComponent; + private static Class titleAction; + private static Field connection; + private static MethodHandle GET_HANDLE; + private static MethodHandle SEND_PACKET; + private static MethodHandle STRING_TO_CHAT; + private static Object enumActionTitle; + private static Object enumActionSubtitle; + private static Object enumChatMessage; + private static Object enumActionbarMessage; + private static boolean SETUP; + private static int MAJOR_VER = -1; + + static { + String[] split = Bukkit.getServer().getClass().getPackage().getName().split("\\."); + version = split[split.length - 1]; + + try { + SETUP = true; + + MAJOR_VER = getVersion(); + + craftPlayer = getClass("{obc}.entity.CraftPlayer"); + Method getHandle = craftPlayer.getMethod("getHandle"); + connection = getHandle.getReturnType().getField("playerConnection"); + Method sendPacket = connection.getType().getMethod("sendPacket", getClass("{nms}.Packet")); + + chatComponentText = getClass("{nms}.ChatComponentText").getConstructor(String.class); + + iChatBaseComponent = getClass("{nms}.IChatBaseComponent"); + + Method stringToChat; + + if (MAJOR_VER < 8) { + stringToChat = getClass("{nms}.ChatSerializer").getMethod("a", String.class); + } else { + stringToChat = getClass("{nms}.IChatBaseComponent$ChatSerializer").getMethod("a", String.class); + } + + GET_HANDLE = MethodHandles.lookup().unreflect(getHandle); + SEND_PACKET = MethodHandles.lookup().unreflect(sendPacket); + STRING_TO_CHAT = MethodHandles.lookup().unreflect(stringToChat); + + packetPlayOutChat = getClass("{nms}.PacketPlayOutChat"); + packetPlayOutTitle = getClass("{nms}.PacketPlayOutTitle"); + + titleAction = getClass("{nms}.PacketPlayOutTitle$EnumTitleAction"); + + enumActionTitle = titleAction.getField("TITLE").get(null); + enumActionSubtitle = titleAction.getField("SUBTITLE").get(null); + + if (MAJOR_VER >= 12) { + Method getChatMessageType = getClass("{nms}.ChatMessageType").getMethod("a", byte.class); + + enumChatMessage = getChatMessageType.invoke(null, (byte) 1); + enumActionbarMessage = getChatMessageType.invoke(null, (byte) 2); + } + + } catch (Exception e) { + e.printStackTrace(); + SETUP = false; + } + + } + + static void sendPacket(Object packet, Player... players) { + if (!SETUP) { + throw new IllegalStateException("ReflectionHelper is not set up!"); + } + if (packet == null) { + return; + } + + for (Player player : players) { + try { + SEND_PACKET.bindTo(connection.get(GET_HANDLE.bindTo(player).invoke())).invoke(packet); + } catch (Throwable e) { + System.err.println("Failed to send packet"); + e.printStackTrace(); + } + } + + } + + private static void setType(Object object, byte type) { + if (MAJOR_VER < 12) { + set("b", object, type); + return; + } + + switch (type) { + case 1: + set("b", object, enumChatMessage); + break; + case 2: + set("b", object, enumActionbarMessage); + break; + default: + throw new IllegalArgumentException("type must be 1 or 2"); + } + } + + static Object createActionbarPacket(String message) { + if (!SETUP) { + throw new IllegalStateException("ReflectionHelper is not set up!"); + } + Object packet = createTextPacket(message); + setType(packet, (byte) 2); + return packet; + } + + static Object createTextPacket(String message) { + if (!SETUP) { + throw new IllegalStateException("ReflectionHelper is not set up!"); + } + try { + Object packet = packetPlayOutChat.newInstance(); + set("a", packet, fromJson(message)); + setType(packet, (byte) 1); + return packet; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + } + + static void sendTextPacket(String message, Player... players) { + try { + for (Player player : players) { + Class chatTypeClass = getClass("{nms}.ChatMessageType"); + Constructor constructor = packetPlayOutChat.getConstructor(getClass("{nms}.IChatBaseComponent"), chatTypeClass, UUID.class); + Object packet = constructor.newInstance(fromJson(message), Enum.valueOf(chatTypeClass, "CHAT"), player.getUniqueId()); + + Object handler = player.getClass().getMethod("getHandle").invoke(player); + Object playerConnection = handler.getClass().getField("playerConnection").get(handler); + playerConnection.getClass().getMethod("sendPacket", getClass("{nms}.Packet")).invoke(playerConnection, packet); + } + } catch (IllegalArgumentException | NoSuchMethodException | NoSuchFieldException | IllegalAccessException | InvocationTargetException | InstantiationException | ClassNotFoundException e) { + e.printStackTrace(); + } + } + + static Object createTitlePacket(String message) { + if (!SETUP) { + throw new IllegalStateException("ReflectionHelper is not set up!"); + } + try { + return packetPlayOutTitle.getConstructor(titleAction, iChatBaseComponent).newInstance(enumActionTitle, fromJson(message)); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + } + + static Object createSubtitlePacket(String message) { + if (!SETUP) { + throw new IllegalStateException("ReflectionHelper is not set up!"); + } + try { + return packetPlayOutTitle.getConstructor(titleAction, iChatBaseComponent).newInstance(enumActionSubtitle, fromJson(message)); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + } + + static Object createTitleTimesPacket(int fadeIn, int stay, int fadeOut) { + if (!SETUP) { + throw new IllegalStateException("ReflectionHelper is not set up!"); + } + try { + return packetPlayOutTitle.getConstructor(int.class, int.class, int.class).newInstance(fadeIn, stay, fadeOut); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + } + + /** + * Creates a ChatComponentText from plain text + * + * @param message The text to convert to a chat component + * @return The chat component + */ + static Object componentText(String message) { + if (!SETUP) { + throw new IllegalStateException("ReflectionHelper is not set up!"); + } + try { + return chatComponentText.newInstance(message); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + } + + /** + * Attempts to convert a String representing a JSON message into a usable object + * + * @param json The JSON to attempt to parse + * @return The object representing the text in JSON form, or null if something went wrong converting the String to JSON data + */ + static Object fromJson(String json) { + if (!SETUP) { + throw new IllegalStateException("ReflectionHelper is not set up!"); + } + if (!json.trim().startsWith("{")) { + return componentText(json); + } + + try { + return STRING_TO_CHAT.invoke(json); + } catch (Throwable e) { + e.printStackTrace(); + return null; + } + + } + + /** + * Returns a class with the given package and name. This method replaces {nms} with net.minecraft.server.[version] and {obc} with org.bukkit.craft.[version] + *
+ *
+ * Example: + * + *

+         * Class entityPlayer = ReflectionHelper.getClass("{nms}.EntityPlayer");
+         * 
+ * + * @param path The path to the {@link Class} + * @return The class + * @throws ClassNotFoundException If the class was not found + */ + static Class getClass(String path) throws ClassNotFoundException { + if (!SETUP) { + throw new IllegalStateException("ReflectionHelper is not set up!"); + } + return Class.forName(path.replace("{nms}", "net.minecraft.server." + version).replace("{obc}", "org.bukkit.craftbukkit." + version)); + } + + /** + * Sets a field with the given name on an object to the value specified + * + * @param field The name of the field to change + * @param obj The object to change the field of + * @param value The new value to set + */ + static void set(String field, Object obj, Object value) { + try { + Field f = obj.getClass().getDeclaredField(field); + f.setAccessible(true); + f.set(obj, value); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static String getStringVersion() { + return version; + } + + static int getVersion() { + if (!SETUP) { + throw new IllegalStateException("ReflectionHelper is not set up!"); + } + try { + return Integer.parseInt(version.split("_")[1]); + } catch (NumberFormatException e) { + e.printStackTrace(); + return 10; + } + + } + + } + + /** + * Defines a section of the message, and represents the format that all JSON messages must follow in Minecraft. + *
+ *
+ * Reference + * + * @author Rayzr + */ + public static class MessagePart { + + private final List styles = new ArrayList<>(); + private MessageEvent onClick; + private MessageEvent onHover; + private ChatColor color; + private String text; + + public MessagePart(String text) { + this.text = text == null ? "null" : text; + } + + /** + * Converts this {@link MessagePart} into a {@link JsonObject} + * + * @return The Minecraft-compatible {@link JsonObject} + */ + public JsonObject toJSON() { + Objects.requireNonNull(text); + + JsonObject obj = new JsonObject(); + obj.addProperty("text", text); + + if (color != null) { + obj.addProperty("color", color.name().toLowerCase()); + } + + for (ChatColor style : styles) { + obj.addProperty(stylesToNames.get(style), true); + } + + if (onClick != null) { + obj.add("clickEvent", onClick.toJSON()); + } + + if (onHover != null) { + obj.add("hoverEvent", onHover.toJSON()); + } + + return obj; + + } + + /** + * @return This {@link MessagePart} in legacy-style color/formatting codes + */ + public String toLegacy() { + StringBuilder output = new StringBuilder(); + if (color != null) { + output.append(color.toString()); + } + styles.stream() + .map(ChatColor::toString) + .forEach(output::append); + + return output.append(text).toString(); + } + + /** + * @return The click event bound + */ + public MessageEvent getOnClick() { + return onClick; + } + + /** + * @param onClick The new click event to bind + */ + public void setOnClick(MessageEvent onClick) { + this.onClick = onClick; + } + + /** + * @return The hover event bound + */ + public MessageEvent getOnHover() { + return onHover; + } + + /** + * @param onHover The new hover event to bind + */ + public void setOnHover(MessageEvent onHover) { + this.onHover = onHover; + } + + /** + * @return The color + */ + public ChatColor getColor() { + return color; + } + + /** + * @param color The color to set + */ + public void setColor(ChatColor color) { + if (!color.isColor()) { + throw new IllegalArgumentException(color.name() + " is not a color!"); + } + this.color = color; + } + + /** + * @return The list of styles + */ + public List getStyles() { + return styles; + } + + /** + * @param style The new style to add + */ + public void addStyle(ChatColor style) { + if (style == null) { + throw new IllegalArgumentException("Style cannot be null!"); + } + if (!style.isFormat()) { + throw new IllegalArgumentException(color.name() + " is not a style!"); + } + styles.add(style); + } + + /** + * @return The raw text + */ + public String getText() { + return text; + } + + /** + * @param text The raw text to set + */ + public void setText(String text) { + this.text = text; + } + + } + +} \ No newline at end of file diff --git a/src/main/java/me/clip/placeholderapi/util/Msg.java b/src/main/java/me/clip/placeholderapi/util/Msg.java index 73b87dd..3d526e4 100644 --- a/src/main/java/me/clip/placeholderapi/util/Msg.java +++ b/src/main/java/me/clip/placeholderapi/util/Msg.java @@ -25,18 +25,19 @@ import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Collectors; -public class Msg { +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 msg(CommandSender s, String... msg) { - Arrays.stream(msg).map(Msg::color).forEach(s::sendMessage); - } + public static void broadcast(String... msg) { + Arrays.stream(msg).filter(Objects::nonNull).map(Msg::color).forEach(Bukkit::broadcastMessage); + } - public static void broadcast(String... msg) { - Arrays.stream(msg).map(Msg::color).forEach(Bukkit::broadcastMessage); - } - - public static String color(String text) { - return ChatColor.translateAlternateColorCodes('&', text); - } + public static String color(String text) { + return ChatColor.translateAlternateColorCodes('&', text); + } } diff --git a/src/main/java/me/clip/placeholderapi/util/TimeFormat.java b/src/main/java/me/clip/placeholderapi/util/TimeFormat.java index a338efc..a9c3190 100644 --- a/src/main/java/me/clip/placeholderapi/util/TimeFormat.java +++ b/src/main/java/me/clip/placeholderapi/util/TimeFormat.java @@ -21,8 +21,8 @@ package me.clip.placeholderapi.util; public enum TimeFormat { - DAYS, - HOURS, - MINUTES, - SECONDS + 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 e076c67..b320ecf 100644 --- a/src/main/java/me/clip/placeholderapi/util/TimeUtil.java +++ b/src/main/java/me/clip/placeholderapi/util/TimeUtil.java @@ -20,156 +20,151 @@ */ package me.clip.placeholderapi.util; +import java.time.Duration; +import java.time.temporal.ChronoUnit; + public class TimeUtil { - public static String getRemaining(int seconds, TimeFormat type) { - if (seconds < 60) { - switch (type) { - case DAYS: - case HOURS: - case MINUTES: - return "0"; - case SECONDS: - return String.valueOf(seconds); - } + public static String getRemaining(int seconds, TimeFormat type) { + if (seconds < 60) { + switch (type) { + case DAYS: + case HOURS: + case MINUTES: + return "0"; + case SECONDS: + return String.valueOf(seconds); + } - return String.valueOf(seconds); + return String.valueOf(seconds); + } + + int minutes = seconds / 60; + int s = 60 * minutes; + int secondsLeft = seconds - s; + + if (minutes < 60) { + switch (type) { + case DAYS: + case HOURS: + return "0"; + case MINUTES: + return String.valueOf(minutes); + case SECONDS: + return String.valueOf(secondsLeft); + } + + return String.valueOf(seconds); + } + + if (minutes < 1440) { + int hours = minutes / 60; + int inMins = 60 * hours; + int leftOver = minutes - inMins; + + switch (type) { + case DAYS: + return "0"; + case HOURS: + return String.valueOf(hours); + case MINUTES: + return String.valueOf(leftOver); + case SECONDS: + return String.valueOf(secondsLeft); + } + + return String.valueOf(seconds); + } + + int days = minutes / 1440; + int inMins = 1440 * days; + int leftOver = minutes - inMins; + + if (leftOver < 60) { + switch (type) { + case DAYS: + return String.valueOf(days); + case HOURS: + return String.valueOf(0); + case MINUTES: + return String.valueOf(leftOver); + case SECONDS: + return String.valueOf(secondsLeft); + } + + return String.valueOf(seconds); + + } else { + int hours = leftOver / 60; + int hoursInMins = 60 * hours; + int minsLeft = leftOver - hoursInMins; + + switch (type) { + case DAYS: + return String.valueOf(days); + case HOURS: + return String.valueOf(hours); + case MINUTES: + return String.valueOf(minsLeft); + case SECONDS: + return String.valueOf(secondsLeft); + } + + return String.valueOf(seconds); + } } - int minutes = seconds / 60; - int s = 60 * minutes; - int secondsLeft = seconds - s; - - if (minutes < 60) { - switch (type) { - case DAYS: - case HOURS: - return "0"; - case MINUTES: - return String.valueOf(minutes); - case SECONDS: - return String.valueOf(secondsLeft); - } - - return String.valueOf(seconds); + public static String getTime(int seconds) { + return getTime(Duration.ofSeconds(seconds)); } - if (minutes < 1440) { - int hours = minutes / 60; - int inMins = 60 * hours; - int leftOver = minutes - inMins; + /** + * Format the given value with s, m, h and d (seconds, minutes, hours and days) + * + * @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(); - switch (type) { - case DAYS: - return "0"; - case HOURS: - return String.valueOf(hours); - case MINUTES: - return String.valueOf(leftOver); - case SECONDS: - return String.valueOf(secondsLeft); - } + long seconds = duration.getSeconds(); + long minutes = seconds / 60; + long hours = minutes / 60; + long days = hours / 24; - return String.valueOf(seconds); + seconds %= 60; + minutes %= 60; + hours %= 60; + days %= 24; + + if (seconds > 0) { + builder.insert(0, seconds + "s"); + } + + if (minutes > 0) { + if (builder.length() > 0) { + builder.insert(0, ' '); + } + + builder.insert(0, minutes + "m"); + } + + if (hours > 0) { + if (builder.length() > 0) { + builder.insert(0, ' '); + } + + builder.insert(0, hours + "h"); + } + + if (days > 0) { + if (builder.length() > 0) { + builder.insert(0, ' '); + } + + builder.insert(0, days + "d"); + } + + return builder.toString(); } - - int days = minutes / 1440; - int inMins = 1440 * days; - int leftOver = minutes - inMins; - - if (leftOver < 60) { - switch (type) { - case DAYS: - return String.valueOf(days); - case HOURS: - return String.valueOf(0); - case MINUTES: - return String.valueOf(leftOver); - case SECONDS: - return String.valueOf(secondsLeft); - } - - return String.valueOf(seconds); - - } else { - int hours = leftOver / 60; - int hoursInMins = 60 * hours; - int minsLeft = leftOver - hoursInMins; - - switch (type) { - case DAYS: - return String.valueOf(days); - case HOURS: - return String.valueOf(hours); - case MINUTES: - return String.valueOf(minsLeft); - case SECONDS: - return String.valueOf(secondsLeft); - } - - return String.valueOf(seconds); - } - } - - public static String getTime(int seconds) { - - if (seconds < 60) { - return seconds + "s"; - } - - int minutes = seconds / 60; - int s = 60 * minutes; - int secondsLeft = seconds - s; - - if (minutes < 60) { - if (secondsLeft > 0) { - return minutes + "m " + secondsLeft + "s"; - } else { - return minutes + "m"; - } - } - - if (minutes < 1440) { - String time; - int hours = minutes / 60; - time = hours + "h"; - int inMins = 60 * hours; - int leftOver = minutes - inMins; - - if (leftOver >= 1) { - time = time + " " + leftOver + "m"; - } - - if (secondsLeft > 0) { - time = time + " " + secondsLeft + "s"; - } - - return time; - } - - String time; - int days = minutes / 1440; - time = days + "d"; - int inMins = 1440 * days; - int leftOver = minutes - inMins; - - if (leftOver >= 1) { - if (leftOver < 60) { - time = time + " " + leftOver + "m"; - } else { - int hours = leftOver / 60; - time = time + " " + hours + "h"; - - int hoursInMins = 60 * hours; - int minsLeft = leftOver - hoursInMins; - time = time + " " + minsLeft + "m"; - } - } - - if (secondsLeft > 0) { - time = time + " " + secondsLeft + "s"; - } - - return time; - } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 3394896..d4031ef 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: ${project.name} main: me.clip.placeholderapi.PlaceholderAPIPlugin version: ${project.version} -api-version: 1.13 +api-version: '1.13' authors: [extended_clip, Glare] description: ${project.description} permissions: