mirror of
https://github.com/PlaceholderAPI/PlaceholderAPI
synced 2025-10-07 11:45:26 +02:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -20,180 +20,278 @@
|
||||
|
||||
package me.clip.placeholderapi.expansion;
|
||||
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import me.clip.placeholderapi.PlaceholderAPIPlugin;
|
||||
import me.clip.placeholderapi.PlaceholderHook;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class PlaceholderExpansion extends PlaceholderHook {
|
||||
public abstract class PlaceholderExpansion extends PlaceholderHook
|
||||
{
|
||||
|
||||
/**
|
||||
* The name of this expansion
|
||||
*
|
||||
* @return {@link #getIdentifier()} by default, name of this expansion if specified
|
||||
*/
|
||||
public String getName() {
|
||||
return getIdentifier();
|
||||
}
|
||||
/**
|
||||
* The placeholder identifier of this expansion
|
||||
*
|
||||
* @return placeholder identifier that is associated with this expansion
|
||||
*/
|
||||
@NotNull
|
||||
public abstract String getIdentifier();
|
||||
|
||||
/**
|
||||
* The placeholder identifier of this expansion
|
||||
*
|
||||
* @return placeholder identifier that is associated with this expansion
|
||||
*/
|
||||
public abstract String getIdentifier();
|
||||
/**
|
||||
* The author of this expansion
|
||||
*
|
||||
* @return name of the author for this expansion
|
||||
*/
|
||||
@NotNull
|
||||
public abstract String getAuthor();
|
||||
|
||||
/**
|
||||
* The author of this expansion
|
||||
*
|
||||
* @return name of the author for this expansion
|
||||
*/
|
||||
public abstract String getAuthor();
|
||||
/**
|
||||
* The version of this expansion
|
||||
*
|
||||
* @return current version of this expansion
|
||||
*/
|
||||
@NotNull
|
||||
public abstract String getVersion();
|
||||
|
||||
/**
|
||||
* The version of this expansion
|
||||
*
|
||||
* @return current version of this expansion
|
||||
*/
|
||||
public abstract String getVersion();
|
||||
|
||||
/**
|
||||
* The name of the plugin that this expansion hooks into. by default will return the deprecated
|
||||
* {@link #getPlugin()} method
|
||||
*
|
||||
* @return plugin name that this expansion requires to function
|
||||
*/
|
||||
public String getRequiredPlugin() {
|
||||
return getPlugin();
|
||||
}
|
||||
|
||||
/**
|
||||
* The placeholders associated with this expansion
|
||||
*
|
||||
* @return placeholder list that this expansion provides
|
||||
*/
|
||||
public List<String> getPlaceholders() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expansions that do not use the ecloud and instead register from the dependency should set this
|
||||
* to true to ensure that your placeholder expansion is not unregistered when the papi reload
|
||||
* command is used
|
||||
*
|
||||
* @return if this expansion should persist through placeholder reloads
|
||||
*/
|
||||
public boolean persist() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this placeholder identifier has already been registered
|
||||
*
|
||||
* @return true if the identifier for this expansion is already registered
|
||||
*/
|
||||
public boolean isRegistered() {
|
||||
Validate.notNull(getIdentifier(), "Placeholder identifier can not be null!");
|
||||
return PlaceholderAPI.isRegistered(getIdentifier());
|
||||
}
|
||||
|
||||
/**
|
||||
* If any requirements need to be checked before this expansion should register, you can check
|
||||
* them here
|
||||
*
|
||||
* @return true if this hook meets all the requirements to register
|
||||
*/
|
||||
public boolean canRegister() {
|
||||
return getRequiredPlugin() == null || Bukkit.getPluginManager().getPlugin(getRequiredPlugin()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to register this PlaceholderExpansion
|
||||
*
|
||||
* @return true if this expansion is now registered with PlaceholderAPI
|
||||
*/
|
||||
public boolean register() {
|
||||
Validate.notNull(getIdentifier(), "Placeholder identifier can not be null!");
|
||||
return canRegister() && getPlaceholderAPI().getLocalExpansionManager().register(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick getter for the {@link PlaceholderAPIPlugin} instance
|
||||
*
|
||||
* @return {@link PlaceholderAPIPlugin} instance
|
||||
*/
|
||||
public PlaceholderAPIPlugin getPlaceholderAPI() {
|
||||
return PlaceholderAPIPlugin.getInstance();
|
||||
}
|
||||
|
||||
public String getString(String path, String def) {
|
||||
return getPlaceholderAPI().getConfig()
|
||||
.getString("expansions." + getIdentifier() + "." + path, def);
|
||||
}
|
||||
|
||||
public int getInt(String path, int def) {
|
||||
return getPlaceholderAPI().getConfig()
|
||||
.getInt("expansions." + getIdentifier() + "." + path, def);
|
||||
}
|
||||
|
||||
public long getLong(String path, long def) {
|
||||
return getPlaceholderAPI().getConfig()
|
||||
.getLong("expansions." + getIdentifier() + "." + path, def);
|
||||
}
|
||||
|
||||
public double getDouble(String path, double def) {
|
||||
return getPlaceholderAPI().getConfig()
|
||||
.getDouble("expansions." + getIdentifier() + "." + path, def);
|
||||
}
|
||||
|
||||
public List<String> getStringList(String path) {
|
||||
return getPlaceholderAPI().getConfig()
|
||||
.getStringList("expansions." + getIdentifier() + "." + path);
|
||||
}
|
||||
|
||||
public Object get(String path, Object def) {
|
||||
return getPlaceholderAPI().getConfig().get("expansions." + getIdentifier() + "." + path, def);
|
||||
}
|
||||
|
||||
public ConfigurationSection getConfigSection(String path) {
|
||||
return getPlaceholderAPI().getConfig()
|
||||
.getConfigurationSection("expansions." + getIdentifier() + "." + path);
|
||||
}
|
||||
|
||||
public ConfigurationSection getConfigSection() {
|
||||
return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier());
|
||||
}
|
||||
|
||||
public boolean configurationContains(String path) {
|
||||
return getPlaceholderAPI().getConfig().contains("expansions." + getIdentifier() + "." + path);
|
||||
}
|
||||
@Nullable
|
||||
@Override /* override for now >:) */
|
||||
public String onRequest(@Nullable final OfflinePlayer player, @NotNull final String params)
|
||||
{
|
||||
return super.onRequest(player, params);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()}
|
||||
*/
|
||||
@Deprecated
|
||||
public String getPlugin() {
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* The name of this expansion
|
||||
*
|
||||
* @return {@link #getIdentifier()} by default, name of this expansion if specified
|
||||
*/
|
||||
@NotNull
|
||||
public String getName()
|
||||
{
|
||||
return getIdentifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to show a description
|
||||
*/
|
||||
@Deprecated
|
||||
public String getDescription() {
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* The name of the plugin that this expansion hooks into. by default will null
|
||||
*
|
||||
* @return plugin name that this expansion requires to function
|
||||
*/
|
||||
@Nullable
|
||||
public String getRequiredPlugin()
|
||||
{
|
||||
return getPlugin();
|
||||
}
|
||||
|
||||
/**
|
||||
* The placeholders associated with this expansion
|
||||
*
|
||||
* @return placeholder list that this expansion provides
|
||||
*/
|
||||
@NotNull
|
||||
public List<String> getPlaceholders()
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Expansions that do not use the ecloud and instead register from the dependency should set this
|
||||
* to true to ensure that your placeholder expansion is not unregistered when the papi reload
|
||||
* command is used
|
||||
*
|
||||
* @return if this expansion should persist through placeholder reloads
|
||||
*/
|
||||
public boolean persist()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if this placeholder identifier has already been registered
|
||||
*
|
||||
* @return true if the identifier for this expansion is already registered
|
||||
*/
|
||||
public final boolean isRegistered()
|
||||
{
|
||||
return getPlaceholderAPI().getLocalExpansionManager().findExpansionByIdentifier(getIdentifier()).map(it -> it.equals(this)).orElse(false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If any requirements need to be checked before this expansion should register, you can check
|
||||
* them here
|
||||
*
|
||||
* @return true if this hook meets all the requirements to register
|
||||
*/
|
||||
public boolean canRegister()
|
||||
{
|
||||
return getRequiredPlugin() == null || Bukkit.getPluginManager().getPlugin(getRequiredPlugin()) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to register this PlaceholderExpansion
|
||||
*
|
||||
* @return true if this expansion is now registered with PlaceholderAPI
|
||||
* @deprecated This is going to be final in the future, startup and shutdown logic will have their own methods soon.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean register()
|
||||
{
|
||||
return canRegister() && getPlaceholderAPI().getLocalExpansionManager().register(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to unregister this PlaceholderExpansion
|
||||
*
|
||||
* @return true if this expansion is now unregistered with PlaceholderAPI
|
||||
*/
|
||||
public final boolean unregister()
|
||||
{
|
||||
return getPlaceholderAPI().getLocalExpansionManager().unregister(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Quick getter for the {@link PlaceholderAPIPlugin} instance
|
||||
*
|
||||
* @return {@link PlaceholderAPIPlugin} instance
|
||||
*/
|
||||
@NotNull
|
||||
public final PlaceholderAPIPlugin getPlaceholderAPI()
|
||||
{
|
||||
return PlaceholderAPIPlugin.getInstance();
|
||||
}
|
||||
|
||||
|
||||
// === Configuration ===
|
||||
|
||||
@Nullable
|
||||
public final ConfigurationSection getConfigSection()
|
||||
{
|
||||
return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public final ConfigurationSection getConfigSection(@NotNull final String path)
|
||||
{
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? null : section.getConfigurationSection(path);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Contract("_, !null -> !null")
|
||||
public final Object get(@NotNull final String path, final Object def)
|
||||
{
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.get(path, def);
|
||||
}
|
||||
|
||||
public final int getInt(@NotNull final String path, final int def)
|
||||
{
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getInt(path, def);
|
||||
}
|
||||
|
||||
public final long getLong(@NotNull final String path, final long def)
|
||||
{
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getLong(path, def);
|
||||
}
|
||||
|
||||
public final double getDouble(@NotNull final String path, final double def)
|
||||
{
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getDouble(path, def);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Contract("_, !null -> !null")
|
||||
public final String getString(@NotNull final String path, @Nullable final String def)
|
||||
{
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? def : section.getString(path, def);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final List<String> getStringList(@NotNull final String path)
|
||||
{
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section == null ? Collections.emptyList() : section.getStringList(path);
|
||||
}
|
||||
|
||||
public final boolean configurationContains(@NotNull final String path)
|
||||
{
|
||||
final ConfigurationSection section = getConfigSection();
|
||||
return section != null && section.contains(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean equals(final Object o)
|
||||
{
|
||||
if (this == o)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof PlaceholderExpansion))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final PlaceholderExpansion expansion = (PlaceholderExpansion) o;
|
||||
|
||||
return getIdentifier().equals(expansion.getIdentifier()) &&
|
||||
getAuthor().equals(expansion.getAuthor()) &&
|
||||
getVersion().equals(expansion.getVersion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int hashCode()
|
||||
{
|
||||
return Objects.hash(getIdentifier(), getAuthor(), getVersion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString()
|
||||
{
|
||||
return String.format("PlaceholderExpansion[name: '%s', author: '%s', version: '%s']", getName(), getAuthor(), getVersion());
|
||||
}
|
||||
|
||||
// === Deprecated API ===
|
||||
|
||||
/**
|
||||
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()}
|
||||
*/
|
||||
@Deprecated
|
||||
public String getPlugin()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to show a description
|
||||
*/
|
||||
@Deprecated
|
||||
public String getDescription()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to display a link
|
||||
*/
|
||||
@Deprecated
|
||||
public String getLink()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to display a link
|
||||
*/
|
||||
@Deprecated
|
||||
public String getLink() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@ import me.clip.placeholderapi.events.ExpansionUnregisterEvent;
|
||||
import me.clip.placeholderapi.expansion.*;
|
||||
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
|
||||
import me.clip.placeholderapi.util.FileUtil;
|
||||
import me.clip.placeholderapi.util.Futures;
|
||||
import me.clip.placeholderapi.util.Msg;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -43,8 +44,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.logging.Level;
|
||||
@@ -134,6 +139,27 @@ public final class LocalExpansionManager implements Listener
|
||||
}
|
||||
|
||||
|
||||
public Optional<PlaceholderExpansion> register(@NotNull final Class<? extends PlaceholderExpansion> clazz)
|
||||
{
|
||||
try
|
||||
{
|
||||
final PlaceholderExpansion expansion = createExpansionInstance(clazz);
|
||||
if (expansion == null || !expansion.register())
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(expansion);
|
||||
}
|
||||
catch (final LinkageError ex)
|
||||
{
|
||||
plugin.getLogger().severe("expansion class " + clazz.getSimpleName() + " is outdated: \n" +
|
||||
"Failed to load due to a [" + ex.getClass().getSimpleName() + "], attempted to use " + ex.getMessage());
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not call this method yourself, use {@link PlaceholderExpansion#register()}
|
||||
*/
|
||||
@@ -198,7 +224,7 @@ public final class LocalExpansionManager implements Listener
|
||||
}
|
||||
|
||||
final PlaceholderExpansion removed = expansions.get(expansion.getIdentifier());
|
||||
if (removed != null && !unregister(removed))
|
||||
if (removed != null && !removed.unregister())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -238,27 +264,9 @@ public final class LocalExpansionManager implements Listener
|
||||
return true;
|
||||
}
|
||||
|
||||
public Optional<PlaceholderExpansion> register(@NotNull final Class<? extends PlaceholderExpansion> clazz)
|
||||
{
|
||||
try
|
||||
{
|
||||
final PlaceholderExpansion expansion = createExpansionInstance(clazz);
|
||||
if (expansion == null || !expansion.register())
|
||||
{
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(expansion);
|
||||
}
|
||||
catch (final LinkageError ex)
|
||||
{
|
||||
plugin.getLogger().severe("expansion class " + clazz.getSimpleName() + " is outdated: \n" +
|
||||
"Failed to load due to a [" + ex.getClass().getSimpleName() + "], attempted to use " + ex.getMessage());
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not call this method yourself, use {@link PlaceholderExpansion#unregister()}
|
||||
*/
|
||||
public boolean unregister(@NotNull final PlaceholderExpansion expansion)
|
||||
{
|
||||
if (expansions.remove(expansion.getIdentifier()) == null)
|
||||
@@ -301,18 +309,17 @@ public final class LocalExpansionManager implements Listener
|
||||
{
|
||||
plugin.getLogger().info("Placeholder expansion registration initializing...");
|
||||
|
||||
findExpansionsOnDisk().whenCompleteAsync((classes, exception) -> {
|
||||
Futures.onMainThread(plugin, findExpansionsOnDisk(), (classes, exception) -> {
|
||||
if (exception != null)
|
||||
{
|
||||
plugin.getLogger().log(Level.SEVERE, "failed to load class files of expansions", exception);
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||
final long registered = classes.stream().map(this::register).filter(Optional::isPresent).count();
|
||||
Msg.msg(sender,
|
||||
registered == 0 ? "&6No expansions were registered!" : registered + "&a placeholder hooks successfully registered!");
|
||||
});
|
||||
final long registered = classes.stream().map(this::register).filter(Optional::isPresent).count();
|
||||
|
||||
Msg.msg(sender,
|
||||
registered == 0 ? "&6No expansions were registered!" : registered + "&a placeholder hooks successfully registered!");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -325,39 +332,32 @@ public final class LocalExpansionManager implements Listener
|
||||
continue;
|
||||
}
|
||||
|
||||
unregister(expansion);
|
||||
expansion.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
public CompletableFuture<List<Class<? extends PlaceholderExpansion>>> findExpansionsOnDisk()
|
||||
public CompletableFuture<@NotNull List<@NotNull Class<? extends PlaceholderExpansion>>> findExpansionsOnDisk()
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try
|
||||
{
|
||||
return FileUtil.getClasses(getExpansionsFolder(), PlaceholderExpansion.class);
|
||||
}
|
||||
catch (final IOException | ClassNotFoundException ex)
|
||||
{
|
||||
throw new CompletionException(ex);
|
||||
}
|
||||
});
|
||||
return Arrays.stream(folder.listFiles((dir, name) -> name.endsWith(".jar")))
|
||||
.map(this::findExpansionInFile)
|
||||
.collect(Futures.collector());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CompletableFuture<List<Class<? extends PlaceholderExpansion>>> findExpansionsInFile(@NotNull final File file)
|
||||
public CompletableFuture<@Nullable Class<? extends PlaceholderExpansion>> findExpansionInFile(@NotNull final File file)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try
|
||||
{
|
||||
final List<@NotNull Class<? extends PlaceholderExpansion>> classes = FileUtil.getClasses(getExpansionsFolder(), PlaceholderExpansion.class, file.getName());
|
||||
if (classes.size() > 1)
|
||||
{
|
||||
throw new IllegalStateException("multiple expansion classes in one file!");
|
||||
}
|
||||
|
||||
return classes;
|
||||
return FileUtil.findClass(file, PlaceholderExpansion.class);
|
||||
}
|
||||
catch (final VerifyError ex)
|
||||
{
|
||||
plugin.getLogger().severe("expansion file " + file.getName() + " is outdated: \n" +
|
||||
"Failed to load due to a [" + ex.getClass().getSimpleName() + "], attempted to use" + ex.getMessage().substring(ex.getMessage().lastIndexOf(' ')));
|
||||
return null;
|
||||
}
|
||||
catch (final Exception ex)
|
||||
{
|
||||
@@ -376,6 +376,11 @@ public final class LocalExpansionManager implements Listener
|
||||
}
|
||||
catch (final Exception ex)
|
||||
{
|
||||
if (ex.getCause() instanceof LinkageError)
|
||||
{
|
||||
throw ((LinkageError) ex.getCause());
|
||||
}
|
||||
|
||||
plugin.getLogger().log(Level.SEVERE, "Failed to load placeholder expansion from class: " + clazz.getName(), ex);
|
||||
return null;
|
||||
}
|
||||
@@ -412,7 +417,7 @@ public final class LocalExpansionManager implements Listener
|
||||
continue;
|
||||
}
|
||||
|
||||
unregister(expansion);
|
||||
expansion.unregister();
|
||||
plugin.getLogger().info("Unregistered placeholder expansion: " + expansion.getName());
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user