Removed Handler, HandlerComponent, and all internal-only API components except Eco; huge backend rework

This commit is contained in:
Auxilor
2022-10-02 01:52:35 +01:00
parent 2a9cbdacfd
commit 29b63a2ebb
73 changed files with 983 additions and 1370 deletions

View File

@@ -1,82 +1,584 @@
package com.willfp.eco.core;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import com.willfp.eco.core.config.updating.ConfigHandler;
import com.willfp.eco.core.data.ExtendedPersistentDataContainer;
import com.willfp.eco.core.data.PlayerProfile;
import com.willfp.eco.core.data.ServerProfile;
import com.willfp.eco.core.data.keys.PersistentDataKey;
import com.willfp.eco.core.drops.DropQueue;
import com.willfp.eco.core.entities.ai.EntityController;
import com.willfp.eco.core.events.EventManager;
import com.willfp.eco.core.extensions.ExtensionLoader;
import com.willfp.eco.core.factory.MetadataValueFactory;
import com.willfp.eco.core.factory.NamespacedKeyFactory;
import com.willfp.eco.core.factory.RunnableFactory;
import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.menu.MenuBuilder;
import com.willfp.eco.core.gui.menu.MenuType;
import com.willfp.eco.core.gui.slot.SlotBuilder;
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
import com.willfp.eco.core.items.TestableItem;
import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.proxy.Cleaner;
import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.scheduling.Scheduler;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Mob;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Logger;
/**
* Holds the instance of the eco handler for bridging between the frontend
* Holds the instance of eco for bridging between the frontend
* and backend.
* <p>
* <strong>Do not use this in your plugins!</strong> It can and will contain
* breaking changes between minor versions and even patches, and you will create
* compatibility issues by. All parts of this have been abstracted
* into logically named API components that you can use.
*
* @see Eco#getHandler()
* @see Handler
* @see Eco#get()
*/
@ApiStatus.Internal
public final class Eco {
public interface Eco {
/**
* Instance of eco handler.
*/
@ApiStatus.Internal
private static Handler handler;
/**
* Set the handler.
* Create a scheduler.
*
* @param handler The handler.
* @param plugin The plugin.
* @return The scheduler.
*/
@ApiStatus.Internal
public static void setHandler(@NotNull final Handler handler) {
Validate.isTrue(Eco.handler == null, "Already initialized!");
Eco.handler = handler;
}
@NotNull
Scheduler createScheduler(@NotNull EcoPlugin plugin);
/**
* Get the instance of the eco handler; the bridge between the api frontend
* and the implementation backend.
* <p>
* <strong>Do not use the handler in your plugins!</strong> It can and will contain
* breaking changes between minor versions and even patches, and you will create
* compatibility issues by using the handler. All parts of the handler have been abstracted
* into logically named API components that you can use.
* <p>
* Prior to version 6.12.0, the handler was considered as an API component, but it has
* since been moved into an internal component, and in 6.17.0, the first breaking change
* was introduced to {@link com.willfp.eco.core.config.wrapper.ConfigFactory}. This means
* that any usages of the handler can now cause problems in your plugins.
* Create an event manager.
*
* @param plugin The plugin.
* @return The event manager.
*/
@NotNull
EventManager createEventManager(@NotNull EcoPlugin plugin);
/**
* Create a NamespacedKey factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin);
/**
* Create a MetadataValue factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin);
/**
* Create a Runnable factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin);
/**
* Create an ExtensionLoader.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin);
/**
* Create a config handler.
*
* @param plugin The plugin.
* @return The handler.
*/
@NotNull
ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin);
/**
* Create a logger.
*
* @param plugin The plugin.
* @return The logger.
*/
@NotNull
Logger createLogger(@NotNull EcoPlugin plugin);
/**
* Create a PAPI integration.
*
* @param plugin The plugin.
* @return The integration.
*/
@NotNull
PlaceholderIntegration createPAPIIntegration(@NotNull EcoPlugin plugin);
/**
* Create a proxy factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin);
/**
* Get eco Spigot plugin.
*
* @return The plugin.
*/
@NotNull
EcoPlugin getEcoPlugin();
/**
* Updatable config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param type The config type.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param requiresChangesToSave If the config must be changed in order to save the config.
* @return The config implementation.
*/
LoadableConfig createUpdatableConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
boolean removeUnused,
@NotNull ConfigType type,
boolean requiresChangesToSave,
@NotNull String... updateBlacklist);
/**
* Loadable config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param type The config type.
* @param requiresChangesToSave If the config must be changed in order to save the config.
* @return The config implementation.
*/
LoadableConfig createLoadableConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
@NotNull ConfigType type,
boolean requiresChangesToSave);
/**
* Create config.
*
* @param config The handle.
* @return The config implementation.
*/
Config wrapConfigurationSection(@NotNull ConfigurationSection config);
/**
* Create config.
*
* @param values The values.
* @param type The config type.
* @return The config implementation.
*/
Config createConfig(@NotNull Map<String, Object> values,
@NotNull ConfigType type);
/**
* Create config.
*
* @param contents The file contents.
* @param type The type.
* @return The config implementation.
*/
Config createConfig(@NotNull String contents,
@NotNull ConfigType type);
/**
* Create a Drop Queue.
*
* @return The player..
*/
@NotNull
DropQueue createDropQueue(@NotNull Player player);
/**
* Create slot builder.
*
* @param provider The provider.
* @return The builder.
*/
@NotNull
SlotBuilder createSlotBuilder(@NotNull SlotProvider provider);
/**
* Create menu builder.
*
* @param rows The amount of rows.
* @param type The type.
* @return The builder.
*/
@NotNull
MenuBuilder createMenuBuilder(int rows,
@NotNull MenuType type);
/**
* Combine the state of two menus together.
*
* @param base The base menu.
* @param additional The additional state.
* @return The menu.
*/
@NotNull
Menu blendMenuState(@NotNull Menu base,
@NotNull Menu additional);
/**
* Get cleaner.
*
* @return The cleaner.
*/
@NotNull
Cleaner getCleaner();
/**
* Add new plugin.
*
* @param plugin The plugin.
*/
void addNewPlugin(@NotNull EcoPlugin plugin);
/**
* Get plugin by name.
*
* @param name The name.
* @return The plugin.
*/
@Nullable
EcoPlugin getPluginByName(@NotNull String name);
/**
* Get all loaded eco plugins.
*
* @return A list of plugin names in lowercase.
*/
@NotNull
List<String> getLoadedPlugins();
/**
* Create a FastItemStack.
*
* @param itemStack The base ItemStack.
* @return The FastItemStack.
*/
@NotNull
FastItemStack createFastItemStack(@NotNull ItemStack itemStack);
/**
* Register bStats metrics.
*
* @param plugin The plugin.
*/
void registerBStats(@NotNull EcoPlugin plugin);
/**
* Get Adventure audiences.
*
* @return The audiences.
*/
@Nullable
BukkitAudiences getAdventure();
/**
* Register a persistent data key to be stored.
*
* @param key The key.
*/
void registerPersistentKey(@NotNull PersistentDataKey<?> key);
/**
* Get all registered keys.
*
* @return The keys.
*/
Set<PersistentDataKey<?>> getRegisteredPersistentDataKeys();
/**
* Get persistent data key from namespaced key.
*
* @param namespacedKey The key.
* @return The key, or null if not found.
*/
@Nullable
PersistentDataKey<?> getPersistentDataKeyFrom(@NotNull NamespacedKey namespacedKey);
/**
* Load a player profile.
*
* @param uuid The UUID.
* @return The profile.
*/
PlayerProfile loadPlayerProfile(@NotNull UUID uuid);
/**
* Load the server profile.
*
* @return The profile.
*/
ServerProfile getServerProfile();
/**
* Unload a player profile from memory.
* <p>
* This will not save the profile first.
*
* @param uuid The uuid.
*/
void unloadPlayerProfile(@NotNull UUID uuid);
/**
* Save keys for a player.
* <p>
* Can run async if using MySQL.
*
* @param uuid The uuid.
* @param keys The keys.
*/
void savePersistentDataKeysFor(@NotNull UUID uuid,
@NotNull Set<PersistentDataKey<?>> keys);
/**
* Commit all changes to the file.
* <p>
* Does nothing if using MySQL.
*/
void saveAllProfiles();
/**
* Create dummy entity - never spawned, exists purely in code.
*
* @param location The location.
* @return The entity.
*/
@NotNull
Entity createDummyEntity(@NotNull Location location);
/**
* Create a {@link NamespacedKey} quickly
* <p>
* Bypasses the constructor, allowing for the creation of invalid keys,
* therefore this is considered unsafe and should only be called after
* the key has been confirmed to be valid.
*
* @param namespace The namespace.
* @param key The key.
* @return The key.
*/
@NotNull
NamespacedKey createNamespacedKey(@NotNull String namespace,
@NotNull String key);
/**
* Return or get props for a plugin.
*
* @param existing The existing constructor props.
* @param plugin The plugin.
* @return The props.
*/
@NotNull
PluginProps getProps(@Nullable PluginProps existing,
@NotNull Class<? extends EcoPlugin> plugin);
/**
* Format a string with MiniMessage.
*
* @param message The message.
* @return The formatted string.
*/
@NotNull
String formatMiniMessage(@NotNull String message);
/**
* Create controlled entity from a mob.
*
* @param mob The mob.
* @param <T> The mob type.
* @return The controlled entity.
*/
@NotNull <T extends Mob> EntityController<T> createEntityController(@NotNull T mob);
/**
* Adapt base PDC to extended PDC.
*
* @param container The container.
* @return The extended container.
*/
@NotNull
ExtendedPersistentDataContainer adaptPdc(@NotNull PersistentDataContainer container);
/**
* Create new PDC.
*
* @return The container.
*/
@NotNull
PersistentDataContainer newPdc();
/**
* Get item from SNBT.
*
* @param snbt The NBT string.
* @return The ItemStack, or null if invalid.
*/
@Nullable
ItemStack fromSNBT(@NotNull String snbt);
/**
* Convert item to SNBT.
*
* @param itemStack The item.
* @return The NBT string.
*/
@NotNull
String toSNBT(@NotNull ItemStack itemStack);
/**
* Make TestableItem from SNBT.
*
* @param snbt The NBT string.
* @return The TestableItem.
*/
@NotNull
TestableItem testableItemFromSNBT(@NotNull String snbt);
/**
* Get the texture of a skull.
*
* @param meta The skull meta.
* @return The texture, or null if not found.
*/
@Nullable
String getSkullTexture(@NotNull SkullMeta meta);
/**
* Set the texture of a skull.
*
* @param meta The skull meta.
* @param base64 The texture.
*/
void setSkullTexture(@NotNull SkullMeta meta,
@NotNull String base64);
/**
* Get the current server TPS.
*
* @return The TPS.
*/
double getTPS();
/**
* Evaluate an expression.
*
* @param expression The expression.
* @param player The player.
* @param injectable The injectable placeholders.
* @param additionalPlayers The additional players.
* @return The value of the expression, or zero if invalid.
*/
double evaluate(@NotNull String expression,
@Nullable Player player,
@NotNull PlaceholderInjectable injectable,
@NotNull Collection<AdditionalPlayer> additionalPlayers);
/**
* Get the menu a player currently has open.
*
* @param player The player.
* @return The menu, or null if no menu open.
*/
@Nullable
Menu getOpenMenu(@NotNull Player player);
/**
* Get the instance of eco; the bridge between the api frontend
* and the implementation backend.
*
* @return The instance of eco.
*/
@ApiStatus.Internal
public static Handler getHandler() {
return handler;
static Eco get() {
return Instance.get();
}
/**
* Eco Handler components are internals, so if a class is marked as a handler component,
* then it should be treated the same as if it was marked with {@link ApiStatus.Internal}.
* <p>
* If a class is marked with {@link HandlerComponent}, <strong>Do not reference it in
* your code!</strong> It can and will contain breaking changes between minor versions and
* even patches, and you will create compatibility issues by using them.
* <p>
* Handler components should also be marked with {@link ApiStatus.Internal} in order to
* cause compiler / IDE warnings.
* Manages the internal frontend -> backend communication.
*/
@Documented
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.TYPE})
public @interface HandlerComponent {
@ApiStatus.Internal
final class Instance {
/**
* Instance of eco.
*/
@ApiStatus.Internal
private static Eco eco;
}
/**
* Initialize eco.
*
* @param eco The instance of eco.
*/
@ApiStatus.Internal
static void set(@NotNull final Eco eco) {
Validate.isTrue(Instance.eco == null, "Already initialized!");
private Eco() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
Instance.eco = eco;
}
/**
* Get eco.
*
* @return eco.
*/
static Eco get() {
return eco;
}
private Instance() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}
}
}

