Revert "Performance Improvements (#340)"

This reverts commit 54d5757d
This commit is contained in:
extendedclip 2020-07-20 16:57:16 -04:00
parent 8972f7cff4
commit 4ce0b03852
52 changed files with 873 additions and 874 deletions

34
pom.xml
View File

@ -5,8 +5,8 @@
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.10.7-DEV-${BUILD_NUMBER}</version>
<version>2.10.7-DEV-${BUILD_NUMBER}</version>
<name>PlaceholderAPI</name>
<description>An awesome placeholder provider!</description>
<url>http://extendedclip.com</url>
@ -53,7 +53,7 @@
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>1.7</version>
<version>1.5</version>
</dependency>
<dependency>
<groupId>me.rayzr522</groupId>
@ -83,27 +83,27 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<configuration>
<minimizeJar>false</minimizeJar>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>me.clip.placeholderapi.util</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.code.gson</pattern>
<shadedPattern>me.clip.placeholderapi.libs.gson</shadedPattern>
</relocation>
</relocations>
</configuration>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>false</minimizeJar>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>me.clip.placeholderapi.metrics</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.code.gson</pattern>
<shadedPattern>me.clip.placeholderapi.libs.gson</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>

View File

@ -20,13 +20,14 @@
*/
package me.clip.placeholderapi;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import me.clip.placeholderapi.events.ExpansionRegisterEvent;
import me.clip.placeholderapi.events.ExpansionUnregisterEvent;
import me.clip.placeholderapi.expansion.Cacheable;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.expansion.Relational;
import me.clip.placeholderapi.util.Msg;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
@ -34,17 +35,18 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static me.clip.placeholderapi.util.Msg.color;
public class PlaceholderAPI {
protected static final Map<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 RELATIONAL_PLACEHOLDER_PATTERN = Pattern.compile("[%](rel_)([^%]+)[%]");
private static final Map<String, PlaceholderHook> placeholders = new HashMap<>();
private PlaceholderAPI() {
}
@ -56,7 +58,9 @@ public class PlaceholderAPI {
* @return true if identifier is already registered
*/
public static boolean isRegistered(String identifier) {
return PLACEHOLDERS.containsKey(identifier.toLowerCase(Locale.ENGLISH));
return getRegisteredIdentifiers().stream()
.filter(id -> id.equalsIgnoreCase(identifier))
.findFirst().orElse(null) != null;
}
/**
@ -69,11 +73,15 @@ public class PlaceholderAPI {
* registered for the specified identifier
*/
public static boolean registerPlaceholderHook(String identifier, PlaceholderHook placeholderHook) {
Validate.notEmpty(identifier, "Placeholder identifier cannot be null or empty");
Objects.requireNonNull(placeholderHook, "Placeholder hook cannot be null");
Validate.notNull(identifier, "Identifier can not be null");
Validate.notNull(placeholderHook, "Placeholderhook can not be null");
if (isRegistered(identifier)) {
return false;
}
placeholders.put(identifier.toLowerCase(), placeholderHook);
if (isRegistered(identifier)) return false;
PLACEHOLDERS.put(identifier.toLowerCase(Locale.ENGLISH), placeholderHook);
return true;
}
@ -85,8 +93,8 @@ public class PlaceholderAPI {
* placeholder hook registered for the identifier specified
*/
public static boolean unregisterPlaceholderHook(String identifier) {
Validate.notEmpty(identifier, "Identifier cannot be null");
return PLACEHOLDERS.remove(identifier.toLowerCase(Locale.ENGLISH)) != null;
Validate.notNull(identifier, "Identifier can not be null");
return placeholders.remove(identifier.toLowerCase()) != null;
}
/**
@ -95,7 +103,7 @@ public class PlaceholderAPI {
* @return All registered placeholder identifiers
*/
public static Set<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
*/
public static Map<String, PlaceholderHook> getPlaceholders() {
return ImmutableMap.copyOf(PLACEHOLDERS);
return ImmutableMap.copyOf(placeholders);
}
public static Set<PlaceholderExpansion> getExpansions() {
Set<PlaceholderExpansion> expansions = new HashSet<>();
for (PlaceholderHook expansion : PLACEHOLDERS.values()) {
if (expansion.isExpansion()) expansions.add((PlaceholderExpansion) expansion);
}
Set<PlaceholderExpansion> set = getPlaceholders().values().stream()
.filter(PlaceholderExpansion.class::isInstance).map(PlaceholderExpansion.class::cast)
.collect(Collectors.toCollection(HashSet::new));
return ImmutableSet.copyOf(expansions);
return ImmutableSet.copyOf(set);
}
/**
@ -123,7 +130,7 @@ public class PlaceholderAPI {
* @return true if String contains any registered placeholder identifiers, false otherwise
*/
public static boolean containsPlaceholders(String text) {
return !Strings.isNullOrEmpty(text) && PERCENT_PLACEHOLDER_PATTERN.matcher(text).find();
return text != null && PLACEHOLDER_PATTERN.matcher(text).find();
}
/**
@ -133,7 +140,7 @@ public class PlaceholderAPI {
* @return true if String contains any registered placeholder identifiers, false otherwise
*/
public static boolean containsBracketPlaceholders(String text) {
return !Strings.isNullOrEmpty(text) && BRACKET_PLACEHOLDER_PATTERN.matcher(text).find();
return text != null && BRACKET_PLACEHOLDER_PATTERN.matcher(text).find();
}
/**
@ -170,7 +177,7 @@ public class PlaceholderAPI {
* @return String containing all translated placeholders
*/
public static List<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
*/
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
*/
public static List<String> setPlaceholders(OfflinePlayer player, List<String> text, Pattern pattern, boolean colorize) {
if (text == null) return null;
List<String> lines = new ArrayList<>();
for (String line : text) {
lines.add(setPlaceholders(player, line, pattern, colorize));
if (text == null) {
return null;
}
return lines;
return text.stream()
.map(line -> setPlaceholders(player, line, pattern, colorize))
.collect(Collectors.toList());
}
/**
@ -255,7 +262,7 @@ public class PlaceholderAPI {
* @return String containing all translated placeholders
*/
public static String setPlaceholders(OfflinePlayer player, String text) {
return PlaceholderReplacer.evaluatePlaceholders(player, text, PlaceholderReplacer.Closure.PERCENT, false);
return setPlaceholders(player, text, PLACEHOLDER_PATTERN);
}
/**
@ -268,7 +275,7 @@ public class PlaceholderAPI {
* @return The text containing the parsed placeholders
*/
public static String setPlaceholders(OfflinePlayer player, String text, boolean colorize) {
return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize);
return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize);
}
/**
@ -297,51 +304,43 @@ public class PlaceholderAPI {
* @return The text containing the parsed placeholders
*/
public static String setPlaceholders(OfflinePlayer player, String text, Pattern pattern, boolean colorize) {
if (text == null) return null;
if (PLACEHOLDERS.isEmpty()) return colorize ? color(text) : text;
if (text == null) {
return null;
}
if (placeholders.isEmpty()) {
return colorize ? color(text) : text;
}
final Matcher matcher = pattern.matcher(text);
final Map<String, PlaceholderHook> hooks = getPlaceholders();
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
String format = matcher.group(1);
int index = format.indexOf('_');
if (index <= 0 || index >= format.length()) continue;
final String format = matcher.group(1);
final int index = format.indexOf("_");
// We don't need to use getPlaceholders() because we know what we're doing and we won't modify the map.
// And instead of looking for the element twice using contains() and get() we only get it and check if it's null.
String identifier = format.substring(0, index).toLowerCase(Locale.ENGLISH);
PlaceholderHook handler = PLACEHOLDERS.get(identifier);
if (index <= 0 || index >= format.length()) {
continue;
}
if (handler != null) {
String params = format.substring(index + 1);
String value = handler.onRequest(player, params);
final String identifier = format.substring(0, index).toLowerCase();
final String params = format.substring(index + 1);
final PlaceholderHook hook = hooks.get(identifier);
if (value != null) {
text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value));
}
if (hook == null) {
continue;
}
final String value = hook.onRequest(player, params);
if (value != null) {
text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value));
}
}
return colorize ? color(text) : text;
}
/**
* Optimized version of {@link #setPlaceholders(OfflinePlayer, String, Pattern, boolean)}
*
* @param player player to parse the placeholders against.
* @param text the text to translate.
* @param closure the closing points of a placeholder. %, {, [ etc...
* @param colorize if we should colorize this text using the common & symbol.
* @return the translated text.
*/
public static String setPlaceholders(OfflinePlayer player, String text, PlaceholderReplacer.Closure closure, boolean colorize) {
if (text == null) return null;
if (text.isEmpty()) return "";
if (PLACEHOLDERS.isEmpty()) return colorize ? color(text) : text;
// We don't want to dirty our class.
return PlaceholderReplacer.evaluatePlaceholders(player, text, closure, colorize);
}
/**
* Translate placeholders in the provided List based on the relation of the two provided players.
* <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
*/
public static List<String> setRelationalPlaceholders(Player one, Player two, List<String> text, boolean colorize) {
if (text == null) return null;
List<String> lines = new ArrayList<>();
for (String line : text) {
lines.add(setRelationalPlaceholders(one, two, line, colorize));
if (text == null) {
return null;
}
return lines;
return text.stream()
.map(line -> setRelationalPlaceholders(one, two, line, colorize))
.collect(Collectors.toList());
}
/**
@ -397,31 +397,43 @@ public class PlaceholderAPI {
* @param colorize If color codes (&[0-1a-fk-o]) should be translated
* @return The text containing the parsed relational placeholders
*/
@SuppressWarnings("DuplicatedCode")
public static String setRelationalPlaceholders(Player one, Player two, String text, boolean colorize) {
if (text == null) return null;
if (PLACEHOLDERS.isEmpty()) return colorize ? color(text) : text;
if (text == null) {
return null;
}
if (placeholders.isEmpty()) {
return colorize ? Msg.color(text) : text;
}
final Matcher matcher = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text);
final Map<String, PlaceholderHook> hooks = getPlaceholders();
Matcher matcher = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text);
while (matcher.find()) {
String format = matcher.group(2);
int index = format.indexOf('_');
if (index <= 0 || index >= format.length()) continue;
final String format = matcher.group(2);
final int index = format.indexOf("_");
String identifier = format.substring(0, index).toLowerCase(Locale.ENGLISH);
PlaceholderHook handler = PLACEHOLDERS.get(identifier);
if (index <= 0 || index >= format.length()) {
continue;
}
if (handler.isRelational()) {
Relational relational = (Relational) handler;
String params = format.substring(index + 1);
String value = relational.onPlaceholderRequest(one, two, params);
String identifier = format.substring(0, index).toLowerCase();
String params = format.substring(index + 1);
final PlaceholderHook hook = hooks.get(identifier);
if (value != null) {
text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value));
}
if (!(hook instanceof Relational)) {
continue;
}
final String value = ((Relational) hook).onPlaceholderRequest(one, two, params);
if (value != null) {
text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value));
}
}
return colorize ? color(text) : text;
return colorize ? Msg.color(text) : text;
}
/**
@ -429,34 +441,43 @@ public class PlaceholderAPI {
*/
protected static void unregisterAll() {
unregisterAllProvidedExpansions();
PLACEHOLDERS.clear();
placeholders.clear();
}
/**
* Unregister all expansions provided by PlaceholderAPI
*/
public static void unregisterAllProvidedExpansions() {
if (PLACEHOLDERS.isEmpty()) return;
final Set<PlaceholderHook> set = new HashSet<>(placeholders.values());
for (PlaceholderHook handler : PLACEHOLDERS.values()) {
if (handler.isExpansion()) {
PlaceholderExpansion expansion = (PlaceholderExpansion) handler;
if (!expansion.persist()) unregisterExpansion(expansion);
for (PlaceholderHook hook : set) {
if (hook instanceof PlaceholderExpansion) {
final PlaceholderExpansion expansion = (PlaceholderExpansion) hook;
if (!expansion.persist()) {
unregisterExpansion(expansion);
}
}
if (hook instanceof Cacheable) {
((Cacheable) hook).clear();
}
}
}
public static boolean registerExpansion(PlaceholderExpansion expansion) {
ExpansionRegisterEvent event = new ExpansionRegisterEvent(expansion);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) return false;
public static boolean registerExpansion(PlaceholderExpansion ex) {
ExpansionRegisterEvent ev = new ExpansionRegisterEvent(ex);
Bukkit.getPluginManager().callEvent(ev);
if (ev.isCancelled()) {
return false;
}
return registerPlaceholderHook(expansion.getIdentifier(), expansion);
return registerPlaceholderHook(ex.getIdentifier(), ex);
}
public static boolean unregisterExpansion(PlaceholderExpansion expansion) {
if (unregisterPlaceholderHook(expansion.getIdentifier())) {
Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(expansion));
public static boolean unregisterExpansion(PlaceholderExpansion ex) {
if (unregisterPlaceholderHook(ex.getIdentifier())) {
Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(ex));
return true;
}
@ -469,7 +490,7 @@ public class PlaceholderAPI {
* @return The pattern for {@literal %<identifier>_<params>%}
*/
public static Pattern getPlaceholderPattern() {
return PERCENT_PLACEHOLDER_PATTERN;
return PLACEHOLDER_PATTERN;
}
/**
@ -511,19 +532,19 @@ public class PlaceholderAPI {
}
public static String setPlaceholders(Player player, String text) {
return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, true);
return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true);
}
public static String setPlaceholders(Player player, String text, boolean colorize) {
return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize);
return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize);
}
public static List<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) {
return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize);
return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize);
}
public static String setBracketPlaceholders(Player player, String text) {

View File

@ -21,63 +21,66 @@
package me.clip.placeholderapi;
import me.clip.placeholderapi.commands.CommandHandler;
import me.clip.placeholderapi.commands.CompletionHandler;
import me.clip.placeholderapi.configuration.PlaceholderAPIConfig;
import me.clip.placeholderapi.expansion.ExpansionManager;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.expansion.Version;
import me.clip.placeholderapi.expansion.cloud.ExpansionCloudManager;
import me.clip.placeholderapi.external.EZPlaceholderHook;
import me.clip.placeholderapi.listeners.ApacheListener;
import me.clip.placeholderapi.listeners.PlaceholderListener;
import me.clip.placeholderapi.listeners.ServerLoadEventListener;
import me.clip.placeholderapi.updatechecker.UpdateChecker;
import me.clip.placeholderapi.util.TimeUtil;
import me.clip.placeholderapi.util.UpdateChecker;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.plugin.java.JavaPlugin;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* Yes I have a shit load of work to do...
*
* @author Ryan McCarthy
*/
public class PlaceholderAPIPlugin extends JavaPlugin {
private static final Version serverVersion;
private static PlaceholderAPIPlugin instance;
private static DateTimeFormatter dateFormat;
private static SimpleDateFormat dateFormat;
private static String booleanTrue;
private static String booleanFalse;
static {
// It's not possible to be null or throw an index exception unless it's a bug.
String nmsVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
boolean spigot;
try {
Class.forName("org.spigotmc.SpigotConfig");
spigot = true;
} catch (ExceptionInInitializerError | ClassNotFoundException ignored) {
spigot = false;
}
serverVersion = new Version(nmsVersion, spigot);
}
private static Version serverVersion;
private PlaceholderAPIConfig config;
private ExpansionManager expansionManager;
private ExpansionCloudManager expansionCloud;
private long startTime;
private static Version getVersion() {
String v = "unknown";
boolean spigot = false;
try {
v = Bukkit.getServer().getClass().getPackage().getName()
.split("\\.")[3];
} catch (ArrayIndexOutOfBoundsException ex) {
}
try {
Class.forName("org.spigotmc.SpigotConfig");
Class.forName("net.md_5.bungee.api.chat.BaseComponent");
spigot = true;
} catch (ExceptionInInitializerError | ClassNotFoundException ignored) {
}
return new Version(v, spigot);
}
/**
* Gets the static instance of the main class for PlaceholderAPI. This class is not the actual API
* class, this is the main class that extends JavaPlugin. For most API methods, use static methods
@ -95,8 +98,9 @@ public class PlaceholderAPIPlugin extends JavaPlugin {
*
* @return date format
*/
public static DateTimeFormatter getDateFormat() {
return dateFormat != null ? dateFormat : DateTimeFormatter.ofPattern("MM/dd/yy HH:mm:ss");
public static SimpleDateFormat getDateFormat() {
return dateFormat != null ? dateFormat : new SimpleDateFormat(
"MM/dd/yy HH:mm:ss");
}
/**
@ -118,26 +122,26 @@ public class PlaceholderAPIPlugin extends JavaPlugin {
}
public static Version getServerVersion() {
return serverVersion;
return serverVersion != null ? serverVersion : getVersion();
}
@Override
public void onLoad() {
startTime = System.currentTimeMillis();
instance = this;
serverVersion = getVersion();
config = new PlaceholderAPIConfig(this);
expansionManager = new ExpansionManager(this);
}
@Override
public void onEnable() {
startTime = System.currentTimeMillis();
instance = this;
config = new PlaceholderAPIConfig(this);
config.loadDefConfig();
setupOptions();
expansionManager = new ExpansionManager(this);
Objects.requireNonNull(getCommand("placeholderapi")).setExecutor(new CommandHandler());
new PlaceholderListener(this);
PluginCommand command = getCommand("placeholderapi");
command.setExecutor(new CommandHandler());
command.setTabCompleter(new CompletionHandler());
new ApacheListener(this);
try {
Class.forName("org.bukkit.event.server.ServerLoadEvent");
new ServerLoadEventListener(this);
@ -146,7 +150,7 @@ public class PlaceholderAPIPlugin extends JavaPlugin {
getLogger().info("Placeholder expansion registration initializing...");
//fetch any hooks that may have registered externally onEnable first otherwise they will be lost
Map<String, PlaceholderHook> alreadyRegistered = PlaceholderAPI.PLACEHOLDERS;
final Map<String, PlaceholderHook> alreadyRegistered = PlaceholderAPI.getPlaceholders();
getExpansionManager().registerAllExpansions();
if (alreadyRegistered != null && !alreadyRegistered.isEmpty()) {
@ -155,8 +159,13 @@ public class PlaceholderAPIPlugin extends JavaPlugin {
}, 1);
}
if (config.checkUpdates()) new UpdateChecker(this).fetch();
if (config.isCloudEnabled()) enableCloud();
if (config.checkUpdates()) {
new UpdateChecker(this).fetch();
}
if (config.isCloudEnabled()) {
enableCloud();
}
setupMetrics();
getServer().getScheduler().runTaskLater(this, this::checkHook, 40);
@ -166,13 +175,14 @@ public class PlaceholderAPIPlugin extends JavaPlugin {
public void onDisable() {
disableCloud();
PlaceholderAPI.unregisterAll();
Bukkit.getScheduler().cancelTasks(this);
expansionManager = null;
Bukkit.getScheduler().cancelTasks(this);
serverVersion = null;
instance = null;
}
public void reloadConf(CommandSender s) {
boolean cloudEnabled = this.expansionCloud != null;
PlaceholderAPI.unregisterAllProvidedExpansions();
reloadConfig();
setupOptions();
@ -180,70 +190,79 @@ public class PlaceholderAPIPlugin extends JavaPlugin {
if (!config.isCloudEnabled()) {
disableCloud();
} else if (this.expansionCloud != null) {
} else if (!cloudEnabled) {
enableCloud();
}
s.sendMessage(ChatColor.translateAlternateColorCodes('&', PlaceholderAPI.PLACEHOLDERS.size() + " &aplaceholder hooks successfully registered!"));
s.sendMessage(ChatColor.translateAlternateColorCodes('&',
PlaceholderAPI.getRegisteredIdentifiers().size()
+ " &aplaceholder hooks successfully registered!"));
}
@SuppressWarnings("deprecation")
private void checkHook() {
for (PlaceholderHook hook : PlaceholderAPI.PLACEHOLDERS.values()) {
if (hook instanceof EZPlaceholderHook) {
String pluginName = ((EZPlaceholderHook) hook).getPluginName();
Map<String, PlaceholderHook> loaded = PlaceholderAPI.getPlaceholders();
loaded.values().forEach(h -> {
if (h instanceof EZPlaceholderHook) {
String author;
try {
author = Bukkit.getPluginManager().getPlugin(pluginName).getDescription().getAuthors().toString();
author = Bukkit.getPluginManager().getPlugin(((EZPlaceholderHook) h).getPluginName()).getDescription().getAuthors().toString();
} catch (Exception ex) {
author = "the author of the hook's plugin";
}
getLogger().severe(pluginName +
getLogger().severe(((EZPlaceholderHook) h).getPluginName() +
" is currently using a deprecated method to hook into PlaceholderAPI. Placeholders for that plugin no longer work. " +
"Please consult " + author + " and urge them to update it ASAP.");
"Please consult {author} and urge them to update it ASAP.".replace("{author}", author));
// disable the hook on startup
PlaceholderAPI.unregisterPlaceholderHook(((EZPlaceholderHook) hook).getPlaceholderName());
PlaceholderAPI.unregisterPlaceholderHook(((EZPlaceholderHook) h).getPlaceholderName());
}
}
});
}
private void setupOptions() {
booleanTrue = config.booleanTrue();
if (booleanTrue == null) booleanTrue = "true";
if (booleanTrue == null) {
booleanTrue = "true";
}
booleanFalse = config.booleanFalse();
if (booleanFalse == null) booleanFalse = "false";
if (booleanFalse == null) {
booleanFalse = "false";
}
try {
dateFormat = DateTimeFormatter.ofPattern(config.dateFormat());
} catch (Exception ignored) {
dateFormat = DateTimeFormatter.ofPattern("MM/dd/yy HH:mm:ss");
dateFormat = new SimpleDateFormat(config.dateFormat());
} catch (Exception e) {
dateFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss");
}
}
private void setupMetrics() {
// This is NOT the plugin resource ID. it's the bStats ID.
Metrics metrics = new Metrics(this, 438);
metrics.addCustomChart(new Metrics.SimplePie("using_expansion_cloud",
() -> getExpansionCloud() != null ? "yes" : "no"));
Metrics m = new Metrics(this);
m.addCustomChart(new Metrics.SimplePie("using_expansion_cloud", () -> getExpansionCloud() != null ? "yes" : "no"));
metrics.addCustomChart(new Metrics.SimplePie("using_spigot",
() -> getServerVersion().isSpigot() ? "yes" : "no"));
m.addCustomChart(new Metrics.SimplePie("using_spigot", () -> getServerVersion().isSpigot() ? "yes" : "no"));
metrics.addCustomChart(new Metrics.AdvancedPie("expansions_used", () -> {
m.addCustomChart(new Metrics.AdvancedPie("expansions_used", () -> {
Map<String, Integer> map = new HashMap<>();
for (PlaceholderHook hook : PlaceholderAPI.PLACEHOLDERS.values()) {
if (hook.isExpansion()) {
PlaceholderExpansion ex = (PlaceholderExpansion) hook;
map.put(ex.getRequiredPlugin() == null ? ex.getIdentifier()
: ex.getRequiredPlugin(), 1);
Map<String, PlaceholderHook> hooks = PlaceholderAPI.getPlaceholders();
if (!hooks.isEmpty()) {
for (PlaceholderHook hook : hooks.values()) {
if (hook instanceof PlaceholderExpansion) {
PlaceholderExpansion expansion = (PlaceholderExpansion) hook;
map.put(expansion.getRequiredPlugin() == null ? expansion.getIdentifier() : expansion.getRequiredPlugin(), 1);
}
}
}
return map;
}));
}
@ -257,7 +276,10 @@ public class PlaceholderAPIPlugin extends JavaPlugin {
}
public void disableCloud() {
if (expansionCloud != null) expansionCloud = null;
if (expansionCloud != null) {
expansionCloud.clean();
expansionCloud = null;
}
}
/**
@ -283,6 +305,6 @@ public class PlaceholderAPIPlugin extends JavaPlugin {
}
public long getUptimeMillis() {
return System.currentTimeMillis() - startTime;
return (System.currentTimeMillis() - startTime);
}
}

View File

@ -20,14 +20,13 @@
*/
package me.clip.placeholderapi;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.expansion.Relational;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
public abstract class PlaceholderHook {
/**
* Called when a placeholder value is requested from this hook.
* called when a placeholder value is requested from this hook
*
* @param player {@link OfflinePlayer} to request the placeholder value for, null if not needed for a
* player
@ -42,12 +41,8 @@ public abstract class PlaceholderHook {
return onPlaceholderRequest(null, params);
}
public PlaceholderAPIPlugin getPlaceholderAPI() {
return PlaceholderAPIPlugin.getInstance();
}
/**
* Called when a placeholder is requested from this hook.
* called when a placeholder is requested from this hook
*
* @param player {@link Player} to request the placeholder value for, null if not needed for a player
* @param params String passed to the hook to determine what value to return
@ -56,12 +51,4 @@ public abstract class PlaceholderHook {
public String onPlaceholderRequest(Player player, String params) {
return null;
}
public boolean isExpansion() {
return this instanceof PlaceholderExpansion;
}
public boolean isRelational() {
return this instanceof Relational;
}
}

View File

@ -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;
}
}
}

View File

@ -1,42 +1,52 @@
package me.clip.placeholderapi.commands;
import com.google.common.collect.ImmutableSet;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public abstract class Command {
private static final Options EMPTY_OPTIONS = new Options(null, 0);
private static final Options EMPTY_OPTIONS = new Options(null, 0, null);
private final String match;
private final String usage;
private final int minimumArguments;
/**
* Commands should not have multiple permissions. This can lead to a lot of confusions.
* This is also a lot more appropriate for maintainability, I saw a lot of commands regitered with wrong permissions.
* We will use the main command name to parse our permission.
*/
private final String permission;
private final Set<String> permissions;
protected Command(String match) {
protected Command(@NotNull final String match) {
this(match, EMPTY_OPTIONS);
}
protected Command(String match, Options options) {
protected Command(@NotNull final String match, @NotNull final Options options) {
this.match = match;
this.usage = options.usage == null ? "/papi " + match + " <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;
}
protected static Options options(String usage, int minimumArguments) {
return new Options(usage, minimumArguments);
protected static Options usage(@NotNull final String usage, final int minimumArguments) {
return new Options(usage, minimumArguments, null);
}
protected static Options permissions(@NotNull final String... permissions) {
return new Options(null, 0, permissions);
}
protected static Options options(@NotNull final String usage, final int minimumArguments,
@NotNull final String... permissions) {
return new Options(usage, minimumArguments, permissions);
}
@NotNull
public String getMatch() {
return match;
}
@NotNull
public String getUsage() {
return usage;
}
@ -45,23 +55,28 @@ public abstract class Command {
return minimumArguments;
}
public String getPermission() {
return permission;
@NotNull
public Set<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();
}
private static class Options {
private final String usage;
private final int minimumArguments;
private final String[] permissions;
private Options(String usage, int minimumArguments) {
private Options(@Nullable final String usage, final int minimumArguments,
@Nullable final String[] permissions) {
this.usage = usage;
this.minimumArguments = minimumArguments;
this.permissions = permissions;
}
}
}

View File

@ -1,33 +1,25 @@
package me.clip.placeholderapi.commands;
import com.google.common.collect.Lists;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.command.*;
import me.clip.placeholderapi.commands.command.ecloud.EcloudInfoCommand;
import me.clip.placeholderapi.commands.command.ecloud.EcloudListCommand;
import me.clip.placeholderapi.commands.command.ecloud.*;
import me.clip.placeholderapi.util.Msg;
import org.apache.commons.lang.StringUtils;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Pattern;
public final class CommandHandler implements CommandExecutor {
private static final Command DEFAULT = new VersionCommand();
protected static final List<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(),
private static final List<Command> COMMANDS = Lists.newArrayList(
new EcloudClearCommand(),
new EcloudDownloadCommand(),
new EcloudInfoCommand(),
@ -36,57 +28,74 @@ public final class CommandHandler implements CommandExecutor {
new EcloudRefreshCommand(),
new EcloudStatusCommand(),
new EcloudVersionInfoCommand(),
new EcloudDisableCommand(),
new EcloudEnableCommand()
new EcloudCommand(),
new BcParseCommand(),
new ParseCommand(),
new ParseRelCommand(),
new DisableEcloudCommand(),
new EnableCloudCommand(),
new HelpCommand(),
new InfoCommand(),
new ListCommand(),
new RegisterCommand(),
new ReloadCommand(),
DEFAULT,
new UnregisterCommand()
);
static {
COMMANDS.sort((command1, command2) -> {
int comparison = Integer.compare(command1.getMatch().length(), command2.getMatch().length());
final int comparison = Integer.compare(command1.getMatch().length(), command2.getMatch().length());
if (comparison == 1) return -1;
if (comparison == -1) return 1;
return 0;
});
Objects.requireNonNull(PlaceholderAPIPlugin.getInstance().getCommand("placeholderapi"))
.setTabCompleter(new CompletionHandler(COMMANDS));
}
private static String[] splitArguments(String joinedArguments, String command) {
joinedArguments = StringUtils.remove(joinedArguments, command).trim();
String[] args = StringUtils.split(joinedArguments);
return args.length == 1 && args[0].isEmpty() ? new String[0] : args;
}
private static final Pattern SPACE_PATTERN = Pattern.compile(" ");
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull org.bukkit.command.Command bukkitCommand, @NotNull String name, String[] args) {
public boolean onCommand(@NotNull final CommandSender sender, @NotNull final org.bukkit.command.Command bukkitCommand,
@NotNull final String name, @NotNull String[] args) {
if (args.length == 0) {
DEFAULT.execute(sender, args);
return true;
}
String joined = String.join(" ", args).toLowerCase();
Optional<Command> optional = COMMANDS.stream()
final String joined = String.join(" ", args).toLowerCase();
final Optional<Command> optional = COMMANDS.stream()
.filter(command -> joined.startsWith(command.getMatch()))
.findFirst();
if (!optional.isPresent()) {
Msg.msg(sender, "&cUnknown command.");
sender.sendMessage("Specified command is not valid.");
return true;
}
Command command = optional.get();
String permission = command.getPermission();
if (!sender.hasPermission(permission)) {
Msg.msg(sender, "&cYou do not have the permission to use this command.");
final Command command = optional.get();
if (!command.getPermissions().isEmpty() && command.getPermissions().stream().noneMatch(sender::hasPermission)) {
sender.sendMessage("You do not have the permission to execute specified command.");
return true;
}
args = splitArguments(joined, command.getMatch());
if (args.length < command.getMinimumArguments()) {
Msg.msg(sender, command.getUsage());
return true;
}
command.execute(sender, args);
return true;
}
static String[] splitArguments(@NotNull final String joinedArguments, @NotNull final String command) {
final String[] args = SPACE_PATTERN.split(joinedArguments.replace(command, "").trim());
return args.length == 1 && args[0].isEmpty() ? new String[]{} : args;
}
}

View File

@ -1,37 +1,32 @@
package me.clip.placeholderapi.commands;
import org.apache.commons.lang.StringUtils;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.Optional;
public final class CompletionHandler implements TabCompleter {
private static String[] splitArguments(String[] args, String command) {
int skip = StringUtils.split(command).length;
return Arrays.stream(args).skip(skip).toArray(String[]::new);
private final List<Command> commands;
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's because of the list order. Even if they wanted to change that, they couldn't for the sake of backward compatibility. ~Crypto
@NotNull
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, org.bukkit.command.@NotNull Command bukkitCommand, @NotNull String name, String[] args) {
String joined = String.join(" ", args).toLowerCase(Locale.ENGLISH);
public List<String> onTabComplete(@NotNull final CommandSender sender, @NotNull final org.bukkit.command.Command bukkitCommand,
@NotNull final String name, @NotNull final String[] args) {
final String joined = String.join(" ", args).toLowerCase();
final Optional<Command> optional = commands.stream()
.filter(command -> joined.startsWith(command.getMatch()))
.findAny();
if (args.length > 1) {
return CommandHandler.COMMANDS.stream()
.filter(command -> sender.hasPermission(command.getPermission()) && joined.startsWith(command.getMatch()))
.findFirst()
.map(command -> command.handleCompletion(sender, splitArguments(args, command.getMatch())))
.orElse(Collections.emptyList());
}
return CommandHandler.COMMANDS.stream()
.filter(command -> sender.hasPermission(command.getPermission()) && (args[0].isEmpty() || command.getMatch().startsWith(joined)))
.map(Command::getMatch).collect(Collectors.toList());
return optional
.map(command -> command.handleCompletion(sender, CommandHandler.splitArguments(joined, command.getMatch())))
.orElse(Collections.emptyList());
}
}

View File

@ -8,34 +8,40 @@ import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public final class BcParseCommand extends Command {
public BcParseCommand() {
super("bcparse", options("&cYou must specify a player.", 1));
super("bcparse", options("&cYou must specify a player.", 1, "placeholderapi.parse"));
}
@Override
public void execute(CommandSender sender, String[] args) {
OfflinePlayer player;
String input = args[0];
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final OfflinePlayer player;
final String input = args[0];
if (input.equalsIgnoreCase("me")) {
if (sender instanceof Player) {
player = (Player) sender;
} else {
Msg.msg(sender, "&cThis command must target a player when used by console");
return;
}
} else {
player = Bukkit.getPlayer(input);
if (player == null) player = Bukkit.getOfflinePlayer(input);
if (player == null || !player.hasPlayedBefore()) {
Msg.msg(sender, "&cCould not find player&8: &f" + input);
return;
if (Bukkit.getPlayer(input) != null) {
player = Bukkit.getPlayer(input);
} else {
player = Bukkit.getOfflinePlayer(input);
}
}
String parse = StringUtils.join(args, " ", 2, args.length);
if (player == null || !player.hasPlayedBefore()) {
Msg.msg(sender, "&cFailed to find player: &f" + input);
return;
}
final String parse = StringUtils.join(args, " ", 2, args.length);
Msg.broadcast("&r" + PlaceholderAPI.setPlaceholders(player, parse));
}
}

View File

@ -1,25 +1,29 @@
package me.clip.placeholderapi.commands.command.ecloud;
package me.clip.placeholderapi.commands.command;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.Command;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public final class EcloudDisableCommand extends Command {
public EcloudDisableCommand() {
super("ecloud disable");
public final class DisableEcloudCommand extends Command {
public DisableEcloudCommand() {
super("disablecloud", permissions("placeholderapi.ecloud"));
}
@Override
public void execute(CommandSender sender, String[] args) {
PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
if (plugin.getExpansionCloud() == null) {
Msg.msg(sender, "&7The cloud is already disabled!");
return;
}
plugin.disableCloud();
plugin.getPlaceholderAPIConfig().setCloudEnabled(false);
Msg.msg(sender, "&aThe cloud has been disabled!");
return;
}
}

View File

@ -6,6 +6,7 @@ import me.clip.placeholderapi.commands.Command;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@ -21,18 +22,16 @@ public final class EcloudCommand extends Command {
"placeholders",
"refresh",
"status",
"versioninfo",
"enable",
"disable"
"versioninfo"
);
public EcloudCommand() {
super("ecloud");
super("ecloud", permissions("placeholderapi.ecloud"));
}
@Override
public void execute(CommandSender sender, String[] args) {
PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
if (args.length == 0) {
Msg.msg(sender, "&bExpansion cloud commands",
@ -58,6 +57,7 @@ public final class EcloudCommand extends Command {
if (plugin.getExpansionCloud() == null) {
Msg.msg(sender, "&7The expansion cloud is not enabled!");
return;
}
@ -69,9 +69,9 @@ public final class EcloudCommand extends Command {
sender.sendMessage("Specified command is not valid.");
}
@NotNull
@Override
public List<String> handleCompletion(CommandSender sender, String[] args) {
public List<String> handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) {
if (args.length == MAXIMUM_ARGUMENTS) {
return StringUtil.copyPartialMatches(args[0], COMPLETIONS, new ArrayList<>(COMPLETIONS.size()));
}

View File

@ -1,20 +1,22 @@
package me.clip.placeholderapi.commands.command.ecloud;
package me.clip.placeholderapi.commands.command;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.Command;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public final class EcloudEnableCommand extends Command {
public EcloudEnableCommand() {
super("ecloud enable");
public final class EnableCloudCommand extends Command {
public EnableCloudCommand() {
super("enablecloud", permissions("placeholderapi.ecloud"));
}
@Override
public void execute(CommandSender sender, String[] args) {
PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
if (plugin.getExpansionCloud() != null) {
Msg.msg(sender, "&7The cloud is already enabled!");
return;
}

View File

@ -4,14 +4,15 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.Command;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public final class HelpCommand extends Command {
public HelpCommand() {
super("help");
super("help", permissions("placeholderapi.ecloud"));
}
@Override
public void execute(CommandSender sender, String[] args) {
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
Msg.msg(sender, "PlaceholderAPI &aHelp &e(&f" + PlaceholderAPIPlugin.getInstance().getDescription().getVersion() + "&e)",
"&b/papi",
"&fView plugin info/version info",

View File

@ -7,6 +7,7 @@ import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@ -16,13 +17,13 @@ public final class InfoCommand extends Command {
private static final int MINIMUM_ARGUMENTS = 1;
public InfoCommand() {
super("info", options("&cIncorrect usage! &7/papi info <expansion>", MINIMUM_ARGUMENTS));
super("info", options("&cIncorrect usage! &7/papi info <expansion>", MINIMUM_ARGUMENTS, "placeholderapi.info"));
}
@Override
public void execute(CommandSender sender, String[] args) {
String requestedExpansion = args[0];
PlaceholderExpansion ex = PlaceholderAPIPlugin.getInstance().getExpansionManager().getRegisteredExpansion(requestedExpansion);
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final String requestedExpansion = args[0];
final PlaceholderExpansion ex = PlaceholderAPIPlugin.getInstance().getExpansionManager().getRegisteredExpansion(requestedExpansion);
if (ex == null) {
Msg.msg(sender, "&cThere is no expansion loaded with the identifier: &f" + requestedExpansion);
@ -53,11 +54,11 @@ public final class InfoCommand extends Command {
}
}
@NotNull
@Override
public List<String> handleCompletion(CommandSender sender, String[] args) {
public List<String> handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) {
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()));
}

View File

@ -4,18 +4,19 @@ import me.clip.placeholderapi.PlaceholderAPI;
import me.clip.placeholderapi.commands.Command;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
import java.util.stream.Collectors;
public final class ListCommand extends Command {
public ListCommand() {
super("list");
super("list", permissions("placeholderapi.list"));
}
@Override
public void execute(CommandSender sender, String[] args) {
Set<String> registered = PlaceholderAPI.getRegisteredIdentifiers();
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final Set<String> registered = PlaceholderAPI.getRegisteredIdentifiers();
if (registered.isEmpty()) {
Msg.msg(sender, "&7There are no placeholder hooks currently registered!");
return;

View File

@ -7,53 +7,41 @@ import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull;
public final class ParseCommand extends Command {
public ParseCommand() {
super("parse", options("&cYou must specify a player.", 1));
super("parse", options("&cYou must specify a player.", 1, "placeholderapi.parse"));
}
@Override
public void execute(CommandSender sender, String[] args) {
OfflinePlayer player;
String input = args[0];
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final OfflinePlayer player;
final String input = args[0];
if (input.equalsIgnoreCase("me")) {
if (sender instanceof Player) {
player = (Player) sender;
} else {
Msg.msg(sender, "&cThis command must target a player when used by console");
return;
}
} else {
player = Bukkit.getPlayer(input);
if (player == null) player = Bukkit.getOfflinePlayer(input);
if (player == null || !player.hasPlayedBefore()) {
Msg.msg(sender, "&cCould not find player&8: &f" + input);
return;
if (Bukkit.getPlayer(input) != null) {
player = Bukkit.getPlayer(input);
} else {
player = Bukkit.getOfflinePlayer(input);
}
}
String parse = StringUtils.join(args, " ", 1, args.length);
if (player == null || !player.hasPlayedBefore()) {
Msg.msg(sender, "&cFailed to find player: &f" + input);
return;
}
final String parse = StringUtils.join(args, " ", 1, args.length);
Msg.msg(sender, "&r" + PlaceholderAPI.setPlaceholders(player, parse));
}
@Override
public List<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<>();
}
}

View File

@ -7,27 +7,30 @@ import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public final class ParseRelCommand extends Command {
public ParseRelCommand() {
super("parserel", options("&cYou must specify at least two players.", 2));
super("parserel", options("&cYou must specify at least two players.", 2, "placeholderapi.parse"));
}
@Override
public void execute(CommandSender sender, String[] args) {
Player one = Bukkit.getPlayer(args[0]);
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final Player one = Bukkit.getPlayer(args[0]);
if (one == null) {
Msg.msg(sender, args[0] + " &cis not online!");
return;
}
Player two = Bukkit.getPlayer(args[1]);
final Player two = Bukkit.getPlayer(args[1]);
if (two == null) {
Msg.msg(sender, args[1] + " &cis not online!");
return;
}
String parse = StringUtils.join(args, " ", 1, args.length);
final String parse = StringUtils.join(args, " ", 1, args.length);
Msg.msg(sender, "&r" + PlaceholderAPI.setRelationalPlaceholders(one, two, parse));
}
}

View File

@ -4,21 +4,22 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.Command;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.util.Msg;
import org.apache.commons.lang.StringUtils;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public final class RegisterCommand extends Command {
public RegisterCommand() {
super("register", options("&cAn expansion file name must be specified!", 1));
super("register", options("&cAn expansion file name must be specified!", 1,"placeholderapi.register"));
}
@Override
public void execute(CommandSender sender, String[] args) {
String fileName = StringUtils.remove(args[0], ".jar");
PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionManager().registerExpansion(fileName);
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final String fileName = args[0].replace(".jar", "");
final PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionManager().registerExpansion(fileName);
if (expansion == null) {
Msg.msg(sender, "&cFailed to register expansion from " + fileName);
return;
}

View File

@ -4,14 +4,15 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.Command;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public final class ReloadCommand extends Command {
public ReloadCommand() {
super("reload");
super("reload", permissions("placeholderapi.reload"));
}
@Override
public void execute(CommandSender sender, String[] args) {
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
Msg.msg(sender, "&fPlaceholder&7API &bconfiguration reloaded!");
PlaceholderAPIPlugin.getInstance().reloadConf(sender);
}

View File

@ -7,6 +7,7 @@ import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@ -16,17 +17,18 @@ public final class UnregisterCommand extends Command {
private static final int MINIMUM_ARGUMENTS = 1;
public UnregisterCommand() {
super("unregister", options("&cAn expansion name must be specified!", MINIMUM_ARGUMENTS));
super("unregister", options("&cAn expansion name must be specified!", MINIMUM_ARGUMENTS, "placeholderapi.register"));
}
@Override
public void execute(CommandSender sender, String[] args) {
String requestedExpansion = args[0];
PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionManager()
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final String requestedExpansion = args[0];
final PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionManager()
.getRegisteredExpansion(requestedExpansion);
if (expansion == null) {
Msg.msg(sender, "&cFailed to find expansion: &f" + requestedExpansion);
return;
}
@ -37,11 +39,12 @@ public final class UnregisterCommand extends Command {
}
}
@NotNull
@Override
public List<String> handleCompletion(CommandSender sender, String[] args) {
public List<String> handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) {
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()));
}

View File

@ -7,6 +7,7 @@ import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
@ -33,8 +34,8 @@ public final class VersionCommand extends Command {
}
@Override
public void execute(CommandSender sender, String[] args) {
PluginDescriptionFile description = PlaceholderAPIPlugin.getInstance().getDescription();
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final PluginDescriptionFile description = PlaceholderAPIPlugin.getInstance().getDescription();
Msg.msg(sender, "PlaceholderAPI &7version &b&o" + description.getVersion(),
"&fCreated by&7: &b" + description.getAuthors(),
@ -42,9 +43,9 @@ public final class VersionCommand extends Command {
"&fEcloud commands: &b/papi ecloud");
}
@NotNull
@Override
public List<String> handleCompletion(CommandSender sender, String[] args) {
public List<String> handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) {
if (args.length == 1) {
return StringUtil.copyPartialMatches(args[0], COMPLETIONS, new ArrayList<>(COMPLETIONS.size()));
}

View File

@ -4,14 +4,15 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.Command;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public final class EcloudClearCommand extends Command {
public EcloudClearCommand() {
super("ecloud clear");
super("ecloud clear", permissions("placeholderapi.ecloud"));
}
@Override
public void execute(CommandSender sender, String[] args) {
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
PlaceholderAPIPlugin.getInstance().getExpansionCloud().clean();
Msg.msg(sender, "&aThe cache has been cleared!!");
}

View File

@ -9,24 +9,25 @@ import me.clip.placeholderapi.expansion.cloud.ExpansionCloudManager;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public final class EcloudDownloadCommand extends Command {
public EcloudDownloadCommand() {
super("ecloud download", options("&cAn expansion name must be specified!", 1));
super("ecloud download", options("&cAn expansion name must be specified!", 1, "placeholderapi.ecloud"));
}
@Override
public void execute(CommandSender sender, String[] args) {
PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
String input = args[0];
CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(input);
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
final String input = args[0];
final CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(input);
if (expansion == null) {
Msg.msg(sender, "&cNo expansion found with the name: &f" + input);
return;
}
PlaceholderExpansion loaded = plugin.getExpansionManager().getRegisteredExpansion(input);
final PlaceholderExpansion loaded = plugin.getExpansionManager().getRegisteredExpansion(input);
if (loaded != null && loaded.isRegistered()) {
PlaceholderAPI.unregisterPlaceholderHook(loaded.getIdentifier());
}
@ -45,23 +46,10 @@ public final class EcloudDownloadCommand extends Command {
}
Msg.msg(sender, "&aDownload starting for expansion: &f" + expansion.getName() + " &aversion: &f" + version);
String player = ((sender instanceof Player) ? sender.getName() : null);
ExpansionCloudManager cloud = plugin.getExpansionCloud();
final String player = ((sender instanceof Player) ? sender.getName() : null);
final ExpansionCloudManager cloud = plugin.getExpansionCloud();
cloud.downloadExpansion(player, expansion, version);
cloud.clean();
cloud.fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());
}
// @Override
// public List<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;
// }
}

View File

@ -7,18 +7,19 @@ import me.clip.placeholderapi.util.Msg;
import me.rayzr522.jsonmessage.JSONMessage;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import static me.clip.placeholderapi.util.Msg.color;
public final class EcloudInfoCommand extends Command {
public EcloudInfoCommand() {
super("ecloud info", options("&cAn expansion name must be specified!", 1));
super("ecloud info", options("&cAn expansion name must be specified!", 1, "placeholderapi.ecloud"));
}
@Override
public void execute(CommandSender sender, String[] args) {
String input = args[0];
CloudExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionCloud().getCloudExpansion(input);
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final String input = args[0];
final CloudExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionCloud().getCloudExpansion(input);
if (expansion == null) {
Msg.msg(sender, "&cNo expansion found by the name: &f" + input);
@ -34,7 +35,7 @@ public final class EcloudInfoCommand extends Command {
return;
}
Player p = (Player) sender;
final Player p = (Player) sender;
Msg.msg(sender, "&bExpansion&7: &f" + expansion.getName(),
"&bAuthor: &f" + expansion.getAuthor(),
@ -42,7 +43,7 @@ public final class EcloudInfoCommand extends Command {
);
// latest version
JSONMessage latestVersion = JSONMessage
final JSONMessage latestVersion = JSONMessage
.create(color("&bLatest version: &f" + expansion.getLatestVersion()));
latestVersion.tooltip(color("&bReleased: &f" + expansion.getTimeSinceLastUpdate()
+ "\n&bUpdate information: &f" + expansion.getVersion().getReleaseNotes()
@ -50,7 +51,7 @@ public final class EcloudInfoCommand extends Command {
latestVersion.send(p);
// versions
JSONMessage versions = JSONMessage
final JSONMessage versions = JSONMessage
.create(color("&bVersions available: &f" + expansion.getVersions().size()));
versions.tooltip(color(String.join("&b, &f", expansion.getAvailableVersions())));
versions.suggestCommand(
@ -59,7 +60,7 @@ public final class EcloudInfoCommand extends Command {
// placeholders
if (expansion.getPlaceholders() != null) {
JSONMessage placeholders = JSONMessage
final JSONMessage placeholders = JSONMessage
.create(color("&bPlaceholders: &f" + expansion.getPlaceholders().size()));
placeholders.tooltip(color(String.join("&b, &f", expansion.getPlaceholders())));
placeholders.suggestCommand("/papi ecloud placeholders " + expansion.getName());

View File

@ -9,6 +9,7 @@ import me.rayzr522.jsonmessage.JSONMessage;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.stream.Collectors;
@ -24,12 +25,13 @@ public final class EcloudListCommand extends Command {
);
public EcloudListCommand() {
super("ecloud list", options("&cIncorrect usage! &7/papi ecloud list <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
public void execute(CommandSender sender, String[] args) {
PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
int page = 1;
String author;
@ -101,7 +103,7 @@ public final class EcloudListCommand extends Command {
Msg.msg(sender, "&6Gold = Expansions which need updated");
if (!(sender instanceof Player)) {
Map<String, CloudExpansion> expansions = new HashMap<>();
final Map<String, CloudExpansion> expansions = new HashMap<>();
for (CloudExpansion exp : ex.values()) {
if (exp == null || exp.getName() == null) {
@ -111,7 +113,7 @@ public final class EcloudListCommand extends Command {
expansions.put(exp.getName(), exp);
}
List<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];
@ -120,7 +122,7 @@ public final class EcloudListCommand extends Command {
continue;
}
CloudExpansion expansion = expansions.get(name);
final CloudExpansion expansion = expansions.get(name);
Msg.msg(sender,
"&b" + i + "&7: " + (expansion.shouldUpdate() ? "&6"
@ -132,11 +134,11 @@ public final class EcloudListCommand extends Command {
return;
}
Player p = (Player) sender;
final Player p = (Player) sender;
Map<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) {
continue;
}
@ -144,7 +146,7 @@ public final class EcloudListCommand extends Command {
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;
@ -153,8 +155,8 @@ public final class EcloudListCommand extends Command {
continue;
}
CloudExpansion expansion = expansions.get(name);
StringBuilder sb = new StringBuilder();
final CloudExpansion expansion = expansions.get(name);
final StringBuilder sb = new StringBuilder();
if (expansion.shouldUpdate()) {
sb.append("&6Click to update to the latest version of this expansion\n\n");
@ -170,13 +172,13 @@ public final class EcloudListCommand extends Command {
sb.append("&bLast updated&7: &f").append(expansion.getTimeSinceLastUpdate()).append(" ago\n");
sb.append("\n").append(expansion.getDescription());
String msg = color(
final String msg = color(
"&b" + (i + 1) + "&7: " + (expansion.shouldUpdate() ? "&6"
: (expansion.hasExpansion() ? "&a" : "")) + expansion.getName());
String hover = color(sb.toString());
final String hover = color(sb.toString());
JSONMessage line = JSONMessage.create(msg);
final JSONMessage line = JSONMessage.create(msg);
line.tooltip(hover);
if (expansion.shouldUpdate() || !expansion.hasExpansion()) {
@ -190,9 +192,9 @@ public final class EcloudListCommand extends Command {
}
}
@NotNull
@Override
public List<String> handleCompletion(CommandSender sender, String[] args) {
public List<String> handleCompletion(@NotNull final CommandSender sender, @NotNull final String[] args) {
if (args.length == MINIMUM_ARGUMENTS) {
return StringUtil.copyPartialMatches(args[0], COMPLETIONS, new ArrayList<>(COMPLETIONS.size()));
}

View File

@ -8,26 +8,27 @@ import me.clip.placeholderapi.util.Msg;
import me.rayzr522.jsonmessage.JSONMessage;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public final class EcloudPlaceholdersCommand extends Command {
public EcloudPlaceholdersCommand() {
super("ecloud placeholders", options("&cAn expansion name must be specified!", 1));
super("ecloud placeholders", options("&cAn expansion name must be specified!", 1, "placeholderapi.ecloud"));
}
@Override
public void execute(CommandSender sender, String[] args) {
PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
String input = args[0];
CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(input);
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
final String input = args[0];
final CloudExpansion expansion = plugin.getExpansionCloud().getCloudExpansion(input);
if (expansion == null) {
Msg.msg(sender, "&cNo expansion found by the name: &f" + input);
return;
}
List<String> placeholders = expansion.getPlaceholders();
final List<String> placeholders = expansion.getPlaceholders();
if (placeholders == null) {
Msg.msg(sender, "&cThe expansion: &f" + expansion.getName()
+ " &cdoes not have any placeholders listed.",
@ -44,15 +45,15 @@ public final class EcloudPlaceholdersCommand extends Command {
return;
}
Player p = (Player) sender;
JSONMessage message = JSONMessage.create(Msg.color("&bPlaceholders: &f" + placeholders.size()));
final Player p = (Player) sender;
final JSONMessage message = JSONMessage.create(Msg.color("&bPlaceholders: &f" + placeholders.size()));
message.then("\n");
for (int i = 0; i < placeholders.size(); i++) {
message.then(i == placeholders.size() - 1 ? placeholders.get(i) : Msg.color(placeholders.get(i) + "&b, &f"));
try {
message.tooltip(PlaceholderAPI.setPlaceholders(p, placeholders.get(i)));
} catch (Exception ignored) {
} catch (final Exception ignored) {
// Ignored exception
}
}

View File

@ -5,16 +5,17 @@ import me.clip.placeholderapi.commands.Command;
import me.clip.placeholderapi.expansion.cloud.ExpansionCloudManager;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public final class EcloudRefreshCommand extends Command {
public EcloudRefreshCommand() {
super("ecloud refresh");
super("ecloud refresh", permissions("placeholderapi.ecloud"));
}
@Override
public void execute(CommandSender sender, String[] args) {
PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
ExpansionCloudManager cloud = plugin.getExpansionCloud();
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
final ExpansionCloudManager cloud = plugin.getExpansionCloud();
Msg.msg(sender, "&aRefresh task started. Use &f/papi ecloud list all &ain a few!!");
cloud.clean();
cloud.fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());

View File

@ -4,15 +4,16 @@ import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.Command;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public final class EcloudStatusCommand extends Command {
public EcloudStatusCommand() {
super("ecloud status");
super("ecloud status", permissions("placeholderapi.ecloud"));
}
@Override
public void execute(CommandSender sender, String[] args) {
PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final PlaceholderAPIPlugin plugin = PlaceholderAPIPlugin.getInstance();
Msg.msg(sender, "&bThere are &f" + plugin.getExpansionCloud().getCloudExpansions().size()
+ " &bexpansions available on the cloud.",
"&7A total of &f" + plugin.getExpansionCloud().getCloudAuthorCount()

View File

@ -7,22 +7,24 @@ import me.clip.placeholderapi.util.Msg;
import me.rayzr522.jsonmessage.JSONMessage;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
public final class EcloudVersionInfoCommand extends Command {
public EcloudVersionInfoCommand() {
super("ecloud versioninfo", options("&cIncorrect usage! &7/papi ecloud versioninfo <name> <version>", 2));
super("ecloud versioninfo", options("&cIncorrect usage! &7/papi ecloud versioninfo <name> <version>",
2, "placeholderapi.ecloud"));
}
@Override
public void execute(CommandSender sender, String[] args) {
String input = args[0];
CloudExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionCloud().getCloudExpansion(input);
public void execute(@NotNull final CommandSender sender, @NotNull final String[] args) {
final String input = args[0];
final CloudExpansion expansion = PlaceholderAPIPlugin.getInstance().getExpansionCloud().getCloudExpansion(input);
if (expansion == null) {
Msg.msg(sender, "&cNo expansion found by the name: &f" + input);
return;
}
CloudExpansion.Version version = expansion.getVersion(args[1]);
final CloudExpansion.Version version = expansion.getVersion(args[1]);
if (version == null) {
Msg.msg(sender, "&cThe version specified does not exist for expansion: &f" + expansion.getName());
return;
@ -37,10 +39,10 @@ public final class EcloudVersionInfoCommand extends Command {
return;
}
Player p = (Player) sender;
JSONMessage download = JSONMessage.create(Msg.color("&7Click to download this version"));
final Player p = (Player) sender;
final JSONMessage download = JSONMessage.create(Msg.color("&7Click to download this version"));
download.suggestCommand(
"/papi ecloud download " + expansion.getName() + ' ' + version.getVersion());
"/papi ecloud download " + expansion.getName() + " " + version.getVersion());
download.send(p);
}
}

View File

@ -0,0 +1,8 @@
package me.clip.placeholderapi.exceptions;
public final class NoDefaultCommandException extends RuntimeException {
public NoDefaultCommandException(final String message) {
super(message);
}
}

View File

@ -28,6 +28,7 @@ package me.clip.placeholderapi.expansion;
* @author Ryan McCarthy
*/
public interface Cacheable {
/**
* Called when the implementing class is unregistered from PlaceholderAPI
*/

View File

@ -30,10 +30,11 @@ import org.bukkit.entity.Player;
* @author Ryan McCarthy
*/
public interface Cleanable {
/**
* Called when a player leaves the server
*
* @param player (@link Player} who left the server
* @param p (@link Player} who left the server
*/
void cleanup(Player player);
void cleanup(Player p);
}

View File

@ -20,7 +20,6 @@
*/
package me.clip.placeholderapi.expansion;
import com.google.common.base.Strings;
import me.clip.placeholderapi.PlaceholderAPI;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.PlaceholderHook;
@ -42,13 +41,15 @@ public final class ExpansionManager {
public ExpansionManager(PlaceholderAPIPlugin instance) {
plugin = instance;
File f = new File(plugin.getDataFolder(), "expansions");
if (!f.exists()) f.mkdirs();
File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), "expansions");
if (!f.exists()) {
f.mkdirs();
}
}
public PlaceholderExpansion getRegisteredExpansion(String name) {
for (Entry<String, PlaceholderHook> hook : PlaceholderAPI.getPlaceholders().entrySet()) {
if (hook.getValue().isExpansion()) {
if (hook.getValue() instanceof PlaceholderExpansion) {
if (name.equalsIgnoreCase(hook.getKey())) {
return (PlaceholderExpansion) hook.getValue();
}
@ -59,28 +60,31 @@ public final class ExpansionManager {
}
public boolean registerExpansion(PlaceholderExpansion expansion) {
if (expansion == null || expansion.getIdentifier() == null) return false;
if (expansion == null || expansion.getIdentifier() == null) {
return false;
}
if (expansion instanceof Configurable) {
Map<String, Object> defaults = ((Configurable) expansion).getDefaults();
String pre = expansion.getPathStarter();
String pre = "expansions." + expansion.getIdentifier() + ".";
FileConfiguration cfg = plugin.getConfig();
boolean save = false;
if (defaults != null) {
for (Entry<String, Object> entry : defaults.entrySet()) {
String key = entry.getKey();
if (Strings.isNullOrEmpty(key)) continue;
for (Entry<String, Object> entries : defaults.entrySet()) {
if (entries.getKey() == null || entries.getKey().isEmpty()) {
continue;
}
if (entry.getValue() == null) {
if (cfg.contains(pre + key)) {
if (entries.getValue() == null) {
if (cfg.contains(pre + entries.getKey())) {
save = true;
cfg.set(pre + key, null);
cfg.set(pre + entries.getKey(), null);
}
} else {
if (!cfg.contains(pre + key)) {
if (!cfg.contains(pre + entries.getKey())) {
save = true;
cfg.set(pre + key, entry.getValue());
cfg.set(pre + entries.getKey(), entries.getValue());
}
}
}
@ -103,11 +107,17 @@ public final class ExpansionManager {
}
}
if (!expansion.canRegister()) return false;
if (!expansion.register()) return false;
if (!expansion.canRegister()) {
return false;
}
if (!expansion.register()) {
return false;
}
if (expansion instanceof Listener) {
Bukkit.getPluginManager().registerEvents((Listener) expansion, plugin);
Listener l = (Listener) expansion;
Bukkit.getPluginManager().registerEvents(l, plugin);
}
plugin.getLogger().info("Successfully registered expansion: " + expansion.getIdentifier());
@ -133,18 +143,29 @@ public final class ExpansionManager {
public PlaceholderExpansion registerExpansion(String fileName) {
List<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
PlaceholderExpansion ex = createInstance(subs.get(0));
if (registerExpansion(ex)) return ex;
if (registerExpansion(ex)) {
return ex;
}
return null;
}
public void registerAllExpansions() {
if (plugin == null) {
return;
}
List<Class<?>> subs = FileUtil.getClasses("expansions", null, PlaceholderExpansion.class);
if (subs == null || subs.isEmpty()) return;
if (subs == null || subs.isEmpty()) {
return;
}
for (Class<?> klass : subs) {
PlaceholderExpansion ex = createInstance(klass);
@ -159,29 +180,34 @@ public final class ExpansionManager {
}
}
private PlaceholderExpansion createInstance(Class<?> clazz) {
if (clazz == null) return null;
if (!PlaceholderExpansion.class.isAssignableFrom(clazz)) return null;
private PlaceholderExpansion createInstance(Class<?> klass) {
if (klass == null) {
return null;
}
PlaceholderExpansion ex = null;
if (!PlaceholderExpansion.class.isAssignableFrom(klass)) {
return null;
}
PlaceholderExpansion expansion = null;
try {
Constructor<?>[] constructors = clazz.getConstructors();
if (constructors.length == 0) {
expansion = (PlaceholderExpansion) clazz.newInstance();
Constructor<?>[] c = klass.getConstructors();
if (c.length == 0) {
ex = (PlaceholderExpansion) klass.newInstance();
} else {
for (Constructor<?> ctor : constructors) {
if (ctor.getParameterTypes().length == 0) {
expansion = (PlaceholderExpansion) ctor.newInstance();
for (Constructor<?> con : c) {
if (con.getParameterTypes().length == 0) {
ex = (PlaceholderExpansion) klass.newInstance();
break;
}
}
}
} catch (Throwable t) {
plugin.getLogger()
.severe("Failed to init placeholder expansion from class: " + clazz.getName());
.severe("Failed to init placeholder expansion from class: " + klass.getName());
plugin.getLogger().severe(t.getMessage());
}
return expansion;
return ex;
}
}

View File

@ -20,28 +20,26 @@
*/
package me.clip.placeholderapi.expansion;
import com.google.common.base.Enums;
import java.util.Optional;
public enum NMSVersion {
UNKNOWN("unknown"),
SPIGOT_1_7_R1("v1_7_R1"),
SPIGOT_1_7_R2("v1_7_R2"),
SPIGOT_1_7_R3("v1_7_R3"),
SPIGOT_1_7_R4("v1_7_R4"),
SPIGOT_1_8_R1("v1_8_R1"),
SPIGOT_1_8_R2("v1_8_R2"),
SPIGOT_1_8_R3("v1_8_R3"),
SPIGOT_1_9_R1("v1_9_R1"),
SPIGOT_1_9_R2("v1_9_R2"),
SPIGOT_1_10_R1("v1_10_R1"),
SPIGOT_1_11_R1("v1_11_R1"),
SPIGOT_1_12_R1("v1_12_R1"),
SPIGOT_1_13_R1("v1_13_R1"),
SPIGOT_1_13_R2("v1_13_R2"),
SPIGOT_1_14_R1("v1_14_R1"),
SPIGOT_1_15_R1("v1_15_R1");
UNKNOWN("unknown"),
SPIGOT_1_7_R1("v1_7_R1"),
SPIGOT_1_7_R2("v1_7_R2"),
SPIGOT_1_7_R3("v1_7_R3"),
SPIGOT_1_7_R4("v1_7_R4"),
SPIGOT_1_8_R1("v1_8_R1"),
SPIGOT_1_8_R2("v1_8_R2"),
SPIGOT_1_8_R3("v1_8_R3"),
SPIGOT_1_9_R1("v1_9_R1"),
SPIGOT_1_9_R2("v1_9_R2"),
SPIGOT_1_10_R1("v1_10_R1"),
SPIGOT_1_11_R1("v1_11_R1"),
SPIGOT_1_12_R1("v1_12_R1"),
SPIGOT_1_13_R1("v1_13_R1"),
SPIGOT_1_13_R2("v1_13_R2"),
SPIGOT_1_14_R1("v1_14_R1"),
SPIGOT_1_15_R1("v1_15_R1"),
SPIGOT_1_16_R1("v1_16_R1");
private final String version;
@ -50,12 +48,17 @@ public enum NMSVersion {
}
public static NMSVersion getVersion(String version) {
// Guava caches values() as well.
Optional<NMSVersion> opt = Enums.getIfPresent(NMSVersion.class, version).toJavaUtil();
return opt.orElse(NMSVersion.UNKNOWN);
for (NMSVersion v : values()) {
if (v.getVersion().equalsIgnoreCase(version)) {
return v;
}
}
return NMSVersion.UNKNOWN;
}
public String getVersion() {
return version;
}
}

View File

@ -26,11 +26,11 @@ import me.clip.placeholderapi.PlaceholderHook;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration;
import java.util.List;
public abstract class PlaceholderExpansion extends PlaceholderHook {
/**
* The name of this expansion
*
@ -123,58 +123,60 @@ public abstract class PlaceholderExpansion extends PlaceholderHook {
}
/**
* Quick getter for the {@link PlaceholderAPIPlugin} config.
* Quick getter for the {@link PlaceholderAPIPlugin} instance
*
* @return {@link PlaceholderAPIPlugin} config instance.
* @return {@link PlaceholderAPIPlugin} instance
*/
public FileConfiguration getConfig() {
return PlaceholderAPIPlugin.getInstance().getConfig();
public PlaceholderAPIPlugin getPlaceholderAPI() {
return PlaceholderAPIPlugin.getInstance();
}
public String getString(String path, String def) {
return getConfig().getString(getPathStarter() + path, def);
return getPlaceholderAPI().getConfig()
.getString("expansions." + getIdentifier() + "." + path, def);
}
public int getInt(String path, int def) {
return getConfig().getInt(getPathStarter() + path, def);
return getPlaceholderAPI().getConfig()
.getInt("expansions." + getIdentifier() + "." + path, def);
}
public long getLong(String path, long def) {
return getConfig().getLong(getPathStarter() + path, def);
return getPlaceholderAPI().getConfig()
.getLong("expansions." + getIdentifier() + "." + path, def);
}
public double getDouble(String path, double def) {
return getConfig().getDouble(getPathStarter() + path, def);
return getPlaceholderAPI().getConfig()
.getDouble("expansions." + getIdentifier() + "." + path, def);
}
public List<String> getStringList(String path) {
return getConfig().getStringList(getPathStarter() + path);
return getPlaceholderAPI().getConfig()
.getStringList("expansions." + getIdentifier() + "." + path);
}
public Object get(String path, Object def) {
return getConfig().get(getPathStarter() + path, def);
return getPlaceholderAPI().getConfig().get("expansions." + getIdentifier() + "." + path, def);
}
public ConfigurationSection getConfigSection(String path) {
return getConfig().getConfigurationSection(getPathStarter() + path);
return getPlaceholderAPI().getConfig()
.getConfigurationSection("expansions." + getIdentifier() + "." + path);
}
public ConfigurationSection getConfigSection() {
return getConfig().getConfigurationSection("expansions." + getIdentifier());
return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier());
}
public boolean configurationContains(String path) {
return getConfig().contains(getPathStarter() + path);
return getPlaceholderAPI().getConfig().contains("expansions." + getIdentifier() + "." + path);
}
protected String getPathStarter() {
return "expansions." + getIdentifier() + '.';
}
/**
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()}
*/
@SuppressWarnings("DeprecatedIsStillUsed")
@Deprecated
public String getPlugin() {
return null;

View File

@ -23,5 +23,6 @@ package me.clip.placeholderapi.expansion;
import org.bukkit.entity.Player;
public interface Relational {
String onPlaceholderRequest(Player one, Player two, String identifier);
}

View File

@ -20,7 +20,9 @@
*/
package me.clip.placeholderapi.expansion;
public interface Taskable {
/**
* Called when the implementing class has successfully been registered to the placeholder map
* Tasks that need to be performed when this expansion is registered should go here

View File

@ -21,6 +21,7 @@
package me.clip.placeholderapi.expansion;
public final class Version {
private final boolean isSpigot;
private final String version;
@ -40,4 +41,5 @@ public final class Version {
public boolean compareTo(String version) {
return getVersion().equalsIgnoreCase(version);
}
}

View File

@ -36,5 +36,5 @@ public interface VersionSpecific {
*
* @return true if your expansion is compatible with the version the server is running.
*/
boolean isCompatibleWith(Version version);
boolean isCompatibleWith(Version v);
}

View File

@ -26,8 +26,11 @@ import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
public class CloudExpansion {
private String name, author,
private String name,
author,
latest_version,
description,
source_url,
@ -71,12 +74,14 @@ public class CloudExpansion {
}
public Version getVersion() {
return latest_version == null ? null : getVersion(latest_version);
return getLatestVersion() == null ? null : getVersion(getLatestVersion());
}
public Version getVersion(String version) {
return versions == null ? null : versions.stream()
.filter(v -> v.getVersion().equals(version)).findFirst().orElse(null);
.filter(v -> v.getVersion().equals(version))
.findFirst()
.orElse(null);
}
public List<String> getAvailableVersions() {
@ -135,10 +140,6 @@ public class CloudExpansion {
return verified;
}
public void setVerified(boolean verified) {
this.verified = verified;
}
public long getLastUpdate() {
return last_update;
}
@ -155,10 +156,6 @@ public class CloudExpansion {
return average_rating;
}
public void setAverage_rating(double average_rating) {
this.average_rating = average_rating;
}
public List<String> getPlaceholders() {
return placeholders;
}
@ -175,11 +172,7 @@ public class CloudExpansion {
this.versions = versions;
}
public void setRatings_count(long ratings_count) {
this.ratings_count = ratings_count;
}
public static class Version {
public class Version {
private String url, version, release_notes;
public String getUrl() {

View File

@ -37,29 +37,37 @@ import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class ExpansionCloudManager {
private static final String API_URL = "http://api.extendedclip.com/v2/";
private static final Gson GSON = new Gson();
private final PlaceholderAPIPlugin plugin;
private final File expansionsDir;
private final Set<String> downloading = new HashSet<>();
private final List<String> downloading = new ArrayList<>();
private final Map<Integer, CloudExpansion> remote = new TreeMap<>();
public ExpansionCloudManager(PlaceholderAPIPlugin plugin) {
this.plugin = plugin;
expansionsDir = new File(plugin.getDataFolder(), "expansions");
if (expansionsDir.mkdirs()) {
final boolean result = expansionsDir.mkdirs();
if (result) {
plugin.getLogger().info("Created Expansions Directory");
}
}
public void clean() {
remote.clear();
downloading.clear();
}
public Map<Integer, CloudExpansion> getCloudExpansions() {
return remote;
}
@ -72,6 +80,7 @@ public class ExpansionCloudManager {
.orElse(null);
}
public int getCloudAuthorCount() {
return remote.values()
.stream()
@ -117,10 +126,14 @@ public class ExpansionCloudManager {
public int getPagesAvailable(Map<Integer, CloudExpansion> map, int amount) {
if (map == null) return 0;
if (map == null) {
return 0;
}
int pages = map.size() > 0 ? 1 : 0;
if (pages == 0) return 0;
if (pages == 0) {
return pages;
}
if (map.size() > amount) {
pages = map.size() / amount;
@ -146,11 +159,12 @@ public class ExpansionCloudManager {
return ex;
}
public void fetch(boolean allowUnverified) {
plugin.getLogger().info("Fetching available expansion information...");
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
Map<String, CloudExpansion> data = new HashMap<>();
final Map<String, CloudExpansion> data = new HashMap<>();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(API_URL).openStream()))) {
data.putAll(GSON.fromJson(reader, new TypeToken<Map<String, CloudExpansion>>() {
@ -159,12 +173,11 @@ public class ExpansionCloudManager {
if (plugin.getPlaceholderAPIConfig().isDebugMode()) {
ex.printStackTrace();
} else {
plugin.getLogger().warning("Unable to fetch expansions!\nThere was an error with the server host connecting to the PlaceholderAPI eCloud (https://api" +
".extendedclip.com/v2/)");
plugin.getLogger().warning("Unable to fetch expansions!\nThere was an error with the server host connecting to the PlaceholderAPI eCloud (https://api.extendedclip.com/v2/)");
}
}
List<CloudExpansion> unsorted = new ArrayList<>();
final List<CloudExpansion> unsorted = new ArrayList<>();
data.forEach((name, cexp) -> {
if ((allowUnverified || cexp.isVerified()) && cexp.getLatestVersion() != null && cexp.getVersion(cexp.getLatestVersion()) != null) {
@ -191,6 +204,7 @@ public class ExpansionCloudManager {
}
plugin.getLogger().info(count + " placeholder expansions are available on the cloud.");
long updates = getToUpdateCount();
if (updates > 0) {
@ -206,15 +220,19 @@ public class ExpansionCloudManager {
private void download(URL url, String name) throws IOException {
InputStream is = null;
FileOutputStream fos = null;
try {
URLConnection urlConn = url.openConnection();
is = urlConn.getInputStream();
fos = new FileOutputStream(
expansionsDir.getAbsolutePath() + File.separator + "Expansion-" + name + ".jar");
byte[] buffer = new byte[is.available()];
int l;
while ((l = is.read(buffer)) > 0) {
@ -234,35 +252,42 @@ public class ExpansionCloudManager {
}
public void downloadExpansion(String player, CloudExpansion ex) {
public void downloadExpansion(final String player, final CloudExpansion ex) {
downloadExpansion(player, ex, ex.getLatestVersion());
}
public void downloadExpansion(String player, CloudExpansion ex, String version) {
public void downloadExpansion(final String player, final CloudExpansion ex, final String version) {
if (downloading.contains(ex.getName())) {
return;
}
CloudExpansion.Version ver = ex.getVersions()
final CloudExpansion.Version ver = ex.getVersions()
.stream()
.filter(v -> v.getVersion().equals(version))
.findFirst()
.orElse(null);
if (ver == null) return;
if (ver == null) {
return;
}
downloading.add(ex.getName());
plugin.getLogger().info("Attempting download of expansion: " + ex.getName() + (player != null ? " by user: " + player : "") + " from url: " + ver.getUrl());
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
try {
download(new URL(ver.getUrl()), ex.getName());
plugin.getLogger().info("Download of expansion: " + ex.getName() + " complete!");
} catch (Exception e) {
plugin.getLogger()
.warning("Failed to download expansion: " + ex.getName() + " from: " + ver.getUrl());
Bukkit.getScheduler().runTask(plugin, () -> {
downloading.remove(ex.getName());
if (player != null) {
@ -289,6 +314,7 @@ public class ExpansionCloudManager {
}
}
});
});
}
}

View File

@ -25,7 +25,9 @@ import me.clip.placeholderapi.PlaceholderHook;
import org.apache.commons.lang.Validate;
import org.bukkit.plugin.Plugin;
@SuppressWarnings("DeprecatedIsStillUsed")
/**
* Use {@link me.clip.placeholderapi.expansion.PlaceholderExpansion} instead
*/
@Deprecated
public abstract class EZPlaceholderHook extends PlaceholderHook {
@ -33,8 +35,8 @@ public abstract class EZPlaceholderHook extends PlaceholderHook {
private final String plugin;
public EZPlaceholderHook(Plugin plugin, String identifier) {
Validate.notNull(plugin, "Plugin cannot be null");
Validate.notNull(identifier, "Placeholder name cannot be null");
Validate.notNull(plugin, "Plugin can not be null!");
Validate.notNull(identifier, "Placeholder name can not be null!");
this.identifier = identifier;
this.plugin = plugin.getName();
}

View File

@ -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;
}
}

View File

@ -37,8 +37,13 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.server.PluginDisableEvent;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class PlaceholderListener implements Listener {
private final PlaceholderAPIPlugin plugin;
public PlaceholderListener(PlaceholderAPIPlugin instance) {
@ -48,23 +53,22 @@ public class PlaceholderListener implements Listener {
@EventHandler
public void onExpansionUnregister(ExpansionUnregisterEvent event) {
PlaceholderExpansion expansion = event.getExpansion();
if (expansion instanceof Listener) {
HandlerList.unregisterAll((Listener) expansion);
if (event.getExpansion() instanceof Listener) {
HandlerList.unregisterAll((Listener) event.getExpansion());
}
if (expansion instanceof Taskable) {
((Taskable) expansion).stop();
if (event.getExpansion() instanceof Taskable) {
((Taskable) event.getExpansion()).stop();
}
if (expansion instanceof Cacheable) {
((Cacheable) expansion).clear();
if (event.getExpansion() instanceof Cacheable) {
((Cacheable) event.getExpansion()).clear();
}
if (plugin.getExpansionCloud() != null) {
CloudExpansion ex = plugin.getExpansionCloud()
.getCloudExpansion(expansion.getName());
.getCloudExpansion(event.getExpansion().getName());
if (ex != null) {
ex.setHasExpansion(false);
@ -74,20 +78,28 @@ public class PlaceholderListener implements Listener {
}
@EventHandler(priority = EventPriority.HIGH)
public void onPluginUnload(PluginDisableEvent event) {
// A plugin name cannot be null.
String name = event.getPlugin().getName();
if (name.equals(plugin.getName())) return;
public void onPluginUnload(PluginDisableEvent e) {
String n = e.getPlugin().getName();
for (PlaceholderHook hook : PlaceholderAPI.getPlaceholders().values()) {
if (hook.isExpansion()) {
PlaceholderExpansion ex = (PlaceholderExpansion) hook;
if (n.equals(plugin.getName())) {
return;
}
if (ex.getRequiredPlugin() == null) continue;
Map<String, PlaceholderHook> hooks = PlaceholderAPI.getPlaceholders();
if (ex.getRequiredPlugin().equalsIgnoreCase(name)) {
if (PlaceholderAPI.unregisterExpansion(ex)) {
plugin.getLogger().info("Unregistered placeholder expansion: " + ex.getIdentifier());
for (Entry<String, PlaceholderHook> entry : hooks.entrySet()) {
PlaceholderHook hook = entry.getValue();
if (hook instanceof PlaceholderExpansion) {
PlaceholderExpansion expansion = (PlaceholderExpansion) hook;
if (expansion.getRequiredPlugin() == null) {
continue;
}
if (expansion.getRequiredPlugin().equalsIgnoreCase(n)) {
if (PlaceholderAPI.unregisterExpansion(expansion)) {
plugin.getLogger().info("Unregistered placeholder expansion: " + expansion.getIdentifier());
}
}
}
@ -95,10 +107,16 @@ public class PlaceholderListener implements Listener {
}
@EventHandler
public void onQuit(PlayerQuitEvent event) {
for (PlaceholderHook hook : PlaceholderAPI.getPlaceholders().values()) {
if (hook instanceof Cleanable) {
((Cleanable) hook).cleanup(event.getPlayer());
public void onQuit(PlayerQuitEvent e) {
Set<PlaceholderExpansion> expansions = PlaceholderAPI.getExpansions();
if (expansions.isEmpty()) {
return;
}
for (PlaceholderExpansion ex : expansions) {
if (ex instanceof Cleanable) {
((Cleanable) ex).cleanup(e.getPlayer());
}
}
}

View File

@ -31,6 +31,7 @@ import org.bukkit.event.server.ServerLoadEvent;
import java.util.Map;
public class ServerLoadEventListener implements Listener {
private final PlaceholderAPIPlugin plugin;
public ServerLoadEventListener(PlaceholderAPIPlugin instance) {
@ -39,19 +40,19 @@ public class ServerLoadEventListener implements Listener {
}
/**
* This method will be called when the server is first loaded.
* This method will be called when the server is first loaded
* <p>
* 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>
* This will ensure no issues with expanions and hooks.
*
* @param event the server load event.
* @param e the server load event
*/
@EventHandler
public void onServerLoad(ServerLoadEvent event) {
public void onServerLoad(ServerLoadEvent e) {
plugin.getLogger().info("Placeholder expansion registration initializing...");
Map<String, PlaceholderHook> alreadyRegistered = PlaceholderAPI.getPlaceholders();
final Map<String, PlaceholderHook> alreadyRegistered = PlaceholderAPI.getPlaceholders();
plugin.getExpansionManager().registerAllExpansions();
if (alreadyRegistered != null && !alreadyRegistered.isEmpty()) {

View File

@ -18,13 +18,13 @@
*
*
*/
package me.clip.placeholderapi.util;
package me.clip.placeholderapi.updatechecker;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import org.apache.commons.lang.StringUtils;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
@ -32,11 +32,10 @@ import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public class UpdateChecker implements Listener {
private static final int RESOURCE_ID = 6245;
private static final String SPIGOT_API = "https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID;
private final int RESOURCE_ID = 6245;
private final PlaceholderAPIPlugin plugin;
private final String pluginVersion;
private String spigotVersion;
@ -58,35 +57,39 @@ public class UpdateChecker implements Listener {
public void fetch() {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
try {
HttpsURLConnection con = (HttpsURLConnection) new URL(SPIGOT_API).openConnection();
// Prevents the server from freezing with bad internet connection.
HttpsURLConnection con = (HttpsURLConnection) new URL(
"https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection();
con.setRequestMethod("GET");
con.setConnectTimeout(2000);
con.setReadTimeout(2000);
spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8)).readLine();
spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine();
} catch (Exception ex) {
plugin.getLogger().warning("Failed to check for updates on spigot.");
plugin.getLogger().info("Failed to check for updates on spigot.");
return;
}
if (spigotVersion == null || spigotVersion.isEmpty()) {
return;
}
if (spigotVersion == null || spigotVersion.isEmpty()) return;
updateAvailable = spigotIsNewer();
if (!updateAvailable) return;
if (!updateAvailable) {
return;
}
Bukkit.getScheduler().runTask(plugin, () -> {
plugin.getLogger()
.info("An update for PlaceholderAPI (v" + spigotVersion + ") is available at:");
.info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:");
plugin.getLogger()
.info("https://www.spigotmc.org/resources/" + RESOURCE_ID + '/');
.info("https://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + "/");
Bukkit.getPluginManager().registerEvents(this, plugin);
});
});
}
private boolean spigotIsNewer() {
if (spigotVersion == null || spigotVersion.isEmpty()) return false;
if (spigotVersion == null || spigotVersion.isEmpty()) {
return false;
}
String plV = toReadable(pluginVersion);
String spV = toReadable(spigotVersion);
@ -94,17 +97,21 @@ public class UpdateChecker implements Listener {
}
private String toReadable(String version) {
if (version.contains("-DEV-")) version = StringUtils.split(version, "-DEV-")[0];
return StringUtils.remove(version, '.');
if (version.contains("-DEV-")) {
version = version.split("-DEV-")[0];
}
return version.replaceAll("\\.", "");
}
@EventHandler
public void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
if (player.hasPermission("placeholderapi.updatenotify")) {
Msg.msg(player,
"&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getSpigotVersion() + "&e)",
"&bis available at &ehttps://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + '/');
@EventHandler(priority = EventPriority.MONITOR)
public void onJoin(PlayerJoinEvent e) {
if (e.getPlayer().hasPermission("placeholderapi.updatenotify")) {
Msg.msg(e.getPlayer(),
"&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getSpigotVersion()
+ "&e)"
, "&bis available at &ehttps://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID
+ "/");
}
}
}

View 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";
}

View File

@ -42,50 +42,65 @@ public class FileUtil {
try {
File f = new File(PlaceholderAPIPlugin.getInstance().getDataFolder(), folder);
if (!f.exists()) return list;
if (!f.exists()) {
return list;
}
FilenameFilter fileNameFilter = (dir, name) -> {
boolean isJar = name.endsWith(".jar");
if (fileName != null) {
return isJar && name.substring(0, name.length() - 4)
.equalsIgnoreCase(fileName.substring(0, fileName.length() - 4));
return name.endsWith(".jar") && name.replace(".jar", "")
.equalsIgnoreCase(fileName.replace(".jar", ""));
}
return isJar;
return name.endsWith(".jar");
};
File[] jars = f.listFiles(fileNameFilter);
if (jars == null) return list;
if (jars == null) {
return list;
}
for (File file : jars) {
list = gather(file.toURI().toURL(), list, type);
}
return list;
} catch (Throwable ignored) {
} catch (Throwable t) {
}
return null;
}
private static List<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());
JarInputStream jis = new JarInputStream(jar.openStream())) {
JarEntry entry;
while ((entry = jis.getNextJarEntry()) != null) {
String name = entry.getName();
if (name == null || name.isEmpty()) continue;
while (true) {
JarEntry j = jis.getNextJarEntry();
if (j == null) {
break;
}
String name = j.getName();
if (name == null || name.isEmpty()) {
continue;
}
if (name.endsWith(".class")) {
name = name.substring(0, name.length() - 6).replace('/', '.');
name = name.replace("/", ".");
String cname = name.substring(0, name.lastIndexOf(".class"));
Class<?> loaded = cl.loadClass(name);
if (clazz.isAssignableFrom(loaded)) list.add(loaded);
Class<?> c = cl.loadClass(cname);
if (clazz.isAssignableFrom(c)) {
list.add(c);
}
}
}
} catch (Throwable ignored) {
} catch (Throwable t) {
}
return list;

View File

@ -24,20 +24,17 @@ import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
public class Msg {
public static void msg(CommandSender sender, String... messages) {
for (String message : messages) {
String msg = color(message);
sender.sendMessage(msg);
}
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;
public final class Msg {
public static void msg(CommandSender s, String... msg) {
s.sendMessage(Arrays.stream(msg).filter(Objects::nonNull).map(Msg::color).collect(Collectors.joining("\n")));
}
public static void broadcast(String... messages) {
CommandSender sender = Bukkit.getConsoleSender();
for (String message : messages) {
String msg = color(message);
sender.sendMessage(msg);
}
public static void broadcast(String... msg) {
Arrays.stream(msg).filter(Objects::nonNull).map(Msg::color).forEach(Bukkit::broadcastMessage);
}
public static String color(String text) {

View 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
}

View File

@ -22,10 +22,10 @@ package me.clip.placeholderapi.util;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.TimeUnit;
public class TimeUtil {
public static String getRemaining(int seconds, TimeUnit type) {
public static String getRemaining(int seconds, TimeFormat type) {
if (seconds < 60) {
switch (type) {
case DAYS:
@ -124,8 +124,8 @@ public class TimeUtil {
* @param duration {@link Duration} (eg, Duration.of(20, {@link ChronoUnit#SECONDS}) for 20 seconds)
* @return formatted time
*/
public static String getTime(Duration duration) {
StringBuilder builder = new StringBuilder();
public static String getTime(final Duration duration) {
final StringBuilder builder = new StringBuilder();
long seconds = duration.getSeconds();
long minutes = seconds / 60;

View File

@ -4,51 +4,39 @@ version: ${project.version}
api-version: '1.13'
authors: [extended_clip, Glare]
description: ${project.description}
commands:
placeholderapi:
description: PlaceholderAPI command
aliases: [papi]
permissions:
placeholderapi.*:
description: ability to use all commands
children:
placeholderapi.admin: true
placeholderapi.admin:
description: ability to use all commands
children:
placeholderapi.list: true
placeholderapi.reload: true
placeholderapi.ecloud: true
placeholderapi.parse: true
placeholderapi.register: true
placeholderapi.updatenotify: true
placeholderapi.list:
description: ability to use the list command
default: op
placeholderapi.reload:
description: ability to use the reload command
default: op
placeholderapi.parse:
description: ability to use parse command
default: op
placeholderapi.register:
description: ability to register or unregister placeholder expansions
default: op
placeholderapi.ecloud:
description: allows the usage of ecloud commands
default: op
children:
placeholderapi.ecloud.enable: true
placeholderapi.ecloud.disable: true
placeholderapi.ecloud.list: true
placeholderapi.ecloud.info: true
placeholderapi.ecloud.clear: true
placeholderapi.ecloud.status: true
placeholderapi.ecloud.refresh: true
placeholderapi.ecloud.download: true
placeholderapi.ecloud.versioninfo: true
placeholderapi.updatenotify:
description: notifies you when there is a PAPI update
default: op
placeholderapi.*:
description: ability to use all commands
children:
placeholderapi.admin: true
placeholderapi.admin:
description: ability to use all commands
children:
placeholderapi.list: true
placeholderapi.reload: true
placeholderapi.ecloud: true
placeholderapi.parse: true
placeholderapi.register: true
placeholderapi.updatenotify: true
placeholderapi.list:
description: ability to use the list command
default: op
placeholderapi.reload:
description: ability to use the reload command
default: op
placeholderapi.parse:
description: ability to use parse command
default: op
placeholderapi.register:
description: ability to register or unregister placeholder expansions
default: op
placeholderapi.ecloud:
description: allows the usage of ecloud commands
default: op
placeholderapi.updatenotify:
description: notifies you when there is a PAPI update
default: op
commands:
placeholderapi:
description: PlaceholderAPI command
aliases: [papi]