Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3341093735 | ||
|
|
714d04e48f | ||
|
|
73b7ccea3a | ||
|
|
606bf8fcd2 | ||
|
|
fbbf893d64 | ||
|
|
36001373eb | ||
|
|
9ac34288eb | ||
|
|
6345d1fe92 | ||
|
|
a7fa0ecf26 | ||
|
|
a65f16cfac | ||
|
|
49965c091b | ||
|
|
f9bc2aba99 | ||
|
|
5627582bd5 | ||
|
|
ab8065d06e | ||
|
|
444764e481 | ||
|
|
c240e94a6b | ||
|
|
9da28a1dff | ||
|
|
cf3c1f8394 | ||
|
|
f98befbdce | ||
|
|
d0d8ea07e4 | ||
|
|
109347a601 | ||
|
|
43bef762bf | ||
|
|
69a2e0e247 | ||
|
|
874a9b4f32 | ||
|
|
5690221c27 | ||
|
|
f19b143804 | ||
|
|
10a313bef5 | ||
|
|
9ae40ae09e | ||
|
|
7b4e1d8d24 | ||
|
|
7035280731 | ||
|
|
a1e3d53cd2 | ||
|
|
d7885f05c3 | ||
|
|
415c425097 | ||
|
|
cb4d992e7d | ||
|
|
cb64d088d1 | ||
|
|
bbbf19c041 | ||
|
|
61ace5c8e5 | ||
|
|
94b73ef35c | ||
|
|
5cfc2068e7 | ||
|
|
0ce7d1dd6c | ||
|
|
19eefaf879 | ||
|
|
1ebf7fb875 | ||
|
|
e8afd15d80 | ||
|
|
d024c9238e | ||
|
|
1356bd1f26 | ||
|
|
407ccca5e0 | ||
|
|
82de602d47 | ||
|
|
b0873112af | ||
|
|
3a0b81b7de | ||
|
|
5142b9ce92 | ||
|
|
9403a1cbcb | ||
|
|
e4ebea354d | ||
|
|
d32b31f1e5 | ||
|
|
384657f1dc |
@@ -51,6 +51,9 @@ allprojects {
|
||||
|
||||
// CombatLogX
|
||||
maven { url 'https://nexus.sirblobman.xyz/repository/public/' }
|
||||
|
||||
// Head Database
|
||||
maven { url 'https://mvn.intellectualsites.com/content/groups/public/' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -305,10 +305,27 @@ public abstract class EcoPlugin extends JavaPlugin {
|
||||
this.logger = Eco.getHandler().createLogger(this);
|
||||
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.getHandler().createProxyFactory(this);
|
||||
|
||||
this.langYml = new LangYml(this);
|
||||
this.configYml = new ConfigYml(this);
|
||||
this.langYml = this.createLangYml();
|
||||
this.configYml = this.createConfigYml();
|
||||
|
||||
Eco.getHandler().addNewPlugin(this);
|
||||
|
||||
/*
|
||||
The minimum eco version check was moved here because it's very common
|
||||
to add a lot of code in the constructor of plugins; meaning that the plugin
|
||||
can throw errors without it being obvious to the user that the reason is
|
||||
because they have an outdated version of eco installed.
|
||||
*/
|
||||
|
||||
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().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!");
|
||||
this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion());
|
||||
this.getLogger().severe("Download the newest version here:");
|
||||
this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW");
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -336,29 +353,22 @@ public abstract class EcoPlugin extends JavaPlugin {
|
||||
});
|
||||
}
|
||||
|
||||
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().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!");
|
||||
this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion());
|
||||
this.getLogger().severe("Download the newest version here:");
|
||||
this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW");
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
}
|
||||
|
||||
if (this.getBStatsId() != 0) {
|
||||
Eco.getHandler().registerBStats(this);
|
||||
}
|
||||
|
||||
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).collect(Collectors.toSet());
|
||||
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins())
|
||||
.map(Plugin::getName)
|
||||
.map(String::toLowerCase)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (enabledPlugins.contains("PlaceholderAPI")) {
|
||||
if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) {
|
||||
this.loadedIntegrations.add("PlaceholderAPI");
|
||||
PlaceholderManager.addIntegration(Eco.getHandler().createPAPIIntegration(this));
|
||||
}
|
||||
|
||||
this.loadIntegrationLoaders().forEach((integrationLoader -> {
|
||||
if (enabledPlugins.contains(integrationLoader.getPluginName())) {
|
||||
if (enabledPlugins.contains(integrationLoader.getPluginName().toLowerCase())) {
|
||||
this.loadedIntegrations.add(integrationLoader.getPluginName());
|
||||
integrationLoader.load();
|
||||
}
|
||||
@@ -571,6 +581,28 @@ public abstract class EcoPlugin extends JavaPlugin {
|
||||
*/
|
||||
protected abstract List<Listener> loadListeners();
|
||||
|
||||
/**
|
||||
* Useful for custom LangYml implementations.
|
||||
* <p>
|
||||
* Override if needed.
|
||||
*
|
||||
* @return lang.yml.
|
||||
*/
|
||||
protected LangYml createLangYml() {
|
||||
return new LangYml(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Useful for custom ConfigYml implementations.
|
||||
* <p>
|
||||
* Override if needed.
|
||||
*
|
||||
* @return config.yml.
|
||||
*/
|
||||
protected ConfigYml createConfigYml() {
|
||||
return new ConfigYml(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the display module for the plugin.
|
||||
*
|
||||
|
||||
@@ -13,9 +13,11 @@ import com.willfp.eco.core.gui.GUIFactory;
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
|
||||
import com.willfp.eco.core.proxy.Cleaner;
|
||||
import com.willfp.eco.core.proxy.ProxyFactory;
|
||||
import com.willfp.eco.core.requirement.RequirementFactory;
|
||||
import com.willfp.eco.core.scheduling.Scheduler;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
@@ -30,6 +32,7 @@ public interface Handler {
|
||||
* @param plugin The plugin.
|
||||
* @return The scheduler.
|
||||
*/
|
||||
@NotNull
|
||||
Scheduler createScheduler(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
@@ -38,6 +41,7 @@ public interface Handler {
|
||||
* @param plugin The plugin.
|
||||
* @return The event manager.
|
||||
*/
|
||||
@NotNull
|
||||
EventManager createEventManager(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
@@ -46,6 +50,7 @@ public interface Handler {
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
@@ -54,6 +59,7 @@ public interface Handler {
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
@@ -62,6 +68,7 @@ public interface Handler {
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
@@ -70,6 +77,7 @@ public interface Handler {
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
@@ -78,6 +86,7 @@ public interface Handler {
|
||||
* @param plugin The plugin.
|
||||
* @return The handler.
|
||||
*/
|
||||
@NotNull
|
||||
ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
@@ -86,6 +95,7 @@ public interface Handler {
|
||||
* @param plugin The plugin.
|
||||
* @return The logger.
|
||||
*/
|
||||
@NotNull
|
||||
Logger createLogger(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
@@ -94,6 +104,7 @@ public interface Handler {
|
||||
* @param plugin The plugin.
|
||||
* @return The integration.
|
||||
*/
|
||||
@NotNull
|
||||
PlaceholderIntegration createPAPIIntegration(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
@@ -102,6 +113,7 @@ public interface Handler {
|
||||
* @param plugin The plugin.
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
@@ -109,6 +121,7 @@ public interface Handler {
|
||||
*
|
||||
* @return The plugin.
|
||||
*/
|
||||
@NotNull
|
||||
EcoPlugin getEcoPlugin();
|
||||
|
||||
/**
|
||||
@@ -116,6 +129,7 @@ public interface Handler {
|
||||
*
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
ConfigFactory getConfigFactory();
|
||||
|
||||
/**
|
||||
@@ -123,6 +137,7 @@ public interface Handler {
|
||||
*
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
DropQueueFactory getDropQueueFactory();
|
||||
|
||||
/**
|
||||
@@ -130,6 +145,7 @@ public interface Handler {
|
||||
*
|
||||
* @return The factory.
|
||||
*/
|
||||
@NotNull
|
||||
GUIFactory getGUIFactory();
|
||||
|
||||
/**
|
||||
@@ -137,6 +153,7 @@ public interface Handler {
|
||||
*
|
||||
* @return The cleaner.
|
||||
*/
|
||||
@NotNull
|
||||
Cleaner getCleaner();
|
||||
|
||||
/**
|
||||
@@ -152,6 +169,7 @@ public interface Handler {
|
||||
* @param name The name.
|
||||
* @return The plugin.
|
||||
*/
|
||||
@Nullable
|
||||
EcoPlugin getPluginByName(@NotNull String name);
|
||||
|
||||
/**
|
||||
@@ -159,6 +177,7 @@ public interface Handler {
|
||||
*
|
||||
* @return A list of plugin names in lowercase.
|
||||
*/
|
||||
@NotNull
|
||||
List<String> getLoadedPlugins();
|
||||
|
||||
/**
|
||||
@@ -167,6 +186,7 @@ public interface Handler {
|
||||
* @param itemStack The base ItemStack.
|
||||
* @return The FastItemStack.
|
||||
*/
|
||||
@NotNull
|
||||
FastItemStack createFastItemStack(@NotNull ItemStack itemStack);
|
||||
|
||||
/**
|
||||
@@ -175,4 +195,11 @@ public interface Handler {
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
void registerBStats(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Get the requirement factory.
|
||||
*
|
||||
* @return The factory.
|
||||
*/
|
||||
RequirementFactory getRequirementFactory();
|
||||
}
|
||||
|
||||
@@ -9,11 +9,12 @@ import org.jetbrains.annotations.NotNull;
|
||||
*
|
||||
* @param <T> The eco plugin type.
|
||||
*/
|
||||
public abstract class PluginDependent<T extends EcoPlugin> {
|
||||
public abstract class PluginDependent<@NotNull T extends EcoPlugin> {
|
||||
/**
|
||||
* The {@link EcoPlugin} that is stored.
|
||||
*/
|
||||
@Getter(AccessLevel.PROTECTED)
|
||||
@NotNull
|
||||
private final T plugin;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.willfp.eco.core.config.json;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in the plugin's base directory (eg config.json).
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*/
|
||||
public abstract class JSONBaseConfig extends LoadableJSONConfigWrapper {
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
*/
|
||||
protected JSONBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused, updateBlacklist
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
protected JSONBaseConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
||||
configName,
|
||||
plugin,
|
||||
"",
|
||||
plugin.getClass(),
|
||||
removeUnused
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.willfp.eco.core.config.json;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.config.json.wrapper.LoadableJSONConfigWrapper;
|
||||
import com.willfp.eco.core.config.yaml.wrapper.LoadableYamlConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Config implementation for configs present in one of two places:
|
||||
* <ul>
|
||||
* <li>Plugin base directory (eg config.yml, lang.yml)</li>
|
||||
* <li>Other extension's configs</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* Automatically updates.
|
||||
*/
|
||||
public abstract class JSONExtendableConfig extends LoadableJSONConfigWrapper {
|
||||
/**
|
||||
* @param configName The name of the config
|
||||
* @param removeUnused Whether keys not present in the default config should be removed on update.
|
||||
* @param plugin The plugin.
|
||||
* @param updateBlacklist Substring of keys to not add/remove keys for.
|
||||
* @param subDirectoryPath The subdirectory path.
|
||||
* @param source The class that owns the resource.
|
||||
*/
|
||||
protected JSONExtendableConfig(@NotNull final String configName,
|
||||
final boolean removeUnused,
|
||||
@NotNull final EcoPlugin plugin,
|
||||
@NotNull final Class<?> source,
|
||||
@NotNull final String subDirectoryPath,
|
||||
@NotNull final String... updateBlacklist) {
|
||||
super(
|
||||
Eco.getHandler().getConfigFactory().createUpdatableJSONConfig(
|
||||
configName,
|
||||
plugin,
|
||||
subDirectoryPath,
|
||||
source,
|
||||
removeUnused,
|
||||
updateBlacklist
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,24 @@ public interface ConfigFactory {
|
||||
boolean removeUnused,
|
||||
@NotNull String... updateBlacklist);
|
||||
|
||||
/**
|
||||
* 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 updateBlacklist Substring of keys to not add/remove keys for.
|
||||
* @return The config implementation.
|
||||
*/
|
||||
JSONConfig createUpdatableJSONConfig(@NotNull String configName,
|
||||
@NotNull EcoPlugin plugin,
|
||||
@NotNull String subDirectoryPath,
|
||||
@NotNull Class<?> source,
|
||||
boolean removeUnused,
|
||||
@NotNull String... updateBlacklist);
|
||||
|
||||
/**
|
||||
* JSON loadable config.
|
||||
*
|
||||
|
||||
@@ -1,22 +1,12 @@
|
||||
package com.willfp.eco.core.display;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Utility class to manage client-side item display.
|
||||
*/
|
||||
@@ -28,29 +18,9 @@ public class Display {
|
||||
public static final String PREFIX = "§z";
|
||||
|
||||
/**
|
||||
* All registered display modules.
|
||||
* The display handler.
|
||||
*/
|
||||
private static final Map<DisplayPriority, List<DisplayModule>> MODULES = new HashMap<>();
|
||||
|
||||
/**
|
||||
* NamespacedKey for finalizing.
|
||||
*/
|
||||
private static NamespacedKey finalizeKey = null;
|
||||
|
||||
/**
|
||||
* Register display module.
|
||||
*
|
||||
* @param module The module.
|
||||
*/
|
||||
public void registerDisplayModule(@NotNull final DisplayModule module) {
|
||||
List<DisplayModule> modules = MODULES.get(module.getPriority());
|
||||
|
||||
modules.removeIf(module1 -> module1.getPluginName().equalsIgnoreCase(module.getPluginName()));
|
||||
|
||||
modules.add(module);
|
||||
|
||||
MODULES.put(module.getPriority(), modules);
|
||||
}
|
||||
public static DisplayHandler handler = null;
|
||||
|
||||
/**
|
||||
* Display on ItemStacks.
|
||||
@@ -71,35 +41,7 @@ public class Display {
|
||||
*/
|
||||
public ItemStack display(@NotNull final ItemStack itemStack,
|
||||
@Nullable final Player player) {
|
||||
Map<String, Object[]> pluginVarArgs = new HashMap<>();
|
||||
|
||||
for (DisplayPriority priority : DisplayPriority.values()) {
|
||||
List<DisplayModule> modules = MODULES.get(priority);
|
||||
for (DisplayModule module : modules) {
|
||||
pluginVarArgs.put(module.getPluginName(), module.generateVarArgs(itemStack));
|
||||
}
|
||||
}
|
||||
|
||||
revert(itemStack);
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
|
||||
if (meta == null) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
for (DisplayPriority priority : DisplayPriority.values()) {
|
||||
List<DisplayModule> modules = MODULES.get(priority);
|
||||
for (DisplayModule module : modules) {
|
||||
Object[] varargs = pluginVarArgs.get(module.getPluginName());
|
||||
module.display(itemStack, varargs);
|
||||
if (player != null) {
|
||||
module.display(itemStack, player, varargs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
return handler.display(itemStack, player);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,31 +73,7 @@ public class Display {
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
public ItemStack revert(@NotNull final ItemStack itemStack) {
|
||||
if (Display.isFinalized(itemStack)) {
|
||||
unfinalize(itemStack);
|
||||
}
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
|
||||
if (meta == null) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
List<String> lore = meta.getLore();
|
||||
|
||||
if (lore != null && lore.removeIf(line -> line.startsWith(Display.PREFIX))) { // only apply lore modification if needed
|
||||
meta.setLore(lore);
|
||||
itemStack.setItemMeta(meta);
|
||||
}
|
||||
|
||||
for (DisplayPriority priority : DisplayPriority.values()) {
|
||||
List<DisplayModule> modules = MODULES.get(priority);
|
||||
for (DisplayModule module : modules) {
|
||||
module.revert(itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
return itemStack;
|
||||
return handler.revert(itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,21 +83,7 @@ public class Display {
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
public ItemStack finalize(@NotNull final ItemStack itemStack) {
|
||||
Validate.notNull(finalizeKey, "Key cannot be null!");
|
||||
|
||||
if (itemStack.getType().getMaxStackSize() > 1) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
if (meta == null) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
container.set(finalizeKey, PersistentDataType.INTEGER, 1);
|
||||
itemStack.setItemMeta(meta);
|
||||
return itemStack;
|
||||
return handler.finalize(itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,18 +93,7 @@ public class Display {
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
public ItemStack unfinalize(@NotNull final ItemStack itemStack) {
|
||||
Validate.notNull(finalizeKey, "Key cannot be null!");
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
|
||||
if (meta == null) {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
container.remove(finalizeKey);
|
||||
itemStack.setItemMeta(meta);
|
||||
return itemStack;
|
||||
return handler.unfinalize(itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,31 +103,62 @@ public class Display {
|
||||
* @return If finalized.
|
||||
*/
|
||||
public boolean isFinalized(@NotNull final ItemStack itemStack) {
|
||||
Validate.notNull(finalizeKey, "Key cannot be null!");
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
|
||||
if (meta == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
return container.has(finalizeKey, PersistentDataType.INTEGER);
|
||||
return handler.isFinalized(itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set key to be used for finalization.
|
||||
* Register a new display module.
|
||||
*
|
||||
* @param finalizeKey The key.
|
||||
* @param module The module.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void setFinalizeKey(@NotNull final NamespacedKey finalizeKey) {
|
||||
Display.finalizeKey = finalizeKey;
|
||||
public void registerDisplayModule(@NotNull final DisplayModule module) {
|
||||
handler.registerDisplayModule(module);
|
||||
}
|
||||
|
||||
static {
|
||||
for (DisplayPriority priority : DisplayPriority.values()) {
|
||||
MODULES.put(priority, new ArrayList<>());
|
||||
/**
|
||||
* Initialize the display system.
|
||||
*
|
||||
* @param handler The handler.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public static void init(@NotNull final DisplayHandler handler) {
|
||||
if (Display.handler != null) {
|
||||
throw new IllegalArgumentException("Already Initialized!");
|
||||
}
|
||||
Display.handler = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extremely janky method - also internal, so don't use it. <b>This method is
|
||||
* NOT part of the API and may be removed at any time!</b>
|
||||
* <p>
|
||||
* This calls a display module with the specified parameters, now
|
||||
* you might ask why I need a static java method when the DisplayHandler
|
||||
* implementation could just call it itself? Well, kotlin doesn't really
|
||||
* like dealing with vararg ambiguity, and so while kotlin can't figure out
|
||||
* what is and isn't a vararg when I call display with a player, java can.
|
||||
* <p>
|
||||
* Because of this, I need to have this part of the code in java.
|
||||
*
|
||||
* <b>Don't call this method as part of your plugins!</b>
|
||||
* <p>
|
||||
* No, seriously - don't. This skips a bunch of checks and you'll almost
|
||||
* definitely break something.
|
||||
*
|
||||
* @param module The display module.
|
||||
* @param itemStack The ItemStack.
|
||||
* @param player The player.
|
||||
* @param args The args.
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:FinalParameters")
|
||||
@ApiStatus.Internal
|
||||
public static void callDisplayModule(@NotNull final DisplayModule module,
|
||||
@NotNull final ItemStack itemStack,
|
||||
@Nullable final Player player,
|
||||
@NotNull final Object... args) {
|
||||
module.display(itemStack, args);
|
||||
if (player != null) {
|
||||
module.display(itemStack, player, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.willfp.eco.core.display;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Interface for display implementations.
|
||||
*/
|
||||
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 final ItemStack itemStack,
|
||||
@Nullable final Player player);
|
||||
|
||||
/**
|
||||
* Revert on ItemStacks.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack revert(@NotNull final ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Finalize an ItemStacks.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack finalize(@NotNull final ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* Unfinalize an ItemStacks.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @return The ItemStack.
|
||||
*/
|
||||
ItemStack unfinalize(@NotNull final ItemStack itemStack);
|
||||
|
||||
/**
|
||||
* If an item is finalized.
|
||||
*
|
||||
* @param itemStack The item.
|
||||
* @return If finalized.
|
||||
*/
|
||||
boolean isFinalized(@NotNull final ItemStack itemStack);
|
||||
}
|
||||
@@ -36,8 +36,8 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
||||
* @param itemStack The item.
|
||||
* @param args Optional args for display.
|
||||
*/
|
||||
protected void display(@NotNull final ItemStack itemStack,
|
||||
@NotNull final Object... args) {
|
||||
public void display(@NotNull final ItemStack itemStack,
|
||||
@NotNull final Object... args) {
|
||||
// Technically optional.
|
||||
}
|
||||
|
||||
@@ -48,9 +48,9 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
||||
* @param player The player.
|
||||
* @param args Optional args for display.
|
||||
*/
|
||||
protected void display(@NotNull final ItemStack itemStack,
|
||||
@Nullable final Player player,
|
||||
@NotNull final Object... args) {
|
||||
public void display(@NotNull final ItemStack itemStack,
|
||||
@Nullable final Player player,
|
||||
@NotNull final Object... args) {
|
||||
// Technically optional.
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
||||
*
|
||||
* @param itemStack The item.
|
||||
*/
|
||||
protected void revert(@NotNull final ItemStack itemStack) {
|
||||
public void revert(@NotNull final ItemStack itemStack) {
|
||||
// Technically optional.
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
|
||||
* @param itemStack The itemStack.
|
||||
* @return The plugin-specific varargs.
|
||||
*/
|
||||
protected Object[] generateVarArgs(@NotNull final ItemStack itemStack) {
|
||||
public Object[] generateVarArgs(@NotNull final ItemStack itemStack) {
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.willfp.eco.core.integrations.customitems;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
|
||||
/**
|
||||
* Wrapper class for custom item integrations.
|
||||
*/
|
||||
public interface CustomItemsWrapper {
|
||||
public interface CustomItemsWrapper extends Integration {
|
||||
/**
|
||||
* Register all the custom items for a specific plugin into eco.
|
||||
*
|
||||
|
||||
@@ -5,7 +5,9 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -18,7 +20,7 @@ public class PlaceholderManager {
|
||||
/**
|
||||
* All registered placeholders.
|
||||
*/
|
||||
private static final Set<PlaceholderEntry> REGISTERED_PLACEHOLDERS = new HashSet<>();
|
||||
private static final Map<String, PlaceholderEntry> REGISTERED_PLACEHOLDERS = new HashMap<>();
|
||||
|
||||
/**
|
||||
* All registered placeholder integrations.
|
||||
@@ -41,8 +43,8 @@ public class PlaceholderManager {
|
||||
* @param expansion The {@link PlaceholderEntry} to register.
|
||||
*/
|
||||
public static void registerPlaceholder(@NotNull final PlaceholderEntry expansion) {
|
||||
REGISTERED_PLACEHOLDERS.removeIf(placeholderEntry -> placeholderEntry.getIdentifier().equalsIgnoreCase(expansion.getIdentifier()));
|
||||
REGISTERED_PLACEHOLDERS.add(expansion);
|
||||
REGISTERED_PLACEHOLDERS.remove(expansion.getIdentifier());
|
||||
REGISTERED_PLACEHOLDERS.put(expansion.getIdentifier(), expansion);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,14 +56,15 @@ public class PlaceholderManager {
|
||||
*/
|
||||
public static String getResult(@Nullable final Player player,
|
||||
@NotNull final String identifier) {
|
||||
Optional<PlaceholderEntry> matching = REGISTERED_PLACEHOLDERS.stream().filter(expansion -> expansion.getIdentifier().equalsIgnoreCase(identifier)).findFirst();
|
||||
if (matching.isEmpty()) {
|
||||
PlaceholderEntry entry = REGISTERED_PLACEHOLDERS.get(identifier.toLowerCase());
|
||||
if (entry == null) {
|
||||
return "";
|
||||
}
|
||||
PlaceholderEntry entry = matching.get();
|
||||
|
||||
if (player == null && entry.requiresPlayer()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return entry.getResult(player);
|
||||
}
|
||||
|
||||
@@ -74,8 +77,10 @@ public class PlaceholderManager {
|
||||
*/
|
||||
public static String translatePlaceholders(@NotNull final String text,
|
||||
@Nullable final Player player) {
|
||||
AtomicReference<String> translatedReference = new AtomicReference<>(text);
|
||||
REGISTERED_INTEGRATIONS.forEach(placeholderIntegration -> translatedReference.set(placeholderIntegration.translate(translatedReference.get(), player)));
|
||||
return translatedReference.get();
|
||||
String processed = text;
|
||||
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
|
||||
processed = integration.translate(processed, player);
|
||||
}
|
||||
return processed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.willfp.eco.core.integrations.shop;
|
||||
|
||||
import com.willfp.eco.core.integrations.Integration;
|
||||
|
||||
/**
|
||||
* Wrapper class for shop integrations.
|
||||
*/
|
||||
public interface ShopWrapper {
|
||||
public interface ShopWrapper extends Integration {
|
||||
/**
|
||||
* Register eco item provider for shop plugins.
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.willfp.eco.core.items;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -47,6 +50,12 @@ public class CustomItem implements TestableItem {
|
||||
this.key = key;
|
||||
this.test = test;
|
||||
this.item = item;
|
||||
|
||||
Eco.getHandler().getEcoPlugin().getScheduler().runLater(() -> {
|
||||
if (!matches(getItem())) {
|
||||
Bukkit.getLogger().severe("Item with key " + key + " is invalid!");
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.willfp.eco.core.items;
|
||||
|
||||
import com.willfp.eco.core.items.args.LookupArgParser;
|
||||
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
|
||||
import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
|
||||
import com.willfp.eco.core.recipe.parts.ModifiedTestableItem;
|
||||
@@ -8,18 +9,19 @@ import com.willfp.eco.util.NamespacedKeyUtils;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Class to manage all custom and vanilla items.
|
||||
@@ -29,19 +31,33 @@ public final class Items {
|
||||
/**
|
||||
* All recipe parts.
|
||||
*/
|
||||
private static final Map<NamespacedKey, CustomItem> REGISTRY = new HashMap<>();
|
||||
private static final Map<NamespacedKey, CustomItem> REGISTRY = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Register a new recipe part.
|
||||
* All recipe parts.
|
||||
*/
|
||||
private static final List<LookupArgParser> ARG_PARSERS = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Register a new custom item.
|
||||
*
|
||||
* @param key The key of the recipe part.
|
||||
* @param part The recipe part.
|
||||
* @param key The key of the item.
|
||||
* @param part The item.
|
||||
*/
|
||||
public void registerCustomItem(@NotNull final NamespacedKey key,
|
||||
@NotNull final CustomItem part) {
|
||||
REGISTRY.put(key, part);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new arg parser.
|
||||
*
|
||||
* @param parser The parser.
|
||||
*/
|
||||
public void registerArgParser(@NotNull final LookupArgParser parser) {
|
||||
ARG_PARSERS.add(parser);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item.
|
||||
*
|
||||
@@ -52,12 +68,27 @@ public final class Items {
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup item from string.
|
||||
* This is the backbone of the entire eco item system.
|
||||
* <p>
|
||||
* Used for recipes.
|
||||
* You can lookup a TestableItem for any material, custom item,
|
||||
* or item in general, and it will return it with any modifiers
|
||||
* passed as parameters. This includes stack size (item amount)
|
||||
* and enchantments that should be present on the item.
|
||||
* <p>
|
||||
* If you want to get an ItemStack instance from this, then just call
|
||||
* {@link TestableItem#getItem()}.
|
||||
* <p>
|
||||
* The advantages of the testable item system are that there is the inbuilt
|
||||
* {@link TestableItem#matches(ItemStack)} - this allows to check if any item
|
||||
* is that testable item; which may sound negligible but actually it allows for
|
||||
* much more power an flexibility. For example, you can have an item with an
|
||||
* extra metadata tag, extra lore lines, different display name - and it
|
||||
* will still work as long as the test passes. This is very important
|
||||
* for custom crafting recipes where other plugins may add metadata
|
||||
* values or the play may rename the item.
|
||||
*
|
||||
* @param key The string to test.
|
||||
* @return The found testable item, or an empty item if not found.
|
||||
* @param key The lookup string.
|
||||
* @return The testable item, or an {@link EmptyTestableItem}.
|
||||
*/
|
||||
public TestableItem lookup(@NotNull final String key) {
|
||||
if (key.contains("?")) {
|
||||
@@ -79,6 +110,8 @@ public final class Items {
|
||||
|
||||
TestableItem item = null;
|
||||
|
||||
int stackAmount = 1;
|
||||
|
||||
String[] split = args[0].toLowerCase().split(":");
|
||||
|
||||
if (split.length == 1) {
|
||||
@@ -92,90 +125,87 @@ public final class Items {
|
||||
if (split.length == 2) {
|
||||
CustomItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1]));
|
||||
|
||||
/*
|
||||
Legacy id:amount format
|
||||
This has been superseded by id amount
|
||||
*/
|
||||
if (part == null) {
|
||||
Material material = Material.getMaterial(split[0].toUpperCase());
|
||||
if (material == null || material == Material.AIR) {
|
||||
return new EmptyTestableItem();
|
||||
}
|
||||
item = new TestableStack(new MaterialTestableItem(material), Integer.parseInt(split[1]));
|
||||
item = new MaterialTestableItem(material);
|
||||
stackAmount = Integer.parseInt(split[1]);
|
||||
} else {
|
||||
item = part;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Legacy namespace:id:amount format
|
||||
This has been superseded by namespace:id amount
|
||||
*/
|
||||
if (split.length == 3) {
|
||||
CustomItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1]));
|
||||
item = part == null ? new EmptyTestableItem() : new TestableStack(part, Integer.parseInt(split[2]));
|
||||
if (part == null) {
|
||||
return new EmptyTestableItem();
|
||||
}
|
||||
item = part;
|
||||
stackAmount = Integer.parseInt(split[2]);
|
||||
}
|
||||
|
||||
boolean usingNewStackFormat = false;
|
||||
|
||||
if (args.length >= 2) {
|
||||
try {
|
||||
stackAmount = Integer.parseInt(args[1]);
|
||||
usingNewStackFormat = true;
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
// Marked as redundant but i am covering all bases here
|
||||
if (item == null || item instanceof EmptyTestableItem) {
|
||||
return new EmptyTestableItem();
|
||||
}
|
||||
|
||||
String[] enchantArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||
|
||||
Map<Enchantment, Integer> requiredEnchantments = new HashMap<>();
|
||||
|
||||
for (String enchantArg : enchantArgs) {
|
||||
String[] enchantArgSplit = enchantArg.split(":");
|
||||
|
||||
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(enchantArgSplit[0].toLowerCase()));
|
||||
int level = Integer.parseInt(enchantArgSplit[1]);
|
||||
|
||||
requiredEnchantments.put(enchantment, level);
|
||||
}
|
||||
|
||||
if (requiredEnchantments.isEmpty()) {
|
||||
return item;
|
||||
}
|
||||
|
||||
ItemStack example = item.getItem();
|
||||
ItemMeta meta = example.getItemMeta();
|
||||
assert meta != null;
|
||||
|
||||
if (example.getItemMeta() instanceof EnchantmentStorageMeta storageMeta) {
|
||||
requiredEnchantments.forEach((enchantment, integer) -> storageMeta.addStoredEnchant(enchantment, integer, true));
|
||||
example.setItemMeta(storageMeta);
|
||||
} else {
|
||||
ItemMeta meta = example.getItemMeta();
|
||||
assert meta != null;
|
||||
requiredEnchantments.forEach((enchantment, integer) -> meta.addEnchant(enchantment, integer, true));
|
||||
example.setItemMeta(meta);
|
||||
String[] modifierArgs = Arrays.copyOfRange(args, usingNewStackFormat ? 2 : 1, args.length);
|
||||
|
||||
List<Predicate<ItemStack>> predicates = new ArrayList<>();
|
||||
|
||||
for (LookupArgParser argParser : ARG_PARSERS) {
|
||||
Predicate<ItemStack> predicate = argParser.parseArguments(modifierArgs, meta);
|
||||
if (predicate != null) {
|
||||
predicates.add(argParser.parseArguments(modifierArgs, meta));
|
||||
}
|
||||
}
|
||||
|
||||
return new ModifiedTestableItem(
|
||||
item,
|
||||
itemStack -> {
|
||||
if (!itemStack.hasItemMeta()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
|
||||
assert meta != null;
|
||||
|
||||
if (meta instanceof EnchantmentStorageMeta storageMeta) {
|
||||
for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
|
||||
if (!storageMeta.hasStoredEnchant(entry.getKey())) {
|
||||
return false;
|
||||
}
|
||||
if (storageMeta.getStoredEnchantLevel(entry.getKey()) < entry.getValue()) {
|
||||
example.setItemMeta(meta);
|
||||
if (!predicates.isEmpty()) {
|
||||
item = new ModifiedTestableItem(
|
||||
item,
|
||||
test -> {
|
||||
for (Predicate<ItemStack> predicate : predicates) {
|
||||
if (!predicate.test(test)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
|
||||
if (!meta.hasEnchant(entry.getKey())) {
|
||||
return false;
|
||||
}
|
||||
if (meta.getEnchantLevel(entry.getKey()) < entry.getValue()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
example
|
||||
);
|
||||
return true;
|
||||
},
|
||||
example
|
||||
);
|
||||
}
|
||||
|
||||
if (stackAmount <= 1) {
|
||||
return item;
|
||||
} else {
|
||||
return new TestableStack(item, stackAmount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.willfp.eco.core.items.args;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Parses enchantment arguments.
|
||||
*/
|
||||
public class EnchantmentArgParser implements LookupArgParser {
|
||||
@Override
|
||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
@NotNull final ItemMeta meta) {
|
||||
Map<Enchantment, Integer> requiredEnchantments = new HashMap<>();
|
||||
|
||||
for (String enchantArg : args) {
|
||||
String[] enchantArgSplit = enchantArg.split(":");
|
||||
|
||||
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(enchantArgSplit[0].toLowerCase()));
|
||||
if (enchantment == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (enchantArgSplit.length < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int level = Integer.parseInt(enchantArgSplit[1]);
|
||||
|
||||
requiredEnchantments.put(enchantment, level);
|
||||
}
|
||||
|
||||
if (requiredEnchantments.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (meta instanceof EnchantmentStorageMeta storageMeta) {
|
||||
requiredEnchantments.forEach((enchantment, integer) -> storageMeta.addStoredEnchant(enchantment, integer, true));
|
||||
} else {
|
||||
requiredEnchantments.forEach((enchantment, integer) -> meta.addEnchant(enchantment, integer, true));
|
||||
}
|
||||
|
||||
return test -> {
|
||||
if (!test.hasItemMeta()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemMeta testMeta = test.getItemMeta();
|
||||
|
||||
assert testMeta != null;
|
||||
|
||||
if (testMeta instanceof EnchantmentStorageMeta storageMeta) {
|
||||
for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
|
||||
if (!storageMeta.hasStoredEnchant(entry.getKey())) {
|
||||
return false;
|
||||
}
|
||||
if (storageMeta.getStoredEnchantLevel(entry.getKey()) < entry.getValue()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
|
||||
if (!testMeta.hasEnchant(entry.getKey())) {
|
||||
return false;
|
||||
}
|
||||
if (testMeta.getEnchantLevel(entry.getKey()) < entry.getValue()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.willfp.eco.core.items.args;
|
||||
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* An argument parser should generate the predicate as well
|
||||
* as modify the ItemMeta for {@link TestableItem#getItem()}.
|
||||
*/
|
||||
public interface LookupArgParser {
|
||||
/**
|
||||
* Parse the arguments.
|
||||
*
|
||||
* @param args The arguments.
|
||||
* @param meta The ItemMeta to modify.
|
||||
* @return The predicate test to apply to the modified item.
|
||||
*/
|
||||
@Nullable Predicate<ItemStack> parseArguments(@NotNull String[] args,
|
||||
@NotNull ItemMeta meta);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.willfp.eco.core.items.args;
|
||||
|
||||
import com.willfp.eco.util.SkullUtils;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Parse skull textures.
|
||||
*/
|
||||
public class TextureArgParser implements LookupArgParser {
|
||||
@Override
|
||||
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
|
||||
@NotNull final ItemMeta meta) {
|
||||
String skullTexture = null;
|
||||
|
||||
for (String arg : args) {
|
||||
String[] argSplit = arg.split(":");
|
||||
if (!argSplit[0].equalsIgnoreCase("texture")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (argSplit.length < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
skullTexture = argSplit[1];
|
||||
}
|
||||
|
||||
if (meta instanceof SkullMeta skullMeta && skullTexture != null) {
|
||||
SkullUtils.setSkullTexture(skullMeta, skullTexture);
|
||||
}
|
||||
|
||||
if (skullTexture == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String finalSkullTexture = skullTexture;
|
||||
return test -> {
|
||||
if (!test.hasItemMeta()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemMeta testMeta = test.getItemMeta();
|
||||
|
||||
assert testMeta != null;
|
||||
|
||||
if (testMeta instanceof SkullMeta skullMeta && finalSkullTexture != null) {
|
||||
return finalSkullTexture.equalsIgnoreCase(SkullUtils.getSkullTexture(skullMeta));
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.willfp.eco.core.recipe.parts;
|
||||
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -23,6 +24,8 @@ public class MaterialTestableItem implements TestableItem {
|
||||
* @param material The material.
|
||||
*/
|
||||
public MaterialTestableItem(@NotNull final Material material) {
|
||||
Validate.isTrue(material != Material.AIR, "You can't have air as the type!");
|
||||
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.willfp.eco.core.recipe.parts;
|
||||
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
package com.willfp.eco.core.recipe.parts;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Stacks of items.
|
||||
*/
|
||||
@@ -36,7 +31,8 @@ public class TestableStack implements TestableItem {
|
||||
*/
|
||||
public TestableStack(@NotNull final TestableItem item,
|
||||
final int amount) {
|
||||
Validate.isTrue(!(item instanceof TestableStack));
|
||||
Validate.isTrue(!(item instanceof TestableStack), "You can't stack a stack!");
|
||||
Validate.isTrue(!(item instanceof EmptyTestableItem), "You can't stack air!");
|
||||
|
||||
this.handle = item;
|
||||
this.amount = amount;
|
||||
@@ -56,19 +52,7 @@ public class TestableStack implements TestableItem {
|
||||
@Override
|
||||
public ItemStack getItem() {
|
||||
ItemStack temp = handle.getItem().clone();
|
||||
ItemMeta meta = temp.getItemMeta();
|
||||
assert meta != null;
|
||||
|
||||
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
|
||||
assert lore != null;
|
||||
lore.add("");
|
||||
String add = Eco.getHandler().getEcoPlugin().getLangYml().getString("multiple-in-craft");
|
||||
add = add.replace("%amount%", String.valueOf(amount));
|
||||
lore.add(add);
|
||||
meta.setLore(lore);
|
||||
temp.setItemMeta(meta);
|
||||
temp.setAmount(amount);
|
||||
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
package com.willfp.eco.core.recipe.recipes;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import com.willfp.eco.core.PluginDependent;
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import com.willfp.eco.core.recipe.Recipes;
|
||||
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
|
||||
import com.willfp.eco.core.recipe.parts.TestableStack;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.RecipeChoice;
|
||||
import org.bukkit.inventory.ShapedRecipe;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -79,6 +82,10 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
|
||||
ShapedRecipe shapedRecipe = new ShapedRecipe(this.getKey(), this.getOutput());
|
||||
shapedRecipe.shape("012", "345", "678");
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (parts.get(i) instanceof EmptyTestableItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char character = String.valueOf(i).toCharArray()[0];
|
||||
shapedRecipe.setIngredient(character, parts.get(i).getItem().getType());
|
||||
}
|
||||
@@ -86,8 +93,28 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
|
||||
ShapedRecipe displayedRecipe = new ShapedRecipe(this.getDisplayedKey(), this.getOutput());
|
||||
displayedRecipe.shape("012", "345", "678");
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (parts.get(i) instanceof EmptyTestableItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char character = String.valueOf(i).toCharArray()[0];
|
||||
displayedRecipe.setIngredient(character, new RecipeChoice.ExactChoice(parts.get(i).getItem()));
|
||||
ItemStack item = parts.get(i).getItem();
|
||||
|
||||
if (parts.get(i) instanceof TestableStack) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
assert meta != null;
|
||||
|
||||
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
|
||||
assert lore != null;
|
||||
lore.add("");
|
||||
String add = Eco.getHandler().getEcoPlugin().getLangYml().getString("multiple-in-craft");
|
||||
add = add.replace("%amount%", String.valueOf(item.getAmount()));
|
||||
lore.add(add);
|
||||
meta.setLore(lore);
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
displayedRecipe.setIngredient(character, new RecipeChoice.ExactChoice(item));
|
||||
}
|
||||
|
||||
Bukkit.getServer().addRecipe(shapedRecipe);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.willfp.eco.core.requirement;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A requirement is a defined goal that a player must meet.
|
||||
*/
|
||||
public abstract class Requirement {
|
||||
/**
|
||||
* Create a new requirement.
|
||||
*/
|
||||
protected Requirement() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the player meets the requirement.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param args The arguments.
|
||||
* @return The requirement.
|
||||
*/
|
||||
public abstract boolean doesPlayerMeet(@NotNull Player player,
|
||||
@NotNull List<String> args);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.willfp.eco.core.requirement;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Interface for internal requirement factory implementations.
|
||||
*/
|
||||
public interface RequirementFactory {
|
||||
/**
|
||||
* Create a requirement.
|
||||
*
|
||||
* @param name The name.
|
||||
* @return The requirement returned for the name.
|
||||
* Will return a requirement that is always true if not found.
|
||||
*/
|
||||
Requirement create(@NotNull String name);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.willfp.eco.core.requirement;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Contains methods and fields pertaining to requirements.
|
||||
*/
|
||||
@UtilityClass
|
||||
public class Requirements {
|
||||
/**
|
||||
* Requires a player to have a permission.
|
||||
*/
|
||||
public static final Requirement HAS_PERMISSION = Eco.getHandler().getRequirementFactory().create("has-permission");
|
||||
|
||||
/**
|
||||
* Placeholder equals value.
|
||||
*/
|
||||
public static final Requirement PLACEHOLDER_EQUALS = Eco.getHandler().getRequirementFactory().create("placeholder-equals");
|
||||
|
||||
/**
|
||||
* Numeric placeholder greater than value.
|
||||
*/
|
||||
public static final Requirement PLACEHOLDER_GREATER_THAN = Eco.getHandler().getRequirementFactory().create("placeholder-greater-than");
|
||||
|
||||
/**
|
||||
* Numeric placeholder less than value.
|
||||
*/
|
||||
public static final Requirement PLACEHOLDER_LESS_THAN = Eco.getHandler().getRequirementFactory().create("placeholder-less-than");
|
||||
|
||||
/**
|
||||
* Get Requirements matching ID.
|
||||
*
|
||||
* @param name The ID to search for.
|
||||
* @return The matching Requirements.
|
||||
*/
|
||||
public static Requirement getByID(@NotNull final String name) {
|
||||
return Eco.getHandler().getRequirementFactory().create(name);
|
||||
}
|
||||
}
|
||||
@@ -38,4 +38,26 @@ public class Pair<A, B> {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
/**
|
||||
* component1 exists to allow a pair to be destructured by kotlin.
|
||||
* The default kotlin pair already has this, however there is no default
|
||||
* pair in java so this exists for parity.
|
||||
*
|
||||
* @return First.
|
||||
*/
|
||||
public A component1() {
|
||||
return first;
|
||||
}
|
||||
|
||||
/**
|
||||
* component2 exists to allow a pair to be destructured by kotlin.
|
||||
* The default kotlin pair already has this, however there is no default
|
||||
* pair in java so this exists for parity.
|
||||
*
|
||||
* @return First.
|
||||
*/
|
||||
public B component2() {
|
||||
return second;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,4 +34,15 @@ public class Triplet<A, B, C> extends Pair<A, B> {
|
||||
|
||||
this.third = third;
|
||||
}
|
||||
|
||||
/**
|
||||
* component3 exists to allow a pair to be destructured by kotlin.
|
||||
* The default kotlin pair already has this, however there is no default
|
||||
* pair in java so this exists for parity.
|
||||
*
|
||||
* @return First.
|
||||
*/
|
||||
public C component3() {
|
||||
return third;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ public class ArrowUtils {
|
||||
* Get the bow from an arrow.
|
||||
*
|
||||
* @param arrow The arrow.
|
||||
* @return The bow.
|
||||
* @return The bow, or null if no bow.
|
||||
*/
|
||||
@Nullable
|
||||
public ItemStack getBow(@NotNull final Arrow arrow) {
|
||||
|
||||
@@ -63,6 +63,7 @@ public class BlockUtils {
|
||||
* @param limit The maximum size of vein to return.
|
||||
* @return A set of all {@link Block}s.
|
||||
*/
|
||||
@NotNull
|
||||
public Set<Block> getVein(@NotNull final Block start,
|
||||
@NotNull final List<Material> allowedMaterials,
|
||||
final int limit) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.willfp.eco.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -10,18 +11,37 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
@UtilityClass
|
||||
public class LightningUtils {
|
||||
|
||||
/**
|
||||
* Strike lightning on player without fire.
|
||||
*
|
||||
* @param victim The entity to smite.
|
||||
* @param damage The damage to deal.
|
||||
* @param silent If the lightning sound should be played locally
|
||||
*/
|
||||
public void strike(@NotNull final LivingEntity victim,
|
||||
final double damage,
|
||||
final boolean silent) {
|
||||
Location loc = victim.getLocation();
|
||||
|
||||
if (silent) {
|
||||
victim.getWorld().spigot().strikeLightningEffect(loc, true);
|
||||
victim.getWorld().playSound(loc, Sound.ENTITY_LIGHTNING_BOLT_IMPACT, 1, 1);
|
||||
} else {
|
||||
victim.getWorld().strikeLightningEffect(loc);
|
||||
}
|
||||
|
||||
victim.damage(damage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strike lightning on a victim without fire.
|
||||
*
|
||||
* @param victim The entity to smite.
|
||||
* @param damage The damage to deal.
|
||||
*/
|
||||
public void strike(@NotNull final LivingEntity victim,
|
||||
final double damage) {
|
||||
Location loc = victim.getLocation();
|
||||
|
||||
victim.getWorld().strikeLightningEffect(loc);
|
||||
|
||||
victim.damage(damage);
|
||||
strike(victim, damage, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -18,8 +20,9 @@ public class ListUtils {
|
||||
* @param <T> The type of the object stored in the list.
|
||||
* @return The list, filled will null objects.
|
||||
*/
|
||||
public <T> List<List<T>> create2DList(final int rows,
|
||||
final int columns) {
|
||||
@NotNull
|
||||
public <@Nullable T> List<List<T>> create2DList(final int rows,
|
||||
final int columns) {
|
||||
List<List<T>> list = new ArrayList<>(rows);
|
||||
while (list.size() < rows) {
|
||||
List<T> row = new ArrayList<>(columns);
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.willfp.eco.util;
|
||||
|
||||
import com.willfp.eco.core.tuples.Pair;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for menus.
|
||||
@@ -14,6 +15,7 @@ public class MenuUtils {
|
||||
* @param slot The slot.
|
||||
* @return The pair of row and columns.
|
||||
*/
|
||||
@NotNull
|
||||
public Pair<Integer, Integer> convertSlotToRowColumn(final int slot) {
|
||||
int row = Math.floorDiv(slot, 9);
|
||||
int column = slot - row * 9;
|
||||
|
||||
@@ -17,6 +17,7 @@ public class NamespacedKeyUtils {
|
||||
* @param string The string.
|
||||
* @return The key.
|
||||
*/
|
||||
@NotNull
|
||||
public NamespacedKey createEcoKey(@NotNull final String string) {
|
||||
return Objects.requireNonNull(NamespacedKey.fromString("eco:" + string));
|
||||
}
|
||||
@@ -28,6 +29,7 @@ public class NamespacedKeyUtils {
|
||||
* @param key The key.
|
||||
* @return The key.
|
||||
*/
|
||||
@NotNull
|
||||
public NamespacedKey create(@NotNull final String namespace,
|
||||
@NotNull final String key) {
|
||||
return Objects.requireNonNull(NamespacedKey.fromString(namespace + ":" + key));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import lombok.experimental.NonFinal;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -109,6 +110,7 @@ public class NumberUtils {
|
||||
* @param number The number to convert.
|
||||
* @return The number, converted to a roman numeral.
|
||||
*/
|
||||
@NotNull
|
||||
public String toNumeral(final int number) {
|
||||
if (number >= 1 && number <= 4096) {
|
||||
int l = NUMERALS.floorKey(number);
|
||||
@@ -199,6 +201,7 @@ public class NumberUtils {
|
||||
* @param toFormat The number to format.
|
||||
* @return Formatted.
|
||||
*/
|
||||
@NotNull
|
||||
public String format(final double toFormat) {
|
||||
DecimalFormat df = new DecimalFormat("0.00");
|
||||
String formatted = df.format(toFormat);
|
||||
|
||||
@@ -5,8 +5,10 @@ import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for player heads.
|
||||
@@ -23,6 +25,11 @@ public class SkullUtils {
|
||||
*/
|
||||
private BiConsumer<SkullMeta, String> metaSetConsumer = null;
|
||||
|
||||
/**
|
||||
* The meta get function.
|
||||
*/
|
||||
private Function<SkullMeta, String> metaGetConsumer = null;
|
||||
|
||||
/**
|
||||
* Set the texture of a skull from base64.
|
||||
*
|
||||
@@ -37,16 +44,33 @@ public class SkullUtils {
|
||||
metaSetConsumer.accept(meta, base64);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the texture of a skull - in base64.
|
||||
*
|
||||
* @param meta The meta to modify.
|
||||
* @return The texture, potentially null.
|
||||
*/
|
||||
@Nullable
|
||||
public String getSkullTexture(@NotNull final SkullMeta meta) {
|
||||
Validate.isTrue(initialized, "Must be initialized!");
|
||||
Validate.notNull(metaGetConsumer, "Must be initialized!");
|
||||
|
||||
return metaGetConsumer.apply(meta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the skull texture function.
|
||||
*
|
||||
* @param function The function.
|
||||
* @param function The function.
|
||||
* @param function2 Get function.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public void initialize(@NotNull final BiConsumer<SkullMeta, String> function) {
|
||||
public void initialize(@NotNull final BiConsumer<SkullMeta, String> function,
|
||||
@NotNull final Function<SkullMeta, String> function2) {
|
||||
Validate.isTrue(!initialized, "Already initialized!");
|
||||
|
||||
metaSetConsumer = function;
|
||||
metaGetConsumer = function2;
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ public class StringUtils {
|
||||
* @param list The messages to format.
|
||||
* @return The message, formatted.
|
||||
*/
|
||||
@NotNull
|
||||
public List<String> formatList(@NotNull final List<String> list) {
|
||||
return formatList(list, (Player) null);
|
||||
}
|
||||
@@ -77,6 +78,7 @@ public class StringUtils {
|
||||
* @param player The player to translate placeholders with respect to.
|
||||
* @return The message, format.
|
||||
*/
|
||||
@NotNull
|
||||
public List<String> formatList(@NotNull final List<String> list,
|
||||
@Nullable final Player player) {
|
||||
return formatList(list, player, FormatOption.WITH_PLACEHOLDERS);
|
||||
@@ -91,6 +93,7 @@ public class StringUtils {
|
||||
* @param option The format option.
|
||||
* @return The message, formatted.
|
||||
*/
|
||||
@NotNull
|
||||
public List<String> formatList(@NotNull final List<String> list,
|
||||
@NotNull final FormatOption option) {
|
||||
return formatList(list, null, option);
|
||||
@@ -106,6 +109,7 @@ public class StringUtils {
|
||||
* @param option The options.
|
||||
* @return The message, format.
|
||||
*/
|
||||
@NotNull
|
||||
public List<String> formatList(@NotNull final List<String> list,
|
||||
@Nullable final Player player,
|
||||
@NotNull final FormatOption option) {
|
||||
@@ -126,6 +130,7 @@ public class StringUtils {
|
||||
* @return The message, formatted.
|
||||
* @see StringUtils#format(String, Player)
|
||||
*/
|
||||
@NotNull
|
||||
public String format(@NotNull final String message) {
|
||||
return format(message, (Player) null);
|
||||
}
|
||||
@@ -139,6 +144,7 @@ public class StringUtils {
|
||||
* @param player The player to translate placeholders with respect to.
|
||||
* @return The message, formatted.
|
||||
*/
|
||||
@NotNull
|
||||
public String format(@NotNull final String message,
|
||||
@Nullable final Player player) {
|
||||
return format(message, player, FormatOption.WITH_PLACEHOLDERS);
|
||||
@@ -154,6 +160,7 @@ public class StringUtils {
|
||||
* @return The message, formatted.
|
||||
* @see StringUtils#format(String, Player)
|
||||
*/
|
||||
@NotNull
|
||||
public String format(@NotNull final String message,
|
||||
@NotNull final FormatOption option) {
|
||||
return format(message, null, option);
|
||||
@@ -169,6 +176,7 @@ public class StringUtils {
|
||||
* @param option The format options.
|
||||
* @return The message, formatted.
|
||||
*/
|
||||
@NotNull
|
||||
public String format(@NotNull final String message,
|
||||
@Nullable final Player player,
|
||||
@NotNull final FormatOption option) {
|
||||
@@ -284,6 +292,7 @@ public class StringUtils {
|
||||
* @param object The object to convert to string.
|
||||
* @return The object stringified.
|
||||
*/
|
||||
@NotNull
|
||||
public String internalToString(@Nullable final Object object) {
|
||||
if (object == null) {
|
||||
return "null";
|
||||
@@ -309,6 +318,7 @@ public class StringUtils {
|
||||
* @param prefix The substring to remove.
|
||||
* @return The string with the prefix removed.
|
||||
*/
|
||||
@NotNull
|
||||
public String removePrefix(@NotNull final String string,
|
||||
@NotNull final String prefix) {
|
||||
if (string.startsWith(prefix)) {
|
||||
@@ -323,6 +333,7 @@ public class StringUtils {
|
||||
* @param legacy The legacy string.
|
||||
* @return The JSON String.
|
||||
*/
|
||||
@NotNull
|
||||
public String legacyToJson(@NotNull final String legacy) {
|
||||
return GsonComponentSerializer.gson().serialize(
|
||||
Component.empty().decoration(TextDecoration.ITALIC, false).append(
|
||||
@@ -337,6 +348,7 @@ public class StringUtils {
|
||||
* @param json The JSON string.
|
||||
* @return The legacy string.
|
||||
*/
|
||||
@NotNull
|
||||
public String jsonToLegacy(@NotNull final String json) {
|
||||
return LEGACY_COMPONENT_SERIALIZER.serialize(
|
||||
GsonComponentSerializer.gson().deserialize(json)
|
||||
|
||||
@@ -43,6 +43,7 @@ public class TeamUtils {
|
||||
* @param color The color to find the team for.
|
||||
* @return The team.
|
||||
*/
|
||||
@NotNull
|
||||
public Team fromChatColor(@NotNull final ChatColor color) {
|
||||
if (CHAT_COLOR_TEAMS.containsKey(color)) {
|
||||
return CHAT_COLOR_TEAMS.get(color);
|
||||
@@ -70,6 +71,7 @@ public class TeamUtils {
|
||||
* @param material The material to find the team from.
|
||||
* @return The team.
|
||||
*/
|
||||
@NotNull
|
||||
public Team getMaterialColorTeam(@NotNull final Material material) {
|
||||
return fromChatColor(MATERIAL_COLORS.getOrDefault(material, ChatColor.WHITE));
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ public class VectorUtils {
|
||||
* @param vec The vector to simplify.
|
||||
* @return The vector, simplified.
|
||||
*/
|
||||
@NotNull
|
||||
public Vector simplifyVector(@NotNull final Vector vec) {
|
||||
double x = Math.abs(vec.getX());
|
||||
double y = Math.abs(vec.getY());
|
||||
@@ -76,6 +77,7 @@ public class VectorUtils {
|
||||
* @param radius The radius.
|
||||
* @return An array of {@link Vector}s.
|
||||
*/
|
||||
@NotNull
|
||||
public Vector[] getCircle(final int radius) {
|
||||
Vector[] cached = CIRCLE_CACHE.get(radius);
|
||||
if (cached != null) {
|
||||
@@ -112,6 +114,7 @@ public class VectorUtils {
|
||||
* @param radius The radius of the square.
|
||||
* @return An array of {@link Vector}s.
|
||||
*/
|
||||
@NotNull
|
||||
public Vector[] getSquare(final int radius) {
|
||||
List<Vector> vectors = new ArrayList<>();
|
||||
|
||||
@@ -136,6 +139,7 @@ public class VectorUtils {
|
||||
* @param radius The radius of the cube.
|
||||
* @return An array of {@link Vector}s.
|
||||
*/
|
||||
@NotNull
|
||||
public Vector[] getCube(final int radius) {
|
||||
List<Vector> vectors = new ArrayList<>();
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.willfp.eco.core.config.interfaces.JSONConfig
|
||||
import com.willfp.eco.core.config.wrapper.ConfigFactory
|
||||
import com.willfp.eco.internal.config.json.EcoJSONConfigSection
|
||||
import com.willfp.eco.internal.config.json.EcoLoadableJSONConfig
|
||||
import com.willfp.eco.internal.config.json.EcoUpdatableJSONConfig
|
||||
import com.willfp.eco.internal.config.yaml.EcoLoadableYamlConfig
|
||||
import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig
|
||||
import com.willfp.eco.internal.config.yaml.EcoYamlConfigSection
|
||||
@@ -30,6 +31,24 @@ class EcoConfigFactory : ConfigFactory {
|
||||
)
|
||||
}
|
||||
|
||||
override fun createUpdatableJSONConfig(
|
||||
configName: String,
|
||||
plugin: EcoPlugin,
|
||||
subDirectoryPath: String,
|
||||
source: Class<*>,
|
||||
removeUnused: Boolean,
|
||||
vararg updateBlacklist: String
|
||||
): JSONConfig {
|
||||
return EcoUpdatableJSONConfig(
|
||||
configName,
|
||||
plugin,
|
||||
subDirectoryPath,
|
||||
source,
|
||||
removeUnused,
|
||||
*updateBlacklist
|
||||
)
|
||||
}
|
||||
|
||||
override fun createLoadableJSONConfig(
|
||||
configName: String,
|
||||
plugin: EcoPlugin,
|
||||
|
||||
@@ -8,11 +8,11 @@ import java.nio.file.Files
|
||||
import java.nio.file.StandardOpenOption
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class EcoLoadableJSONConfig(
|
||||
open class EcoLoadableJSONConfig(
|
||||
configName: String,
|
||||
private val plugin: EcoPlugin,
|
||||
private val subDirectoryPath: String,
|
||||
private val source: Class<*>
|
||||
val source: Class<*>
|
||||
) : EcoJSONConfigWrapper(), LoadableConfig {
|
||||
|
||||
private val configFile: File
|
||||
@@ -65,7 +65,7 @@ class EcoLoadableJSONConfig(
|
||||
|
||||
@Throws(FileNotFoundException::class)
|
||||
fun init(file: File) {
|
||||
super.init(handle.fromJson(FileReader(file), Map::class.java) as @NotNull MutableMap<String, Any>)
|
||||
super.init(handle.fromJson(FileReader(file), Map::class.java) as MutableMap<String, Any>)
|
||||
}
|
||||
|
||||
override fun getName(): String {
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.willfp.eco.internal.config.json
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import org.bukkit.configuration.InvalidConfigurationException
|
||||
import org.bukkit.configuration.file.YamlConfiguration
|
||||
import java.io.BufferedReader
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
import java.nio.charset.StandardCharsets
|
||||
|
||||
open class EcoUpdatableJSONConfig(
|
||||
configName: String,
|
||||
plugin: EcoPlugin,
|
||||
subDirectoryPath: String,
|
||||
source: Class<*>,
|
||||
private val removeUnused: Boolean,
|
||||
vararg updateBlacklist: String
|
||||
) : EcoLoadableJSONConfig(configName, plugin, subDirectoryPath, source) {
|
||||
|
||||
private val updateBlacklist: MutableList<String> = mutableListOf(*updateBlacklist)
|
||||
|
||||
fun update() {
|
||||
super.clearCache()
|
||||
try {
|
||||
this.init(configFile)
|
||||
val newConfig = configInJar
|
||||
if (newConfig.getKeys(true) == this.getKeys(true)) {
|
||||
return
|
||||
}
|
||||
newConfig.getKeys(true).forEach { key: String ->
|
||||
if (!this.getKeys(true).contains(key)) {
|
||||
if (updateBlacklist.stream().noneMatch { s: String -> key.contains(s) }) {
|
||||
this.set(key, newConfig[key])
|
||||
}
|
||||
}
|
||||
}
|
||||
if (removeUnused) {
|
||||
this.getKeys(true).forEach { s ->
|
||||
if (!newConfig.getKeys(true).contains(s)) {
|
||||
if (updateBlacklist.stream().noneMatch(s::contains)) {
|
||||
this.set(s, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.save()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: InvalidConfigurationException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private val configInJar: YamlConfiguration
|
||||
get() {
|
||||
val newIn = this.source.getResourceAsStream(resourcePath) ?: throw NullPointerException("$name is null?")
|
||||
val reader = BufferedReader(InputStreamReader(newIn, StandardCharsets.UTF_8))
|
||||
val newConfig = YamlConfiguration()
|
||||
try {
|
||||
newConfig.load(reader)
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: InvalidConfigurationException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return newConfig
|
||||
}
|
||||
|
||||
init {
|
||||
this.updateBlacklist.removeIf { obj: String -> obj.isEmpty() }
|
||||
plugin.configHandler.addConfig(this)
|
||||
update()
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import com.willfp.eco.core.config.interfaces.LoadableConfig
|
||||
import com.willfp.eco.core.config.updating.ConfigHandler
|
||||
import com.willfp.eco.core.config.updating.ConfigUpdater
|
||||
import com.willfp.eco.internal.config.json.EcoLoadableJSONConfig
|
||||
import com.willfp.eco.internal.config.json.EcoUpdatableJSONConfig
|
||||
import com.willfp.eco.internal.config.updating.exceptions.InvalidUpdateMethodException
|
||||
import com.willfp.eco.internal.config.yaml.EcoLoadableYamlConfig
|
||||
import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig
|
||||
@@ -55,6 +56,7 @@ class EcoConfigHandler(
|
||||
for (config in configs) {
|
||||
when (config) {
|
||||
is EcoUpdatableYamlConfig -> config.update()
|
||||
is EcoUpdatableJSONConfig -> config.update()
|
||||
is EcoLoadableYamlConfig -> config.reloadFromFile()
|
||||
is EcoLoadableJSONConfig -> config.reloadFromFile()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.willfp.eco.internal.display
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.display.Display
|
||||
import com.willfp.eco.core.display.DisplayHandler
|
||||
import com.willfp.eco.core.display.DisplayModule
|
||||
import com.willfp.eco.core.display.DisplayPriority
|
||||
import com.willfp.eco.core.fast.FastItemStack
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
class EcoDisplayHandler(plugin: EcoPlugin) : DisplayHandler {
|
||||
/**
|
||||
* All registered display modules.
|
||||
*/
|
||||
private val registeredModules = mutableMapOf<DisplayPriority, MutableList<DisplayModule>>()
|
||||
|
||||
/**
|
||||
* NamespacedKey for finalizing.
|
||||
*/
|
||||
private val finalizeKey: NamespacedKey = plugin.namespacedKeyFactory.create("finalized")
|
||||
|
||||
init {
|
||||
for (priority in DisplayPriority.values()) {
|
||||
registeredModules[priority] = mutableListOf()
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerDisplayModule(module: DisplayModule) {
|
||||
val modules = registeredModules[module.priority] ?: return
|
||||
modules.removeIf { module1: DisplayModule ->
|
||||
module1.pluginName.equals(module.pluginName, ignoreCase = true)
|
||||
}
|
||||
modules.add(module)
|
||||
registeredModules[module.priority] = modules
|
||||
}
|
||||
|
||||
override fun display(itemStack: ItemStack, player: Player?): ItemStack {
|
||||
val pluginVarArgs = mutableMapOf<String, Array<Any>>()
|
||||
|
||||
for (priority in DisplayPriority.values()) {
|
||||
val modules = registeredModules[priority] ?: continue
|
||||
for (module in modules) {
|
||||
pluginVarArgs[module.pluginName] = module.generateVarArgs(itemStack)
|
||||
}
|
||||
}
|
||||
|
||||
Display.revert(itemStack)
|
||||
|
||||
itemStack.itemMeta ?: return itemStack
|
||||
|
||||
for (priority in DisplayPriority.values()) {
|
||||
val modules = registeredModules[priority] ?: continue
|
||||
for (module in modules) {
|
||||
val varargs = pluginVarArgs[module.pluginName] ?: continue
|
||||
Display.callDisplayModule(module, itemStack, player, *varargs)
|
||||
}
|
||||
}
|
||||
|
||||
return itemStack
|
||||
}
|
||||
|
||||
override fun revert(itemStack: ItemStack): ItemStack {
|
||||
if (Display.isFinalized(itemStack)) {
|
||||
Display.unfinalize(itemStack)
|
||||
}
|
||||
|
||||
val fast = FastItemStack.wrap(itemStack)
|
||||
val lore = fast.lore
|
||||
|
||||
if (lore.isNotEmpty() && lore.removeIf { line: String ->
|
||||
line.startsWith(
|
||||
Display.PREFIX
|
||||
)
|
||||
}) { // Only modify lore if needed.
|
||||
fast.lore = lore
|
||||
}
|
||||
|
||||
for (priority in DisplayPriority.values()) {
|
||||
val modules = registeredModules[priority] ?: continue
|
||||
for (module in modules) {
|
||||
module.revert(itemStack)
|
||||
}
|
||||
}
|
||||
|
||||
return itemStack
|
||||
}
|
||||
|
||||
override fun finalize(itemStack: ItemStack): ItemStack {
|
||||
if (itemStack.type.maxStackSize > 1) {
|
||||
return itemStack
|
||||
}
|
||||
|
||||
val meta = itemStack.itemMeta ?: return itemStack
|
||||
|
||||
val container = meta.persistentDataContainer
|
||||
container.set(finalizeKey, PersistentDataType.INTEGER, 1)
|
||||
itemStack.itemMeta = meta
|
||||
return itemStack
|
||||
}
|
||||
|
||||
override fun unfinalize(itemStack: ItemStack): ItemStack {
|
||||
val meta = itemStack.itemMeta ?: return itemStack
|
||||
|
||||
val container = meta.persistentDataContainer
|
||||
container.remove(finalizeKey)
|
||||
itemStack.itemMeta = meta
|
||||
return itemStack
|
||||
}
|
||||
|
||||
override fun isFinalized(itemStack: ItemStack): Boolean {
|
||||
val meta = itemStack.itemMeta ?: return false
|
||||
|
||||
val container = meta.persistentDataContainer
|
||||
return container.has(finalizeKey, PersistentDataType.INTEGER)
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import org.bukkit.Bukkit
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
|
||||
class EcoEventManager constructor(private val plugin: EcoPlugin) : EventManager {
|
||||
class EcoEventManager (private val plugin: EcoPlugin) : EventManager {
|
||||
override fun registerListener(listener: Listener) {
|
||||
Bukkit.getPluginManager().registerEvents(listener, plugin)
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ class EcoMenu(
|
||||
|
||||
fun handleClose(event: InventoryCloseEvent) {
|
||||
onClose.handle(event, this)
|
||||
MenuHandler.unregisterMenu(event.inventory)
|
||||
}
|
||||
|
||||
override fun getRows(): Int {
|
||||
|
||||
@@ -15,7 +15,7 @@ class EcoCaptivatorSlot : EcoSlot(
|
||||
{ _, _, _ -> }
|
||||
) {
|
||||
companion object {
|
||||
val plugin = Eco.getHandler().ecoPlugin!!
|
||||
val plugin = Eco.getHandler().ecoPlugin
|
||||
|
||||
val allowMovingItem = SlotHandler { event, _, _ ->
|
||||
event.isCancelled = false
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.willfp.eco.internal.requirement
|
||||
|
||||
import com.willfp.eco.core.requirement.Requirement
|
||||
import com.willfp.eco.core.requirement.RequirementFactory
|
||||
import com.willfp.eco.internal.requirement.requirements.*
|
||||
|
||||
class EcoRequirementFactory: RequirementFactory {
|
||||
override fun create(name: String): Requirement {
|
||||
return when (name.lowercase()) {
|
||||
"has-permission" -> RequirementHasPermission()
|
||||
"placeholder-equals" -> RequirementPlaceholderEquals()
|
||||
"placeholder-greater-than" -> RequirementPlaceholderGreaterThan()
|
||||
"placeholder-less-than" -> RequirementPlaceholderLessThan()
|
||||
else -> RequirementTrue()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.willfp.eco.internal.requirement.requirements
|
||||
|
||||
import com.willfp.eco.core.requirement.Requirement
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class RequirementHasPermission : Requirement() {
|
||||
override fun doesPlayerMeet(
|
||||
player: Player,
|
||||
args: List<String>
|
||||
): Boolean {
|
||||
if (args.isEmpty()) {
|
||||
return false
|
||||
}
|
||||
|
||||
val permission = args[0]
|
||||
return player.hasPermission(permission)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.willfp.eco.internal.requirement.requirements
|
||||
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||
import com.willfp.eco.core.requirement.Requirement
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class RequirementPlaceholderEquals : Requirement() {
|
||||
override fun doesPlayerMeet(
|
||||
player: Player,
|
||||
args: List<String>
|
||||
): Boolean {
|
||||
if (args.size < 2) {
|
||||
return false
|
||||
}
|
||||
|
||||
val placeholder = args[0]
|
||||
val equals = args[1]
|
||||
return PlaceholderManager.translatePlaceholders(placeholder, player).equals(equals, ignoreCase = true)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.willfp.eco.internal.requirement.requirements
|
||||
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||
import com.willfp.eco.core.requirement.Requirement
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class RequirementPlaceholderGreaterThan : Requirement() {
|
||||
override fun doesPlayerMeet(
|
||||
player: Player,
|
||||
args: List<String>
|
||||
): Boolean {
|
||||
if (args.size < 2) {
|
||||
return false
|
||||
}
|
||||
|
||||
val placeholder = args[0]
|
||||
val equals = args[1].toDoubleOrNull() ?: return false
|
||||
return PlaceholderManager.translatePlaceholders(placeholder, player).toDoubleOrNull() ?: 0.0 >= equals
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.willfp.eco.internal.requirement.requirements
|
||||
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||
import com.willfp.eco.core.requirement.Requirement
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class RequirementPlaceholderLessThan : Requirement() {
|
||||
override fun doesPlayerMeet(
|
||||
player: Player,
|
||||
args: List<String>
|
||||
): Boolean {
|
||||
if (args.size < 2) {
|
||||
return false
|
||||
}
|
||||
|
||||
val placeholder = args[0]
|
||||
val equals = args[1].toDoubleOrNull() ?: return false
|
||||
return PlaceholderManager.translatePlaceholders(placeholder, player).toDoubleOrNull() ?: 0.0 < equals
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.willfp.eco.internal.requirement.requirements
|
||||
|
||||
import com.willfp.eco.core.requirement.Requirement
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class RequirementTrue : Requirement() {
|
||||
override fun doesPlayerMeet(
|
||||
player: Player,
|
||||
args: List<String>
|
||||
): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,43 @@
|
||||
package com.willfp.eco.proxy.v1_16_R3
|
||||
|
||||
import com.mojang.authlib.GameProfile
|
||||
import com.mojang.authlib.properties.Property
|
||||
import org.bukkit.inventory.meta.SkullMeta
|
||||
import com.willfp.eco.proxy.SkullProxy
|
||||
import org.bukkit.inventory.meta.SkullMeta
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Method
|
||||
import java.util.*
|
||||
|
||||
class Skull : SkullProxy {
|
||||
private lateinit var setProfile: Method
|
||||
private lateinit var profile: Field
|
||||
|
||||
override fun setSkullTexture(
|
||||
meta: SkullMeta,
|
||||
base64: String
|
||||
) {
|
||||
try {
|
||||
if (!this::setProfile.isInitialized) {
|
||||
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
|
||||
setProfile.isAccessible = true
|
||||
}
|
||||
val uuid = UUID(
|
||||
base64.substring(base64.length - 20).hashCode().toLong(),
|
||||
base64.substring(base64.length - 10).hashCode().toLong()
|
||||
)
|
||||
val profile = GameProfile(uuid, "eco")
|
||||
profile.properties.put("textures", Property("textures", base64))
|
||||
setProfile.invoke(meta, profile)
|
||||
} catch (e: ReflectiveOperationException) {
|
||||
e.printStackTrace()
|
||||
if (!this::setProfile.isInitialized) {
|
||||
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
|
||||
setProfile.isAccessible = true
|
||||
}
|
||||
val uuid = UUID(
|
||||
base64.substring(base64.length - 20).hashCode().toLong(),
|
||||
base64.substring(base64.length - 10).hashCode().toLong()
|
||||
)
|
||||
val profile = GameProfile(uuid, "eco")
|
||||
profile.properties.put("textures", Property("textures", base64))
|
||||
setProfile.invoke(meta, profile)
|
||||
}
|
||||
|
||||
override fun getSkullTexture(
|
||||
meta: SkullMeta
|
||||
): String? {
|
||||
if (!this::profile.isInitialized) {
|
||||
profile = meta.javaClass.getDeclaredField("profile")
|
||||
profile.isAccessible = true
|
||||
}
|
||||
val profile = profile[meta] as GameProfile?
|
||||
val property = profile?.properties?.get("textures") as Property?
|
||||
return property?.value
|
||||
}
|
||||
}
|
||||
@@ -4,30 +4,40 @@ import com.mojang.authlib.GameProfile
|
||||
import com.mojang.authlib.properties.Property
|
||||
import com.willfp.eco.proxy.SkullProxy
|
||||
import org.bukkit.inventory.meta.SkullMeta
|
||||
import java.lang.reflect.Field
|
||||
import java.lang.reflect.Method
|
||||
import java.util.*
|
||||
|
||||
class Skull : SkullProxy {
|
||||
private lateinit var setProfile: Method
|
||||
private lateinit var profile: Field
|
||||
|
||||
override fun setSkullTexture(
|
||||
meta: SkullMeta,
|
||||
base64: String
|
||||
) {
|
||||
try {
|
||||
if (!this::setProfile.isInitialized) {
|
||||
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
|
||||
setProfile.isAccessible = true
|
||||
}
|
||||
val uuid = UUID(
|
||||
base64.substring(base64.length - 20).hashCode().toLong(),
|
||||
base64.substring(base64.length - 10).hashCode().toLong()
|
||||
)
|
||||
val profile = GameProfile(uuid, "eco")
|
||||
profile.properties.put("textures", Property("textures", base64))
|
||||
setProfile.invoke(meta, profile)
|
||||
} catch (e: ReflectiveOperationException) {
|
||||
e.printStackTrace()
|
||||
if (!this::setProfile.isInitialized) {
|
||||
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
|
||||
setProfile.isAccessible = true
|
||||
}
|
||||
val uuid = UUID(
|
||||
base64.substring(base64.length - 20).hashCode().toLong(),
|
||||
base64.substring(base64.length - 10).hashCode().toLong()
|
||||
)
|
||||
val profile = GameProfile(uuid, "eco")
|
||||
profile.properties.put("textures", Property("textures", base64))
|
||||
setProfile.invoke(meta, profile)
|
||||
}
|
||||
|
||||
override fun getSkullTexture(
|
||||
meta: SkullMeta
|
||||
): String? {
|
||||
if (!this::profile.isInitialized) {
|
||||
profile = meta.javaClass.getDeclaredField("profile")
|
||||
profile.isAccessible = true
|
||||
}
|
||||
val profile = profile[meta] as GameProfile?
|
||||
val property = profile?.properties?.get("textures") as Property?
|
||||
return property?.value
|
||||
}
|
||||
}
|
||||
@@ -21,8 +21,8 @@ dependencies {
|
||||
compileOnly 'me.clip:placeholderapi:2.10.9'
|
||||
compileOnly 'com.willfp:Oraxen:e1f4003d8d'
|
||||
compileOnly 'com.github.brcdev-minecraft:shopgui-api:2.2.0'
|
||||
|
||||
compileOnly 'com.github.LoneDev6:API-ItemsAdder:2.3.8'
|
||||
compileOnly 'com.github.LoneDev6:API-ItemsAdder:2.4.7'
|
||||
compileOnly 'me.arcaniax:HeadDatabase-API:1.2.0'
|
||||
|
||||
// CombatLogX V10 + NewbieHelper Expansion
|
||||
compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT'
|
||||
|
||||
@@ -98,16 +98,65 @@ public class ShapedRecipeListener extends PluginDependent<EcoPlugin> implements
|
||||
return;
|
||||
}
|
||||
|
||||
this.getPlugin().getScheduler().runLater(() -> {
|
||||
for (int i = 0; i < 9; i++) {
|
||||
ItemStack inMatrix = event.getInventory().getMatrix()[i];
|
||||
TestableItem inRecipe = matched.getParts().get(i);
|
||||
boolean isStackedRecipe = false;
|
||||
|
||||
if (inRecipe instanceof TestableStack testableStack) {
|
||||
int upperBound = 64;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
ItemStack inMatrix = event.getInventory().getMatrix()[i];
|
||||
TestableItem inRecipe = matched.getParts().get(i);
|
||||
|
||||
if (inRecipe instanceof TestableStack testableStack) {
|
||||
int max = Math.floorDiv(inMatrix.getAmount(), testableStack.getAmount());
|
||||
if (max < upperBound) {
|
||||
upperBound = max;
|
||||
}
|
||||
isStackedRecipe = true;
|
||||
} else if (inMatrix != null) {
|
||||
int max = inMatrix.getAmount();
|
||||
if (max < upperBound) {
|
||||
upperBound = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isStackedRecipe) {
|
||||
return;
|
||||
}
|
||||
|
||||
int toGivePerRecipe = event.getRecipe().getResult().getAmount();
|
||||
int maxStackSize = event.getRecipe().getResult().getMaxStackSize();
|
||||
while (toGivePerRecipe * upperBound > maxStackSize) {
|
||||
upperBound--;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 9; i++) {
|
||||
ItemStack inMatrix = event.getInventory().getMatrix()[i];
|
||||
TestableItem inRecipe = matched.getParts().get(i);
|
||||
|
||||
if (inRecipe instanceof TestableStack testableStack) {
|
||||
if (event.isShiftClick()) {
|
||||
int amount = inMatrix.getAmount() + 1;
|
||||
for (int j = 0; j < upperBound; j++) {
|
||||
amount -= testableStack.getAmount();
|
||||
}
|
||||
inMatrix.setAmount(amount);
|
||||
} else {
|
||||
inMatrix.setAmount(inMatrix.getAmount() - (testableStack.getAmount() - 1));
|
||||
}
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
int finalUpperBound = upperBound;
|
||||
|
||||
if (event.isShiftClick()) {
|
||||
ItemStack result = event.getInventory().getResult();
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
result.setAmount(result.getAmount() * finalUpperBound);
|
||||
event.getInventory().setResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.willfp.eco.core.gui.GUIFactory
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration
|
||||
import com.willfp.eco.core.proxy.Cleaner
|
||||
import com.willfp.eco.core.proxy.ProxyFactory
|
||||
import com.willfp.eco.core.requirement.RequirementFactory
|
||||
import com.willfp.eco.core.scheduling.Scheduler
|
||||
import com.willfp.eco.internal.EcoCleaner
|
||||
import com.willfp.eco.internal.Plugins
|
||||
@@ -30,6 +31,7 @@ import com.willfp.eco.internal.gui.EcoGUIFactory
|
||||
import com.willfp.eco.internal.integrations.PlaceholderIntegrationPAPI
|
||||
import com.willfp.eco.internal.logging.EcoLogger
|
||||
import com.willfp.eco.internal.proxy.EcoProxyFactory
|
||||
import com.willfp.eco.internal.requirement.EcoRequirementFactory
|
||||
import com.willfp.eco.internal.scheduling.EcoScheduler
|
||||
import com.willfp.eco.proxy.FastItemStackFactoryProxy
|
||||
import com.willfp.eco.spigot.integrations.bstats.MetricHandler
|
||||
@@ -39,6 +41,7 @@ import java.util.logging.Logger
|
||||
@Suppress("UNUSED")
|
||||
class EcoHandler : EcoSpigotPlugin(), Handler {
|
||||
private val cleaner = EcoCleaner()
|
||||
private val requirementFactory = EcoRequirementFactory()
|
||||
|
||||
override fun createScheduler(plugin: EcoPlugin): Scheduler {
|
||||
return EcoScheduler(plugin)
|
||||
@@ -119,4 +122,8 @@ class EcoHandler : EcoSpigotPlugin(), Handler {
|
||||
override fun registerBStats(plugin: EcoPlugin) {
|
||||
MetricHandler.createMetrics(plugin, this.ecoPlugin)
|
||||
}
|
||||
|
||||
override fun getRequirementFactory(): RequirementFactory {
|
||||
return requirementFactory
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,10 @@ import com.willfp.eco.core.integrations.antigrief.AntigriefManager
|
||||
import com.willfp.eco.core.integrations.customitems.CustomItemsManager
|
||||
import com.willfp.eco.core.integrations.mcmmo.McmmoManager
|
||||
import com.willfp.eco.core.integrations.shop.ShopManager
|
||||
import com.willfp.eco.core.items.Items
|
||||
import com.willfp.eco.core.items.args.EnchantmentArgParser
|
||||
import com.willfp.eco.core.items.args.TextureArgParser
|
||||
import com.willfp.eco.internal.display.EcoDisplayHandler
|
||||
import com.willfp.eco.internal.drops.DropManager
|
||||
import com.willfp.eco.proxy.BlockBreakProxy
|
||||
import com.willfp.eco.proxy.FastItemStackFactoryProxy
|
||||
@@ -20,6 +24,7 @@ import com.willfp.eco.spigot.eventlisteners.*
|
||||
import com.willfp.eco.spigot.gui.GUIListener
|
||||
import com.willfp.eco.spigot.integrations.anticheat.*
|
||||
import com.willfp.eco.spigot.integrations.antigrief.*
|
||||
import com.willfp.eco.spigot.integrations.customitems.CustomItemsItemsAdder
|
||||
import com.willfp.eco.spigot.integrations.customitems.CustomItemsOraxen
|
||||
import com.willfp.eco.spigot.integrations.mcmmo.McmmoIntegrationImpl
|
||||
import com.willfp.eco.spigot.integrations.shop.ShopShopGuiPlus
|
||||
@@ -41,13 +46,23 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
"&a"
|
||||
) {
|
||||
init {
|
||||
Display.setFinalizeKey(namespacedKeyFactory.create("finalized"))
|
||||
Items.registerArgParser(EnchantmentArgParser())
|
||||
Items.registerArgParser(TextureArgParser())
|
||||
|
||||
val skullProxy = getProxy(SkullProxy::class.java)
|
||||
SkullUtils.initialize { meta: SkullMeta, base64: String -> skullProxy.setSkullTexture(meta, base64) }
|
||||
SkullUtils.initialize(
|
||||
{ meta: SkullMeta, base64: String -> skullProxy.setSkullTexture(meta, base64) },
|
||||
{ meta: SkullMeta -> skullProxy.getSkullTexture(meta) }
|
||||
)
|
||||
|
||||
val blockBreakProxy = getProxy(BlockBreakProxy::class.java)
|
||||
BlockUtils.initialize { player: Player, block: Block -> blockBreakProxy.breakBlock(player, block) }
|
||||
|
||||
postInit()
|
||||
}
|
||||
|
||||
private fun postInit() {
|
||||
Display.handler = EcoDisplayHandler(this)
|
||||
}
|
||||
|
||||
override fun handleEnable() {
|
||||
@@ -79,6 +94,7 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
|
||||
override fun handleAfterLoad() {
|
||||
CustomItemsManager.registerAllItems()
|
||||
ShopManager.registerEcoProvider()
|
||||
}
|
||||
|
||||
override fun loadIntegrationLoaders(): List<IntegrationLoader> {
|
||||
@@ -111,9 +127,10 @@ abstract class EcoSpigotPlugin : EcoPlugin(
|
||||
|
||||
// Custom Items
|
||||
IntegrationLoader("Oraxen") { CustomItemsManager.register(CustomItemsOraxen()) },
|
||||
IntegrationLoader("ItemsAdder") { CustomItemsManager.register(CustomItemsItemsAdder(this)) },
|
||||
|
||||
// Shop
|
||||
IntegrationLoader("ShopGuiPlus") { ShopManager.register(ShopShopGuiPlus()) },
|
||||
IntegrationLoader("ShopGUIPlus") { ShopManager.register(ShopShopGuiPlus()) },
|
||||
|
||||
// Misc
|
||||
IntegrationLoader("mcMMO") { McmmoManager.register(McmmoIntegrationImpl()) }
|
||||
|
||||
@@ -73,9 +73,7 @@ class GUIListener(private val plugin: EcoPlugin) : Listener {
|
||||
|
||||
val menu = MenuHandler.getMenu(inv) ?: return
|
||||
|
||||
val rowColumn = MenuUtils.convertSlotToRowColumn(inv.firstEmpty())
|
||||
val row = rowColumn.first!!
|
||||
val column = rowColumn.second!!
|
||||
val (row, column) = MenuUtils.convertSlotToRowColumn(inv.firstEmpty())
|
||||
val slot = menu.getSlot(row, column)
|
||||
|
||||
if (!slot.isCaptive) {
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.willfp.eco.spigot.integrations.customitems
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.integrations.customitems.CustomItemsWrapper
|
||||
import com.willfp.eco.core.items.CustomItem
|
||||
import com.willfp.eco.util.NamespacedKeyUtils
|
||||
import dev.lone.itemsadder.api.CustomStack
|
||||
import dev.lone.itemsadder.api.ItemsAdder
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import java.util.function.Predicate
|
||||
|
||||
class CustomItemsItemsAdder(
|
||||
private val plugin: EcoPlugin
|
||||
) : CustomItemsWrapper {
|
||||
override fun registerAllItems() {
|
||||
plugin.scheduler.runLater({
|
||||
for (item in ItemsAdder.getAllItems()) {
|
||||
val stack = item.itemStack
|
||||
val id = item.id
|
||||
val key = NamespacedKeyUtils.create("itemsadder", id.lowercase())
|
||||
CustomItem(
|
||||
key,
|
||||
Predicate { test: ItemStack ->
|
||||
val customStack = CustomStack.byItemStack(test) ?: return@Predicate false
|
||||
customStack.id.equals(id, ignoreCase = true)
|
||||
},
|
||||
stack
|
||||
).register()
|
||||
}
|
||||
}, 2)
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "ItemsAdder"
|
||||
}
|
||||
}
|
||||
@@ -6,13 +6,15 @@ import com.willfp.eco.util.NamespacedKeyUtils
|
||||
import io.th0rgal.oraxen.items.OraxenItems
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import java.util.*
|
||||
import java.util.function.Predicate
|
||||
|
||||
class CustomItemsOraxen : CustomItemsWrapper {
|
||||
override fun registerAllItems() {
|
||||
for (item in OraxenItems.getItems()) {
|
||||
val stack = item.build()
|
||||
val id: String = OraxenItems.getIdByItem(item)
|
||||
val id: String = Objects.requireNonNullElse(OraxenItems.getIdByItem(item), "")
|
||||
if (id.isEmpty()) continue
|
||||
val key: NamespacedKey = NamespacedKeyUtils.create("oraxen", id.lowercase())
|
||||
CustomItem(
|
||||
key, Predicate { test: ItemStack ->
|
||||
@@ -23,4 +25,8 @@ class CustomItemsOraxen : CustomItemsWrapper {
|
||||
).register()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "Oraxen"
|
||||
}
|
||||
}
|
||||
@@ -28,4 +28,8 @@ class ShopShopGuiPlus : ShopWrapper {
|
||||
return Items.getCustomItem(itemStack1)?.key == Items.getCustomItem(itemStack2)?.key
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "ShopGUIPlus"
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ main: com.willfp.eco.spigot.EcoHandler
|
||||
api-version: 1.16
|
||||
authors: [Auxilor]
|
||||
website: willfp.com
|
||||
load: STARTUP
|
||||
depend:
|
||||
- ProtocolLib
|
||||
softdepend:
|
||||
@@ -20,7 +21,10 @@ softdepend:
|
||||
- PlaceholderAPI
|
||||
- mcMMO
|
||||
- CombatLogX
|
||||
- ShopGuiPlus
|
||||
- ShopGUIPlus
|
||||
- ItemsAdder
|
||||
- Oraxen
|
||||
- HeadDatabase
|
||||
libraries:
|
||||
- org.reflections:reflections:0.9.12
|
||||
- org.apache.maven:maven-artifact:3.0.3
|
||||
|
||||
@@ -8,4 +8,8 @@ interface SkullProxy : AbstractProxy {
|
||||
meta: SkullMeta,
|
||||
base64: String
|
||||
)
|
||||
|
||||
fun getSkullTexture(
|
||||
meta: SkullMeta
|
||||
): String?
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
version = 6.6.1
|
||||
version = 6.8.0
|
||||
plugin-name = eco
|
||||
Reference in New Issue
Block a user