View File

@@ -260,28 +260,28 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
*/
protected EcoPlugin(@Nullable final PluginProps pluginProps) {
/*
The handler must be initialized before any plugin's constructors
are called, as the constructors call Eco#getHandler().
Eco must be initialized before any plugin's constructors
are called, as the constructors call Eco#get().
To fix this, EcoSpigotPlugin an abstract class and the 'actual'
plugin class is EcoHandler - that way I can create the handler
plugin class is EcoImpl - that way I can initialize eco
before any plugins are loaded while still having a separation between
the plugin class and the handler class (for code clarity).
the plugin class and the implementation class (for code clarity).
I don't really like the fact that the handler class *is* the
I don't really like the fact that the implementation class *is* the
spigot plugin, but it is what it is.
There is probably a better way of doing it - maybe with
some sort of HandlerCreator interface in order to still have
a standalone handler class, but then there would be an interface
some sort of EcoCrater interface in order to still have
a standalone eco class, but then there would be an interface
left in the API that doesn't really help anything.
The other alternative would be to use reflection to get a 'createHandler'
The other alternative would be to use reflection to get a 'createEco'
method that only exists in EcoSpigotPlugin - but that feels filthy,
and I'd rather only use reflection where necessary.
*/
if (Eco.getHandler() == null && this instanceof Handler) {
if (Eco.get() == null && this instanceof Eco) {
/*
This code is only ever called by EcoSpigotPlugin (EcoHandler)
as it's the first plugin to load, and it is a handler.
@@ -290,12 +290,12 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
will have already been initialized.
*/
Eco.setHandler((Handler) this);
Eco.Instance.set((Eco) this);
}
assert Eco.getHandler() != null;
assert Eco.get() != null;
PluginProps generatedProps = Eco.getHandler().getProps(pluginProps, this.getClass());
PluginProps generatedProps = Eco.get().getProps(pluginProps, this.getClass());
generatedProps.validate();
PluginProps props = this.mutateProps(generatedProps);
props.validate();
@@ -306,23 +306,23 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.color = props.getColor();
this.supportingExtensions = props.isSupportingExtensions();
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.getHandler().createProxyFactory(this);
this.logger = Eco.getHandler().createLogger(this);
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.get().createProxyFactory(this);
this.logger = Eco.get().createLogger(this);
this.getLogger().info("Initializing " + this.getColor() + this.getName());
this.scheduler = Eco.getHandler().createScheduler(this);
this.eventManager = Eco.getHandler().createEventManager(this);
this.namespacedKeyFactory = Eco.getHandler().createNamespacedKeyFactory(this);
this.metadataValueFactory = Eco.getHandler().createMetadataValueFactory(this);
this.runnableFactory = Eco.getHandler().createRunnableFactory(this);
this.extensionLoader = Eco.getHandler().createExtensionLoader(this);
this.configHandler = Eco.getHandler().createConfigHandler(this);
this.scheduler = Eco.get().createScheduler(this);
this.eventManager = Eco.get().createEventManager(this);
this.namespacedKeyFactory = Eco.get().createNamespacedKeyFactory(this);
this.metadataValueFactory = Eco.get().createMetadataValueFactory(this);
this.runnableFactory = Eco.get().createRunnableFactory(this);
this.extensionLoader = Eco.get().createExtensionLoader(this);
this.configHandler = Eco.get().createConfigHandler(this);
this.langYml = this.createLangYml();
this.configYml = this.createConfigYml();
Eco.getHandler().addNewPlugin(this);
Eco.get().addNewPlugin(this);
/*
The minimum eco version check was moved here because it's very common
@@ -331,7 +331,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
they have an outdated version of eco installed.
*/
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().getEcoPlugin().getDescription().getVersion());
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.get().getEcoPlugin().getDescription().getVersion());
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion());
if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) {
this.getLogger().severe("You are running an outdated version of eco!");
@@ -352,7 +352,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
this.getLogger().info("");
this.getLogger().info("Loading " + this.getColor() + this.getName());
if (this.getResourceId() != 0 && !Eco.getHandler().getEcoPlugin().getConfigYml().getBool("no-update-checker")) {
if (this.getResourceId() != 0 && !Eco.get().getEcoPlugin().getConfigYml().getBool("no-update-checker")) {
new UpdateChecker(this).getVersion(version -> {
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(this.getDescription().getVersion());
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
@@ -366,7 +366,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
}
if (this.getBStatsId() != 0) {
Eco.getHandler().registerBStats(this);
Eco.get().registerBStats(this);
}
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins())
@@ -376,7 +376,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) {
this.loadedIntegrations.add("PlaceholderAPI");
PlaceholderManager.addIntegration(Eco.getHandler().createPAPIIntegration(this));
PlaceholderManager.addIntegration(Eco.get().createPAPIIntegration(this));
}
this.loadIntegrationLoaders().forEach(integrationLoader -> {
@@ -435,7 +435,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
}
this.getLogger().info("Cleaning up...");
Eco.getHandler().getCleaner().clean(this);
Eco.get().getCleaner().clean(this);
}
/**
@@ -748,7 +748,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The plugin.
*/
public static EcoPlugin getPlugin(@NotNull final String pluginName) {
return Eco.getHandler().getPluginByName(pluginName);
return Eco.get().getPluginByName(pluginName);
}
/**
@@ -757,7 +757,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
* @return The set of names.
*/
public static Set<String> getPluginNames() {
return new HashSet<>(Eco.getHandler().getLoadedPlugins());
return new HashSet<>(Eco.get().getLoadedPlugins());
}
/**

View File

@@ -1,366 +0,0 @@
package com.willfp.eco.core;
import com.willfp.eco.core.config.updating.ConfigHandler;
import com.willfp.eco.core.config.wrapper.ConfigFactory;
import com.willfp.eco.core.data.ExtendedPersistentDataContainer;
import com.willfp.eco.core.data.ProfileHandler;
import com.willfp.eco.core.data.keys.KeyRegistry;
import com.willfp.eco.core.drops.DropQueueFactory;
import com.willfp.eco.core.entities.ai.EntityController;
import com.willfp.eco.core.events.EventManager;
import com.willfp.eco.core.extensions.ExtensionLoader;
import com.willfp.eco.core.factory.MetadataValueFactory;
import com.willfp.eco.core.factory.NamespacedKeyFactory;
import com.willfp.eco.core.factory.RunnableFactory;
import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.core.gui.GUIFactory;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
import com.willfp.eco.core.items.SNBTHandler;
import com.willfp.eco.core.placeholder.AdditionalPlayer;
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.proxy.Cleaner;
import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.scheduling.Scheduler;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Mob;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.logging.Logger;
/**
* @see Eco#getHandler()
*/
@ApiStatus.Internal
public interface Handler {
/**
* Create a scheduler.
*
* @param plugin The plugin.
* @return The scheduler.
*/
@NotNull
Scheduler createScheduler(@NotNull EcoPlugin plugin);
/**
* Create an event manager.
*
* @param plugin The plugin.
* @return The event manager.
*/
@NotNull
EventManager createEventManager(@NotNull EcoPlugin plugin);
/**
* Create a NamespacedKey factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin);
/**
* Create a MetadataValue factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin);
/**
* Create a Runnable factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin);
/**
* Create an ExtensionLoader.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin);
/**
* Create a config handler.
*
* @param plugin The plugin.
* @return The handler.
*/
@NotNull
ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin);
/**
* Create a logger.
*
* @param plugin The plugin.
* @return The logger.
*/
@NotNull
Logger createLogger(@NotNull EcoPlugin plugin);
/**
* Create a PAPI integration.
*
* @param plugin The plugin.
* @return The integration.
*/
@NotNull
PlaceholderIntegration createPAPIIntegration(@NotNull EcoPlugin plugin);
/**
* Create a proxy factory.
*
* @param plugin The plugin.
* @return The factory.
*/
@NotNull
ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin);
/**
* Get eco Spigot plugin.
*
* @return The plugin.
*/
@NotNull
EcoPlugin getEcoPlugin();
/**
* Get config factory.
*
* @return The factory.
*/
@NotNull
ConfigFactory getConfigFactory();
/**
* Get drop queue factory.
*
* @return The factory.
*/
@NotNull
DropQueueFactory getDropQueueFactory();
/**
* Get GUI factory.
*
* @return The factory.
*/
@NotNull
GUIFactory getGUIFactory();
/**
* Get cleaner.
*
* @return The cleaner.
*/
@NotNull
Cleaner getCleaner();
/**
* Add new plugin.
*
* @param plugin The plugin.
*/
void addNewPlugin(@NotNull EcoPlugin plugin);
/**
* Get plugin by name.
*
* @param name The name.
* @return The plugin.
*/
@Nullable
EcoPlugin getPluginByName(@NotNull String name);
/**
* Get all loaded eco plugins.
*
* @return A list of plugin names in lowercase.
*/
@NotNull
List<String> getLoadedPlugins();
/**
* Create a FastItemStack.
*
* @param itemStack The base ItemStack.
* @return The FastItemStack.
*/
@NotNull
FastItemStack createFastItemStack(@NotNull ItemStack itemStack);
/**
* Register bStats metrics.
*
* @param plugin The plugin.
*/
void registerBStats(@NotNull EcoPlugin plugin);
/**
* Get Adventure audiences.
*
* @return The audiences.
*/
@Nullable
BukkitAudiences getAdventure();
/**
* Get the key registry.
*
* @return The registry.
*/
@NotNull
KeyRegistry getKeyRegistry();
/**
* Get the PlayerProfile handler.
*
* @return The handler.
*/
@NotNull
ProfileHandler getProfileHandler();
/**
* Create dummy entity - never spawned, exists purely in code.
*
* @param location The location.
* @return The entity.
*/
@NotNull
Entity createDummyEntity(@NotNull Location location);
/**
* Create a {@link NamespacedKey} quickly
* <p>
* Bypasses the constructor, allowing for the creation of invalid keys,
* therefore this is considered unsafe and should only be called after
* the key has been confirmed to be valid.
*
* @param namespace The namespace.
* @param key The key.
* @return The key.
*/
@NotNull
NamespacedKey createNamespacedKey(@NotNull String namespace,
@NotNull String key);
/**
* Return or get props for a plugin.
*
* @param existing The existing constructor props.
* @param plugin The plugin.
* @return The props.
*/
@NotNull
PluginProps getProps(@Nullable PluginProps existing,
@NotNull Class<? extends EcoPlugin> plugin);
/**
* Format a string with MiniMessage.
*
* @param message The message.
* @return The formatted string.
*/
@NotNull
String formatMiniMessage(@NotNull String message);
/**
* Create controlled entity from a mob.
*
* @param mob The mob.
* @param <T> The mob type.
* @return The controlled entity.
*/
@NotNull <T extends Mob> EntityController<T> createEntityController(@NotNull T mob);
/**
* Adapt base PDC to extended PDC.
*
* @param container The container.
* @return The extended container.
*/
@NotNull
ExtendedPersistentDataContainer adaptPdc(@NotNull PersistentDataContainer container);
/**
* Create new PDC.
*
* @return The container.
*/
@NotNull
PersistentDataContainer newPdc();
/**
* Get SNBT handler.
*
* @return The SNBT handler.
*/
@NotNull
SNBTHandler getSNBTHandler();
/**
* Get the texture of a skull.
*
* @param meta The skull meta.
* @return The texture, or null if not found.
*/
@Nullable
String getSkullTexture(@NotNull SkullMeta meta);
/**
* Set the texture of a skull.
*
* @param meta The skull meta.
* @param base64 The texture.
*/
void setSkullTexture(@NotNull SkullMeta meta,
@NotNull String base64);
/**
* Get the current server TPS.
*
* @return The TPS.
*/
double getTPS();
/**
* Evaluate an expression.
*
* @param expression The expression.
* @param player The player.
* @param injectable The injectable placeholders.
* @param additionalPlayers The additional players.
* @return The value of the expression, or zero if invalid.
*/
double evaluate(@NotNull String expression,
@Nullable Player player,
@NotNull PlaceholderInjectable injectable,
@NotNull Collection<AdditionalPlayer> additionalPlayers);
/**
* Get the menu a player currently has open.
*
* @param player The player.
* @return The menu, or null if no menu open.
*/
@Nullable
Menu getOpenMenu(@NotNull Player player);
}

