Compare commits

..

66 Commits

Author SHA1 Message Date
Auxilor
b223f8457d Removed unused param 2022-04-27 18:23:36 +01:00
Auxilor
694d57edf4 Changing state will no longer re-render 2022-04-27 18:20:36 +01:00
Auxilor
02afe7d788 Fixed state-render infinite loops 2022-04-27 16:20:48 +01:00
Auxilor
0593e631ea Improved reactive state 2022-04-27 16:16:00 +01:00
Auxilor
2f22e02ff1 Added MenuBuilder#onRender to add reactive state 2022-04-27 16:14:28 +01:00
Auxilor
fb240bfd0a Replaced Menu data with Menu state 2022-04-27 16:07:38 +01:00
Auxilor
11c49a543f Improved config DSL 2022-04-27 14:17:13 +01:00
Auxilor
c565f5248d Fixed ShopWrapper deprecation comment 2022-04-27 13:44:51 +01:00
Auxilor
fac4f40430 Fixed codestyle 2022-04-27 13:28:04 +01:00
Auxilor
a20cb63755 Improved integration API 2022-04-27 13:18:57 +01:00
Auxilor
f17f67227f Commented CustomItem 2022-04-27 13:16:53 +01:00
Auxilor
106c9b37fc Removed unneeded test 2022-04-27 13:11:25 +01:00
Auxilor
f7cfcd5cbb Fixed redundant method 2022-04-27 13:06:35 +01:00
Auxilor
44d9581222 Cleanup 2022-04-27 13:04:57 +01:00
Auxilor
0fa30a5f62 Finally removed Display#callDisplayModule 2022-04-27 13:04:24 +01:00
Auxilor
84f439976c Fixed refactoring bugs 2022-04-27 12:51:45 +01:00
Auxilor
01bcb62b31 Refactored -Wrapper suffix to -Integration 2022-04-27 12:42:20 +01:00
Auxilor
47c8ea3341 Switched from DisplayPriority to weight 2022-04-27 12:31:27 +01:00
Auxilor
e28c4288a3 Removed ItemMeta usage in EcoDisplayHandler 2022-04-27 12:22:58 +01:00
Auxilor
386792d7ca Reworked PersistentDataContainer 2022-04-27 12:15:37 +01:00
Auxilor
8c6d98a666 Added string progress bars 2022-04-26 11:17:24 +01:00
Auxilor
6f42224593 Various codestyle improvements 2022-04-25 20:24:52 +01:00
Auxilor
36c857086b Fixed KDoc 2022-04-25 20:17:46 +01:00
Auxilor
014bcddc0a Fixed problem with extension functinos 2022-04-25 20:16:36 +01:00
Auxilor
96c56b0291 Codestyle 2022-04-25 20:03:09 +01:00
Auxilor
c1fe633e72 Improved config DSL 2022-04-25 20:02:28 +01:00
Auxilor
c9a9d86160 Added ConfigHelpers.kt 2022-04-25 19:44:01 +01:00
Auxilor
e79c7e9881 Codestyle 2022-04-25 13:40:26 +01:00
Auxilor
be617241e7 Removed ScriptUtils 2022-04-25 13:39:18 +01:00
Auxilor
cb9b59ae01 Added ScriptUtils 2022-04-25 11:32:47 +01:00
Auxilor
a993acae72 Fixed deprecated method use 2022-04-25 10:20:49 +01:00
Auxilor
e6cdc7d2ba Added PlayerUtils#tryAsPlayer 2022-04-25 10:14:24 +01:00
Auxilor
94534b2f61 Refactoring 2022-04-25 10:09:09 +01:00
Auxilor
fe6b7805c7 Added ShopSellEvent as well as integrations for zShop, EconomyShopGUI, and DeluxeSellwands 2022-04-25 10:03:23 +01:00
Auxilor
be25f2f4fc Added startup message in constructor 2022-04-25 09:42:03 +01:00
Auxilor
a19cc7df1e Added ExtendedPersistentDataContainer.create 2022-04-23 15:54:40 +01:00
Auxilor
13dbd08dcc Removed debug and now-unused API 2022-04-23 14:14:43 +01:00
Auxilor
a48885b79a Added kotlin extensions to ExtendedPersistentDataContainer 2022-04-22 21:18:14 +01:00
Auxilor
350c2d8775 Added ExtendedPersistentDataContainer#getBase 2022-04-22 20:53:26 +01:00
Auxilor
5988dfb1fd Fixed ExtendedPersistentDataContainer 2022-04-22 20:47:21 +01:00
Auxilor
57687859e4 Updated to 6.35.0 2022-04-22 20:45:16 +01:00
Auxilor
ef42e689ae Added ExtendedPersistentDataContainer 2022-04-22 20:44:59 +01:00
Auxilor
9a3aac9a66 Stripped out current mining speed check 2022-04-22 20:15:02 +01:00
Auxilor
7be5fbfbc4 Debug changes 2022-04-22 16:35:15 +01:00
Auxilor
4b344ccd18 More changes 2022-04-22 16:31:44 +01:00
Auxilor
3f50ae0a44 Began javassisting 2022-04-22 11:36:44 +01:00
Auxilor
afb498b4bf Added more mappings to FastItemStack 2022-04-22 10:48:33 +01:00
Auxilor
6b18b06763 Fixed placeholder equality 2022-04-22 09:55:55 +01:00
Auxilor
033e334877 Codestyle and reduced memory garbage 2022-04-22 09:53:40 +01:00
Auxilor
eb9112e480 Updated placeholder injection 2022-04-22 09:48:11 +01:00
Auxilor
b75e4d59e4 Changed getNearbyBlocks 2022-04-21 10:04:16 +01:00
Auxilor
c69bb6904f Minor fixes 2022-04-20 11:31:37 +01:00
Auxilor
9f193b7206 Fixed val using annotations 2022-04-20 11:28:55 +01:00
Auxilor
6fce2c13fe Updated to 6.34.0 2022-04-20 11:25:19 +01:00
Auxilor
02342c11a6 Added utility methods for base NBT 2022-04-20 11:25:00 +01:00
Auxilor
2fde56df0d Added ability to modify full item NBT via PersistentDataContainers and FastItemStack 2022-04-20 11:19:24 +01:00
Auxilor
cb64dedd74 Updated to kotlin 1.6.21 2022-04-20 10:57:27 +01:00
Auxilor
a7c489413e Moved IridiumSkyblock to use jar 2022-04-20 10:56:47 +01:00
Auxilor
f9ed174e31 Added PersistentDataHolder to FastItemStack 2022-04-13 13:21:37 +01:00
Auxilor
496d878a14 Added missing FIS method 2022-04-13 12:55:48 +01:00
Auxilor
00853d4a92 Fixed getSkullTexture 2022-04-13 12:39:32 +01:00
Auxilor
5eb0d2380a Updated to 6.33.0 2022-04-13 12:37:19 +01:00
Auxilor
d19cff9a42 Added component methods to FastItemStack 2022-04-13 12:36:49 +01:00
Auxilor
234b5fdd8e Fixed newbiehelper and bentobox 2022-04-11 15:02:29 +01:00
Auxilor
2dbe6c7fe4 Updated to 6.32.2 2022-04-11 14:55:48 +01:00
Auxilor
9d4d1ace08 Fixed use_spell and tempt 2022-04-11 14:55:35 +01:00
145 changed files with 2483 additions and 690 deletions

View File

@@ -4,7 +4,7 @@ buildscript {
} }
dependencies { dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.21")
} }
} }
@@ -13,7 +13,7 @@ plugins {
id("com.github.johnrengelman.shadow") version "7.1.2" id("com.github.johnrengelman.shadow") version "7.1.2"
id("maven-publish") id("maven-publish")
id("java") id("java")
kotlin("jvm") version "1.6.10" kotlin("jvm") version "1.6.21"
} }
dependencies { dependencies {
@@ -71,9 +71,6 @@ allprojects {
// CombatLogX // CombatLogX
maven("https://nexus.sirblobman.xyz/repository/public/") maven("https://nexus.sirblobman.xyz/repository/public/")
// IridiumSkyblock
maven("https://nexus.iridiumdevelopment.net/repository/maven-releases/")
// MythicMobs // MythicMobs
maven("https://mvn.lumine.io/repository/maven-public/") maven("https://mvn.lumine.io/repository/maven-public/")
@@ -85,6 +82,9 @@ allprojects {
} }
dependencies { dependencies {
// Kotlin
implementation(kotlin("stdlib", version = "1.6.21"))
// Included in spigot jar, no need to move to implementation // Included in spigot jar, no need to move to implementation
compileOnly("org.jetbrains:annotations:23.0.0") compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("com.google.guava:guava:31.1-jre") compileOnly("com.google.guava:guava:31.1-jre")
@@ -102,8 +102,7 @@ allprojects {
// Other // Other
implementation("com.github.ben-manes.caffeine:caffeine:3.0.6") implementation("com.github.ben-manes.caffeine:caffeine:3.0.6")
implementation("org.apache.maven:maven-artifact:3.8.4") implementation("org.apache.maven:maven-artifact:3.8.5")
implementation(kotlin("stdlib", version = "1.6.10"))
} }
tasks.withType<JavaCompile> { tasks.withType<JavaCompile> {

View File

@@ -319,6 +319,8 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
Eco.getHandler().addNewPlugin(this); Eco.getHandler().addNewPlugin(this);
this.getLogger().info("Initializing " + this.getColor() + this.getName());
/* /*
The minimum eco version check was moved here because it's very common 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 to add a lot of code in the constructor of plugins; meaning that the plugin

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core;
import com.willfp.eco.core.config.updating.ConfigHandler; import com.willfp.eco.core.config.updating.ConfigHandler;
import com.willfp.eco.core.config.wrapper.ConfigFactory; import com.willfp.eco.core.config.wrapper.ConfigFactory;
import com.willfp.eco.core.data.ExtendedPersistentDataContainer;
import com.willfp.eco.core.data.ProfileHandler; import com.willfp.eco.core.data.ProfileHandler;
import com.willfp.eco.core.data.keys.KeyRegistry; import com.willfp.eco.core.data.keys.KeyRegistry;
import com.willfp.eco.core.drops.DropQueueFactory; import com.willfp.eco.core.drops.DropQueueFactory;
@@ -23,6 +24,7 @@ import org.bukkit.NamespacedKey;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Mob; import org.bukkit.entity.Mob;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -282,4 +284,21 @@ public interface Handler {
*/ */
@NotNull @NotNull
<T extends Mob> EntityController<T> createEntityController(@NotNull T mob); <T extends Mob> EntityController<T> createEntityController(@NotNull T mob);
/**
* Adapt base PDC to extended PDC.
*
* @param container The container.
* @return The extended container.
*/
@NotNull
ExtendedPersistentDataContainer adaptPdc(@NotNull PersistentDataContainer container);
/**
* Create new PDC.
*
* @return The container.
*/
@NotNull
PersistentDataContainer newPdc();
} }

View File

@@ -1,6 +1,5 @@
package com.willfp.eco.core; package com.willfp.eco.core;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -234,7 +233,6 @@ public final class PluginProps {
* @param supportsExtensions If the plugin should attempt to look for extensions. * @param supportsExtensions If the plugin should attempt to look for extensions.
* @return The props. * @return The props.
*/ */
@ApiStatus.Internal
static PluginProps createSimple(final int resourceId, static PluginProps createSimple(final int resourceId,
final int bStatsId, final int bStatsId,
@NotNull final String proxyPackage, @NotNull final String proxyPackage,

View File

@@ -3,8 +3,8 @@ package com.willfp.eco.core.config.interfaces;
import com.willfp.eco.core.config.BuildableConfig; import com.willfp.eco.core.config.BuildableConfig;
import com.willfp.eco.core.config.ConfigType; import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.TransientConfig; import com.willfp.eco.core.config.TransientConfig;
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.core.placeholder.PlaceholderInjectable; import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.placeholder.StaticPlaceholder;
import com.willfp.eco.util.NumberUtils; import com.willfp.eco.util.NumberUtils;
import com.willfp.eco.util.StringUtils; import com.willfp.eco.util.StringUtils;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
@@ -471,7 +471,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
*/ */
default double getDoubleFromExpression(@NotNull String path, default double getDoubleFromExpression(@NotNull String path,
@Nullable Player player) { @Nullable Player player) {
return NumberUtils.evaluateExpression(this.getString(path), player, this.getInjectedPlaceholders()); return NumberUtils.evaluateExpression(this.getString(path), player, this);
} }
/** /**
@@ -539,12 +539,12 @@ public interface Config extends Cloneable, PlaceholderInjectable {
Config clone(); Config clone();
@Override @Override
default void injectPlaceholders(@NotNull Iterable<StaticPlaceholder> placeholders) { default void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders) {
// Do nothing. // Do nothing.
} }
@Override @Override
default List<StaticPlaceholder> getInjectedPlaceholders() { default @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@@ -2,7 +2,7 @@ package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.config.ConfigType; import com.willfp.eco.core.config.ConfigType;
import com.willfp.eco.core.config.interfaces.Config; import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.core.placeholder.StaticPlaceholder; import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.util.StringUtils; import com.willfp.eco.util.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -145,18 +145,13 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
} }
@Override @Override
public void injectPlaceholders(@NotNull final StaticPlaceholder... placeholders) { public void addInjectablePlaceholder(@NotNull final Iterable<InjectablePlaceholder> placeholders) {
handle.injectPlaceholders(placeholders); handle.addInjectablePlaceholder(placeholders);
} }
@Override @Override
public void injectPlaceholders(@NotNull final Iterable<StaticPlaceholder> placeholders) { public @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
handle.injectPlaceholders(placeholders); return handle.getPlaceholderInjections();
}
@Override
public List<StaticPlaceholder> getInjectedPlaceholders() {
return handle.getInjectedPlaceholders();
} }
@Override @Override

View File

@@ -0,0 +1,101 @@
package com.willfp.eco.core.data;
import com.willfp.eco.core.Eco;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
/**
* Persistent data container wrapper that allows for full string (non-namespaced) keys.
*/
public interface ExtendedPersistentDataContainer {
/**
* Set a key.
*
* @param key The key.
* @param dataType The data type.
* @param value The value.
* @param <T> The type.
* @param <Z> The type.
*/
<T, Z> void set(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType, @NotNull Z value);
/**
* Get if there is a key.
*
* @param key The key.
* @param dataType The data type.
* @param <T> The type.
* @param <Z> The type.
* @return If the key is present.
*/
<T, Z> boolean has(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType);
/**
* Get a value.
*
* @param key The key.
* @param dataType The data type.
* @param <T> The type.
* @param <Z> The type.
* @return The value, or null if not found.
*/
@Nullable <T, Z> Z get(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType);
/**
* Get a value or default if not present.
*
* @param key The key.
* @param dataType The data type.
* @param defaultValue The default value.
* @param <T> The type.
* @param <Z> The type.
* @return The value, or the default if not found.
*/
@NotNull <T, Z> Z getOrDefault(@NotNull String key, @NotNull PersistentDataType<T, Z> dataType, @NotNull Z defaultValue);
/**
* Get all keys, including namespaced keys.
*
* @return The keys.
*/
@NotNull
Set<String> getAllKeys();
/**
* Remove a key.
*
* @param key The key.
*/
void remove(@NotNull String key);
/**
* Get the base PDC.
*
* @return The base.
*/
@NotNull
PersistentDataContainer getBase();
/**
* Get extension for PersistentDataContainers to add non-namespaced keys.
*
* @param base The base container.
* @return The extended container.
*/
static ExtendedPersistentDataContainer extend(@NotNull PersistentDataContainer base) {
return Eco.getHandler().adaptPdc(base);
}
/**
* Create a new extended container.
*
* @return The extended container.
*/
static ExtendedPersistentDataContainer create() {
return extend(Eco.getHandler().newPdc());
}
}

View File

@@ -113,52 +113,6 @@ public final class Display {
handler.registerDisplayModule(module); handler.registerDisplayModule(module);
} }
/**
* 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.
*/
@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);
}
}
/** /**
* Set the display handler. * Set the display handler.
* <p> * <p>

View File

@@ -14,7 +14,7 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
/** /**
* The priority of the module. * The priority of the module.
*/ */
private final DisplayPriority priority; private final int weight;
/** /**
* Create a new display module. * Create a new display module.
@@ -25,7 +25,19 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
protected DisplayModule(@NotNull final EcoPlugin plugin, protected DisplayModule(@NotNull final EcoPlugin plugin,
@NotNull final DisplayPriority priority) { @NotNull final DisplayPriority priority) {
super(plugin); super(plugin);
this.priority = priority; this.weight = priority.getWeight();
}
/**
* Create a new display module.
*
* @param plugin The plugin that the display is for.
* @param weight The weight/priority of the module.
*/
protected DisplayModule(@NotNull final EcoPlugin plugin,
final int weight) {
super(plugin);
this.weight = weight;
} }
/** /**
@@ -84,8 +96,25 @@ public abstract class DisplayModule extends PluginDependent<EcoPlugin> {
* Get the display priority. * Get the display priority.
* *
* @return The priority. * @return The priority.
* @deprecated Use getWeight instead.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
public DisplayPriority getPriority() { public DisplayPriority getPriority() {
return this.priority; return switch (this.weight) {
case 100 -> DisplayPriority.LOWEST;
case 200 -> DisplayPriority.LOW;
case 300 -> DisplayPriority.HIGH;
case 400 -> DisplayPriority.HIGHEST;
default -> DisplayPriority.CUSTOM;
};
}
/**
* Get the display weight.
*
* @return The weight.
*/
public int getWeight() {
return this.weight;
} }
} }

View File

@@ -4,23 +4,51 @@ package com.willfp.eco.core.display;
* The priority (order) of display modules. * The priority (order) of display modules.
*/ */
public enum DisplayPriority { public enum DisplayPriority {
/**
* Custom weight.
*/
CUSTOM(250),
/** /**
* Ran first. * Ran first.
*/ */
LOWEST, LOWEST(100),
/** /**
* Ran second. * Ran second.
*/ */
LOW, LOW(200),
/** /**
* Ran third. * Ran third.
*/ */
HIGH, HIGH(300),
/** /**
* Ran last. * Ran last.
*/ */
HIGHEST HIGHEST(400);
/**
* The display priority weight.
*/
private final int weight;
/**
* Create new display priority.
*
* @param weight The weight.
*/
DisplayPriority(final int weight) {
this.weight = weight;
}
/**
* Get the weight.
*
* @return The weight.
*/
public int getWeight() {
return weight;
}
} }

View File

@@ -13,5 +13,6 @@ public interface NamespacedKeyFactory {
* @param key The key in the {@link NamespacedKey}. * @param key The key in the {@link NamespacedKey}.
* @return The created {@link NamespacedKey}. * @return The created {@link NamespacedKey}.
*/ */
@NotNull
NamespacedKey create(@NotNull String key); NamespacedKey create(@NotNull String key);
} }

View File

