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