View File

@@ -40,7 +40,7 @@ public abstract class BaseConfig extends LoadableConfigWrapper {
final boolean removeUnused,
@NotNull final ConfigType type,
final boolean requiresChangeToSave) {
super(Eco.getHandler().getConfigFactory().createUpdatableConfig(
super(Eco.get().createUpdatableConfig(
configName,
plugin,
"",

View File

@@ -31,7 +31,7 @@ public abstract class ExtendableConfig extends LoadableConfigWrapper {
@NotNull final String subDirectoryPath,
@NotNull final ConfigType type,
@NotNull final String... updateBlacklist) {
super(Eco.getHandler().getConfigFactory().createUpdatableConfig(
super(Eco.get().createUpdatableConfig(
configName,
plugin,
subDirectoryPath,

View File

@@ -21,7 +21,7 @@ public abstract class StaticBaseConfig extends LoadableConfigWrapper {
protected StaticBaseConfig(@NotNull final String configName,
@NotNull final PluginLike plugin,
@NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createLoadableConfig(
super(Eco.get().createLoadableConfig(
configName,
plugin,
"",

View File

@@ -26,7 +26,7 @@ public class TransientConfig extends ConfigWrapper<Config> {
* @param config The ConfigurationSection handle.
*/
public TransientConfig(@NotNull final ConfigurationSection config) {
super(Eco.getHandler().getConfigFactory().createConfig(config));
super(Eco.get().wrapConfigurationSection(config));
}
/**
@@ -42,7 +42,7 @@ public class TransientConfig extends ConfigWrapper<Config> {
* @param stream The InputStream.
*/
public TransientConfig(@Nullable final InputStream stream) {
super(stream != null ? Eco.getHandler().getConfigFactory().createConfig(YamlConfiguration.loadConfiguration(
super(stream != null ? Eco.get().wrapConfigurationSection(YamlConfiguration.loadConfiguration(
new InputStreamReader(stream)
)) : new TransientConfig());
}
@@ -62,7 +62,7 @@ public class TransientConfig extends ConfigWrapper<Config> {
*/
public TransientConfig(@Nullable final File file,
@NotNull final ConfigType type) {
super(file != null ? Eco.getHandler().getConfigFactory().createConfig(readFile(file), type)
super(file != null ? Eco.get().createConfig(readFile(file), type)
: new TransientConfig());
}
@@ -72,7 +72,7 @@ public class TransientConfig extends ConfigWrapper<Config> {
* @param values The values.
*/
public TransientConfig(@NotNull final Map<String, Object> values) {
super(Eco.getHandler().getConfigFactory().createConfig(values, ConfigType.YAML));
super(Eco.get().createConfig(values, ConfigType.YAML));
}
/**
@@ -83,7 +83,7 @@ public class TransientConfig extends ConfigWrapper<Config> {
*/
public TransientConfig(@NotNull final Map<String, Object> values,
@NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createConfig(values, type));
super(Eco.get().createConfig(values, type));
}
/**
@@ -99,7 +99,7 @@ public class TransientConfig extends ConfigWrapper<Config> {
*/
public TransientConfig(@NotNull final String contents,
@NotNull final ConfigType type) {
super(Eco.getHandler().getConfigFactory().createConfig(contents, type));
super(Eco.get().createConfig(contents, type));
}
/**

View File

@@ -1,87 +0,0 @@
package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.PluginLike;
import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.config.interfaces.LoadableConfig;
import org.bukkit.configuration.ConfigurationSection;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
/**
* Internal component to create backend config implementations.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface ConfigFactory {
/**
* Updatable config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param removeUnused Whether keys not present in the default config should be removed on update.
* @param type The config type.
* @param updateBlacklist Substring of keys to not add/remove keys for.
* @param requiresChangesToSave If the config must be changed in order to save the config.
* @return The config implementation.
*/
LoadableConfig createUpdatableConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
boolean removeUnused,
@NotNull ConfigType type,
boolean requiresChangesToSave,
@NotNull String... updateBlacklist);
/**
* Loadable config.
*
* @param configName The name of the config
* @param plugin The plugin.
* @param subDirectoryPath The subdirectory path.
* @param source The class that owns the resource.
* @param type The config type.
* @param requiresChangesToSave If the config must be changed in order to save the config.
* @return The config implementation.
*/
LoadableConfig createLoadableConfig(@NotNull String configName,
@NotNull PluginLike plugin,
@NotNull String subDirectoryPath,
@NotNull Class<?> source,
@NotNull ConfigType type,
boolean requiresChangesToSave);
/**
* Create config.
*
* @param config The handle.
* @return The config implementation.
*/
Config createConfig(@NotNull ConfigurationSection config);
/**
* Create config.
*
* @param values The values.
* @param type The config type.
* @return The config implementation.
*/
Config createConfig(@NotNull Map<String, Object> values,
@NotNull ConfigType type);
/**
* Create config.
*
* @param contents The file contents.
* @param type The type.
* @return The config implementation.
*/
Config createConfig(@NotNull String contents,
@NotNull ConfigType type);
}

View File

@@ -87,7 +87,7 @@ public interface ExtendedPersistentDataContainer {
* @return The extended container.
*/
static ExtendedPersistentDataContainer extend(@NotNull PersistentDataContainer base) {
return Eco.getHandler().adaptPdc(base);
return Eco.get().adaptPdc(base);
}
/**
@@ -96,6 +96,6 @@ public interface ExtendedPersistentDataContainer {
* @return The extended container.
*/
static ExtendedPersistentDataContainer create() {
return extend(Eco.getHandler().newPdc());
return extend(Eco.get().newPdc());
}
}

View File

@@ -31,6 +31,6 @@ public interface PlayerProfile extends Profile {
*/
@NotNull
static PlayerProfile load(@NotNull final UUID uuid) {
return Eco.getHandler().getProfileHandler().load(uuid);
return Eco.get().loadPlayerProfile(uuid);
}
}

View File

@@ -1,94 +0,0 @@
package com.willfp.eco.core.data;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.data.keys.PersistentDataKey;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
import java.util.UUID;
/**
* API to handle profiles.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface ProfileHandler {
/**
* Load a player profile.
*
* @param uuid The UUID.
* @return The profile.
*/
PlayerProfile load(@NotNull UUID uuid);
/**
* Load the server profile.
*
* @return The profile.
*/
ServerProfile loadServerProfile();
/**
* Unload a player profile from memory.
* <p>
* This will not save the profile first.
*
* @param uuid The uuid.
*/
void unloadPlayer(@NotNull UUID uuid);
/**
* Save a player profile.
* <p>
* Can run async if using MySQL.
*
* @param uuid The uuid.
* @deprecated Saving changes is faster and should be used. Saving a player manually is not recommended.
*/
@Deprecated
default void savePlayer(@NotNull UUID uuid) {
this.saveKeysFor(uuid, PersistentDataKey.values());
}
/**
* Save keys for a player.
* <p>
* Can run async if using MySQL.
*
* @param uuid The uuid.
* @param keys The keys.
*/
void saveKeysFor(@NotNull UUID uuid,
@NotNull Set<PersistentDataKey<?>> keys);
/**
* Save all player data.
*
* @param async If the saving should be done asynchronously.
* @deprecated async is now handled automatically depending on implementation.
*/
@Deprecated(forRemoval = true)
default void saveAll(boolean async) {
saveAll();
}
/**
* Save all player data.
* <p>
* Can run async if using MySQL.
*
* @deprecated Never used.
*/
@Deprecated(since = "6.36.0", forRemoval = true)
default void saveAll() {
// Do nothing.
}
/**
* Commit all changes to the file.
* <p>
* Does nothing if using MySQL.
*/
void save();
}

View File

@@ -16,6 +16,6 @@ public interface ServerProfile extends Profile {
*/
@NotNull
static ServerProfile load() {
return Eco.getHandler().getProfileHandler().loadServerProfile();
return Eco.get().getServerProfile();
}
}

View File

@@ -1,39 +0,0 @@
package com.willfp.eco.core.data.keys;
import com.willfp.eco.core.Eco;
import org.bukkit.NamespacedKey;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
/**
* API to register persistent data keys.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface KeyRegistry {
/**
* Register a persistent data key to be stored.
*
* @param key The key.
*/
void registerKey(@NotNull PersistentDataKey<?> key);
/**
* Get all registered keys.
*
* @return The keys.
*/
Set<PersistentDataKey<?>> getRegisteredKeys();
/**
* Get persistent data key from namespaced key.
*
* @param namespacedKey The key.
* @return The key, or null if not found.
*/
@Nullable
PersistentDataKey<?> getKeyFrom(@NotNull NamespacedKey namespacedKey);
}

View File

@@ -43,7 +43,7 @@ public final class PersistentDataKey<T> {
this.defaultValue = defaultValue;
this.type = type;
Eco.getHandler().getKeyRegistry().registerKey(this);
Eco.get().registerPersistentKey(this);
}
@Override
@@ -126,7 +126,7 @@ public final class PersistentDataKey<T> {
* @return The keys.
*/
public static Set<PersistentDataKey<?>> values() {
return Eco.getHandler().getKeyRegistry().getRegisteredKeys();
return Eco.get().getRegisteredPersistentDataKeys();
}
@Override

View File

@@ -1,11 +1,22 @@
package com.willfp.eco.core.display;
import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.util.NamespacedKeyUtils;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
* Utility class to manage client-side item display.
*/
@@ -16,9 +27,14 @@ public final class Display {
public static final String PREFIX = "§z";
/**
* The display handler.
* All registered modules.
*/
private static DisplayHandler handler = null;
private static final Map<Integer, List<DisplayModule>> REGISTERED_MODULES = new TreeMap<>();
/**
* The finalize key.
*/
private static final NamespacedKey FINALIZE_KEY = NamespacedKeyUtils.createEcoKey("finalized");
/**
* Display on ItemStacks.
@@ -39,7 +55,49 @@ public final class Display {
*/
public static ItemStack display(@NotNull final ItemStack itemStack,
@Nullable final Player player) {
return handler.display(itemStack, player);
Map<String, Object[]> pluginVarArgs = new HashMap<>();
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
for (DisplayModule module : modules) {
pluginVarArgs.put(module.getPluginName(), module.generateVarArgs(itemStack));
}
}
Display.revert(itemStack);
if (!itemStack.hasItemMeta()) {
return itemStack;
}
ItemStack original = itemStack.clone();
Inventory inventory = player == null ? null : player.getOpenInventory().getTopInventory();
boolean inInventory = inventory != null && inventory.contains(original);
boolean inGui = inventory != null && inventory.getHolder() == null;
DisplayProperties properties = new DisplayProperties(
inInventory,
inGui,
original
);
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
for (DisplayModule module : modules) {
Object[] varargs = pluginVarArgs.get(module.getPluginName());
if (varargs == null) {
continue;
}
module.display(itemStack, varargs);
if (player != null) {
module.display(itemStack, player, varargs);
module.display(itemStack, player, properties, varargs);
}
}
}
return itemStack;
}
/**
@@ -71,7 +129,25 @@ public final class Display {
* @return The ItemStack.
*/
public static ItemStack revert(@NotNull final ItemStack itemStack) {
return handler.revert(itemStack);
if (Display.isFinalized(itemStack)) {
Display.unfinalize(itemStack);
}
FastItemStack fast = FastItemStack.wrap(itemStack);
List<String> lore = fast.getLore();
if (!lore.isEmpty() && lore.removeIf(line -> line.startsWith(Display.PREFIX))) {
fast.setLore(lore);
}
for (List<DisplayModule> modules : REGISTERED_MODULES.values()) {
for (DisplayModule module : modules) {
module.revert(itemStack);
}
}
return itemStack;
}
/**
@@ -81,7 +157,15 @@ public final class Display {
* @return The ItemStack.
*/
public static ItemStack finalize(@NotNull final ItemStack itemStack) {
return handler.finalize(itemStack);
if (itemStack.getType().getMaxStackSize() > 1) {
return itemStack;
}
FastItemStack.wrap(itemStack)
.getPersistentDataContainer()
.set(FINALIZE_KEY, PersistentDataType.INTEGER, 1);
return itemStack;
}
/**
@@ -91,7 +175,11 @@ public final class Display {
* @return The ItemStack.
*/
public static ItemStack unfinalize(@NotNull final ItemStack itemStack) {
return handler.unfinalize(itemStack);
FastItemStack.wrap(itemStack)
.getPersistentDataContainer()
.remove(FINALIZE_KEY);
return itemStack;
}
/**
@@ -101,7 +189,9 @@ public final class Display {
* @return If finalized.
*/
public static boolean isFinalized(@NotNull final ItemStack itemStack) {
return handler.isFinalized(itemStack);
return FastItemStack.wrap(itemStack)
.getPersistentDataContainer()
.has(FINALIZE_KEY, PersistentDataType.INTEGER);
}
/**
@@ -110,23 +200,15 @@ public final class Display {
* @param module The module.
*/
public static void registerDisplayModule(@NotNull final DisplayModule module) {
handler.registerDisplayModule(module);
}
List<DisplayModule> modules = REGISTERED_MODULES.getOrDefault(
module.getWeight(),
new ArrayList<>()
);
/**
* Set the display handler.
* <p>
* Internal API component, you will cause bugs if you create your own handler.
*
* @param handler The handler.
*/
@ApiStatus.Internal
public static void setHandler(@NotNull final DisplayHandler handler) {
if (Display.handler != null) {
throw new IllegalStateException("Display already initialized!");
}
modules.removeIf(it -> it.getPluginName().equalsIgnoreCase(module.getPluginName()));
modules.add(module);
Display.handler = handler;
REGISTERED_MODULES.put(module.getWeight(), modules);
}
private Display() {

View File

@@ -1,64 +0,0 @@
package com.willfp.eco.core.display;
import com.willfp.eco.core.Eco;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Interface for display implementations.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface DisplayHandler {
/**
* Register display module.
*
* @param module The module.
*/
void registerDisplayModule(@NotNull DisplayModule module);
/**
* Display on ItemStacks.
*
* @param itemStack The item.
* @param player The player.
* @return The ItemStack.
*/
ItemStack display(@NotNull ItemStack itemStack,
@Nullable Player player);
/**
* Revert on ItemStacks.
*
* @param itemStack The item.
* @return The ItemStack.
*/
ItemStack revert(@NotNull ItemStack itemStack);
/**
* Finalize an ItemStacks.
*
* @param itemStack The item.
* @return The ItemStack.
*/
ItemStack finalize(@NotNull ItemStack itemStack);
/**
* Unfinalize an ItemStacks.
*
* @param itemStack The item.
* @return The ItemStack.
*/
ItemStack unfinalize(@NotNull ItemStack itemStack);
/**
* If an item is finalized.
*
* @param itemStack The item.
* @return If finalized.
*/
boolean isFinalized(@NotNull ItemStack itemStack);
}

View File

@@ -21,13 +21,25 @@ public class DropQueue {
/**
* The internally used {@link DropQueue}.
*/
private final InternalDropQueue handle;
private final DropQueue delegate;
/**
* Create a new DropQueue.
*
* @param player The player.
*/
public DropQueue(@NotNull final Player player) {
handle = Eco.getHandler().getDropQueueFactory().create(player);
this.delegate = Eco.get().createDropQueue(player);
}
/**
* Create a new DropQueue with no delegate.
* <p>
* Call this constructor if you're creating custom DropQueue
* implementations.
*/
protected DropQueue() {
this.delegate = null;
}
/**
@@ -37,7 +49,11 @@ public class DropQueue {
* @return The DropQueue.
*/
public DropQueue addItem(@NotNull final ItemStack item) {
handle.addItem(item);
if (delegate == null) {
return this;
}
delegate.addItem(item);
return this;
}
@@ -48,7 +64,11 @@ public class DropQueue {
* @return The DropQueue.
*/
public DropQueue addItems(@NotNull final Collection<ItemStack> itemStacks) {
handle.addItems(itemStacks);
if (delegate == null) {
return this;
}
delegate.addItems(itemStacks);
return this;
}
@@ -59,7 +79,11 @@ public class DropQueue {
* @return The DropQueue.
*/
public DropQueue addXP(final int amount) {
handle.addXP(amount);
if (delegate == null) {
return this;
}
delegate.addXP(amount);
return this;
}
@@ -70,7 +94,11 @@ public class DropQueue {
* @return The DropQueue.
*/
public DropQueue setLocation(@NotNull final Location location) {
handle.setLocation(location);
if (delegate == null) {
return this;
}
delegate.setLocation(location);
return this;
}
@@ -80,7 +108,11 @@ public class DropQueue {
* @return The DropQueue.
*/
public DropQueue forceTelekinesis() {
handle.forceTelekinesis();
if (delegate == null) {
return this;
}
delegate.forceTelekinesis();
return this;
}
@@ -88,6 +120,10 @@ public class DropQueue {
* Push the queue.
*/
public void push() {
handle.push();
if (delegate == null) {
return;
}
delegate.push();
}
}

View File

@@ -1,21 +0,0 @@
package com.willfp.eco.core.drops;
import com.willfp.eco.core.Eco;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* Internal component to create backend DropQueue implementations.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface DropQueueFactory {
/**
* Create a DropQueue.
*
* @param player The player.
* @return The Queue.
*/
InternalDropQueue create(@NotNull Player player);
}

View File

@@ -1,60 +0,0 @@
package com.willfp.eco.core.drops;
import com.willfp.eco.core.Eco;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* Internal interface for backend DropQueue implementations.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface InternalDropQueue {
/**
* Add item to queue.
*
* @param item The item to add.
* @return The DropQueue.
*/
InternalDropQueue addItem(@NotNull ItemStack item);
/**
* Add multiple items to queue.
*
* @param itemStacks The items to add.
* @return The DropQueue.
*/
InternalDropQueue addItems(@NotNull Collection<ItemStack> itemStacks);
/**
* Add xp to queue.
*
* @param amount The amount to add.
* @return The DropQueue.
*/
InternalDropQueue addXP(int amount);
/**
* Set location of the origin of the drops.
*
* @param location The location.
* @return The DropQueue.
*/
InternalDropQueue setLocation(@NotNull Location location);
/**
* Force the queue to act as if player is telekinetic.
*
* @return The DropQueue.
*/
InternalDropQueue forceTelekinesis();
/**
* Push the queue.
*/
void push();
}

View File

@@ -101,6 +101,6 @@ public interface EntityController<T extends Mob> {
* @return The entity controller.
*/
static <T extends Mob> EntityController<T> getFor(@NotNull final T entity) {
return Eco.getHandler().createEntityController(entity);
return Eco.get().createEntityController(entity);
}
}

View File

@@ -28,6 +28,6 @@ public class EmptyTestableEntity implements TestableEntity {
public Entity spawn(@NotNull final Location location) {
Validate.notNull(location.getWorld());
return Eco.getHandler().createDummyEntity(location);
return Eco.get().createDummyEntity(location);
}
}

View File

@@ -72,6 +72,7 @@ public interface FastItemStack extends PersistentDataHolder {
* @deprecated Poorly named method. Use getEnchantmentLevel instead.
*/
@Deprecated(since = "6.34.0", forRemoval = true)
@SuppressWarnings("DeprecatedIsStillUsed")
default int getLevelOnItem(@NotNull Enchantment enchantment,
boolean checkStored) {
return getEnchantmentLevel(enchantment, checkStored);
@@ -271,6 +272,6 @@ public interface FastItemStack extends PersistentDataHolder {
* @return The FastItemStack.
*/
static FastItemStack wrap(@Nullable final ItemStack itemStack) {
return Eco.getHandler().createFastItemStack(Objects.requireNonNullElseGet(itemStack, () -> new ItemStack(Material.AIR)));
return Eco.get().createFastItemStack(Objects.requireNonNullElseGet(itemStack, () -> new ItemStack(Material.AIR)));
}
}

View File

@@ -1,4 +1,4 @@
package com.willfp.eco.core.gui.component;
package com.willfp.eco.core.gui;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.slot.Slot;

View File

@@ -1,50 +0,0 @@
package com.willfp.eco.core.gui;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.menu.MenuBuilder;
import com.willfp.eco.core.gui.menu.MenuType;
import com.willfp.eco.core.gui.slot.SlotBuilder;
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* Internal component used by {@link com.willfp.eco.core.gui.menu.Menu#builder(int)}
* and {@link com.willfp.eco.core.gui.slot.Slot#builder(ItemStack)}.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface GUIFactory {
/**
* Create slot builder.
*
* @param provider The provider.
* @return The builder.
*/
@NotNull
SlotBuilder createSlotBuilder(@NotNull SlotProvider provider);
/**
* Create menu builder.
*
* @param rows The amount of rows.
* @param type The type.
* @return The builder.
*/
@NotNull
MenuBuilder createMenuBuilder(int rows,
@NotNull MenuType type);
/**
* Combine the state of two menus together.
*
* @param base The base menu.
* @param additional The additional state.
* @return The menu.
*/
@NotNull
Menu blendMenuState(@NotNull Menu base,
@NotNull Menu additional);
}

View File

@@ -241,7 +241,7 @@ public interface Menu {
* @return The builder.
*/
static MenuBuilder builder(final int rows) {
return Eco.getHandler().getGUIFactory().createMenuBuilder(
return Eco.get().createMenuBuilder(
rows,
MenuType.NORMAL
);
@@ -254,6 +254,6 @@ public interface Menu {
* @return The builder.
*/
static MenuBuilder builder(@NotNull final MenuType type) {
return Eco.getHandler().getGUIFactory().createMenuBuilder(type.getDefaultRows(), type);
return Eco.get().createMenuBuilder(type.getDefaultRows(), type);
}
}

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.core.gui.menu;
import com.willfp.eco.core.gui.component.GUIComponent;
import com.willfp.eco.core.gui.GUIComponent;
import com.willfp.eco.core.gui.page.Page;
import com.willfp.eco.core.gui.page.PageBuilder;
import com.willfp.eco.core.gui.slot.FillerMask;

View File

@@ -1,7 +1,7 @@
package com.willfp.eco.core.gui.page;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.component.GUIComponent;
import com.willfp.eco.core.gui.GUIComponent;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.menu.MenuBuilder;
import com.willfp.eco.core.gui.slot.Slot;
@@ -82,7 +82,7 @@ public final class Page implements GUIComponent {
}
if (delegate == null) {
delegate = Eco.getHandler().getGUIFactory().blendMenuState(page, menu);
delegate = Eco.get().blendMenuState(page, menu);
}
return page.getSlot(row, column, player, delegate);

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.core.gui.page;
import com.willfp.eco.core.gui.component.GUIComponent;
import com.willfp.eco.core.gui.GUIComponent;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.menu.MenuLayer;
import com.willfp.eco.core.gui.slot.FillerMask;

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.core.gui.page;
import com.willfp.eco.core.gui.component.GUIComponent;
import com.willfp.eco.core.gui.GUIComponent;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.slot.Slot;
import org.bukkit.entity.Player;

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.gui.component.GUIComponent;
import com.willfp.eco.core.gui.GUIComponent;
import com.willfp.eco.core.items.builder.ItemStackBuilder;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
import com.willfp.eco.core.recipe.parts.MaterialTestableItem;

View File

@@ -1,7 +1,7 @@
package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.component.GUIComponent;
import com.willfp.eco.core.gui.GUIComponent;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import com.willfp.eco.core.items.TestableItem;
@@ -97,7 +97,7 @@ public interface Slot extends GUIComponent {
* @return The builder.
*/
static SlotBuilder builder() {
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> new ItemStack(Material.AIR));
return Eco.get().createSlotBuilder((player, menu) -> new ItemStack(Material.AIR));
}
/**
@@ -107,7 +107,7 @@ public interface Slot extends GUIComponent {
* @return The builder.
*/
static SlotBuilder builder(@NotNull final ItemStack itemStack) {
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> itemStack);
return Eco.get().createSlotBuilder((player, menu) -> itemStack);
}
/**
@@ -117,7 +117,7 @@ public interface Slot extends GUIComponent {
* @return The builder.
*/
static SlotBuilder builder(@NotNull final TestableItem item) {
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> item.getItem());
return Eco.get().createSlotBuilder((player, menu) -> item.getItem());
}
/**
@@ -127,7 +127,7 @@ public interface Slot extends GUIComponent {
* @return The builder.
*/
static SlotBuilder builder(@NotNull final Function<Player, ItemStack> provider) {
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> provider.apply(player));
return Eco.get().createSlotBuilder((player, menu) -> provider.apply(player));
}
/**
@@ -137,7 +137,7 @@ public interface Slot extends GUIComponent {
* @return The builder.
*/
static SlotBuilder builder(@NotNull final SlotProvider provider) {
return Eco.getHandler().getGUIFactory().createSlotBuilder(provider);
return Eco.get().createSlotBuilder(provider);
}
/**

View File

@@ -38,7 +38,7 @@ public final class AnticheatManager {
*/
public static void register(@NotNull final AnticheatIntegration anticheat) {
if (anticheat instanceof Listener) {
Eco.getHandler().getEcoPlugin().getEventManager().registerListener((Listener) anticheat);
Eco.get().getEcoPlugin().getEventManager().registerListener((Listener) anticheat);
}
ANTICHEATS.removeIf(it -> it.getPluginName().equalsIgnoreCase(anticheat.getPluginName()));
ANTICHEATS.add(anticheat);

View File

@@ -158,13 +158,13 @@ public class PlaceholderEntry {
Placeholder toModernPlaceholder() {
if (this.requiresPlayer) {
return new PlayerPlaceholder(
Objects.requireNonNullElse(plugin, Eco.getHandler().getEcoPlugin()),
Objects.requireNonNullElse(plugin, Eco.get().getEcoPlugin()),
identifier,
function
);
} else {
return new PlayerlessPlaceholder(
Objects.requireNonNullElse(plugin, Eco.getHandler().getEcoPlugin()),
Objects.requireNonNullElse(plugin, Eco.get().getEcoPlugin()),
identifier,
() -> function.apply(null)
);

View File

@@ -92,7 +92,7 @@ public final class PlaceholderManager {
throw new IllegalArgumentException("Static placeholders cannot be registered!");
}
EcoPlugin plugin = placeholder.getPlugin() == null ? Eco.getHandler().getEcoPlugin() : placeholder.getPlugin();
EcoPlugin plugin = placeholder.getPlugin() == null ? Eco.get().getEcoPlugin() : placeholder.getPlugin();
Map<String, Placeholder> pluginPlaceholders = REGISTERED_PLACEHOLDERS
.getOrDefault(plugin, new HashMap<>());
pluginPlaceholders.put(placeholder.getIdentifier(), placeholder);
@@ -136,11 +136,11 @@ public final class PlaceholderManager {
public static String getResult(@Nullable final Player player,
@NotNull final String identifier,
@Nullable final EcoPlugin plugin) {
EcoPlugin owner = plugin == null ? Eco.getHandler().getEcoPlugin() : plugin;
EcoPlugin owner = plugin == null ? Eco.get().getEcoPlugin() : plugin;
Placeholder placeholder = REGISTERED_PLACEHOLDERS.getOrDefault(owner, new HashMap<>()).get(identifier.toLowerCase());
if (placeholder == null && plugin != null) {
Placeholder alternate = REGISTERED_PLACEHOLDERS.getOrDefault(Eco.getHandler().getEcoPlugin(), new HashMap<>())
Placeholder alternate = REGISTERED_PLACEHOLDERS.getOrDefault(Eco.get().getEcoPlugin(), new HashMap<>())
.get(identifier.toLowerCase());
if (alternate != null) {
placeholder = alternate;

View File

@@ -30,22 +30,6 @@ public final class ShopManager {
REGISTERED.add(integration);
}
/**
* Register the events with eco.
*
* @param plugin Instance of eco.
*/
@ApiStatus.Internal
public static void registerEvents(@NotNull final EcoPlugin plugin) {
for (ShopIntegration integration : REGISTERED) {
Listener listener = integration.getSellEventAdapter();
if (listener != null) {
plugin.getEventManager().registerListener(listener);
}
}
}
/**
* Register eco item provider for shop plugins.
*/
@@ -89,6 +73,15 @@ public final class ShopManager {
return 0.0;
}
/**
* Get all registered integrations.
*
* @return The integrations.
*/
public static Set<ShopIntegration> getRegisteredIntegrations() {
return new HashSet<>(REGISTERED);
}
private ShopManager() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}

View File

@@ -53,7 +53,7 @@ public class CustomItem implements TestableItem {
immediately after due to registration order; so eco waits until the item should be
working in order to check.
*/
Eco.getHandler().getEcoPlugin().getScheduler().runLater(() -> {
Eco.get().getEcoPlugin().getScheduler().runLater(() -> {
if (!matches(getItem())) {
Bukkit.getLogger().severe("Item with key " + key + " is invalid!");
}

View File

@@ -192,7 +192,7 @@ public final class Items {
@NotNull
public static TestableItem lookup(@NotNull final String key) {
if (key.startsWith("{")) {
return Eco.getHandler().getSNBTHandler().createTestable(key);
return Eco.get().testableItemFromSNBT(key);
}
return ITEMS_LOOKUP_HANDLER.parseKey(key);
@@ -538,7 +538,7 @@ public final class Items {
*/
@NotNull
public static String toSNBT(@NotNull final ItemStack itemStack) {
return Eco.getHandler().getSNBTHandler().toSNBT(itemStack);
return Eco.get().toSNBT(itemStack);
}
/**
@@ -549,7 +549,7 @@ public final class Items {
*/
@Nullable
public static ItemStack fromSNBT(@NotNull final String snbt) {
return Eco.getHandler().getSNBTHandler().fromSNBT(snbt);
return Eco.get().fromSNBT(snbt);
}
/**

View File

@@ -1,41 +0,0 @@
package com.willfp.eco.core.items;
import com.willfp.eco.core.Eco;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* API to handle SNBT conversion.
*/
@ApiStatus.Internal
@Eco.HandlerComponent
public interface SNBTHandler {
/**
* Get item from SNBT.
*
* @param snbt The NBT string.
* @return The ItemStack, or null if invalid.
*/
@Nullable
ItemStack fromSNBT(@NotNull String snbt);
/**
* Convert item to SNBT.
*
* @param itemStack The item.
* @return The NBT string.
*/
@NotNull
String toSNBT(@NotNull ItemStack itemStack);
/**
* Make TestableItem from SNBT.
*
* @param snbt The NBT string.
* @return The TestableItem.
*/
@NotNull
TestableItem createTestable(@NotNull String snbt);
}

View File

@@ -9,6 +9,6 @@ import com.willfp.eco.core.EcoPlugin;
public sealed interface InjectablePlaceholder extends Placeholder permits PlayerStaticPlaceholder, StaticPlaceholder {
@Override
default EcoPlugin getPlugin() {
return Eco.getHandler().getEcoPlugin();
return Eco.get().getEcoPlugin();
}
}

View File

@@ -96,7 +96,7 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
shapedRecipe.setIngredient(character, parts.get(i).getItem().getType());
}
if (Eco.getHandler().getEcoPlugin().getConfigYml().getBool("displayed-recipes")) {
if (Eco.get().getEcoPlugin().getConfigYml().getBool("displayed-recipes")) {
ShapedRecipe displayedRecipe = new ShapedRecipe(this.getDisplayedKey(), this.getOutput());
displayedRecipe.shape("012", "345", "678");
for (int i = 0; i < 9; i++) {
@@ -124,7 +124,7 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
assert lore != null;
lore.add("");
String add = Eco.getHandler().getEcoPlugin().getLangYml().getFormattedString("multiple-in-craft");
String add = Eco.get().getEcoPlugin().getLangYml().getFormattedString("multiple-in-craft");
add = add.replace("%amount%", String.valueOf(item.getAmount()));
lore.add(add);
meta.setLore(lore);

View File

@@ -101,7 +101,7 @@ public final class ShapelessCraftingRecipe extends PluginDependent<EcoPlugin> im
shapelessRecipe.addIngredient(part.getItem().getType());
}
if (Eco.getHandler().getEcoPlugin().getConfigYml().getBool("displayed-recipes")) {
if (Eco.get().getEcoPlugin().getConfigYml().getBool("displayed-recipes")) {
ShapelessRecipe displayedRecipe = new ShapelessRecipe(this.getDisplayedKey(), this.getOutput());
for (TestableItem part : parts) {
List<TestableItem> items = new ArrayList<>();
@@ -122,7 +122,7 @@ public final class ShapelessCraftingRecipe extends PluginDependent<EcoPlugin> im
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
assert lore != null;
lore.add("");
String add = Eco.getHandler().getEcoPlugin().getLangYml().getFormattedString("multiple-in-craft");
String add = Eco.get().getEcoPlugin().getLangYml().getFormattedString("multiple-in-craft");
add = add.replace("%amount%", String.valueOf(item.getAmount()));
lore.add(add);
meta.setLore(lore);

View File

@@ -59,7 +59,7 @@ public class Paste {
* @param callback The consumer to accept the response token.
*/
public void getHastebinToken(@NotNull final Consumer<String> callback) {
Eco.getHandler().getEcoPlugin().getScheduler().runAsync(() -> {
Eco.get().getEcoPlugin().getScheduler().runAsync(() -> {
try {
byte[] postData = URLEncoder.encode(contents, StandardCharsets.UTF_8).getBytes(StandardCharsets.UTF_8);
int postDataLength = postData.length;

View File

@@ -70,7 +70,7 @@ public final class MenuUtils {
*/
@Nullable
public static Menu getOpenMenu(@NotNull final Player player) {
return Eco.getHandler().getOpenMenu(player);
return Eco.get().getOpenMenu(player);
}
private MenuUtils() {

View File

@@ -32,7 +32,7 @@ public final class NamespacedKeyUtils {
@NotNull
public static NamespacedKey create(@NotNull final String namespace,
@NotNull final String key) {
return Eco.getHandler().createNamespacedKey(
return Eco.get().createNamespacedKey(
namespace,
key
);

View File

@@ -323,7 +323,7 @@ public final class NumberUtils {
@Nullable final Player player,
@NotNull final PlaceholderInjectable context,
@NotNull final Collection<AdditionalPlayer> additionalPlayers) {
return Eco.getHandler().evaluate(expression, player, context, additionalPlayers);
return Eco.get().evaluate(expression, player, context, additionalPlayers);
}
private NumberUtils() {

View File

@@ -42,7 +42,7 @@ public final class PlayerUtils {
*/
@NotNull
public static Audience getAudience(@NotNull final Player player) {
BukkitAudiences adventure = Eco.getHandler().getAdventure();
BukkitAudiences adventure = Eco.get().getAdventure();
if (Prerequisite.HAS_PAPER.isMet()) {
if (player instanceof Audience) {
@@ -67,7 +67,7 @@ public final class PlayerUtils {
*/
@NotNull
public static Audience getAudience(@NotNull final CommandSender sender) {
BukkitAudiences adventure = Eco.getHandler().getAdventure();
BukkitAudiences adventure = Eco.get().getAdventure();
if (Prerequisite.HAS_PAPER.isMet()) {
if (sender instanceof Audience) {

View File

@@ -1,29 +1,18 @@
package com.willfp.eco.util;
import org.apache.commons.lang.Validate;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.function.Supplier;
import com.willfp.eco.core.Eco;
/**
* Utilities / API methods for the server.
*/
public final class ServerUtils {
/**
* The TPS supplier.
*/
private static Supplier<Double> tpsSupplier = null;
/**
* Get the current server TPS.
*
* @return The TPS.
*/
public static double getTps() {
Validate.notNull(tpsSupplier, "Not initialized!");
double tps = tpsSupplier.get();
double tps = Eco.get().getTPS();
if (tps > 20) {
return 20;
@@ -32,18 +21,6 @@ public final class ServerUtils {
}
}
/**
* Initialize the tps supplier function.
*
* @param function The function.
*/
@ApiStatus.Internal
public static void initialize(@NotNull final Supplier<Double> function) {
Validate.isTrue(tpsSupplier == null, "Already initialized!");
tpsSupplier = function;
}
private ServerUtils() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}

View File

@@ -17,7 +17,7 @@ public final class SkullUtils {
*/
public static void setSkullTexture(@NotNull final SkullMeta meta,
@NotNull final String base64) {
Eco.getHandler().setSkullTexture(meta, base64);
Eco.get().setSkullTexture(meta, base64);
}
/**
@@ -28,7 +28,7 @@ public final class SkullUtils {
*/
@Nullable
public static String getSkullTexture(@NotNull final SkullMeta meta) {
return Eco.getHandler().getSkullTexture(meta);
return Eco.get().getSkullTexture(meta);
}
private SkullUtils() {

View File

@@ -339,7 +339,7 @@ public final class StringUtils {
}
private static String translateMiniMessage(@NotNull final String message) {
return Eco.getHandler().formatMiniMessage(message);
return Eco.get().formatMiniMessage(message);
}
private static String translateHexColorCodes(@NotNull final String message) {