@@ -1,10 +1,13 @@
package com.willfp.eco.core.fast; package com.willfp.eco.core.fast;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import net.kyori.adventure.text.Component;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataHolder;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -16,7 +19,7 @@ import java.util.Set;
/** /**
* FastItemStack contains methods to modify and read items faster than in default bukkit. * FastItemStack contains methods to modify and read items faster than in default bukkit.
*/ */
public interface FastItemStack { public interface FastItemStack extends PersistentDataHolder {
/** /**
* Get all enchantments on an item. * Get all enchantments on an item.
* *
@@ -45,17 +48,54 @@ public interface FastItemStack {
* @param checkStored If stored enchantments should be accounted for. * @param checkStored If stored enchantments should be accounted for.
* @return A map of all enchantments. * @return A map of all enchantments.
*/ */
@NotNull
Map<Enchantment, Integer> getEnchants(boolean checkStored); Map<Enchantment, Integer> getEnchants(boolean checkStored);
/**
* Get the level of an enchantment on an item.
*
* @param enchantment The enchantment.
* @return The enchantment level, or 0 if not found.
* @deprecated Poorly named method. Use getEnchantmentLevel instead.
*/
@Deprecated(since = "6.34.0", forRemoval = true)
default int getLevelOnItem(@NotNull Enchantment enchantment) {
return getEnchantmentLevel(enchantment, false);
}
/** /**
* Get the level of an enchantment on an item. * Get the level of an enchantment on an item.
* *
* @param enchantment The enchantment. * @param enchantment The enchantment.
* @param checkStored If the stored NBT should also be checked. * @param checkStored If the stored NBT should also be checked.
* @return The enchantment level, or 0 if not found. * @return The enchantment level, or 0 if not found.
* @deprecated Poorly named method. Use getEnchantmentLevel instead.
*/ */
int getLevelOnItem(@NotNull Enchantment enchantment, @Deprecated(since = "6.34.0", forRemoval = true)
boolean checkStored); default int getLevelOnItem(@NotNull Enchantment enchantment,
boolean checkStored) {
return getEnchantmentLevel(enchantment, checkStored);
}
/**
* Get the level of an enchantment.
*
* @param enchantment The enchantment.
* @return The enchantment level, or 0 if not found.
*/
default int getEnchantmentLevel(@NotNull Enchantment enchantment) {
return getLevelOnItem(enchantment, false);
}
/**
* Get the level of an enchantment.
*
* @param enchantment The enchantment.
* @param checkStored If the stored NBT should also be checked.
* @return The enchantment level, or 0 if not found.
*/
int getEnchantmentLevel(@NotNull Enchantment enchantment,
boolean checkStored);
/** /**
* Set the item lore. * Set the item lore.
@@ -64,6 +104,13 @@ public interface FastItemStack {
*/ */
void setLore(@Nullable List<String> lore); void setLore(@Nullable List<String> lore);
/**
* Set the item lore.
*
* @param lore The lore.
*/
void setLoreComponents(@Nullable List<Component> lore);
/** /**
* Get the item lore. * Get the item lore.
* *
@@ -71,6 +118,40 @@ public interface FastItemStack {
*/ */
List<String> getLore(); List<String> getLore();
/**
* Get the item lore.
*
* @return The lore.
*/
List<Component> getLoreComponents();
/**
* Set the item name.
*
* @param name The name.
*/
void setDisplayName(@Nullable Component name);
/**
* Set the item name.
*
* @param name The name.
*/
void setDisplayName(@Nullable String name);
/**
* Get the item display name.
*
* @return The display name.
*/
Component getDisplayNameComponent();
/**
* Get the item display name.
*
* @return The display name.
*/
String getDisplayName();
/** /**
* Set the rework penalty. * Set the rework penalty.
@@ -81,7 +162,6 @@ public interface FastItemStack {
/** /**
* Get the rework penalty. * Get the rework penalty.
* .
* *
* @return The rework penalty found on the item. * @return The rework penalty found on the item.
*/ */
@@ -116,11 +196,72 @@ public interface FastItemStack {
*/ */
boolean hasItemFlag(@NotNull ItemFlag flag); boolean hasItemFlag(@NotNull ItemFlag flag);
/**
* Get the base NBT tag (Not PublicBukkitValues, the base) as a PersistentDataContainer.
* <p>
* The returned PersistentDataContainer will not modify the item until the tag is set.
*
* @return The base NBT tag.
*/
PersistentDataContainer getBaseTag();
/**
* Set the base NBT tag (Not PublicBukkitValues, the base) from a PersistentDataContainer.
*
* @param container The PersistentDataContainer.
*/
void setBaseTag(@Nullable PersistentDataContainer container);
/**
* Get the type of the item.
*
* @return The type.
*/
@NotNull
Material getType();
/**
* Set the type of the item.
*
* @param material The type.
*/
void setType(@NotNull Material material);
/**
* Get the amount of the item.
*
* @return The amount.
*/
int getAmount();
/**
* Set the amount of the item.
*
* @param amount The amount.
*/
void setAmount(int amount);
/**
* Get the custom model data.
*
* @return The data, or null if none.
*/
@Nullable
Integer getCustomModelData();
/**
* Set the custom model data.
*
* @param data The data, null to remove.
*/
void setCustomModelData(@Nullable Integer data);
/** /**
* Get the Bukkit ItemStack again. * Get the Bukkit ItemStack again.
* *
* @return The ItemStack. * @return The ItemStack.
*/ */
@NotNull
ItemStack unwrap(); ItemStack unwrap();
/** /**

View File

@@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
@@ -59,6 +60,53 @@ public interface Menu {
*/ */
List<ItemStack> getCaptiveItems(@NotNull Player player); List<ItemStack> getCaptiveItems(@NotNull Player player);
/**
* Add state for a player.
*
* @param player The player.
* @param key The key.
* @param value The state.
*/
void addState(@NotNull Player player,
@NotNull String key,
@Nullable Object value);
/**
* Remove state for a player.
*
* @param player The player.
* @param key The key.
*/
void removeState(@NotNull Player player,
@NotNull String key);
/**
* Clear state for a player.
*
* @param player The player.
*/
void clearState(@NotNull Player player);
/**
* Get state for a player.
*
* @param player The player.
* @param key The key.
* @param <T> The type of state.
* @return The value.
*/
@Nullable <T> T getState(@NotNull Player player,
@NotNull String key);
/**
* Get state for a player.
*
* @param player The player.
* @return The state.
*/
Map<String, Object> getState(@NotNull Player player);
/** /**
* Write data. * Write data.
* *
@@ -68,7 +116,9 @@ public interface Menu {
* @param value The value. * @param value The value.
* @param <T> The type. * @param <T> The type.
* @param <Z> The type. * @param <Z> The type.
* @deprecated Use addState instead.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
<T, Z> void writeData(@NotNull Player player, <T, Z> void writeData(@NotNull Player player,
@NotNull NamespacedKey key, @NotNull NamespacedKey key,
@NotNull PersistentDataType<T, Z> type, @NotNull PersistentDataType<T, Z> type,
@@ -83,7 +133,9 @@ public interface Menu {
* @param <T> The type. * @param <T> The type.
* @param <Z> The type. * @param <Z> The type.
* @return The data. * @return The data.
* @deprecated Use getState instead.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
@Nullable <T, Z> T readData(@NotNull Player player, @Nullable <T, Z> T readData(@NotNull Player player,
@NotNull NamespacedKey key, @NotNull NamespacedKey key,
@NotNull PersistentDataType<T, Z> type); @NotNull PersistentDataType<T, Z> type);
@@ -93,7 +145,9 @@ public interface Menu {
* *
* @param player The player. * @param player The player.
* @return The keys. * @return The keys.
* @deprecated Use getState instead.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
Set<NamespacedKey> getKeys(@NotNull Player player); Set<NamespacedKey> getKeys(@NotNull Player player);
/** /**

View File

@@ -2,9 +2,11 @@ package com.willfp.eco.core.gui.menu;
import com.willfp.eco.core.gui.slot.FillerMask; import com.willfp.eco.core.gui.slot.FillerMask;
import com.willfp.eco.core.gui.slot.Slot; import com.willfp.eco.core.gui.slot.Slot;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryCloseEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
/** /**
@@ -66,6 +68,14 @@ public interface MenuBuilder {
*/ */
MenuBuilder onClose(@NotNull CloseHandler action); MenuBuilder onClose(@NotNull CloseHandler action);
/**
* Set the action to run on render.
*
* @param action The action.
* @return The builder.
*/
MenuBuilder onRender(@NotNull BiConsumer<Player, Menu> action);
/** /**
* Build the menu. * Build the menu.
* *

View File

@@ -0,0 +1,18 @@
package com.willfp.eco.core.integrations.afk;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* AFK Integration.
*/
public interface AFKIntegration extends Integration {
/**
* Get if a player is afk.
*
* @param player The player.
* @return If afk.
*/
boolean isAfk(@NotNull Player player);
}

View File

@@ -13,14 +13,15 @@ public final class AFKManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<AFKWrapper> REGISTERED = new HashSet<>(); private static final Set<AFKIntegration> REGISTERED = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
* *
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final AFKWrapper integration) { public static void register(@NotNull final AFKIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
@@ -31,8 +32,8 @@ public final class AFKManager {
* @return If afk. * @return If afk.
*/ */
public static boolean isAfk(@NotNull final Player player) { public static boolean isAfk(@NotNull final Player player) {
for (AFKWrapper afkWrapper : REGISTERED) { for (AFKIntegration integration : REGISTERED) {
if (afkWrapper.isAfk(player)) { if (integration.isAfk(player)) {
return true; return true;
} }
} }

View File

@@ -1,18 +1,11 @@
package com.willfp.eco.core.integrations.afk; package com.willfp.eco.core.integrations.afk;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/** /**
* Wrapper class for afk integrations. * Wrapper class for afk integrations.
*
* @deprecated Use AFKIntegration instead.
*/ */
public interface AFKWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface AFKWrapper extends AFKIntegration {
* Get if a player is afk.
*
* @param player The player.
* @return If afk.
*/
boolean isAfk(@NotNull Player player);
} }

View File

@@ -0,0 +1,24 @@
package com.willfp.eco.core.integrations.anticheat;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* Wrapper class for anticheat integrations.
*/
public interface AnticheatIntegration extends Integration {
/**
* Exempt a player from checks.
*
* @param player The player to exempt.
*/
void exempt(@NotNull Player player);
/**
* Unexempt a player from checks.
*
* @param player The player to unexempt.
*/
void unexempt(@NotNull Player player);
}

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.integrations.anticheat; package com.willfp.eco.core.integrations.anticheat;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@@ -15,19 +16,31 @@ public final class AnticheatManager {
/** /**
* A set of all registered anticheats. * A set of all registered anticheats.
*/ */
private static final Set<AnticheatWrapper> ANTICHEATS = new HashSet<>(); private static final Set<AnticheatIntegration> ANTICHEATS = new HashSet<>();
/** /**
* Register a new anticheat. * Register a new anticheat.
* *
* @param plugin The plugin. * @param plugin The plugin.
* @param anticheat The anticheat to register. * @param anticheat The anticheat to register.
* @deprecated Don't pass instance of eco.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
public static void register(@NotNull final EcoPlugin plugin, public static void register(@NotNull final EcoPlugin plugin,
@NotNull final AnticheatWrapper anticheat) { @NotNull final AnticheatIntegration anticheat) {
register(anticheat);
}
/**
* Register a new anticheat.
*
* @param anticheat The anticheat to register.
*/
public static void register(@NotNull final AnticheatIntegration anticheat) {
if (anticheat instanceof Listener) { if (anticheat instanceof Listener) {
plugin.getEventManager().registerListener((Listener) anticheat); Eco.getHandler().getEcoPlugin().getEventManager().registerListener((Listener) anticheat);
} }
ANTICHEATS.removeIf(it -> it.getPluginName().equalsIgnoreCase(anticheat.getPluginName()));
ANTICHEATS.add(anticheat); ANTICHEATS.add(anticheat);
} }

View File

@@ -1,24 +1,11 @@
package com.willfp.eco.core.integrations.anticheat; package com.willfp.eco.core.integrations.anticheat;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/** /**
* Wrapper class for anticheat integrations. * Wrapper class for anticheat integrations.
*
* @deprecated Use AnticheatIntegration instead.
*/ */
public interface AnticheatWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface AnticheatWrapper extends AnticheatIntegration {
* Exempt a player from checks.
*
* @param player The player to exempt.
*/
void exempt(@NotNull Player player);
/**
* Unexempt a player from checks.
*
* @param player The player to unexempt.
*/
void unexempt(@NotNull Player player);
} }

View File

@@ -0,0 +1,60 @@
package com.willfp.eco.core.integrations.antigrief;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* Wrapper class for antigrief integrations.
*/
public interface AntigriefIntegration extends Integration {
/**
* Can player break block.
*
* @param player The player.
* @param block The block.
* @return If player can break block.
*/
boolean canBreakBlock(@NotNull Player player, @NotNull Block block);
/**
* Can player create explosion at location.
*
* @param player The player.
* @param location The location.
* @return If player can create explosion.
*/
boolean canCreateExplosion(@NotNull Player player, @NotNull Location location);
/**
* Can player place block.
*
* @param player The player.
* @param block The block.
* @return If player can place block.
*/
boolean canPlaceBlock(@NotNull Player player, @NotNull Block block);
/**
* Can player injure living entity.
*
* @param player The player.
* @param victim The victim.
* @return If player can injure.
*/
boolean canInjure(@NotNull Player player, @NotNull LivingEntity victim);
/**
* Can player pick up item.
*
* @param player The player.
* @param location The location.
* @return If player can pick up item.
*/
default boolean canPickupItem(@NotNull Player player, @NotNull Location location) {
return true;
}
}

View File

@@ -16,14 +16,15 @@ public final class AntigriefManager {
/** /**
* Registered antigriefs. * Registered antigriefs.
*/ */
private static final Set<AntigriefWrapper> REGISTERED = new HashSet<>(); private static final Set<AntigriefIntegration> REGISTERED = new HashSet<>();
/** /**
* Register a new AntiGrief/Land Management integration. * Register a new AntiGrief/Land Management integration.
* *
* @param antigrief The integration to register. * @param antigrief The integration to register.
*/ */
public static void register(@NotNull final AntigriefWrapper antigrief) { public static void register(@NotNull final AntigriefIntegration antigrief) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName()));
REGISTERED.add(antigrief); REGISTERED.add(antigrief);
} }
@@ -32,7 +33,7 @@ public final class AntigriefManager {
* *
* @param antigrief The integration to unregister. * @param antigrief The integration to unregister.
*/ */
public static void unregister(@NotNull final AntigriefWrapper antigrief) { public static void unregister(@NotNull final AntigriefIntegration antigrief) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName())); REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(antigrief.getPluginName()));
REGISTERED.remove(antigrief); REGISTERED.remove(antigrief);
} }
@@ -46,7 +47,7 @@ public final class AntigriefManager {
*/ */
public static boolean canPickupItem(@NotNull final Player player, public static boolean canPickupItem(@NotNull final Player player,
@NotNull final Location location) { @NotNull final Location location) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canPickupItem(player, location)); return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canPickupItem(player, location));
} }
/** /**
@@ -58,7 +59,7 @@ public final class AntigriefManager {
*/ */
public static boolean canBreakBlock(@NotNull final Player player, public static boolean canBreakBlock(@NotNull final Player player,
@NotNull final Block block) { @NotNull final Block block) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canBreakBlock(player, block)); return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canBreakBlock(player, block));
} }
/** /**
@@ -70,7 +71,7 @@ public final class AntigriefManager {
*/ */
public static boolean canCreateExplosion(@NotNull final Player player, public static boolean canCreateExplosion(@NotNull final Player player,
@NotNull final Location location) { @NotNull final Location location) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canCreateExplosion(player, location)); return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canCreateExplosion(player, location));
} }
/** /**
@@ -82,7 +83,7 @@ public final class AntigriefManager {
*/ */
public static boolean canPlaceBlock(@NotNull final Player player, public static boolean canPlaceBlock(@NotNull final Player player,
@NotNull final Block block) { @NotNull final Block block) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canPlaceBlock(player, block)); return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canPlaceBlock(player, block));
} }
/** /**
@@ -94,7 +95,7 @@ public final class AntigriefManager {
*/ */
public static boolean canInjure(@NotNull final Player player, public static boolean canInjure(@NotNull final Player player,
@NotNull final LivingEntity victim) { @NotNull final LivingEntity victim) {
return REGISTERED.stream().allMatch(antigriefWrapper -> antigriefWrapper.canInjure(player, victim)); return REGISTERED.stream().allMatch(antigriefIntegration -> antigriefIntegration.canInjure(player, victim));
} }
private AntigriefManager() { private AntigriefManager() {

View File

@@ -1,60 +1,11 @@
package com.willfp.eco.core.integrations.antigrief; package com.willfp.eco.core.integrations.antigrief;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/** /**
* Wrapper class for antigrief integrations. * Wrapper class for antigrief integrations.
*
* @deprecated Use AntigriefIntegration instead.
*/ */
public interface AntigriefWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface AntigriefWrapper extends AntigriefIntegration {
* Can player break block.
*
* @param player The player.
* @param block The block.
* @return If player can break block.
*/
boolean canBreakBlock(@NotNull Player player, @NotNull Block block);
/**
* Can player create explosion at location.
*
* @param player The player.
* @param location The location.
* @return If player can create explosion.
*/
boolean canCreateExplosion(@NotNull Player player, @NotNull Location location);
/**
* Can player place block.
*
* @param player The player.
* @param block The block.
* @return If player can place block.
*/
boolean canPlaceBlock(@NotNull Player player, @NotNull Block block);
/**
* Can player injure living entity.
*
* @param player The player.
* @param victim The victim.
* @return If player can injure.
*/
boolean canInjure(@NotNull Player player, @NotNull LivingEntity victim);
/**
* Can player pick up item.
*
* @param player The player.
* @param location The location.
* @return If player can pick up item.
*/
default boolean canPickupItem(@NotNull Player player, @NotNull Location location) {
return true;
}
} }

View File

@@ -0,0 +1,15 @@
package com.willfp.eco.core.integrations.customentities;
import com.willfp.eco.core.integrations.Integration;
/**
* Wrapper class for custom item integrations.
*/
public interface CustomEntitiesIntegration extends Integration {
/**
* Register all the custom entities for a specific plugin into eco.
*
* @see com.willfp.eco.core.entities.Entities
*/
void registerAllEntities();
}

View File

@@ -12,14 +12,15 @@ public final class CustomEntitiesManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<CustomEntitiesWrapper> REGISTERED = new HashSet<>(); private static final Set<CustomEntitiesIntegration> REGISTERED = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
* *
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final CustomEntitiesWrapper integration) { public static void register(@NotNull final CustomEntitiesIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
@@ -29,8 +30,8 @@ public final class CustomEntitiesManager {
* @see com.willfp.eco.core.entities.Entities * @see com.willfp.eco.core.entities.Entities
*/ */
public static void registerAllEntities() { public static void registerAllEntities() {
for (CustomEntitiesWrapper wrapper : REGISTERED) { for (CustomEntitiesIntegration integration : REGISTERED) {
wrapper.registerAllEntities(); integration.registerAllEntities();
} }
} }

View File

@@ -1,15 +1,11 @@
package com.willfp.eco.core.integrations.customentities; package com.willfp.eco.core.integrations.customentities;
import com.willfp.eco.core.integrations.Integration;
/** /**
* Wrapper class for custom item integrations. * Wrapper class for custom item integrations.
*
* @deprecated Use CustomEntitiesIntegration instead.
*/ */
public interface CustomEntitiesWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface CustomEntitiesWrapper extends CustomEntitiesIntegration {
* Register all the custom entities for a specific plugin into eco.
*
* @see com.willfp.eco.core.entities.Entities
*/
void registerAllEntities();
} }

View File

@@ -0,0 +1,24 @@
package com.willfp.eco.core.integrations.customitems;
import com.willfp.eco.core.integrations.Integration;
/**
* Wrapper class for custom item integrations.
*/
public interface CustomItemsIntegration extends Integration {
/**
* Register all the custom items for a specific plugin into eco.
*
* @see com.willfp.eco.core.items.Items
*/
default void registerAllItems() {
// Override when needed.
}
/**
* Register {@link com.willfp.eco.core.items.provider.ItemProvider}s.
*/
default void registerProvider() {
// Override when needed.
}
}

View File

@@ -12,14 +12,15 @@ public final class CustomItemsManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<CustomItemsWrapper> REGISTERED = new HashSet<>(); private static final Set<CustomItemsIntegration> REGISTERED = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
* *
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final CustomItemsWrapper integration) { public static void register(@NotNull final CustomItemsIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
@@ -29,8 +30,8 @@ public final class CustomItemsManager {
* @see com.willfp.eco.core.items.Items * @see com.willfp.eco.core.items.Items
*/ */
public static void registerAllItems() { public static void registerAllItems() {
for (CustomItemsWrapper customItemsWrapper : REGISTERED) { for (CustomItemsIntegration customItemsIntegration : REGISTERED) {
customItemsWrapper.registerAllItems(); customItemsIntegration.registerAllItems();
} }
} }
@@ -40,8 +41,8 @@ public final class CustomItemsManager {
* @see com.willfp.eco.core.items.Items * @see com.willfp.eco.core.items.Items
*/ */
public static void registerProviders() { public static void registerProviders() {
for (CustomItemsWrapper customItemsWrapper : REGISTERED) { for (CustomItemsIntegration customItemsIntegration : REGISTERED) {
customItemsWrapper.registerProvider(); customItemsIntegration.registerProvider();
} }
} }

View File

@@ -1,24 +1,11 @@
package com.willfp.eco.core.integrations.customitems; package com.willfp.eco.core.integrations.customitems;
import com.willfp.eco.core.integrations.Integration;
/** /**
* Wrapper class for custom item integrations. * Wrapper class for custom item integrations.
*
* @deprecated Use CustomItemsIntegration instead.
*/ */
public interface CustomItemsWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface CustomItemsWrapper extends CustomItemsIntegration {
* Register all the custom items for a specific plugin into eco.
*
* @see com.willfp.eco.core.items.Items
*/
default void registerAllItems() {
// Override when needed.
}
/**
* Register {@link com.willfp.eco.core.items.provider.ItemProvider}s.
*/
default void registerProvider() {
// Override when needed.
}
} }

View File

@@ -0,0 +1,48 @@
package com.willfp.eco.core.integrations.economy;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
/**
* Wrapper class for economy integrations.
*/
public interface EconomyIntegration extends Integration {
/**
* Get if a player has a certain amount.
*
* @param player The player.
* @param amount The amount.
* @return If the player has the amount.
*/
boolean hasAmount(@NotNull OfflinePlayer player,
double amount);
/**
* Give money to a player.
*
* @param player The player.
* @param amount The amount to give.
* @return If the transaction was a success.
*/
boolean giveMoney(@NotNull OfflinePlayer player,
double amount);
/**
* Remove money from a player.
*
* @param player The player.
* @param amount The amount to remove.
* @return If the transaction was a success.
*/
boolean removeMoney(@NotNull OfflinePlayer player,
double amount);
/**
* Get the balance of a player.
*
* @param player The player.
* @return The balance.
*/
double getBalance(@NotNull OfflinePlayer player);
}

View File

@@ -13,14 +13,15 @@ public final class EconomyManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<EconomyWrapper> REGISTERED = new HashSet<>(); private static final Set<EconomyIntegration> REGISTERED = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
* *
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final EconomyWrapper integration) { public static void register(@NotNull final EconomyIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
@@ -42,8 +43,8 @@ public final class EconomyManager {
*/ */
public static boolean hasAmount(@NotNull final OfflinePlayer player, public static boolean hasAmount(@NotNull final OfflinePlayer player,
final double amount) { final double amount) {
for (EconomyWrapper wrapper : REGISTERED) { for (EconomyIntegration integration : REGISTERED) {
return wrapper.hasAmount(player, amount); return integration.hasAmount(player, amount);
} }
return false; return false;
@@ -58,8 +59,8 @@ public final class EconomyManager {
*/ */
public static boolean giveMoney(@NotNull final OfflinePlayer player, public static boolean giveMoney(@NotNull final OfflinePlayer player,
final double amount) { final double amount) {
for (EconomyWrapper wrapper : REGISTERED) { for (EconomyIntegration integration : REGISTERED) {
return wrapper.giveMoney(player, amount); return integration.giveMoney(player, amount);
} }
return false; return false;
@@ -74,8 +75,8 @@ public final class EconomyManager {
*/ */
public static boolean removeMoney(@NotNull final OfflinePlayer player, public static boolean removeMoney(@NotNull final OfflinePlayer player,
final double amount) { final double amount) {
for (EconomyWrapper wrapper : REGISTERED) { for (EconomyIntegration integration : REGISTERED) {
return wrapper.removeMoney(player, amount); return integration.removeMoney(player, amount);
} }
return false; return false;
@@ -88,8 +89,8 @@ public final class EconomyManager {
* @return The balance. * @return The balance.
*/ */
public static double getBalance(@NotNull final OfflinePlayer player) { public static double getBalance(@NotNull final OfflinePlayer player) {
for (EconomyWrapper wrapper : REGISTERED) { for (EconomyIntegration integration : REGISTERED) {
return wrapper.getBalance(player); return integration.getBalance(player);
} }
return 0; return 0;

View File

@@ -1,48 +1,11 @@
package com.willfp.eco.core.integrations.economy; package com.willfp.eco.core.integrations.economy;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
/** /**
* Wrapper class for economy integrations. * Wrapper class for economy integrations.
*
* @deprecated Use EconomyIntegration instead.
*/ */
public interface EconomyWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface EconomyWrapper extends EconomyIntegration {
* Get if a player has a certain amount.
*
* @param player The player.
* @param amount The amount.
* @return If the player has the amount.
*/
boolean hasAmount(@NotNull OfflinePlayer player,
double amount);
/**
* Give money to a player.
*
* @param player The player.
* @param amount The amount to give.
* @return If the transaction was a success.
*/
boolean giveMoney(@NotNull OfflinePlayer player,
double amount);
/**
* Remove money from a player.
*
* @param player The player.
* @param amount The amount to remove.
* @return If the transaction was a success.
*/
boolean removeMoney(@NotNull OfflinePlayer player,
double amount);
/**
* Get the balance of a player.
*
* @param player The player.
* @return The balance.
*/
double getBalance(@NotNull OfflinePlayer player);
} }

View File

@@ -0,0 +1,22 @@
package com.willfp.eco.core.integrations.hologram;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Wrapper class for hologram integrations.
*/
public interface HologramIntegration extends Integration {
/**
* Create hologram.
*
* @param location The location.
* @param contents The contents for the hologram.
* @return The hologram.
*/
Hologram createHologram(@NotNull Location location,
@NotNull List<String> contents);
}

View File

@@ -14,14 +14,15 @@ public final class HologramManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<HologramWrapper> REGISTERED = new HashSet<>(); private static final Set<HologramIntegration> REGISTERED = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
* *
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final HologramWrapper integration) { public static void register(@NotNull final HologramIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
@@ -34,8 +35,8 @@ public final class HologramManager {
*/ */
public static Hologram createHologram(@NotNull final Location location, public static Hologram createHologram(@NotNull final Location location,
@NotNull final List<String> contents) { @NotNull final List<String> contents) {
for (HologramWrapper wrapper : REGISTERED) { for (HologramIntegration integration : REGISTERED) {
return wrapper.createHologram(location, contents); return integration.createHologram(location, contents);
} }
return new DummyHologram(); return new DummyHologram();

View File

@@ -1,22 +1,11 @@
package com.willfp.eco.core.integrations.hologram; package com.willfp.eco.core.integrations.hologram;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.Location;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/** /**
* Wrapper class for hologram integrations. * Wrapper class for hologram integrations.
*
* @deprecated Use HologramIntegration instead.
*/ */
public interface HologramWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface HologramWrapper extends HologramIntegration {
* Create hologram.
*
* @param location The location.
* @param contents The contents for the hologram.
* @return The hologram.
*/
Hologram createHologram(@NotNull Location location,
@NotNull List<String> contents);
} }

View File

@@ -0,0 +1,27 @@
package com.willfp.eco.core.integrations.mcmmo;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
/**
* Wrapper class for mcmmo integrations.
*/
public interface McmmoIntegration extends Integration {
/**
* Get bonus drop count of block.
*
* @param block The block.
* @return The drop multiplier.
*/
int getBonusDropCount(@NotNull Block block);
/**
* Get if event is fake.
*
* @param event The event.
* @return If is fake.
*/
boolean isFake(@NotNull Event event);
}

View File

@@ -14,14 +14,15 @@ public final class McmmoManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<McmmoWrapper> REGISTERED = new HashSet<>(); private static final Set<McmmoIntegration> REGISTERED = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
* *
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final McmmoWrapper integration) { public static void register(@NotNull final McmmoIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
@@ -32,8 +33,8 @@ public final class McmmoManager {
* @return The bonus drop count. * @return The bonus drop count.
*/ */
public static int getBonusDropCount(@NotNull final Block block) { public static int getBonusDropCount(@NotNull final Block block) {
for (McmmoWrapper mcmmoWrapper : REGISTERED) { for (McmmoIntegration mcmmoIntegration : REGISTERED) {
return mcmmoWrapper.getBonusDropCount(block); return mcmmoIntegration.getBonusDropCount(block);
} }
return 0; return 0;
} }
@@ -45,8 +46,8 @@ public final class McmmoManager {
* @return If the event is fake. * @return If the event is fake.
*/ */
public static boolean isFake(@NotNull final Event event) { public static boolean isFake(@NotNull final Event event) {
for (McmmoWrapper mcmmoWrapper : REGISTERED) { for (McmmoIntegration mcmmoIntegration : REGISTERED) {
return mcmmoWrapper.isFake(event); return mcmmoIntegration.isFake(event);
} }
return false; return false;
} }

View File

@@ -1,27 +1,11 @@
package com.willfp.eco.core.integrations.mcmmo; package com.willfp.eco.core.integrations.mcmmo;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
/** /**
* Wrapper class for mcmmo integrations. * Wrapper class for mcmmo integrations.
*
* @deprecated Use McmmoIntegration instead.
*/ */
public interface McmmoWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface McmmoWrapper extends McmmoIntegration {
* Get bonus drop count of block.
*
* @param block The block.
* @return The drop multiplier.
*/
int getBonusDropCount(@NotNull Block block);
/**
* Get if event is fake.
*
* @param event The event.
* @return If is fake.
*/
boolean isFake(@NotNull Event event);
} }

View File

@@ -4,8 +4,11 @@ import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.core.placeholder.Placeholder; import com.willfp.eco.core.placeholder.Placeholder;
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.placeholder.PlayerPlaceholder; import com.willfp.eco.core.placeholder.PlayerPlaceholder;
import com.willfp.eco.core.placeholder.PlayerStaticPlaceholder;
import com.willfp.eco.core.placeholder.PlayerlessPlaceholder; import com.willfp.eco.core.placeholder.PlayerlessPlaceholder;
import com.willfp.eco.core.placeholder.StaticPlaceholder; import com.willfp.eco.core.placeholder.StaticPlaceholder;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -43,6 +46,21 @@ public final class PlaceholderManager {
.expireAfterWrite(50, TimeUnit.MILLISECONDS) .expireAfterWrite(50, TimeUnit.MILLISECONDS)
.build(key -> key.entry.getValue(key.player)); .build(key -> key.entry.getValue(key.player));
/**
* Empty injectable object.
*/
private static final PlaceholderInjectable EMPTY_INJECTABLE = new PlaceholderInjectable() {
@Override
public void clearInjectedPlaceholders() {
// Do nothing.
}
@Override
public @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
return Collections.emptyList();
}
};
/** /**
* Register a new placeholder integration. * Register a new placeholder integration.
* *
@@ -144,7 +162,7 @@ public final class PlaceholderManager {
*/ */
public static String translatePlaceholders(@NotNull final String text, public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player) { @Nullable final Player player) {
return translatePlaceholders(text, player, Collections.emptyList()); return translatePlaceholders(text, player, EMPTY_INJECTABLE);
} }
/** /**
@@ -154,17 +172,37 @@ public final class PlaceholderManager {
* @param player The player to translate the placeholders with respect to. * @param player The player to translate the placeholders with respect to.
* @param statics Extra static placeholders. * @param statics Extra static placeholders.
* @return The text, translated. * @return The text, translated.
* @deprecated Use new static system.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
public static String translatePlaceholders(@NotNull final String text, public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player, @Nullable final Player player,
@NotNull final List<StaticPlaceholder> statics) { @NotNull final List<StaticPlaceholder> statics) {
return translatePlaceholders(text, player, EMPTY_INJECTABLE);
}
/**
* Translate all placeholders with respect to a player.
*
* @param text The text that may contain placeholders to translate.
* @param player The player to translate the placeholders with respect to.
* @param context The injectable context.
* @return The text, translated.
*/
public static String translatePlaceholders(@NotNull final String text,
@Nullable final Player player,
@NotNull final PlaceholderInjectable context) {
String processed = text; String processed = text;
for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) { for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
processed = integration.translate(processed, player); processed = integration.translate(processed, player);
} }
for (StaticPlaceholder placeholder : statics) { for (InjectablePlaceholder injection : context.getPlaceholderInjections()) {
// Do I know this is a bad way of doing this? Yes. // Do I know this is a bad way of doing this? Yes.
processed = processed.replace("%" + placeholder.getIdentifier() + "%", placeholder.getValue()); if (injection instanceof StaticPlaceholder placeholder) {
processed = processed.replace("%" + placeholder.getIdentifier() + "%", placeholder.getValue());
} else if (injection instanceof PlayerStaticPlaceholder placeholder && player != null) {
processed = processed.replace("%" + placeholder.getIdentifier() + "%", placeholder.getValue(player));
}
} }
return processed; return processed;
} }

View File

@@ -0,0 +1,28 @@
package com.willfp.eco.core.integrations.shop;
import com.willfp.eco.core.integrations.Integration;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.Nullable;
/**
* Wrapper class for shop integrations.
*/
public interface ShopIntegration extends Integration {
/**
* Register eco item provider for shop plugins.
*/
default void registerEcoProvider() {
// Do nothing unless overridden.
}
/**
* Get the sell event adapter.
*
* @return The listener.
*/
@Nullable
default Listener getSellEventAdapter() {
// Do nothing unless overridden.
return null;
}
}

View File

@@ -1,5 +1,8 @@
package com.willfp.eco.core.integrations.shop; package com.willfp.eco.core.integrations.shop;
import com.willfp.eco.core.EcoPlugin;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashSet; import java.util.HashSet;
@@ -12,23 +15,40 @@ public final class ShopManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private static final Set<ShopWrapper> REGISTERED = new HashSet<>(); private static final Set<ShopIntegration> REGISTERED = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
* *
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public static void register(@NotNull final ShopWrapper integration) { public static void register(@NotNull final ShopIntegration integration) {
REGISTERED.removeIf(it -> it.getPluginName().equalsIgnoreCase(integration.getPluginName()));
REGISTERED.add(integration); REGISTERED.add(integration);
} }
/**
* Register the events with eco.
*
* @param plugin Instance of eco.
*/
@ApiStatus.Internal
public static void registerEvents(@NotNull final EcoPlugin plugin) {
for (ShopIntegration integration : REGISTERED) {
Listener listener = integration.getSellEventAdapter();
if (listener != null) {
plugin.getEventManager().registerListener(listener);
}
}
}
/** /**
* Register eco item provider for shop plugins. * Register eco item provider for shop plugins.
*/ */
public static void registerEcoProvider() { public static void registerEcoProvider() {
for (ShopWrapper shopWrapper : REGISTERED) { for (ShopIntegration shopIntegration : REGISTERED) {
shopWrapper.registerEcoProvider(); shopIntegration.registerEcoProvider();
} }
} }

View File

@@ -0,0 +1,104 @@
package com.willfp.eco.core.integrations.shop;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Unified event for shop plugins to fire in order to have sell multipliers.
*/
public class ShopSellEvent extends PlayerEvent {
/**
* The event handler list.
*/
private static final HandlerList HANDLER_LIST = new HandlerList();
/**
* The sell price.
*/
private double price;
/**
* The item to be sold.
*/
@Nullable
private final ItemStack item;
/**
* Create new shop sell event.
*
* @param who The player.
* @param price The price.
* @param item The item.
*/
public ShopSellEvent(@NotNull final Player who,
final double price,
@Nullable final ItemStack item) {
super(who);
this.price = price;
this.item = item;
}
/**
* Get the price.
*
* @return The price.
*/
public double getPrice() {
return this.price;
}
/**
* Set the price.
*
* @param price The price.
*/
public void setPrice(final double price) {
this.price = price;
}
/**
* Get the item to be sold.
*
* @return The item. Can be null for some plugins, so check hasKnownItem first!
*/
@Nullable
public ItemStack getItem() {
return item;
}
/**
* Get if the item is known. Some shop plugins are lacking this in their event,
* so always check this before getItem(), as getItem() may be null.
*
* @return If the item is known.
*/
public boolean hasKnownItem() {
return item != null;
}
/**
* Bukkit parity.
*
* @return The handlers.
*/
@NotNull
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
/**
* Bukkit parity.
*
* @return The handlers.
*/
@NotNull
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}

View File

@@ -1,13 +1,11 @@
package com.willfp.eco.core.integrations.shop; package com.willfp.eco.core.integrations.shop;
import com.willfp.eco.core.integrations.Integration;
/** /**
* Wrapper class for shop integrations. * Wrapper class for shop integrations.
*
* @deprecated Use ShopIntegration instead.
*/ */
public interface ShopWrapper extends Integration { @Deprecated(since = "6.35.0", forRemoval = true)
/** public interface ShopWrapper extends ShopIntegration {
* Register eco item provider for shop plugins.
*/
void registerEcoProvider();
} }

View File

@@ -48,6 +48,11 @@ public class CustomItem implements TestableItem {
this.test = test; this.test = test;
this.item = item; this.item = item;
/*
This runs the next tick, because it's very likely that the test can't return true
immediately after due to registration order; so eco waits until the item should be
working in order to check.
*/
Eco.getHandler().getEcoPlugin().getScheduler().runLater(() -> { Eco.getHandler().getEcoPlugin().getScheduler().runLater(() -> {
if (!matches(getItem())) { if (!matches(getItem())) {
Bukkit.getLogger().severe("Item with key " + key + " is invalid!"); Bukkit.getLogger().severe("Item with key " + key + " is invalid!");

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.items;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.willfp.eco.core.fast.FastItemStack;
import com.willfp.eco.core.items.args.LookupArgParser; import com.willfp.eco.core.items.args.LookupArgParser;
import com.willfp.eco.core.items.provider.ItemProvider; import com.willfp.eco.core.items.provider.ItemProvider;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem; import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
@@ -16,6 +17,7 @@ import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -489,6 +491,32 @@ public final class Items {
return to; return to;
} }
/**
* Get the base NBT tag on an item.
*
* @param itemStack The ItemStack.
* @return The base NBT.
*/
@NotNull
public static PersistentDataContainer getBaseNBT(@NotNull final ItemStack itemStack) {
return FastItemStack.wrap(itemStack).getBaseTag();
}
/**
* Set the base NBT tag on an item.
*
* @param itemStack The ItemStack.
* @param container The base NBT tag.
* @return The ItemStack, modified. Not required to use, as this modifies the instance.¬
*/
@NotNull
public static ItemStack setBaseNBT(@NotNull final ItemStack itemStack,
@Nullable final PersistentDataContainer container) {
FastItemStack fis = FastItemStack.wrap(itemStack);
fis.setBaseTag(container);
return fis.unwrap();
}
private Items() { private Items() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }

View File

@@ -0,0 +1,14 @@
package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
/**
* Placeholders that can be injected into {@link PlaceholderInjectable} objects.
*/
public sealed interface InjectablePlaceholder extends Placeholder permits PlayerStaticPlaceholder, StaticPlaceholder {
@Override
default EcoPlugin getPlugin() {
return Eco.getHandler().getEcoPlugin();
}
}

View File

@@ -5,7 +5,7 @@ import com.willfp.eco.core.EcoPlugin;
/** /**
* A placeholder represents a string that can hold a value. * A placeholder represents a string that can hold a value.
*/ */
public sealed interface Placeholder permits PlayerPlaceholder, PlayerlessPlaceholder, StaticPlaceholder { public sealed interface Placeholder permits PlayerPlaceholder, PlayerlessPlaceholder, InjectablePlaceholder {
/** /**
* Get the plugin that holds the placeholder. * Get the plugin that holds the placeholder.
* *

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.placeholder;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@@ -22,7 +23,40 @@ public interface PlaceholderInjectable {
* *
* @param placeholders The placeholders. * @param placeholders The placeholders.
*/ */
void injectPlaceholders(@NotNull Iterable<StaticPlaceholder> placeholders); default void injectPlaceholders(@NotNull InjectablePlaceholder... placeholders) {
this.addInjectablePlaceholder(List.of(placeholders));
}
/**
* Inject placeholder.
*
* @param placeholders The placeholders.
*/
@Deprecated(since = "6.35.0", forRemoval = true)
default void injectPlaceholders(@NotNull Iterable<StaticPlaceholder> placeholders) {
List<InjectablePlaceholder> toInject = new ArrayList<>();
for (StaticPlaceholder placeholder : placeholders) {
toInject.add(placeholder);
}
this.addInjectablePlaceholder(toInject);
}
/**
* Inject placeholders.
* <p>
* When implementing a PlaceholderInjectable object, override this method.
*
* @param placeholders The placeholders.
*/
default void addInjectablePlaceholder(@NotNull Iterable<InjectablePlaceholder> placeholders) {
List<StaticPlaceholder> toInject = new ArrayList<>();
for (InjectablePlaceholder placeholder : placeholders) {
if (placeholder instanceof StaticPlaceholder staticPlaceholder) {
toInject.add(staticPlaceholder);
}
}
this.injectPlaceholders(toInject);
}
/** /**
* Clear injected placeholders. * Clear injected placeholders.
@@ -33,6 +67,31 @@ public interface PlaceholderInjectable {
* Get injected placeholders. * Get injected placeholders.
* *
* @return Injected placeholders. * @return Injected placeholders.
* @deprecated Use getPlaceholderInjections.
*/ */
List<StaticPlaceholder> getInjectedPlaceholders(); @Deprecated(since = "6.35.0", forRemoval = true)
@NotNull
default List<StaticPlaceholder> getInjectedPlaceholders() {
List<StaticPlaceholder> found = new ArrayList<>();
for (InjectablePlaceholder placeholder : getPlaceholderInjections()) {
if (placeholder instanceof StaticPlaceholder staticPlaceholder) {
found.add(staticPlaceholder);
}
}
return found;
}
/**
* Get injected placeholders.
* <p>
* Override this method in implementations.
*
* @return Injected placeholders.
*/
@NotNull
default List<InjectablePlaceholder> getPlaceholderInjections() {
return new ArrayList<>(getInjectedPlaceholders());
}
} }

View File

@@ -78,7 +78,7 @@ public final class PlayerPlaceholder implements Placeholder {
if (this == o) { if (this == o) {
return true; return true;
} }
if (!(o instanceof StaticPlaceholder that)) { if (!(o instanceof PlayerPlaceholder that)) {
return false; return false;
} }
return Objects.equals(this.getIdentifier(), that.getIdentifier()) return Objects.equals(this.getIdentifier(), that.getIdentifier())

View File

@@ -0,0 +1,66 @@
package com.willfp.eco.core.placeholder;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.function.Function;
/**
* A placeholder that cannot be registered, and exists purely in injection.
*/
public final class PlayerStaticPlaceholder implements InjectablePlaceholder {
/**
* The name of the placeholder.
*/
private final String identifier;
/**
* The function to retrieve the output of the placeholder.
*/
private final Function<Player, String> function;
/**
* Create a new player placeholder.
*
* @param identifier The identifier.
* @param function The function to retrieve the value.
*/
public PlayerStaticPlaceholder(@NotNull final String identifier,
@NotNull final Function<Player, String> function) {
this.identifier = identifier;
this.function = function;
}
/**
* Get the value of the placeholder.
*
* @param player The player.
* @return The value.
*/
public String getValue(@NotNull final Player player) {
return function.apply(player);
}
@Override
public String getIdentifier() {
return this.identifier;
}
@Override
public boolean equals(@Nullable final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof PlayerStaticPlaceholder that)) {
return false;
}
return Objects.equals(this.getIdentifier(), that.getIdentifier());
}
@Override
public int hashCode() {
return Objects.hash(this.getIdentifier());
}
}

View File

@@ -76,7 +76,7 @@ public final class PlayerlessPlaceholder implements Placeholder {
if (this == o) { if (this == o) {
return true; return true;
} }
if (!(o instanceof StaticPlaceholder that)) { if (!(o instanceof PlayerlessPlaceholder that)) {
return false; return false;
} }
return Objects.equals(this.getIdentifier(), that.getIdentifier()) return Objects.equals(this.getIdentifier(), that.getIdentifier())

View File

@@ -1,7 +1,5 @@
package com.willfp.eco.core.placeholder; package com.willfp.eco.core.placeholder;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -11,7 +9,7 @@ import java.util.function.Supplier;
/** /**
* A placeholder that cannot be registered, and exists purely in injection. * A placeholder that cannot be registered, and exists purely in injection.
*/ */
public final class StaticPlaceholder implements Placeholder { public final class StaticPlaceholder implements InjectablePlaceholder {
/** /**
* The name of the placeholder. * The name of the placeholder.
*/ */
@@ -43,11 +41,6 @@ public final class StaticPlaceholder implements Placeholder {
return function.get(); return function.get();
} }
@Override
public EcoPlugin getPlugin() {
return Eco.getHandler().getEcoPlugin();
}
@Override @Override
public String getIdentifier() { public String getIdentifier() {
return this.identifier; return this.identifier;

View File

@@ -18,25 +18,31 @@ import java.util.Set;
* Utilities / API methods for blocks. * Utilities / API methods for blocks.
*/ */
public final class BlockUtils { public final class BlockUtils {
private static Set<Block> getNearbyBlocks(@NotNull final Block start, /**
* Max blocks to mine (yes, this is to prevent a stack overflow).
*/
private static final int MAX_BLOCKS = 2500;
private static Set<Block> getNearbyBlocks(@NotNull final Block origin,
@NotNull final List<Material> allowedMaterials, @NotNull final List<Material> allowedMaterials,
@NotNull final Set<Block> blocks, @NotNull final Set<Block> blocks,
final int limit) { final int limit) {
for (BlockFace face : BlockFace.values()) { for (BlockFace face : BlockFace.values()) {
Block block = start.getRelative(face); Block block = origin.getRelative(face);
if (!allowedMaterials.contains(block.getType())) {
continue;
}
if (blocks.contains(block)) { if (blocks.contains(block)) {
continue; continue;
} }
if (allowedMaterials.contains(block.getType())) { if (blocks.size() >= limit || blocks.size() > MAX_BLOCKS) {
blocks.add(block); return blocks;
if (blocks.size() > limit || blocks.size() > 2500) {
return blocks;
}
blocks.addAll(getNearbyBlocks(block, allowedMaterials, blocks, limit));
} }
blocks.addAll(getNearbyBlocks(block, allowedMaterials, blocks, limit));
} }
return blocks; return blocks;

View File

@@ -109,8 +109,8 @@ public final class DurabilityUtils {
return; return;
} }
// Suppression because when I fix it, it causes weird compile bugs.
Damageable meta = (Damageable) item.getItemMeta(); @SuppressWarnings("PatternVariableCanBeUsed") Damageable meta = (Damageable) item.getItemMeta();
meta.setDamage(meta.getDamage() + damage); meta.setDamage(meta.getDamage() + damage);
if (meta.getDamage() >= item.getType().getMaxDurability()) { if (meta.getDamage() >= item.getType().getMaxDurability()) {

View File

@@ -1,5 +1,7 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
import com.willfp.eco.core.placeholder.StaticPlaceholder; import com.willfp.eco.core.placeholder.StaticPlaceholder;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -8,7 +10,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@@ -252,7 +256,17 @@ public final class NumberUtils {
*/ */
public static double evaluateExpression(@NotNull final String expression, public static double evaluateExpression(@NotNull final String expression,
@Nullable final Player player) { @Nullable final Player player) {
return evaluateExpression(expression, player, Collections.emptyList()); return evaluateExpression(expression, player, new PlaceholderInjectable() {
@Override
public void clearInjectedPlaceholders() {
// Nothing.
}
@Override
public @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
return Collections.emptyList();
}
});
} }
/** /**
@@ -262,11 +276,41 @@ public final class NumberUtils {
* @param player The player. * @param player The player.
* @param statics The static placeholders. * @param statics The static placeholders.
* @return The value of the expression, or zero if invalid. * @return The value of the expression, or zero if invalid.
* @deprecated Use new statics system.
*/ */
@Deprecated(since = "6.35.0", forRemoval = true)
public static double evaluateExpression(@NotNull final String expression, public static double evaluateExpression(@NotNull final String expression,
@Nullable final Player player, @Nullable final Player player,
@NotNull final Iterable<StaticPlaceholder> statics) { @NotNull final Iterable<StaticPlaceholder> statics) {
return crunch.evaluate(expression, player, statics); return crunch.evaluate(expression, player, new PlaceholderInjectable() {
@Override
public void clearInjectedPlaceholders() {
// Do nothing.
}
@Override
public @NotNull List<InjectablePlaceholder> getPlaceholderInjections() {
List<InjectablePlaceholder> injections = new ArrayList<>();
for (StaticPlaceholder placeholder : statics) {
injections.add(placeholder);
}
return injections;
}
});
}
/**
* Evaluate an expression with respect to a player (for placeholders).
*
* @param expression The expression.
* @param player The player.
* @param context The injectable placeholders.
* @return The value of the expression, or zero if invalid.
*/
public static double evaluateExpression(@NotNull final String expression,
@Nullable final Player player,
@NotNull final PlaceholderInjectable context) {
return crunch.evaluate(expression, player, context);
} }
/** /**
@@ -290,12 +334,12 @@ public final class NumberUtils {
* *
* @param expression The expression. * @param expression The expression.
* @param player The player. * @param player The player.
* @param statics The statics. * @param injectable The injectable placeholders.
* @return The value of the expression, or zero if invalid. * @return The value of the expression, or zero if invalid.
*/ */
double evaluate(@NotNull String expression, double evaluate(@NotNull String expression,
@Nullable Player player, @Nullable Player player,
@NotNull Iterable<StaticPlaceholder> statics); @NotNull PlaceholderInjectable injectable);
} }
private NumberUtils() { private NumberUtils() {

View File

@@ -10,8 +10,14 @@ import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Tameable;
import org.bukkit.projectiles.ProjectileSource;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -142,6 +148,39 @@ public final class PlayerUtils {
} }
} }
/**
* Try an entity as a player.
*
* @param entity The entity.
* @return The player, or null if no player could be found.
*/
@Nullable
public static Player tryAsPlayer(@Nullable final Entity entity) {
if (entity == null) {
return null;
}
if (entity instanceof Player player) {
return player;
}
if (entity instanceof Projectile projectile) {
ProjectileSource shooter = projectile.getShooter();
if (shooter instanceof Player player) {
return player;
}
}
if (entity instanceof Tameable tameable) {
AnimalTamer tamer = tameable.getOwner();
if (tamer instanceof Player player) {
return player;
}
}
return null;
}
private PlayerUtils() { private PlayerUtils() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
} }

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@@ -12,6 +13,7 @@ import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.apache.commons.lang.Validate;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -76,33 +78,37 @@ public final class StringUtils {
.build(StringUtils::processFormatting); .build(StringUtils::processFormatting);
/** /**
* Json -> Legacy Cache. * Json -> Component Cache.
*/ */
private static final LoadingCache<String, String> JSON_TO_LEGACY = Caffeine.newBuilder() private static final Cache<String, Component> JSON_TO_COMPONENT = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.SECONDS) .expireAfterAccess(10, TimeUnit.SECONDS)
.build( .build();
json -> {
try {
Component component = GSON_COMPONENT_SERIALIZER.deserialize(json);
return LEGACY_COMPONENT_SERIALIZER.serialize(component);
} catch (JsonSyntaxException e) {
return json;
}
}
);
/** /**
* Legacy -> Json Cache. * Component -> Json Cache.
*/ */
private static final LoadingCache<String, String> LEGACY_TO_JSON = Caffeine.newBuilder() private static final Cache<Component, String> COMPONENT_TO_JSON = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.SECONDS) .expireAfterAccess(10, TimeUnit.SECONDS)
.build( .build();
legacy -> GSON_COMPONENT_SERIALIZER.serialize(
Component.empty().decoration(TextDecoration.ITALIC, false).append( /**
LEGACY_COMPONENT_SERIALIZER.deserialize(legacy) * Legacy -> Component Cache.
) */
) private static final Cache<String, Component> LEGACY_TO_COMPONENT = Caffeine.newBuilder()
); .expireAfterAccess(10, TimeUnit.SECONDS)
.build();
/**
* Component -> Legacy Cache.
*/
private static final Cache<Component, String> COMPONENT_TO_LEGACY = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.SECONDS)
.build();
/**
* Empty JSON.
*/
private static final String EMPTY_JSON = GSON_COMPONENT_SERIALIZER.serialize(Component.empty());
/** /**
* Color map. * Color map.
@@ -483,12 +489,7 @@ public final class StringUtils {
*/ */
@NotNull @NotNull
public static String legacyToJson(@Nullable final String legacy) { public static String legacyToJson(@Nullable final String legacy) {
String processed = legacy; return componentToJson(toComponent(legacy));
if (legacy == null) {
processed = "";
}
return LEGACY_TO_JSON.get(processed);
} }
/** /**
@@ -499,11 +500,53 @@ public final class StringUtils {
*/ */
@NotNull @NotNull
public static String jsonToLegacy(@Nullable final String json) { public static String jsonToLegacy(@Nullable final String json) {
if (json == null || json.isEmpty()) { return toLegacy(jsonToComponent(json));
return ""; }
/**
* Convert Component to JSON String.
*
* @param component The Component.
* @return The JSON string.
*/
@NotNull
public static String componentToJson(@Nullable final Component component) {
if (component == null) {
return EMPTY_JSON;
} }
return JSON_TO_LEGACY.get(json); return COMPONENT_TO_JSON.get(component, it -> {
try {
return GSON_COMPONENT_SERIALIZER.serialize(
Component.empty().decoration(TextDecoration.ITALIC, false).append(
it
)
);
} catch (JsonSyntaxException e) {
return GSON_COMPONENT_SERIALIZER.serialize(Component.empty());
}
});
}
/**
* Convert JSON String to Component.
*
* @param json The JSON String.
* @return The component.
*/
@NotNull
public static Component jsonToComponent(@Nullable final String json) {
if (json == null || json.isEmpty()) {
return Component.empty();
}
return JSON_TO_COMPONENT.get(json, it -> {
try {
return GSON_COMPONENT_SERIALIZER.deserialize(it);
} catch (JsonSyntaxException e) {
return Component.empty();
}
});
} }
/** /**
@@ -514,12 +557,7 @@ public final class StringUtils {
*/ */
@NotNull @NotNull
public static Component toComponent(@Nullable final String legacy) { public static Component toComponent(@Nullable final String legacy) {
String processed = legacy; return LEGACY_TO_COMPONENT.get(legacy == null ? "" : legacy, LEGACY_COMPONENT_SERIALIZER::deserialize);
if (legacy == null) {
processed = "";
}
return LEGACY_COMPONENT_SERIALIZER.deserialize(processed);
} }
/** /**
@@ -530,7 +568,7 @@ public final class StringUtils {
*/ */
@NotNull @NotNull
public static String toLegacy(@NotNull final Component component) { public static String toLegacy(@NotNull final Component component) {
return LEGACY_COMPONENT_SERIALIZER.serialize(component); return COMPONENT_TO_LEGACY.get(component, LEGACY_COMPONENT_SERIALIZER::serialize);
} }
/** /**
@@ -596,6 +634,59 @@ public final class StringUtils {
return SPACE_AROUND_CHARACTER.get(separator).split(input); return SPACE_AROUND_CHARACTER.get(separator).split(input);
} }
/**
* Create progress bar.
*
* @param character The bar character.
* @param bars The number of bars.
* @param progress The bar progress, between 0 and 1.
* @param completeFormat The color of a complete bar section.
* @param inProgressFormat The color of an in-progress bar section.
* @param incompleteFormat The color of an incomplete bar section.
* @return The progress bar.
*/
@NotNull
public static String createProgressBar(final char character,
final int bars,
final double progress,
@NotNull final String completeFormat,
@NotNull final String inProgressFormat,
@NotNull final String incompleteFormat) {
Validate.isTrue(progress >= 0 && progress <= 1, "Progress must be between 0 and 1!");
Validate.isTrue(bars > 1, "Must have at least 2 bars!");
String completeColor = format(completeFormat);
String inProgressColor = format(inProgressFormat);
String incompleteColor = format(incompleteFormat);
StringBuilder builder = new StringBuilder();
// Full bar special case.
if (progress == 1) {
builder.append(completeColor);
builder.append(String.valueOf(character).repeat(bars));
return builder.toString();
}
int completeBars = (int) Math.floor(progress * bars);
int incompleteBars = bars - completeBars - 1;
if (completeBars > 0) {
builder.append(completeColor)
.append(String.valueOf(character).repeat(completeBars));
}
builder.append(inProgressColor)
.append(character);
if (incompleteBars > 0) {
builder.append(incompleteColor)
.append(String.valueOf(character).repeat(incompleteBars));
}
return builder.toString();
}
/** /**
* Options for formatting. * Options for formatting.
*/ */

View File

@@ -12,7 +12,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors;
/** /**
* Utilities / API methods for teams. * Utilities / API methods for teams.
@@ -49,7 +48,7 @@ public final class TeamUtils {
Team team; Team team;
if (!SCOREBOARD.getTeams().stream().map(Team::getName).collect(Collectors.toList()).contains("EC-" + color.name())) { if (!SCOREBOARD.getTeams().stream().map(Team::getName).toList().contains("EC-" + color.name())) {
team = SCOREBOARD.registerNewTeam("EC-" + color.name()); team = SCOREBOARD.registerNewTeam("EC-" + color.name());
} else { } else {
team = SCOREBOARD.getTeam("EC-" + color.name()); team = SCOREBOARD.getTeam("EC-" + color.name());

View File

@@ -0,0 +1,38 @@
@file:JvmName("ConfigExtensions")
package com.willfp.eco.core.config
import com.willfp.eco.core.config.interfaces.Config
/**
* Helper class to create configs with a kotlin DSL.
*/
class DSLConfig internal constructor(type: ConfigType) : TransientConfig(emptyMap(), type) {
/**
* Map a key to a value.
*
* @param value The value.
*/
infix fun String.to(value: Any?) =
set(this, value)
/**
* Helper function to create configs with a kotlin DSL.
*
* Inherits the config type of the sub-builder.
*
* @param builder The builder.
* @return The config.
*/
fun config(builder: DSLConfig.() -> Unit): Config =
DSLConfig(type).apply(builder)
}
/**
* Helper function to create configs with a kotlin DSL.
*
* @param builder The builder.
* @return The config.
*/
fun config(type: ConfigType = ConfigType.YAML, builder: DSLConfig.() -> Unit): Config =
DSLConfig(type).apply(builder)

View File

@@ -0,0 +1,51 @@
@file:JvmName("PersistentDataContainerExtensions")
package com.willfp.eco.core.data
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType
/**
* @see ExtendedPersistentDataContainer.set
*/
fun <T : Any, Z : Any> PersistentDataContainer.set(key: String, dataType: PersistentDataType<T, Z>, value: Z) =
ExtendedPersistentDataContainer.extend(this).set(key, dataType, value)
/**
* @see ExtendedPersistentDataContainer.has
*/
fun <T : Any, Z : Any> PersistentDataContainer.has(key: String, dataType: PersistentDataType<T, Z>): Boolean =
ExtendedPersistentDataContainer.extend(this).has(key, dataType)
/**
* @see ExtendedPersistentDataContainer.get
*/
fun <T : Any, Z : Any> PersistentDataContainer.get(key: String, dataType: PersistentDataType<T, Z>): Z? =
ExtendedPersistentDataContainer.extend(this).get(key, dataType)
/**
* @see ExtendedPersistentDataContainer.getOrDefault
*/
fun <T : Any, Z : Any> PersistentDataContainer.getOrDefault(
key: String,
dataType: PersistentDataType<T, Z>,
defaultValue: Z
): Z = ExtendedPersistentDataContainer.extend(this).getOrDefault(key, dataType, defaultValue)
/**
* @see ExtendedPersistentDataContainer.getAllKeys
*/
fun PersistentDataContainer.getAllKeys(): Set<String> =
ExtendedPersistentDataContainer.extend(this).allKeys
/**
* @see ExtendedPersistentDataContainer.remove
*/
fun PersistentDataContainer.remove(key: String) =
ExtendedPersistentDataContainer.extend(this).remove(key)
/**
* Create a new PDC without the need for an adapter context.
*/
fun newPersistentDataContainer() =
ExtendedPersistentDataContainer.create().base

View File

@@ -92,6 +92,12 @@ fun MenuBuilder.onClose(action: (InventoryCloseEvent, Menu) -> Unit): MenuBuilde
fun MenuBuilder.modify(modifier: (MenuBuilder) -> Unit): MenuBuilder = fun MenuBuilder.modify(modifier: (MenuBuilder) -> Unit): MenuBuilder =
this.modfiy { modifier(it) } this.modfiy { modifier(it) }
/**
* @see MenuBuilder.onRender
*/
fun MenuBuilder.onRender(action: (Player, Menu) -> Unit): MenuBuilder =
this.onRender { a, b -> action(a, b) }
/** /**
* Kotlin builder for menus. * Kotlin builder for menus.
*/ */

View File

@@ -4,6 +4,7 @@ package com.willfp.eco.core.items
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta import org.bukkit.inventory.meta.ItemMeta
import org.bukkit.persistence.PersistentDataContainer
/** /**
* @see Items.toLookupString * @see Items.toLookupString
@@ -22,3 +23,19 @@ fun ItemStack.mergeFrom(other: ItemStack): ItemStack =
*/ */
fun ItemMeta.mergeFrom(other: ItemMeta): ItemMeta = fun ItemMeta.mergeFrom(other: ItemMeta): ItemMeta =
Items.mergeFrom(other, this) Items.mergeFrom(other, this)
/**
* @see Items.getBaseNBT
* @see Items.setBaseNBT
*/
var ItemStack.baseNBT: PersistentDataContainer
get() = Items.getBaseNBT(this)
set(value) {
Items.setBaseNBT(this, value)
}
/**
* @see Items.setBaseNBT
*/
fun ItemStack.clearNBT() =
Items.setBaseNBT(this, null)

View File

@@ -5,6 +5,7 @@ package com.willfp.eco.util
import net.kyori.adventure.audience.Audience import net.kyori.adventure.audience.Audience
import org.bukkit.OfflinePlayer import org.bukkit.OfflinePlayer
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import org.bukkit.entity.Entity
import org.bukkit.entity.Player import org.bukkit.entity.Player
/** /**
@@ -30,3 +31,15 @@ fun CommandSender.asAudience(): Audience =
*/ */
fun Player.runExempted(action: () -> Unit) = fun Player.runExempted(action: () -> Unit) =
PlayerUtils.runExempted(this, action) PlayerUtils.runExempted(this, action)
/**
* @see PlayerUtils.runExempted
*/
fun Player.runExempted(action: (Player) -> Unit) =
PlayerUtils.runExempted(this, action)
/**
* @see PlayerUtils.tryAsPlayer
*/
fun Entity?.tryAsPlayer(): Player? =
PlayerUtils.tryAsPlayer(this)

View File

@@ -11,12 +11,24 @@ import org.bukkit.entity.Player
fun String.toComponent(): Component = fun String.toComponent(): Component =
StringUtils.toComponent(this) StringUtils.toComponent(this)
/**
* @see StringUtils.jsonToComponent
*/
fun String.jsonToComponent(): Component =
StringUtils.jsonToComponent(this)
/** /**
* @see StringUtils.toLegacy * @see StringUtils.toLegacy
*/ */
fun Component.toLegacy(): String = fun Component.toLegacy(): String =
StringUtils.toLegacy(this) StringUtils.toLegacy(this)
/**
* @see StringUtils.componentToJson
*/
fun Component.toJSON(): String =
StringUtils.componentToJson(this)
/** /**
* @see StringUtils.format * @see StringUtils.format
*/ */

View File

@@ -2,7 +2,7 @@ package com.willfp.eco.internal.config
import com.willfp.eco.core.config.ConfigType import com.willfp.eco.core.config.ConfigType
import com.willfp.eco.core.config.interfaces.Config import com.willfp.eco.core.config.interfaces.Config
import com.willfp.eco.core.placeholder.StaticPlaceholder import com.willfp.eco.core.placeholder.InjectablePlaceholder
import com.willfp.eco.util.StringUtils import com.willfp.eco.util.StringUtils
import org.bukkit.configuration.file.YamlConfiguration import org.bukkit.configuration.file.YamlConfiguration
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@@ -14,7 +14,7 @@ open class EcoConfig(
private val values = ConcurrentHashMap<String, Any?>() private val values = ConcurrentHashMap<String, Any?>()
@Transient @Transient
var injections = mutableListOf<StaticPlaceholder>() var injections = mutableListOf<InjectablePlaceholder>()
fun init(values: Map<String, Any?>) { fun init(values: Map<String, Any?>) {
this.values.clear() this.values.clear()
@@ -156,12 +156,12 @@ open class EcoConfig(
return (get(path) as? Iterable<Number>)?.map { it.toDouble() } return (get(path) as? Iterable<Number>)?.map { it.toDouble() }
} }
override fun injectPlaceholders(placeholders: Iterable<StaticPlaceholder>) { override fun addInjectablePlaceholder(placeholders: Iterable<InjectablePlaceholder>) {
injections.removeIf { placeholders.any { placeholder -> it.identifier == placeholder.identifier } } injections.removeIf { placeholders.any { placeholder -> it.identifier == placeholder.identifier } }
injections.addAll(placeholders) injections.addAll(placeholders)
} }
override fun getInjectedPlaceholders(): List<StaticPlaceholder> { override fun getPlaceholderInjections(): List<InjectablePlaceholder> {
return injections.toList() return injections.toList()
} }

View File

@@ -1,13 +1,13 @@
package com.willfp.eco.internal.config package com.willfp.eco.internal.config
import com.willfp.eco.core.config.ConfigType import com.willfp.eco.core.config.ConfigType
import com.willfp.eco.core.placeholder.StaticPlaceholder import com.willfp.eco.core.placeholder.InjectablePlaceholder
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
class EcoConfigSection( class EcoConfigSection(
type: ConfigType, type: ConfigType,
values: Map<String, Any?> = emptyMap(), values: Map<String, Any?> = emptyMap(),
injections: Collection<StaticPlaceholder> = emptyList() injections: Collection<InjectablePlaceholder> = emptyList()
) : EcoConfig(type) { ) : EcoConfig(type) {
init { init {
this.init(values) this.init(values)

View File

@@ -12,7 +12,7 @@ object EcoGsonSerializer : JsonSerializer<Config> {
.setPrettyPrinting() .setPrettyPrinting()
.disableHtmlEscaping() .disableHtmlEscaping()
.registerTypeAdapter(Config::class.java, this) .registerTypeAdapter(Config::class.java, this)
.create() .create()!!
override fun serialize(src: Config, typeOfSrc: Type, context: JsonSerializationContext): JsonElement { override fun serialize(src: Config, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
return gson.toJsonTree(src.toMap()) return gson.toJsonTree(src.toMap())

View File

@@ -145,6 +145,10 @@ open class EcoLoadableConfig(
} }
configFile = File(directory, name) configFile = File(directory, name)
init(configFile) init(configFile)
addToHandler(plugin)
}
private fun addToHandler(plugin: PluginLike) {
plugin.configHandler.addConfig(this) plugin.configHandler.addConfig(this)
} }
} }

View File

@@ -56,6 +56,10 @@ open class EcoUpdatableConfig(
init { init {
this.updateBlacklist.removeIf { obj: String -> obj.isEmpty() } this.updateBlacklist.removeIf { obj: String -> obj.isEmpty() }
postInit(plugin)
}
private fun postInit(plugin: PluginLike) {
plugin.configHandler.addConfig(this) plugin.configHandler.addConfig(this)
update() update()
} }

View File

@@ -4,7 +4,6 @@ import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.display.Display import com.willfp.eco.core.display.Display
import com.willfp.eco.core.display.DisplayHandler import com.willfp.eco.core.display.DisplayHandler
import com.willfp.eco.core.display.DisplayModule import com.willfp.eco.core.display.DisplayModule
import com.willfp.eco.core.display.DisplayPriority
import com.willfp.eco.core.fast.fast import com.willfp.eco.core.fast.fast
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import org.bukkit.entity.Player import org.bukkit.entity.Player
@@ -12,43 +11,44 @@ import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataType import org.bukkit.persistence.PersistentDataType
class EcoDisplayHandler(plugin: EcoPlugin) : DisplayHandler { class EcoDisplayHandler(plugin: EcoPlugin) : DisplayHandler {
private val registeredModules = mutableMapOf<DisplayPriority, MutableList<DisplayModule>>() private val registeredModules = sortedMapOf<Int, MutableList<DisplayModule>>()
private val finalizeKey: NamespacedKey = plugin.namespacedKeyFactory.create("finalized") private val finalizeKey: NamespacedKey = plugin.namespacedKeyFactory.create("finalized")
init {
for (priority in DisplayPriority.values()) {
registeredModules[priority] = mutableListOf()
}
}
override fun registerDisplayModule(module: DisplayModule) { override fun registerDisplayModule(module: DisplayModule) {
val modules = registeredModules[module.priority] ?: return val modules = registeredModules[module.weight] ?: mutableListOf()
modules.removeIf { module1: DisplayModule -> modules.removeIf {
module1.pluginName.equals(module.pluginName, ignoreCase = true) it.pluginName.equals(module.pluginName, ignoreCase = true)
} }
modules.add(module) modules.add(module)
registeredModules[module.priority] = modules registeredModules[module.weight] = modules
} }
override fun display(itemStack: ItemStack, player: Player?): ItemStack { override fun display(itemStack: ItemStack, player: Player?): ItemStack {
val pluginVarArgs = mutableMapOf<String, Array<Any>>() val pluginVarArgs = mutableMapOf<String, Array<Any>>()
for (priority in DisplayPriority.values()) { for ((_, modules) in registeredModules) {
val modules = registeredModules[priority] ?: continue
for (module in modules) { for (module in modules) {
pluginVarArgs[module.pluginName] = module.generateVarArgs(itemStack) pluginVarArgs[module.pluginName] = module.generateVarArgs(itemStack)
} }
} }
Display.revert(itemStack) Display.revert(itemStack)
itemStack.itemMeta ?: return itemStack if (!itemStack.hasItemMeta()) {
return itemStack
}
for (priority in DisplayPriority.values()) {
val modules = registeredModules[priority] ?: continue for ((_, modules) in registeredModules) {
for (module in modules) { for (module in modules) {
val varargs = pluginVarArgs[module.pluginName] ?: continue val varargs = pluginVarArgs[module.pluginName] ?: continue
Display.callDisplayModule(module, itemStack, player, *varargs)
module.display(itemStack, *varargs)
if (player != null) {
module.display(itemStack, player as Player?, *varargs)
}
} }
} }
@@ -71,8 +71,7 @@ class EcoDisplayHandler(plugin: EcoPlugin) : DisplayHandler {
fast.lore = lore fast.lore = lore
} }
for (priority in DisplayPriority.values()) { for ((_, modules) in registeredModules) {
val modules = registeredModules[priority] ?: continue
for (module in modules) { for (module in modules) {
module.revert(itemStack) module.revert(itemStack)
} }
@@ -86,27 +85,18 @@ class EcoDisplayHandler(plugin: EcoPlugin) : DisplayHandler {
return itemStack return itemStack
} }
val meta = itemStack.itemMeta ?: return itemStack itemStack.fast().persistentDataContainer.set(finalizeKey, PersistentDataType.INTEGER, 1)
val container = meta.persistentDataContainer
container.set(finalizeKey, PersistentDataType.INTEGER, 1)
itemStack.itemMeta = meta
return itemStack return itemStack
} }
override fun unfinalize(itemStack: ItemStack): ItemStack { override fun unfinalize(itemStack: ItemStack): ItemStack {
val meta = itemStack.itemMeta ?: return itemStack itemStack.fast().persistentDataContainer.remove(finalizeKey)
val container = meta.persistentDataContainer
container.remove(finalizeKey)
itemStack.itemMeta = meta
return itemStack return itemStack
} }
override fun isFinalized(itemStack: ItemStack): Boolean { override fun isFinalized(itemStack: ItemStack): Boolean {
val meta = itemStack.itemMeta ?: return false return itemStack.fast().persistentDataContainer.has(finalizeKey, PersistentDataType.INTEGER)
val container = meta.persistentDataContainer
return container.has(finalizeKey, PersistentDataType.INTEGER)
} }
} }

View File

@@ -6,7 +6,7 @@ import com.willfp.eco.internal.drops.impl.EcoDropQueue
import com.willfp.eco.internal.drops.impl.EcoFastCollatedDropQueue import com.willfp.eco.internal.drops.impl.EcoFastCollatedDropQueue
import org.bukkit.entity.Player import org.bukkit.entity.Player
class EcoDropQueueFactory : DropQueueFactory { object EcoDropQueueFactory : DropQueueFactory {
override fun create(player: Player): InternalDropQueue { override fun create(player: Player): InternalDropQueue {
return if (DropManager.type == DropQueueType.COLLATED) EcoFastCollatedDropQueue(player) else EcoDropQueue( return if (DropManager.type == DropQueueType.COLLATED) EcoFastCollatedDropQueue(player) else EcoDropQueue(
player player

View File

@@ -7,7 +7,7 @@ import com.willfp.eco.core.gui.slot.functional.SlotProvider
import com.willfp.eco.internal.gui.menu.EcoMenuBuilder import com.willfp.eco.internal.gui.menu.EcoMenuBuilder
import com.willfp.eco.internal.gui.slot.EcoSlotBuilder import com.willfp.eco.internal.gui.slot.EcoSlotBuilder
class EcoGUIFactory : GUIFactory { object EcoGUIFactory : GUIFactory {
override fun createSlotBuilder(provider: SlotProvider): SlotBuilder { override fun createSlotBuilder(provider: SlotProvider): SlotBuilder {
return EcoSlotBuilder(provider) return EcoSlotBuilder(provider)
} }

View File

@@ -4,6 +4,7 @@ import com.willfp.eco.core.gui.menu.CloseHandler
import com.willfp.eco.core.gui.menu.Menu import com.willfp.eco.core.gui.menu.Menu
import com.willfp.eco.core.gui.slot.Slot import com.willfp.eco.core.gui.slot.Slot
import com.willfp.eco.internal.gui.slot.EcoSlot import com.willfp.eco.internal.gui.slot.EcoSlot
import com.willfp.eco.util.NamespacedKeyUtils
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import org.bukkit.entity.Player import org.bukkit.entity.Player
@@ -17,7 +18,8 @@ class EcoMenu(
private val rows: Int, private val rows: Int,
val slots: List<MutableList<EcoSlot>>, val slots: List<MutableList<EcoSlot>>,
private val title: String, private val title: String,
private val onClose: CloseHandler private val onClose: CloseHandler,
private val onRender: (Player, Menu) -> Unit
) : Menu { ) : Menu {
override fun getSlot(row: Int, column: Int): Slot { override fun getSlot(row: Int, column: Int): Slot {
if (row < 1 || row > this.rows) { if (row < 1 || row > this.rows) {
@@ -73,23 +75,44 @@ class EcoMenu(
key: NamespacedKey, key: NamespacedKey,
type: PersistentDataType<T, Z>, type: PersistentDataType<T, Z>,
value: Z value: Z
) { ) = addState(player, key.toString(), value)
val inventory = player.openInventory.topInventory.asRenderedInventory() ?: return
inventory.data[key] = value
inventory.render()
}
override fun <T : Any, Z : Any> readData(player: Player, key: NamespacedKey, type: PersistentDataType<T, Z>): T? { override fun <T : Any, Z : Any> readData(player: Player, key: NamespacedKey, type: PersistentDataType<T, Z>): T? =
val inventory = player.openInventory.topInventory.asRenderedInventory() ?: return null getState(player, key.toString())
return inventory.data[key] as? T?
}
override fun getKeys(player: Player): Set<NamespacedKey> { override fun getKeys(player: Player): Set<NamespacedKey> {
val inventory = player.openInventory.topInventory.asRenderedInventory() ?: return emptySet() val inventory = player.openInventory.topInventory.asRenderedInventory() ?: return emptySet()
return inventory.data.keys return inventory.state.keys.mapNotNull { NamespacedKeyUtils.fromStringOrNull(it) }.toSet()
}
override fun addState(player: Player, key: String, value: Any?) {
val inventory = player.openInventory.topInventory.asRenderedInventory() ?: return
inventory.state[key] = value
}
override fun getState(player: Player): Map<String, Any?> {
val inventory = player.openInventory.topInventory.asRenderedInventory() ?: return emptyMap()
return inventory.state.toMap()
}
override fun <T : Any> getState(player: Player, key: String): T? {
val inventory = player.openInventory.topInventory.asRenderedInventory() ?: return null
return inventory.state[key] as? T?
}
override fun removeState(player: Player, key: String) {
val inventory = player.openInventory.topInventory.asRenderedInventory() ?: return
inventory.state.remove(key)
}
override fun clearState(player: Player) {
val inventory = player.openInventory.topInventory.asRenderedInventory() ?: return
inventory.state.clear()
} }
override fun refresh(player: Player) { override fun refresh(player: Player) {
player.openInventory.topInventory.asRenderedInventory()?.render() player.openInventory.topInventory.asRenderedInventory()?.render()
} }
fun runOnRender(player: Player) = onRender(player, this)
} }

View File

@@ -11,14 +11,17 @@ import com.willfp.eco.internal.gui.slot.EcoSlot
import com.willfp.eco.util.ListUtils import com.willfp.eco.util.ListUtils
import com.willfp.eco.util.StringUtils import com.willfp.eco.util.StringUtils
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import java.util.function.BiConsumer
import java.util.function.Consumer import java.util.function.Consumer
class EcoMenuBuilder(private val rows: Int) : MenuBuilder { class EcoMenuBuilder(private val rows: Int ) : MenuBuilder {
private var title = "Menu" private var title = "Menu"
private var maskSlots: List<MutableList<Slot?>> private var maskSlots: List<MutableList<Slot?>>
private val slots: List<MutableList<Slot?>> = ListUtils.create2DList(rows, 9) private val slots: List<MutableList<Slot?>> = ListUtils.create2DList(rows, 9)
private var onClose = CloseHandler { _, _ -> } private var onClose = CloseHandler { _, _ -> }
private var onRender: (Player, Menu) -> Unit = { _, _ -> }
override fun setTitle(title: String): MenuBuilder { override fun setTitle(title: String): MenuBuilder {
this.title = StringUtils.format(title) this.title = StringUtils.format(title)
@@ -51,6 +54,11 @@ class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
return this return this
} }
override fun onRender(action: BiConsumer<Player, Menu>): MenuBuilder {
onRender = { a, b -> action.accept(a, b) }
return this
}
override fun build(): Menu { override fun build(): Menu {
val tempSlots: MutableList<MutableList<Slot?>> = ArrayList(maskSlots) val tempSlots: MutableList<MutableList<Slot?>> = ArrayList(maskSlots)
@@ -75,7 +83,7 @@ class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
finalSlots.add(tempRow) finalSlots.add(tempRow)
} }
return EcoMenu(rows, finalSlots, title, onClose) return EcoMenu(rows, finalSlots, title, onClose, onRender)
} }
init { init {

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.internal.gui.menu package com.willfp.eco.internal.gui.menu
import com.willfp.eco.util.MenuUtils import com.willfp.eco.util.MenuUtils
import org.bukkit.NamespacedKey
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.Inventory import org.bukkit.inventory.Inventory
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
@@ -12,7 +11,7 @@ class MenuRenderedInventory(
val player: Player val player: Player
) { ) {
val captiveItems = mutableListOf<ItemStack>() val captiveItems = mutableListOf<ItemStack>()
val data = mutableMapOf<NamespacedKey, Any>() val state = mutableMapOf<String, Any?>()
fun render() { fun render() {
generateCaptive() generateCaptive()
@@ -31,6 +30,8 @@ class MenuRenderedInventory(
i++ i++
} }
} }
menu.runOnRender(player)
} }
private fun generateCaptive() { private fun generateCaptive() {

View File

@@ -4,12 +4,17 @@ import com.willfp.eco.core.entities.ai.EntityGoal
import com.willfp.eco.core.entities.ai.TargetGoal import com.willfp.eco.core.entities.ai.TargetGoal
import com.willfp.eco.internal.spigot.proxy.common.ai.EntityGoalFactory import com.willfp.eco.internal.spigot.proxy.common.ai.EntityGoalFactory
import com.willfp.eco.internal.spigot.proxy.common.ai.TargetGoalFactory import com.willfp.eco.internal.spigot.proxy.common.ai.TargetGoalFactory
import net.minecraft.core.Registry
import net.minecraft.nbt.CompoundTag
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.PathfinderMob import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.item.Item
import org.bukkit.Material
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import org.bukkit.entity.Mob import org.bukkit.entity.Mob
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
private lateinit var impl: CommonsProvider private lateinit var impl: CommonsProvider
@@ -39,9 +44,36 @@ fun <T : EntityGoal<*>> T.getVersionSpecificEntityGoalFactory(): EntityGoalFacto
fun <T : TargetGoal<*>> T.getVersionSpecificEntityGoalFactory(): TargetGoalFactory<T>? = fun <T : TargetGoal<*>> T.getVersionSpecificEntityGoalFactory(): TargetGoalFactory<T>? =
impl.getVersionSpecificTargetGoalFactory(this) impl.getVersionSpecificTargetGoalFactory(this)
private val MATERIAL_TO_ITEM = mutableMapOf<Material, Item>()
fun Material.toItem(): Item =
MATERIAL_TO_ITEM.getOrPut(this) {
Registry.ITEM.getOptional(this.key.toResourceLocation())
.orElseThrow { IllegalArgumentException("Material is not item!") }
}
private val ITEM_TO_MATERIAL = mutableMapOf<Item, Material>()
fun Item.toMaterial(): Material =
ITEM_TO_MATERIAL.getOrPut(this) {
val material = Material.getMaterial(Registry.ITEM.getKey(this).path.uppercase())
?: throw IllegalArgumentException("Invalid material!")
material
}
fun CompoundTag.makePdc(base: Boolean = false): PersistentDataContainer =
impl.makePdc(this, base)
fun CompoundTag.setPdc(pdc: PersistentDataContainer?, item: net.minecraft.world.item.ItemStack? = null) =
impl.setPdc(this, pdc, item)
interface CommonsProvider { interface CommonsProvider {
val nbtTagString: Int val nbtTagString: Int
fun makePdc(tag: CompoundTag, base: Boolean): PersistentDataContainer
fun setPdc(tag: CompoundTag, pdc: PersistentDataContainer?, item: net.minecraft.world.item.ItemStack? = null)
fun toPathfinderMob(mob: Mob): PathfinderMob? fun toPathfinderMob(mob: Mob): PathfinderMob?
fun toResourceLocation(namespacedKey: NamespacedKey): ResourceLocation fun toResourceLocation(namespacedKey: NamespacedKey): ResourceLocation

View File

@@ -10,9 +10,6 @@ import net.minecraft.world.entity.PathfinderMob
import net.minecraft.world.entity.ai.goal.Goal import net.minecraft.world.entity.ai.goal.Goal
import net.minecraft.world.entity.ai.goal.TemptGoal import net.minecraft.world.entity.ai.goal.TemptGoal
import net.minecraft.world.entity.ai.targeting.TargetingConditions import net.minecraft.world.entity.ai.targeting.TargetingConditions
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftLivingEntity
import org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory
import org.bukkit.event.entity.EntityTargetEvent
import java.util.EnumSet import java.util.EnumSet
import kotlin.math.abs import kotlin.math.abs
@@ -57,19 +54,6 @@ class EnhancedTemptGoal(
false false
} else { } else {
player = mob.level.getNearestPlayer(targetingConditions, mob as LivingEntity) player = mob.level.getNearestPlayer(targetingConditions, mob as LivingEntity)
// CraftBukkit start
if (player != null) {
val event = CraftEventFactory.callEntityTargetLivingEvent(
mob,
player,
EntityTargetEvent.TargetReason.TEMPT
)
if (event.isCancelled) {
return false
}
player = if (event.target == null) null else (event.target as CraftLivingEntity?)!!.handle
}
// CraftBukkit end
player != null player != null
} }
} }

View File

@@ -5,7 +5,6 @@ import net.minecraft.world.entity.EntityType
import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.goal.Goal import net.minecraft.world.entity.ai.goal.Goal
import net.minecraft.world.entity.monster.SpellcasterIllager import net.minecraft.world.entity.monster.SpellcasterIllager
import org.bukkit.craftbukkit.v1_17_R1.event.CraftEventFactory
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
class DelegatedSpellcaster(private val handle: SpellcasterIllager) : SpellcasterIllager( class DelegatedSpellcaster(private val handle: SpellcasterIllager) : SpellcasterIllager(
@@ -66,15 +65,6 @@ abstract class OpenUseSpellGoal(
override fun tick() { override fun tick() {
--attackWarmupDelay --attackWarmupDelay
if (attackWarmupDelay == 0) { if (attackWarmupDelay == 0) {
// CraftBukkit start
if (!CraftEventFactory.handleEntitySpellCastEvent(
handle,
spell
)
) {
return
}
// CraftBukkit end
performSpellCasting() performSpellCasting()
handle.playSound(openHandle.openCastingSoundEvent, 1.0f, 1.0f) handle.playSound(openHandle.openCastingSoundEvent, 1.0f, 1.0f)
} }

View File

@@ -1,27 +1,38 @@
package com.willfp.eco.internal.spigot.proxy.common.fast package com.willfp.eco.internal.spigot.proxy.common.item
import com.willfp.eco.core.fast.FastItemStack import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.internal.spigot.proxy.common.NBT_TAG_STRING import com.willfp.eco.internal.spigot.proxy.common.NBT_TAG_STRING
import com.willfp.eco.internal.spigot.proxy.common.asNMSStack import com.willfp.eco.internal.spigot.proxy.common.asNMSStack
import com.willfp.eco.internal.spigot.proxy.common.makePdc
import com.willfp.eco.internal.spigot.proxy.common.mergeIfNeeded import com.willfp.eco.internal.spigot.proxy.common.mergeIfNeeded
import com.willfp.eco.internal.spigot.proxy.common.setPdc
import com.willfp.eco.internal.spigot.proxy.common.toItem
import com.willfp.eco.internal.spigot.proxy.common.toMaterial
import com.willfp.eco.util.NamespacedKeyUtils import com.willfp.eco.util.NamespacedKeyUtils
import com.willfp.eco.util.StringUtils import com.willfp.eco.util.StringUtils
import com.willfp.eco.util.toComponent
import com.willfp.eco.util.toLegacy
import net.kyori.adventure.text.Component
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.ListTag import net.minecraft.nbt.ListTag
import net.minecraft.nbt.StringTag import net.minecraft.nbt.StringTag
import net.minecraft.world.item.EnchantedBookItem import net.minecraft.world.item.EnchantedBookItem
import net.minecraft.world.item.Item import net.minecraft.world.item.Item
import net.minecraft.world.item.Items import net.minecraft.world.item.Items
import org.bukkit.Material
import org.bukkit.NamespacedKey
import org.bukkit.enchantments.Enchantment import org.bukkit.enchantments.Enchantment
import org.bukkit.inventory.ItemFlag import org.bukkit.inventory.ItemFlag
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType
import kotlin.experimental.and import kotlin.experimental.and
@Suppress("UsePropertyAccessSyntax") @Suppress("UsePropertyAccessSyntax")
class EcoFastItemStack( class EcoFastItemStack(
private val bukkit: org.bukkit.inventory.ItemStack private val bukkit: org.bukkit.inventory.ItemStack
) : FastItemStack { ) : FastItemStack {
private var loreCache: List<String>? = null
private val handle = bukkit.asNMSStack() private val handle = bukkit.asNMSStack()
private val pdc = (if (handle.hasTag()) handle.getTag()!! else CompoundTag()).makePdc()
override fun getEnchants(checkStored: Boolean): Map<Enchantment, Int> { override fun getEnchants(checkStored: Boolean): Map<Enchantment, Int> {
val enchantmentNBT = val enchantmentNBT =
@@ -41,7 +52,7 @@ class EcoFastItemStack(
return foundEnchantments return foundEnchantments
} }
override fun getLevelOnItem( override fun getEnchantmentLevel(
enchantment: Enchantment, enchantment: Enchantment,
checkStored: Boolean checkStored: Boolean
): Int { ): Int {
@@ -60,13 +71,14 @@ class EcoFastItemStack(
return 0 return 0
} }
override fun setLore(lore: List<String>?) { override fun setLore(lore: List<String>?) = setLoreComponents(lore?.map { it.toComponent() })
loreCache = null
val jsonLore: MutableList<String> = ArrayList() override fun setLoreComponents(lore: List<Component>?) {
val jsonLore = mutableListOf<String>()
if (lore != null) { if (lore != null) {
for (s in lore) { for (s in lore) {
jsonLore.add(StringUtils.legacyToJson(s)) jsonLore.add(StringUtils.componentToJson(s))
} }
} }
@@ -87,17 +99,7 @@ class EcoFastItemStack(
apply() apply()
} }
override fun getLore(): List<String> { override fun getLoreComponents(): List<Component> {
if (loreCache != null) {
return loreCache!!
}
val lore = this.getLoreJSON().map { StringUtils.jsonToLegacy(it) }
loreCache = lore
return lore
}
private fun getLoreJSON(): List<String> {
val displayTag = handle.getTagElement("display") ?: return emptyList() val displayTag = handle.getTagElement("display") ?: return emptyList()
if (!displayTag.contains("Lore")) { if (!displayTag.contains("Lore")) {
@@ -105,15 +107,47 @@ class EcoFastItemStack(
} }
val loreTag = displayTag.getList("Lore", NBT_TAG_STRING) val loreTag = displayTag.getList("Lore", NBT_TAG_STRING)
val lore = ArrayList<String>(loreTag.size) val jsonLore = mutableListOf<String>()
for (i in loreTag.indices) { for (i in loreTag.indices) {
lore.add(loreTag.getString(i)) jsonLore.add(loreTag.getString(i))
} }
return lore return jsonLore.map { StringUtils.jsonToComponent(it) }
} }
override fun getLore(): List<String> =
getLoreComponents().map { StringUtils.toLegacy(it) }
override fun setDisplayName(name: Component?) {
val displayTag = handle.getOrCreateTagElement("display")
displayTag.remove("Name")
if (name != null) {
displayTag.put("Name", StringTag.valueOf(StringUtils.componentToJson(name)))
}
apply()
}
override fun setDisplayName(name: String?) = setDisplayName(name?.toComponent())
override fun getDisplayNameComponent(): Component {
val displayTag =
handle.getTagElement("display") ?: return Component.translatable(bukkit.type.toItem().getDescriptionId())
if (!displayTag.contains("Name")) {
return Component.translatable(bukkit.type.toItem().getDescriptionId())
}
val nameTag = displayTag.getString("Name")
return StringUtils.jsonToComponent(nameTag)
}
override fun getDisplayName(): String = displayNameComponent.toLegacy()
override fun addItemFlags(vararg hideFlags: ItemFlag) { override fun addItemFlags(vararg hideFlags: ItemFlag) {
for (flag in hideFlags) { for (flag in hideFlags) {
this.flagBits = this.flagBits or getBitModifier(flag) this.flagBits = this.flagBits or getBitModifier(flag)
@@ -151,6 +185,14 @@ class EcoFastItemStack(
return this.flagBits and bitModifier == bitModifier return this.flagBits and bitModifier == bitModifier
} }
override fun getBaseTag(): PersistentDataContainer =
(if (handle.hasTag()) handle.getTag()!! else CompoundTag()).makePdc(base = true)
override fun setBaseTag(container: PersistentDataContainer?) {
(if (handle.hasTag()) handle.getTag()!! else CompoundTag()).setPdc(container, item = handle)
apply()
}
@Suppress("UNNECESSARY_NOT_NULL_ASSERTION") @Suppress("UNNECESSARY_NOT_NULL_ASSERTION")
private var flagBits: Int private var flagBits: Int
get() = get() =
@@ -168,6 +210,41 @@ class EcoFastItemStack(
override fun setRepairCost(cost: Int) { override fun setRepairCost(cost: Int) {
handle.setRepairCost(cost) handle.setRepairCost(cost)
apply()
}
override fun getPersistentDataContainer(): PersistentDataContainer {
return ContinuallyAppliedPersistentDataContainer(this.pdc, this)
}
override fun getAmount(): Int = handle.getCount()
override fun setAmount(amount: Int) {
handle.setCount(amount)
}
override fun setType(material: Material) {
if (material == Material.AIR) {
handle.setTag(null)
}
@Suppress("DEPRECATION")
handle.setItem(material.toItem())
apply()
}
override fun getType(): Material = handle.getItem().toMaterial()
override fun getCustomModelData(): Int? = handle.getTag()?.getInt("CustomModelData")
override fun setCustomModelData(data: Int?) {
if (data == null) {
val tag = handle.getTag() ?: return
tag.remove("CustomModelData")
} else {
handle.getOrCreateTag().putInt("CustomModelData", data)
}
apply()
} }
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
@@ -183,7 +260,11 @@ class EcoFastItemStack(
return handle.getTag()?.hashCode() ?: (0b00010101 * 31 + Item.getId(handle.getItem())) return handle.getTag()?.hashCode() ?: (0b00010101 * 31 + Item.getId(handle.getItem()))
} }
private fun apply() { internal fun apply() {
if (handle.hasTag()) {
handle.getTag()?.setPdc(this.pdc)
}
bukkit.mergeIfNeeded(handle) bukkit.mergeIfNeeded(handle)
} }
@@ -195,3 +276,18 @@ class EcoFastItemStack(
return bukkit return bukkit
} }
} }
private class ContinuallyAppliedPersistentDataContainer(
val handle: PersistentDataContainer,
val fis: EcoFastItemStack
) : PersistentDataContainer by handle {
override fun <T : Any, Z : Any> set(key: NamespacedKey, type: PersistentDataType<T, Z>, value: Z) {
handle.set(key, type, value)
fis.apply()
}
override fun remove(key: NamespacedKey) {
handle.remove(key)
fis.apply()
}
}

View File

@@ -2,6 +2,8 @@ package com.willfp.eco.internal.spigot.proxy.v1_17_R1
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.PathfinderMob import net.minecraft.world.entity.PathfinderMob
import org.bukkit.Bukkit import org.bukkit.Bukkit
@@ -10,11 +12,14 @@ import org.bukkit.craftbukkit.v1_17_R1.CraftServer
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftMob import org.bukkit.craftbukkit.v1_17_R1.entity.CraftMob
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_17_R1.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.v1_17_R1.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.craftbukkit.v1_17_R1.util.CraftMagicNumbers import org.bukkit.craftbukkit.v1_17_R1.util.CraftMagicNumbers
import org.bukkit.craftbukkit.v1_17_R1.util.CraftNamespacedKey import org.bukkit.craftbukkit.v1_17_R1.util.CraftNamespacedKey
import org.bukkit.entity.LivingEntity import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Mob import org.bukkit.entity.Mob
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import java.lang.reflect.Field import java.lang.reflect.Field
class CommonsInitializer : CommonsInitializerProxy { class CommonsInitializer : CommonsInitializerProxy {
@@ -27,6 +32,11 @@ class CommonsInitializer : CommonsInitializerProxy {
isAccessible = true isAccessible = true
} }
private val pdcRegsitry = Class.forName("org.bukkit.craftbukkit.v1_17_R1.inventory.CraftMetaItem")
.getDeclaredField("DATA_TYPE_REGISTRY")
.apply { isAccessible = true }
.get(null) as CraftPersistentDataTypeRegistry
override val nbtTagString = CraftMagicNumbers.NBT.TAG_STRING override val nbtTagString = CraftMagicNumbers.NBT.TAG_STRING
override fun toPathfinderMob(mob: Mob): PathfinderMob? { override fun toPathfinderMob(mob: Mob): PathfinderMob? {
@@ -57,5 +67,69 @@ class CommonsInitializer : CommonsInitializerProxy {
override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? = override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? =
CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity
override fun makePdc(tag: CompoundTag, base: Boolean): PersistentDataContainer {
fun emptyPdc(): CraftPersistentDataContainer = CraftPersistentDataContainer(pdcRegsitry)
fun CompoundTag?.toPdc(): PersistentDataContainer {
val pdc = emptyPdc()
this ?: return pdc
val keys = this.allKeys
for (key in keys) {
pdc.put(key, this[key])
}
return pdc
}
return if (base) {
tag.toPdc()
} else {
if (tag.contains("PublicBukkitValues")) {
tag.getCompound("PublicBukkitValues").toPdc()
} else {
emptyPdc()
}
}
}
override fun setPdc(
tag: CompoundTag,
pdc: PersistentDataContainer?,
item: net.minecraft.world.item.ItemStack?
) {
fun CraftPersistentDataContainer.toTag(): CompoundTag {
val compound = CompoundTag()
val rawPublicMap: Map<String, Tag> = this.raw
for ((key, value) in rawPublicMap) {
compound.put(key, value)
}
return compound
}
val container = when (pdc) {
is CraftPersistentDataContainer? -> pdc
else -> null
}
if (item != null) {
if (container != null && !container.isEmpty) {
for (key in tag.allKeys.toSet()) {
tag.remove(key)
}
tag.merge(container.toTag())
} else {
item.setTag(null)
}
} else {
if (container != null && !container.isEmpty) {
tag.put("PublicBukkitValues", container.toTag())
} else {
tag.remove("PublicBukkitValues")
}
}
}
} }
} }

View File

@@ -0,0 +1,70 @@
package com.willfp.eco.internal.spigot.proxy.v1_17_R1
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import net.minecraft.nbt.Tag
import org.bukkit.craftbukkit.v1_17_R1.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.v1_17_R1.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType
class ExtendedPersistentDataContainerFactory: ExtendedPersistentDataContainerFactoryProxy {
@Suppress("UNCHECKED_CAST")
private val registry: CraftPersistentDataTypeRegistry =
CraftPersistentDataContainer::class.java.getDeclaredField("registry")
.apply { isAccessible = true }.get(null) as CraftPersistentDataTypeRegistry
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance is not supported!")
}
}
override fun newPdc(): PersistentDataContainer {
return CraftPersistentDataContainer(registry)
}
inner class EcoPersistentDataContainer(
val handle: CraftPersistentDataContainer
) : ExtendedPersistentDataContainer {
@Suppress("UNCHECKED_CAST")
private val customDataTags: MutableMap<String, Tag> =
CraftPersistentDataContainer::class.java.getDeclaredField("customDataTags")
.apply { isAccessible = true }.get(handle) as MutableMap<String, Tag>
override fun <T : Any, Z : Any> set(key: String, dataType: PersistentDataType<T, Z>, value: Z) {
customDataTags[key] = registry.wrap(dataType.primitiveType, dataType.toPrimitive(value, handle.adapterContext))
}
override fun <T : Any, Z : Any> has(key: String, dataType: PersistentDataType<T, Z>): Boolean {
val value = customDataTags[key] ?: return false
return registry.isInstanceOf(dataType.primitiveType, value)
}
override fun <T : Any, Z : Any> get(key: String, dataType: PersistentDataType<T, Z>): Z? {
val value = customDataTags[key] ?: return null
return dataType.fromPrimitive(registry.extract(dataType.primitiveType, value), handle.adapterContext)
}
override fun <T : Any, Z : Any> getOrDefault(
key: String,
dataType: PersistentDataType<T, Z>,
defaultValue: Z
): Z {
return get(key, dataType) ?: defaultValue
}
override fun remove(key: String) {
customDataTags.remove(key)
}
override fun getAllKeys(): MutableSet<String> {
return customDataTags.keys
}
override fun getBase(): PersistentDataContainer {
return handle
}
}
}

View File

@@ -2,7 +2,7 @@ package com.willfp.eco.internal.spigot.proxy.v1_17_R1
import com.willfp.eco.core.fast.FastItemStack import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.fast.EcoFastItemStack import com.willfp.eco.internal.spigot.proxy.common.item.EcoFastItemStack
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
class FastItemStackFactory : FastItemStackFactoryProxy { class FastItemStackFactory : FastItemStackFactoryProxy {

View File

@@ -39,6 +39,6 @@ class Skull : SkullProxy {
val profile = profile[meta] as GameProfile? ?: return null val profile = profile[meta] as GameProfile? ?: return null
val properties = profile.properties ?: return null val properties = profile.properties ?: return null
val prop = properties["textures"] ?: return null val prop = properties["textures"] ?: return null
return prop.toMutableList().firstOrNull()?.name return prop.toMutableList().firstOrNull()?.value
} }
} }

View File

@@ -2,6 +2,8 @@ package com.willfp.eco.internal.spigot.proxy.v1_18_R1
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.PathfinderMob import net.minecraft.world.entity.PathfinderMob
import org.bukkit.Bukkit import org.bukkit.Bukkit
@@ -10,11 +12,14 @@ import org.bukkit.craftbukkit.v1_18_R1.CraftServer
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftMob import org.bukkit.craftbukkit.v1_18_R1.entity.CraftMob
import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack import org.bukkit.craftbukkit.v1_18_R1.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_18_R1.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.v1_18_R1.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.craftbukkit.v1_18_R1.util.CraftMagicNumbers import org.bukkit.craftbukkit.v1_18_R1.util.CraftMagicNumbers
import org.bukkit.craftbukkit.v1_18_R1.util.CraftNamespacedKey import org.bukkit.craftbukkit.v1_18_R1.util.CraftNamespacedKey
import org.bukkit.entity.LivingEntity import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Mob import org.bukkit.entity.Mob
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import java.lang.reflect.Field import java.lang.reflect.Field
class CommonsInitializer : CommonsInitializerProxy { class CommonsInitializer : CommonsInitializerProxy {
@@ -27,6 +32,11 @@ class CommonsInitializer : CommonsInitializerProxy {
isAccessible = true isAccessible = true
} }
private val pdcRegsitry = Class.forName("org.bukkit.craftbukkit.v1_18_R1.inventory.CraftMetaItem")
.getDeclaredField("DATA_TYPE_REGISTRY")
.apply { isAccessible = true }
.get(null) as CraftPersistentDataTypeRegistry
override val nbtTagString = CraftMagicNumbers.NBT.TAG_STRING override val nbtTagString = CraftMagicNumbers.NBT.TAG_STRING
override fun toPathfinderMob(mob: Mob): PathfinderMob? { override fun toPathfinderMob(mob: Mob): PathfinderMob? {
@@ -57,5 +67,69 @@ class CommonsInitializer : CommonsInitializerProxy {
override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? = override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? =
CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity
override fun makePdc(tag: CompoundTag, base: Boolean): PersistentDataContainer {
fun emptyPdc(): CraftPersistentDataContainer = CraftPersistentDataContainer(pdcRegsitry)
fun CompoundTag?.toPdc(): PersistentDataContainer {
val pdc = emptyPdc()
this ?: return pdc
val keys = this.allKeys
for (key in keys) {
pdc.put(key, this[key])
}
return pdc
}
return if (base) {
tag.toPdc()
} else {
if (tag.contains("PublicBukkitValues")) {
tag.getCompound("PublicBukkitValues").toPdc()
} else {
emptyPdc()
}
}
}
override fun setPdc(
tag: CompoundTag,
pdc: PersistentDataContainer?,
item: net.minecraft.world.item.ItemStack?
) {
fun CraftPersistentDataContainer.toTag(): CompoundTag {
val compound = CompoundTag()
val rawPublicMap: Map<String, Tag> = this.raw
for ((key, value) in rawPublicMap) {
compound.put(key, value)
}
return compound
}
val container = when (pdc) {
is CraftPersistentDataContainer? -> pdc
else -> null
}
if (item != null) {
if (container != null && !container.isEmpty) {
for (key in tag.allKeys.toSet()) {
tag.remove(key)
}
tag.merge(container.toTag())
} else {
item.setTag(null)
}
} else {
if (container != null && !container.isEmpty) {
tag.put("PublicBukkitValues", container.toTag())
} else {
tag.remove("PublicBukkitValues")
}
}
}
} }
} }

View File

@@ -0,0 +1,70 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R1
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import net.minecraft.nbt.Tag
import org.bukkit.craftbukkit.v1_18_R1.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.v1_18_R1.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
@Suppress("UNCHECKED_CAST")
private val registry: CraftPersistentDataTypeRegistry =
CraftPersistentDataContainer::class.java.getDeclaredField("registry")
.apply { isAccessible = true }.get(null) as CraftPersistentDataTypeRegistry
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance is not supported!")
}
}
override fun newPdc(): PersistentDataContainer {
return CraftPersistentDataContainer(registry)
}
inner class EcoPersistentDataContainer(
val handle: CraftPersistentDataContainer
) : ExtendedPersistentDataContainer {
@Suppress("UNCHECKED_CAST")
private val customDataTags: MutableMap<String, Tag> =
CraftPersistentDataContainer::class.java.getDeclaredField("customDataTags")
.apply { isAccessible = true }.get(handle) as MutableMap<String, Tag>
override fun <T : Any, Z : Any> set(key: String, dataType: PersistentDataType<T, Z>, value: Z) {
customDataTags[key] = registry.wrap(dataType.primitiveType, dataType.toPrimitive(value, handle.adapterContext))
}
override fun <T : Any, Z : Any> has(key: String, dataType: PersistentDataType<T, Z>): Boolean {
val value = customDataTags[key] ?: return false
return registry.isInstanceOf(dataType.primitiveType, value)
}
override fun <T : Any, Z : Any> get(key: String, dataType: PersistentDataType<T, Z>): Z? {
val value = customDataTags[key] ?: return null
return dataType.fromPrimitive(registry.extract(dataType.primitiveType, value), handle.adapterContext)
}
override fun <T : Any, Z : Any> getOrDefault(
key: String,
dataType: PersistentDataType<T, Z>,
defaultValue: Z
): Z {
return get(key, dataType) ?: defaultValue
}
override fun remove(key: String) {
customDataTags.remove(key)
}
override fun getAllKeys(): MutableSet<String> {
return customDataTags.keys
}
override fun getBase(): PersistentDataContainer {
return handle
}
}
}

View File

@@ -2,7 +2,7 @@ package com.willfp.eco.internal.spigot.proxy.v1_18_R1
import com.willfp.eco.core.fast.FastItemStack import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.fast.EcoFastItemStack import com.willfp.eco.internal.spigot.proxy.common.item.EcoFastItemStack
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
class FastItemStackFactory : FastItemStackFactoryProxy { class FastItemStackFactory : FastItemStackFactoryProxy {

View File

@@ -39,6 +39,6 @@ class Skull : SkullProxy {
val profile = profile[meta] as GameProfile? ?: return null val profile = profile[meta] as GameProfile? ?: return null
val properties = profile.properties ?: return null val properties = profile.properties ?: return null
val prop = properties["textures"] ?: return null val prop = properties["textures"] ?: return null
return prop.toMutableList().firstOrNull()?.name return prop.toMutableList().firstOrNull()?.value
} }
} }

View File

@@ -2,6 +2,8 @@ package com.willfp.eco.internal.spigot.proxy.v1_18_R2
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider import com.willfp.eco.internal.spigot.proxy.common.CommonsProvider
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.PathfinderMob import net.minecraft.world.entity.PathfinderMob
import org.bukkit.Bukkit import org.bukkit.Bukkit
@@ -10,11 +12,14 @@ import org.bukkit.craftbukkit.v1_18_R2.CraftServer
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftMob import org.bukkit.craftbukkit.v1_18_R2.entity.CraftMob
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_18_R2.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.v1_18_R2.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.craftbukkit.v1_18_R2.util.CraftMagicNumbers import org.bukkit.craftbukkit.v1_18_R2.util.CraftMagicNumbers
import org.bukkit.craftbukkit.v1_18_R2.util.CraftNamespacedKey import org.bukkit.craftbukkit.v1_18_R2.util.CraftNamespacedKey
import org.bukkit.entity.LivingEntity import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Mob import org.bukkit.entity.Mob
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import java.lang.reflect.Field import java.lang.reflect.Field
class CommonsInitializer : CommonsInitializerProxy { class CommonsInitializer : CommonsInitializerProxy {
@@ -27,6 +32,11 @@ class CommonsInitializer : CommonsInitializerProxy {
isAccessible = true isAccessible = true
} }
private val pdcRegsitry = Class.forName("org.bukkit.craftbukkit.v1_18_R2.inventory.CraftMetaItem")
.getDeclaredField("DATA_TYPE_REGISTRY")
.apply { isAccessible = true }
.get(null) as CraftPersistentDataTypeRegistry
override val nbtTagString = CraftMagicNumbers.NBT.TAG_STRING override val nbtTagString = CraftMagicNumbers.NBT.TAG_STRING
override fun toPathfinderMob(mob: Mob): PathfinderMob? { override fun toPathfinderMob(mob: Mob): PathfinderMob? {
@@ -57,5 +67,69 @@ class CommonsInitializer : CommonsInitializerProxy {
override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? = override fun toBukkitEntity(entity: net.minecraft.world.entity.LivingEntity): LivingEntity? =
CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity CraftEntity.getEntity(Bukkit.getServer() as CraftServer, entity) as? LivingEntity
override fun makePdc(tag: CompoundTag, base: Boolean): PersistentDataContainer {
fun emptyPdc(): CraftPersistentDataContainer = CraftPersistentDataContainer(pdcRegsitry)
fun CompoundTag?.toPdc(): PersistentDataContainer {
val pdc = emptyPdc()
this ?: return pdc
val keys = this.allKeys
for (key in keys) {
pdc.put(key, this[key])
}
return pdc
}
return if (base) {
tag.toPdc()
} else {
if (tag.contains("PublicBukkitValues")) {
tag.getCompound("PublicBukkitValues").toPdc()
} else {
emptyPdc()
}
}
}
override fun setPdc(
tag: CompoundTag,
pdc: PersistentDataContainer?,
item: net.minecraft.world.item.ItemStack?
) {
fun CraftPersistentDataContainer.toTag(): CompoundTag {
val compound = CompoundTag()
val rawPublicMap: Map<String, Tag> = this.raw
for ((key, value) in rawPublicMap) {
compound.put(key, value)
}
return compound
}
val container = when (pdc) {
is CraftPersistentDataContainer? -> pdc
else -> null
}
if (item != null) {
if (container != null && !container.isEmpty) {
for (key in tag.allKeys.toSet()) {
tag.remove(key)
}
tag.merge(container.toTag())
} else {
item.setTag(null)
}
} else {
if (container != null && !container.isEmpty) {
tag.put("PublicBukkitValues", container.toTag())
} else {
tag.remove("PublicBukkitValues")
}
}
}
} }
} }

View File

@@ -0,0 +1,70 @@
package com.willfp.eco.internal.spigot.proxy.v1_18_R2
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import net.minecraft.nbt.Tag
import org.bukkit.craftbukkit.v1_18_R2.persistence.CraftPersistentDataContainer
import org.bukkit.craftbukkit.v1_18_R2.persistence.CraftPersistentDataTypeRegistry
import org.bukkit.persistence.PersistentDataContainer
import org.bukkit.persistence.PersistentDataType
class ExtendedPersistentDataContainerFactory: ExtendedPersistentDataContainerFactoryProxy {
@Suppress("UNCHECKED_CAST")
private val registry: CraftPersistentDataTypeRegistry =
CraftPersistentDataContainer::class.java.getDeclaredField("registry")
.apply { isAccessible = true }.get(null) as CraftPersistentDataTypeRegistry
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
return when (pdc) {
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
else -> throw IllegalArgumentException("Custom PDC instance is not supported!")
}
}
override fun newPdc(): PersistentDataContainer {
return CraftPersistentDataContainer(registry)
}
inner class EcoPersistentDataContainer(
val handle: CraftPersistentDataContainer
) : ExtendedPersistentDataContainer {
@Suppress("UNCHECKED_CAST")
private val customDataTags: MutableMap<String, Tag> =
CraftPersistentDataContainer::class.java.getDeclaredField("customDataTags")
.apply { isAccessible = true }.get(handle) as MutableMap<String, Tag>
override fun <T : Any, Z : Any> set(key: String, dataType: PersistentDataType<T, Z>, value: Z) {
customDataTags[key] = registry.wrap(dataType.primitiveType, dataType.toPrimitive(value, handle.adapterContext))
}
override fun <T : Any, Z : Any> has(key: String, dataType: PersistentDataType<T, Z>): Boolean {
val value = customDataTags[key] ?: return false
return registry.isInstanceOf(dataType.primitiveType, value)
}
override fun <T : Any, Z : Any> get(key: String, dataType: PersistentDataType<T, Z>): Z? {
val value = customDataTags[key] ?: return null
return dataType.fromPrimitive(registry.extract(dataType.primitiveType, value), handle.adapterContext)
}
override fun <T : Any, Z : Any> getOrDefault(
key: String,
dataType: PersistentDataType<T, Z>,
defaultValue: Z
): Z {
return get(key, dataType) ?: defaultValue
}
override fun remove(key: String) {
customDataTags.remove(key)
}
override fun getAllKeys(): MutableSet<String> {
return customDataTags.keys
}
override fun getBase(): PersistentDataContainer {
return handle
}
}
}

View File

@@ -2,7 +2,7 @@ package com.willfp.eco.internal.spigot.proxy.v1_18_R2
import com.willfp.eco.core.fast.FastItemStack import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import com.willfp.eco.internal.spigot.proxy.common.fast.EcoFastItemStack import com.willfp.eco.internal.spigot.proxy.common.item.EcoFastItemStack
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
class FastItemStackFactory : FastItemStackFactoryProxy { class FastItemStackFactory : FastItemStackFactoryProxy {

View File

@@ -39,6 +39,6 @@ class Skull : SkullProxy {
val profile = profile[meta] as GameProfile? ?: return null val profile = profile[meta] as GameProfile? ?: return null
val properties = profile.properties ?: return null val properties = profile.properties ?: return null
val prop = properties["textures"] ?: return null val prop = properties["textures"] ?: return null
return prop.toMutableList().firstOrNull()?.name return prop.toMutableList().firstOrNull()?.value
} }
} }

View File

@@ -13,6 +13,7 @@ dependencies {
implementation 'org.jetbrains.exposed:exposed-jdbc:0.37.3' implementation 'org.jetbrains.exposed:exposed-jdbc:0.37.3'
implementation 'com.zaxxer:HikariCP:5.0.0' implementation 'com.zaxxer:HikariCP:5.0.0'
implementation 'net.kyori:adventure-platform-bukkit:4.1.0' implementation 'net.kyori:adventure-platform-bukkit:4.1.0'
implementation 'org.javassist:javassist:3.28.0-GA'
// Included in spigot jar // Included in spigot jar
compileOnly 'com.google.code.gson:gson:2.8.8' compileOnly 'com.google.code.gson:gson:2.8.8'
@@ -40,11 +41,10 @@ dependencies {
compileOnly 'com.github.EssentialsX:Essentials:2.18.2' compileOnly 'com.github.EssentialsX:Essentials:2.18.2'
compileOnly 'com.bgsoftware:SuperiorSkyblockAPI:1.8.3' compileOnly 'com.bgsoftware:SuperiorSkyblockAPI:1.8.3'
compileOnly 'com.github.MilkBowl:VaultAPI:1.7' compileOnly 'com.github.MilkBowl:VaultAPI:1.7'
compileOnly 'world.bentobox:bentobox:1.17.3-SNAPSHOT'
compileOnly 'com.iridium:IridiumSkyblock:3.1.2'
compileOnly 'com.github.WhipDevelopment:CrashClaim:f9cd7d92eb' compileOnly 'com.github.WhipDevelopment:CrashClaim:f9cd7d92eb'
compileOnly 'com.wolfyscript.wolfyutilities:wolfyutilities:3.16.0.0' compileOnly 'com.wolfyscript.wolfyutilities:wolfyutilities:3.16.0.0'
compileOnly 'com.github.decentsoftware-eu:decentholograms:2.1.2' compileOnly 'com.github.decentsoftware-eu:decentholograms:2.1.2'
compileOnly 'com.github.Gypopo:EconomyShopGUI-API:1.1.0'
// MythicMobs // MythicMobs
compileOnly 'io.lumine:Mythic:5.0.1' compileOnly 'io.lumine:Mythic:5.0.1'
@@ -52,11 +52,9 @@ dependencies {
// CombatLogX V10 + NewbieHelper Expansion // CombatLogX V10 + NewbieHelper Expansion
compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT' compileOnly 'com.SirBlobman.combatlogx:CombatLogX-API:10.0.0.0-SNAPSHOT'
compileOnly 'com.SirBlobman.combatlogx.expansions:NewbieHelper:10.0.0.0-SNAPSHOT'
// CombatLogX V11 + NewbieHelper Expansion // CombatLogX V11 + NewbieHelper Expansion
compileOnly 'com.github.sirblobman.combatlogx:api:11.0.0.0-SNAPSHOT' compileOnly 'com.github.sirblobman.combatlogx:api:11.0.0.0-SNAPSHOT'
compileOnly 'com.github.sirblobman.combatlogx.expansion:newbie-helper:11.0.0.0-SNAPSHOT'
// LibsDisguises // LibsDisguises
compileOnly 'LibsDisguises:LibsDisguises:10.0.26' compileOnly 'LibsDisguises:LibsDisguises:10.0.26'

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.internal.spigot
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.Handler import com.willfp.eco.core.Handler
import com.willfp.eco.core.PluginProps import com.willfp.eco.core.PluginProps
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
import com.willfp.eco.core.entities.ai.EntityController import com.willfp.eco.core.entities.ai.EntityController
import com.willfp.eco.core.fast.FastItemStack import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration
@@ -32,6 +33,7 @@ import com.willfp.eco.internal.spigot.integrations.bstats.MetricHandler
import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy import com.willfp.eco.internal.spigot.proxy.CommonsInitializerProxy
import com.willfp.eco.internal.spigot.proxy.DummyEntityFactoryProxy import com.willfp.eco.internal.spigot.proxy.DummyEntityFactoryProxy
import com.willfp.eco.internal.spigot.proxy.EntityControllerFactoryProxy import com.willfp.eco.internal.spigot.proxy.EntityControllerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import com.willfp.eco.internal.spigot.proxy.MiniMessageTranslatorProxy import com.willfp.eco.internal.spigot.proxy.MiniMessageTranslatorProxy
import net.kyori.adventure.platform.bukkit.BukkitAudiences import net.kyori.adventure.platform.bukkit.BukkitAudiences
@@ -40,6 +42,7 @@ import org.bukkit.NamespacedKey
import org.bukkit.entity.Entity import org.bukkit.entity.Entity
import org.bukkit.entity.Mob import org.bukkit.entity.Mob
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataContainer
import java.util.logging.Logger import java.util.logging.Logger
@Suppress("UNUSED") @Suppress("UNUSED")
@@ -61,120 +64,99 @@ class EcoHandler : EcoSpigotPlugin(), Handler {
if (this.configYml.getBool("use-safer-namespacedkey-creation")) if (this.configYml.getBool("use-safer-namespacedkey-creation"))
SafeInternalNamespacedKeyFactory() else FastInternalNamespacedKeyFactory() SafeInternalNamespacedKeyFactory() else FastInternalNamespacedKeyFactory()
override fun createScheduler(plugin: EcoPlugin): EcoScheduler { override fun createScheduler(plugin: EcoPlugin): EcoScheduler =
return EcoScheduler(plugin) EcoScheduler(plugin)
}
override fun createEventManager(plugin: EcoPlugin): EcoEventManager { override fun createEventManager(plugin: EcoPlugin): EcoEventManager =
return EcoEventManager(plugin) EcoEventManager(plugin)
}
override fun createNamespacedKeyFactory(plugin: EcoPlugin): EcoNamespacedKeyFactory { override fun createNamespacedKeyFactory(plugin: EcoPlugin): EcoNamespacedKeyFactory =
return EcoNamespacedKeyFactory(plugin) EcoNamespacedKeyFactory(plugin)
}
override fun createMetadataValueFactory(plugin: EcoPlugin): EcoMetadataValueFactory { override fun createMetadataValueFactory(plugin: EcoPlugin): EcoMetadataValueFactory =
return EcoMetadataValueFactory(plugin) EcoMetadataValueFactory(plugin)
}
override fun createRunnableFactory(plugin: EcoPlugin): EcoRunnableFactory { override fun createRunnableFactory(plugin: EcoPlugin): EcoRunnableFactory =
return EcoRunnableFactory(plugin) EcoRunnableFactory(plugin)
}
override fun createExtensionLoader(plugin: EcoPlugin): EcoExtensionLoader { override fun createExtensionLoader(plugin: EcoPlugin): EcoExtensionLoader =
return EcoExtensionLoader(plugin) EcoExtensionLoader(plugin)
}
override fun createConfigHandler(plugin: EcoPlugin): EcoConfigHandler { override fun createConfigHandler(plugin: EcoPlugin): EcoConfigHandler =
return EcoConfigHandler(plugin) EcoConfigHandler(plugin)
}
override fun createLogger(plugin: EcoPlugin): Logger { override fun createLogger(plugin: EcoPlugin): Logger =
return EcoLogger(plugin) EcoLogger(plugin)
}
override fun createPAPIIntegration(plugin: EcoPlugin): PlaceholderIntegration { override fun createPAPIIntegration(plugin: EcoPlugin): PlaceholderIntegration =
return PlaceholderIntegrationPAPI(plugin) PlaceholderIntegrationPAPI(plugin)
}
override fun getEcoPlugin(): EcoPlugin { override fun getEcoPlugin(): EcoPlugin =
return this this
}
override fun getConfigFactory(): EcoConfigFactory { override fun getConfigFactory(): EcoConfigFactory =
return EcoConfigFactory EcoConfigFactory
}
override fun getDropQueueFactory(): EcoDropQueueFactory { override fun getDropQueueFactory(): EcoDropQueueFactory =
return EcoDropQueueFactory() EcoDropQueueFactory
}
override fun getGUIFactory(): EcoGUIFactory { override fun getGUIFactory(): EcoGUIFactory =
return EcoGUIFactory() EcoGUIFactory
}
override fun getCleaner(): EcoCleaner { override fun getCleaner(): EcoCleaner =
return cleaner cleaner
}
override fun createProxyFactory(plugin: EcoPlugin): EcoProxyFactory { override fun createProxyFactory(plugin: EcoPlugin): EcoProxyFactory =
return EcoProxyFactory(plugin) EcoProxyFactory(plugin)
}
override fun addNewPlugin(plugin: EcoPlugin) { override fun addNewPlugin(plugin: EcoPlugin) {
Plugins.LOADED_ECO_PLUGINS[plugin.name.lowercase()] = plugin Plugins.LOADED_ECO_PLUGINS[plugin.name.lowercase()] = plugin
} }
override fun getLoadedPlugins(): List<String> { override fun getLoadedPlugins(): List<String> =
return Plugins.LOADED_ECO_PLUGINS.keys.toMutableList() Plugins.LOADED_ECO_PLUGINS.keys.toMutableList()
}
override fun getPluginByName(name: String): EcoPlugin? { override fun getPluginByName(name: String): EcoPlugin? =
return Plugins.LOADED_ECO_PLUGINS[name.lowercase()] Plugins.LOADED_ECO_PLUGINS[name.lowercase()]
}
override fun createFastItemStack(itemStack: ItemStack): FastItemStack { override fun createFastItemStack(itemStack: ItemStack): FastItemStack =
return getProxy(FastItemStackFactoryProxy::class.java).create(itemStack) getProxy(FastItemStackFactoryProxy::class.java).create(itemStack)
}
override fun registerBStats(plugin: EcoPlugin) { override fun registerBStats(plugin: EcoPlugin) =
MetricHandler.createMetrics(plugin) MetricHandler.createMetrics(plugin)
}
override fun getAdventure(): BukkitAudiences? { override fun getAdventure(): BukkitAudiences? =
return adventure adventure
}
override fun getKeyRegistry(): EcoKeyRegistry { override fun getKeyRegistry(): EcoKeyRegistry =
return keyRegistry keyRegistry
}
override fun getProfileHandler(): EcoProfileHandler { override fun getProfileHandler(): EcoProfileHandler =
return playerProfileHandler playerProfileHandler
}
fun setAdventure(adventure: BukkitAudiences) { fun setAdventure(adventure: BukkitAudiences) {
this.adventure = adventure this.adventure = adventure
} }
override fun createDummyEntity(location: Location): Entity { override fun createDummyEntity(location: Location): Entity =
return getProxy(DummyEntityFactoryProxy::class.java).createDummyEntity(location) getProxy(DummyEntityFactoryProxy::class.java).createDummyEntity(location)
}
override fun createNamespacedKey(namespace: String, key: String): NamespacedKey { @Suppress("DEPRECATION")
@Suppress("DEPRECATION") override fun createNamespacedKey(namespace: String, key: String): NamespacedKey =
return keyFactory?.create(namespace, key) ?: NamespacedKey(namespace, key) keyFactory?.create(namespace, key) ?: NamespacedKey(namespace, key)
}
override fun getProps(existing: PluginProps?, plugin: Class<out EcoPlugin>): PluginProps { override fun getProps(existing: PluginProps?, plugin: Class<out EcoPlugin>): PluginProps =
return existing ?: EcoPropsParser.parseForPlugin(plugin) existing ?: EcoPropsParser.parseForPlugin(plugin)
}
override fun <T : Mob> createEntityController(mob: T): EntityController<T> { override fun <T : Mob> createEntityController(mob: T): EntityController<T> =
return getProxy(EntityControllerFactoryProxy::class.java).createEntityController(mob) getProxy(EntityControllerFactoryProxy::class.java).createEntityController(mob)
}
override fun formatMiniMessage(message: String): String { override fun formatMiniMessage(message: String): String =
return getProxy(MiniMessageTranslatorProxy::class.java).format(message) getProxy(MiniMessageTranslatorProxy::class.java).format(message)
}
override fun adaptPdc(container: PersistentDataContainer): ExtendedPersistentDataContainer =
getProxy(ExtendedPersistentDataContainerFactoryProxy::class.java).adapt(container)
override fun newPdc(): PersistentDataContainer =
getProxy(ExtendedPersistentDataContainerFactoryProxy::class.java).newPdc()
} }

View File

@@ -105,7 +105,10 @@ import com.willfp.eco.internal.spigot.integrations.hologram.HologramDecentHologr
import com.willfp.eco.internal.spigot.integrations.hologram.HologramHolographicDisplays import com.willfp.eco.internal.spigot.integrations.hologram.HologramHolographicDisplays
import com.willfp.eco.internal.spigot.integrations.mcmmo.McmmoIntegrationImpl import com.willfp.eco.internal.spigot.integrations.mcmmo.McmmoIntegrationImpl
import com.willfp.eco.internal.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration import com.willfp.eco.internal.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration
import com.willfp.eco.internal.spigot.integrations.shop.ShopDeluxeSellwands
import com.willfp.eco.internal.spigot.integrations.shop.ShopEconomyShopGUI
import com.willfp.eco.internal.spigot.integrations.shop.ShopShopGuiPlus import com.willfp.eco.internal.spigot.integrations.shop.ShopShopGuiPlus
import com.willfp.eco.internal.spigot.integrations.shop.ShopZShop
import com.willfp.eco.internal.spigot.math.evaluateExpression import com.willfp.eco.internal.spigot.math.evaluateExpression
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
import com.willfp.eco.internal.spigot.proxy.SkullProxy import com.willfp.eco.internal.spigot.proxy.SkullProxy
@@ -176,7 +179,7 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
val tpsProxy = getProxy(TPSProxy::class.java) val tpsProxy = getProxy(TPSProxy::class.java)
ServerUtils.initialize { tpsProxy.getTPS() } ServerUtils.initialize { tpsProxy.getTPS() }
NumberUtils.initCrunch { expression, player, statics -> evaluateExpression(expression, player, statics) } NumberUtils.initCrunch { expression, player, context -> evaluateExpression(expression, player, context) }
CustomItemsManager.registerProviders() CustomItemsManager.registerProviders()
@@ -190,6 +193,9 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
override fun handleEnable() { override fun handleEnable() {
CollatedRunnable(this) CollatedRunnable(this)
// Register events for ShopSellEvent
ShopManager.registerEvents(this)
if (!Prerequisite.HAS_PAPER.isMet) { if (!Prerequisite.HAS_PAPER.isMet) {
(Eco.getHandler() as EcoHandler).setAdventure(BukkitAudiences.create(this)) (Eco.getHandler() as EcoHandler).setAdventure(BukkitAudiences.create(this))
} }
@@ -254,12 +260,12 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
}, },
// Anticheat // Anticheat
IntegrationLoader("AAC5") { AnticheatManager.register(this, AnticheatAAC()) }, IntegrationLoader("AAC5") { AnticheatManager.register(AnticheatAAC()) },
IntegrationLoader("Matrix") { AnticheatManager.register(this, AnticheatMatrix()) }, IntegrationLoader("Matrix") { AnticheatManager.register(AnticheatMatrix()) },
IntegrationLoader("NoCheatPlus") { AnticheatManager.register(this, AnticheatNCP()) }, IntegrationLoader("NoCheatPlus") { AnticheatManager.register(AnticheatNCP()) },
IntegrationLoader("Spartan") { AnticheatManager.register(this, AnticheatSpartan()) }, IntegrationLoader("Spartan") { AnticheatManager.register(AnticheatSpartan()) },
IntegrationLoader("Vulcan") { AnticheatManager.register(this, AnticheatVulcan()) }, IntegrationLoader("Vulcan") { AnticheatManager.register(AnticheatVulcan()) },
IntegrationLoader("Alice") { AnticheatManager.register(this, AnticheatAlice()) }, IntegrationLoader("Alice") { AnticheatManager.register(AnticheatAlice()) },
// Custom Entities // Custom Entities
IntegrationLoader("MythicMobs") { CustomEntitiesManager.register(CustomEntitiesMythicMobs()) }, IntegrationLoader("MythicMobs") { CustomEntitiesManager.register(CustomEntitiesMythicMobs()) },
@@ -277,6 +283,9 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
// Shop // Shop
IntegrationLoader("ShopGUIPlus") { ShopManager.register(ShopShopGuiPlus()) }, IntegrationLoader("ShopGUIPlus") { ShopManager.register(ShopShopGuiPlus()) },
IntegrationLoader("zShop") { ShopManager.register(ShopZShop()) },
IntegrationLoader("DeluxeSellwands") { ShopManager.register(ShopDeluxeSellwands()) },
IntegrationLoader("EconomyShopGUI") { ShopManager.register(ShopEconomyShopGUI()) },
// Hologram // Hologram
IntegrationLoader("HolographicDisplays") { HologramManager.register(HologramHolographicDisplays(this)) }, IntegrationLoader("HolographicDisplays") { HologramManager.register(HologramHolographicDisplays(this)) },

View File

@@ -14,7 +14,7 @@ class ArrowDataListener(
) : Listener { ) : Listener {
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
fun onLaunch(event:ProjectileLaunchEvent) { fun onLaunch(event: ProjectileLaunchEvent) {
val arrow = event.entity val arrow = event.entity
if (arrow !is Arrow) { if (arrow !is Arrow) {

View File

@@ -149,7 +149,7 @@ class MySQLDataHandler(
private class ImplementedMySQLHandler( private class ImplementedMySQLHandler(
private val handler: EcoProfileHandler, private val handler: EcoProfileHandler,
private val table: UUIDTable, private val table: UUIDTable,
private val plugin: EcoPlugin, plugin: EcoPlugin,
private val knownKeys: Collection<PersistentDataKey<*>> private val knownKeys: Collection<PersistentDataKey<*>>
) { ) {
private val columns = Caffeine.newBuilder() private val columns = Caffeine.newBuilder()

View File

@@ -1,10 +1,10 @@
package com.willfp.eco.internal.spigot.integrations.afk package com.willfp.eco.internal.spigot.integrations.afk
import com.Zrips.CMI.CMI import com.Zrips.CMI.CMI
import com.willfp.eco.core.integrations.afk.AFKWrapper import com.willfp.eco.core.integrations.afk.AFKIntegration
import org.bukkit.entity.Player import org.bukkit.entity.Player
class AFKIntegrationCMI : AFKWrapper { class AFKIntegrationCMI : AFKIntegration {
override fun isAfk(player: Player): Boolean { override fun isAfk(player: Player): Boolean {
return CMI.getInstance().playerManager.getUser(player)?.isAfk ?: false return CMI.getInstance().playerManager.getUser(player)?.isAfk ?: false
} }

View File

@@ -1,11 +1,11 @@
package com.willfp.eco.internal.spigot.integrations.afk package com.willfp.eco.internal.spigot.integrations.afk
import com.earth2me.essentials.Essentials import com.earth2me.essentials.Essentials
import com.willfp.eco.core.integrations.afk.AFKWrapper import com.willfp.eco.core.integrations.afk.AFKIntegration
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.plugin.java.JavaPlugin import org.bukkit.plugin.java.JavaPlugin
class AFKIntegrationEssentials : AFKWrapper { class AFKIntegrationEssentials : AFKIntegration {
private val ess = JavaPlugin.getPlugin(Essentials::class.java) private val ess = JavaPlugin.getPlugin(Essentials::class.java)
override fun isAfk(player: Player): Boolean { override fun isAfk(player: Player): Boolean {

View File

@@ -1,13 +1,13 @@
package com.willfp.eco.internal.spigot.integrations.anticheat package com.willfp.eco.internal.spigot.integrations.anticheat
import com.willfp.eco.core.integrations.anticheat.AnticheatWrapper import com.willfp.eco.core.integrations.anticheat.AnticheatIntegration
import me.konsolas.aac.api.AACAPI import me.konsolas.aac.api.AACAPI
import me.konsolas.aac.api.AACExemption import me.konsolas.aac.api.AACExemption
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.Listener import org.bukkit.event.Listener
class AnticheatAAC : AnticheatWrapper, Listener { class AnticheatAAC : AnticheatIntegration, Listener {
private val ecoExemption = AACExemption("eco") private val ecoExemption = AACExemption("eco")
private val api = Bukkit.getServicesManager().load(AACAPI::class.java)!! private val api = Bukkit.getServicesManager().load(AACAPI::class.java)!!

View File

@@ -1,6 +1,6 @@
package com.willfp.eco.internal.spigot.integrations.anticheat package com.willfp.eco.internal.spigot.integrations.anticheat
import com.willfp.eco.core.integrations.anticheat.AnticheatWrapper import com.willfp.eco.core.integrations.anticheat.AnticheatIntegration
import me.nik.alice.api.events.AliceViolationEvent import me.nik.alice.api.events.AliceViolationEvent
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
@@ -8,7 +8,7 @@ import org.bukkit.event.EventPriority
import org.bukkit.event.Listener import org.bukkit.event.Listener
import java.util.UUID import java.util.UUID
class AnticheatAlice : AnticheatWrapper, Listener { class AnticheatAlice : AnticheatIntegration, Listener {
private val exempt: MutableSet<UUID> = HashSet() private val exempt: MutableSet<UUID> = HashSet()
override fun getPluginName(): String { override fun getPluginName(): String {

Some files were not shown because too many files have changed in this diff Show More