Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
616fa032d9 | ||
|
|
ea997239fc | ||
|
|
ad04abab73 | ||
|
|
f440ef922b | ||
|
|
933271fb4a | ||
|
|
9679d3100f | ||
|
|
6e20763522 | ||
|
|
18dea2c20c | ||
|
|
62b666559c | ||
|
|
465563523b | ||
|
|
f0f014ed89 | ||
|
|
58811c5d77 | ||
|
|
81d495e76e | ||
|
|
c78e397959 | ||
|
|
95740f155e | ||
|
|
5638d5e152 | ||
|
|
4d3712057c | ||
|
|
458fcd78b3 | ||
|
|
ee13de31f4 | ||
|
|
9588d49788 | ||
|
|
8e7ce298b0 | ||
|
|
32a11ce5b8 | ||
|
|
960f62cc8b | ||
|
|
28ceb83eb5 | ||
|
|
6f748b6b8a | ||
|
|
190ea5d49f | ||
|
|
c0ed083a5c | ||
|
|
04f04bb7a6 | ||
|
|
b8a3806ff9 | ||
|
|
ae49d41542 | ||
|
|
5f2255a3bc | ||
|
|
065ccfbe67 | ||
|
|
17727c9015 | ||
|
|
ea64e69b4d | ||
|
|
07ca6c2359 | ||
|
|
162558b1c2 | ||
|
|
10f9e8dce0 | ||
|
|
b02943d7ff | ||
|
|
1cf08955a0 |
@@ -21,10 +21,8 @@ import com.willfp.eco.core.gui.menu.MenuBuilder;
|
||||
import com.willfp.eco.core.gui.menu.MenuType;
|
||||
import com.willfp.eco.core.gui.slot.SlotBuilder;
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration;
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import com.willfp.eco.core.placeholder.AdditionalPlayer;
|
||||
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
|
||||
import com.willfp.eco.core.math.MathContext;
|
||||
import com.willfp.eco.core.proxy.ProxyFactory;
|
||||
import com.willfp.eco.core.scheduling.Scheduler;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
@@ -42,7 +40,6 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -138,10 +135,9 @@ public interface Eco {
|
||||
* Create a PAPI integration.
|
||||
*
|
||||
* @param plugin The plugin.
|
||||
* @return The integration.
|
||||
*/
|
||||
@NotNull
|
||||
PlaceholderIntegration createPAPIIntegration(@NotNull EcoPlugin plugin);
|
||||
void createPAPIIntegration(@NotNull EcoPlugin plugin);
|
||||
|
||||
/**
|
||||
* Create a proxy factory.
|
||||
@@ -337,15 +333,6 @@ public interface Eco {
|
||||
*/
|
||||
Set<PersistentDataKey<?>> getRegisteredPersistentDataKeys();
|
||||
|
||||
/**
|
||||
* Get persistent data key from namespaced key.
|
||||
*
|
||||
* @param namespacedKey The key.
|
||||
* @return The key, or null if not found.
|
||||
*/
|
||||
@Nullable
|
||||
PersistentDataKey<?> getPersistentDataKeyFrom(@NotNull NamespacedKey namespacedKey);
|
||||
|
||||
/**
|
||||
* Load a player profile.
|
||||
*
|
||||
@@ -370,24 +357,6 @@ public interface Eco {
|
||||
*/
|
||||
void unloadPlayerProfile(@NotNull UUID uuid);
|
||||
|
||||
/**
|
||||
* Save keys for a player.
|
||||
* <p>
|
||||
* Can run async if using MySQL.
|
||||
*
|
||||
* @param uuid The uuid.
|
||||
* @param keys The keys.
|
||||
*/
|
||||
void savePersistentDataKeysFor(@NotNull UUID uuid,
|
||||
@NotNull Set<PersistentDataKey<?>> keys);
|
||||
|
||||
/**
|
||||
* Commit all changes to the file.
|
||||
* <p>
|
||||
* Does nothing if using MySQL.
|
||||
*/
|
||||
void saveAllProfiles();
|
||||
|
||||
/**
|
||||
* Create dummy entity - never spawned, exists purely in code.
|
||||
*
|
||||
@@ -513,16 +482,12 @@ public interface Eco {
|
||||
/**
|
||||
* Evaluate an expression.
|
||||
*
|
||||
* @param expression The expression.
|
||||
* @param player The player.
|
||||
* @param injectable The injectable placeholders.
|
||||
* @param additionalPlayers The additional players.
|
||||
* @param expression The expression.
|
||||
* @param context The context.
|
||||
* @return The value of the expression, or zero if invalid.
|
||||
*/
|
||||
double evaluate(@NotNull String expression,
|
||||
@Nullable Player player,
|
||||
@NotNull PlaceholderInjectable injectable,
|
||||
@NotNull Collection<AdditionalPlayer> additionalPlayers);
|
||||
@NotNull MathContext context);
|
||||
|
||||
/**
|
||||
* Get the menu a player currently has open.
|
||||
|
||||
@@ -13,7 +13,6 @@ import com.willfp.eco.core.factory.MetadataValueFactory;
|
||||
import com.willfp.eco.core.factory.NamespacedKeyFactory;
|
||||
import com.willfp.eco.core.factory.RunnableFactory;
|
||||
import com.willfp.eco.core.integrations.IntegrationLoader;
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
||||
import com.willfp.eco.core.proxy.ProxyFactory;
|
||||
import com.willfp.eco.core.scheduling.Scheduler;
|
||||
import com.willfp.eco.core.web.UpdateChecker;
|
||||
@@ -153,6 +152,31 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
@Nullable
|
||||
private final ProxyFactory proxyFactory;
|
||||
|
||||
/**
|
||||
* The tasks to run on enable.
|
||||
*/
|
||||
private final List<Runnable> onEnable = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The tasks to run on disable.
|
||||
*/
|
||||
private final List<Runnable> onDisable = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The tasks to run on reload.
|
||||
*/
|
||||
private final List<Runnable> onReload = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The tasks to run on load.
|
||||
*/
|
||||
private final List<Runnable> onLoad = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The tasks to run after load.
|
||||
*/
|
||||
private final List<Runnable> afterLoad = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Create a new plugin.
|
||||
* <p>
|
||||
@@ -375,8 +399,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (enabledPlugins.contains("PlaceholderAPI".toLowerCase())) {
|
||||
this.loadedIntegrations.add("PlaceholderAPI");
|
||||
PlaceholderManager.addIntegration(Eco.get().createPAPIIntegration(this));
|
||||
Eco.get().createPAPIIntegration(this);
|
||||
}
|
||||
|
||||
this.loadIntegrationLoaders().forEach(integrationLoader -> {
|
||||
@@ -386,6 +409,8 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
}
|
||||
});
|
||||
|
||||
this.loadedIntegrations.removeIf(pl -> pl.equalsIgnoreCase(this.getName()));
|
||||
|
||||
this.getLogger().info("Loaded integrations: " + String.join(", ", this.getLoadedIntegrations()));
|
||||
|
||||
Prerequisite.update();
|
||||
@@ -414,10 +439,20 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
}
|
||||
|
||||
this.handleEnable();
|
||||
this.onEnable.forEach(Runnable::run);
|
||||
|
||||
this.getLogger().info("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new task to run on enable.
|
||||
*
|
||||
* @param task The task.
|
||||
*/
|
||||
public final void onEnable(@NotNull final Runnable task) {
|
||||
this.onEnable.add(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default code to be executed on plugin disable.
|
||||
*/
|
||||
@@ -429,6 +464,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
this.getScheduler().cancelAll();
|
||||
|
||||
this.handleDisable();
|
||||
this.onDisable.forEach(Runnable::run);
|
||||
|
||||
if (this.isSupportingExtensions()) {
|
||||
this.getExtensionLoader().unloadExtensions();
|
||||
@@ -438,6 +474,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
Eco.get().clean(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new task to run on disable.
|
||||
*
|
||||
* @param task The task.
|
||||
*/
|
||||
public final void onDisable(@NotNull final Runnable task) {
|
||||
this.onDisable.add(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default code to be executed on plugin load.
|
||||
*/
|
||||
@@ -446,6 +491,16 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
super.onLoad();
|
||||
|
||||
this.handleLoad();
|
||||
this.onLoad.forEach(Runnable::run);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new task to run on load.
|
||||
*
|
||||
* @param task The task.
|
||||
*/
|
||||
public final void onLoad(@NotNull final Runnable task) {
|
||||
this.onLoad.add(task);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -478,6 +533,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
}
|
||||
|
||||
this.handleAfterLoad();
|
||||
this.afterLoad.forEach(Runnable::run);
|
||||
|
||||
this.reload();
|
||||
|
||||
@@ -488,6 +544,15 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
this.getLogger().info("Loaded " + this.color + this.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new task to run after load.
|
||||
*
|
||||
* @param task The task.
|
||||
*/
|
||||
public final void afterLoad(@NotNull final Runnable task) {
|
||||
this.afterLoad.add(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the plugin.
|
||||
*/
|
||||
@@ -499,12 +564,22 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike {
|
||||
this.getConfigHandler().callUpdate(); // Call twice to fix issues
|
||||
|
||||
this.handleReload();
|
||||
this.onReload.forEach(Runnable::run);
|
||||
|
||||
for (Extension extension : this.extensionLoader.getLoadedExtensions()) {
|
||||
extension.handleReload();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new task to run on enable.
|
||||
*
|
||||
* @param task The task.
|
||||
*/
|
||||
public final void onReload(@NotNull final Runnable task) {
|
||||
this.onReload.add(task);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the plugin and return the time taken to reload.
|
||||
*
|
||||
|
||||
@@ -6,12 +6,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* Builder for configs to create them programmatically.
|
||||
*/
|
||||
public class BuildableConfig extends TransientConfig {
|
||||
public class BuildableConfig extends GenericConfig {
|
||||
/**
|
||||
* Create a new empty config builder.
|
||||
*/
|
||||
public BuildableConfig() {
|
||||
super();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
157
eco-api/src/main/java/com/willfp/eco/core/config/Configs.java
Normal file
157
eco-api/src/main/java/com/willfp/eco/core/config/Configs.java
Normal file
@@ -0,0 +1,157 @@
|
||||
package com.willfp.eco.core.config;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utilities / API methods for configs.
|
||||
*/
|
||||
public final class Configs {
|
||||
/**
|
||||
* Load a Config from a bukkit {@link ConfigurationSection}.
|
||||
*
|
||||
* @param config The ConfigurationSection.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromBukkit(@Nullable final ConfigurationSection config) {
|
||||
return config == null ? empty() : Eco.get().wrapConfigurationSection(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a config from an {@link InputStream}.
|
||||
* <p>
|
||||
* Only for yaml configs.
|
||||
*
|
||||
* @param stream The InputStream.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromStream(@Nullable final InputStream stream) {
|
||||
return stream != null ? fromBukkit(YamlConfiguration.loadConfiguration(
|
||||
new InputStreamReader(stream)
|
||||
)) : empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a config from a file.
|
||||
*
|
||||
* @param file The file.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromFile(@Nullable final File file) {
|
||||
if (file == null) {
|
||||
return empty();
|
||||
}
|
||||
|
||||
int lastIndex = file.getName().lastIndexOf(".");
|
||||
|
||||
if (lastIndex < 0) {
|
||||
return empty();
|
||||
}
|
||||
|
||||
for (ConfigType type : ConfigType.values()) {
|
||||
if (file.getName().substring(lastIndex + 1).equalsIgnoreCase(type.getExtension())) {
|
||||
return fromFile(file, type);
|
||||
}
|
||||
}
|
||||
|
||||
return empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a config from a file.
|
||||
*
|
||||
* @param file The file.
|
||||
* @param type The type.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromFile(@Nullable final File file,
|
||||
@NotNull final ConfigType type) {
|
||||
if (file == null) {
|
||||
return empty();
|
||||
}
|
||||
|
||||
try {
|
||||
return Eco.get().createConfig(Files.readString(file.toPath()), type);
|
||||
} catch (IOException e) {
|
||||
return empty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load config from map (uses {@link ConfigType#JSON}).
|
||||
*
|
||||
* @param values The values.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromMap(@NotNull final Map<String, Object> values) {
|
||||
return fromMap(values, ConfigType.JSON);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load config from map.
|
||||
*
|
||||
* @param values The values.
|
||||
* @param type The type.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromMap(@NotNull final Map<String, Object> values,
|
||||
@NotNull final ConfigType type) {
|
||||
return Eco.get().createConfig(values, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty config (uses {@link ConfigType#JSON}).
|
||||
*
|
||||
* @return An empty config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config empty() {
|
||||
return fromMap(new HashMap<>(), ConfigType.JSON);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create empty config.
|
||||
*
|
||||
* @param type The type.
|
||||
* @return An empty config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config empty(@NotNull final ConfigType type) {
|
||||
return fromMap(new HashMap<>(), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load config from string.
|
||||
*
|
||||
* @param contents The contents of the config.
|
||||
* @param type The config type.
|
||||
* @return The config.
|
||||
*/
|
||||
@NotNull
|
||||
public static Config fromString(@NotNull final String contents,
|
||||
@NotNull final ConfigType type) {
|
||||
return Eco.get().createConfig(contents, type);
|
||||
}
|
||||
|
||||
private Configs() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.willfp.eco.core.config;
|
||||
|
||||
import com.willfp.eco.core.config.interfaces.Config;
|
||||
import com.willfp.eco.core.config.wrapper.ConfigWrapper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Generic config to simplify creating custom configs without having
|
||||
* to meddle with delegation.
|
||||
*/
|
||||
public abstract class GenericConfig extends ConfigWrapper<Config> {
|
||||
/**
|
||||
* Create a new generic config.
|
||||
*/
|
||||
protected GenericConfig() {
|
||||
super(Configs.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new generic config.
|
||||
*
|
||||
* @param type The config type.
|
||||
*/
|
||||
protected GenericConfig(@NotNull final ConfigType type) {
|
||||
super(Configs.empty(type));
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,10 @@ import java.util.Map;
|
||||
* Config that exists purely in the code, not linked to any file.
|
||||
* <p>
|
||||
* Use for inline configs to move data around or to add subsections to other configs.
|
||||
*
|
||||
* @deprecated Poorly named class, makes the config system seem needlessly complicated.
|
||||
*/
|
||||
@Deprecated(since = "6.44.0", forRemoval = true)
|
||||
public class TransientConfig extends ConfigWrapper<Config> {
|
||||
/**
|
||||
* @param config The ConfigurationSection handle.
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.willfp.eco.core.config.interfaces;
|
||||
|
||||
import com.willfp.eco.core.config.BuildableConfig;
|
||||
import com.willfp.eco.core.config.ConfigType;
|
||||
import com.willfp.eco.core.config.TransientConfig;
|
||||
import com.willfp.eco.core.config.Configs;
|
||||
import com.willfp.eco.core.placeholder.AdditionalPlayer;
|
||||
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
|
||||
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
|
||||
@@ -103,7 +103,7 @@ public interface Config extends Cloneable, PlaceholderInjectable {
|
||||
*/
|
||||
@NotNull
|
||||
default Config getSubsection(@NotNull String path) {
|
||||
return Objects.requireNonNullElse(getSubsectionOrNull(path), new TransientConfig());
|
||||
return Objects.requireNonNullElse(getSubsectionOrNull(path), Configs.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,6 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@@ -110,15 +110,32 @@ public interface Menu {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add state for a player.
|
||||
* Set 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);
|
||||
default void setState(@NotNull Player player,
|
||||
@NotNull String key,
|
||||
@Nullable Object value) {
|
||||
// Blank method for backwards compatibility.
|
||||
}
|
||||
|
||||
/**
|
||||
* Add state for a player.
|
||||
*
|
||||
* @param player The player.
|
||||
* @param key The key.
|
||||
* @param value The state.
|
||||
* @deprecated Poorly named, use setState instead.
|
||||
*/
|
||||
@Deprecated(since = "6.44.0", forRemoval = true)
|
||||
default void addState(@NotNull Player player,
|
||||
@NotNull String key,
|
||||
@Nullable Object value) {
|
||||
this.setState(player, key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove state for a player.
|
||||
@@ -221,7 +238,7 @@ public interface Menu {
|
||||
@NotNull final NamespacedKey key,
|
||||
@NotNull final PersistentDataType<T, Z> type,
|
||||
@NotNull final Z value) {
|
||||
this.addState(player, key.toString(), value);
|
||||
this.setState(player, key.toString(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -139,7 +139,7 @@ public interface MenuBuilder extends PageBuilder {
|
||||
* @return The builder.
|
||||
*/
|
||||
default MenuBuilder maxPages(@NotNull final Function<Player, Integer> pages) {
|
||||
return onOpen((player, menu) -> menu.addState(player, Page.MAX_PAGE_KEY, pages.apply(player)));
|
||||
return onRender((player, menu) -> menu.setState(player, Page.MAX_PAGE_KEY, pages.apply(player)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,8 +9,6 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A page is a component representing another menu.
|
||||
* This allows full component support in pagination.
|
||||
|
||||
@@ -48,7 +48,7 @@ public final class PageChanger implements GUIComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
menu.addState(player, Page.PAGE_KEY, newPage);
|
||||
menu.setState(player, Page.PAGE_KEY, newPage);
|
||||
menu.callEvent(player, new PageChangeEvent(
|
||||
newPage,
|
||||
page
|
||||
|
||||
@@ -51,10 +51,15 @@ public final class PlaceholderManager {
|
||||
.expireAfterWrite(50, TimeUnit.MILLISECONDS)
|
||||
.build(key -> key.entry.getValue(key.player));
|
||||
|
||||
/**
|
||||
* The default PlaceholderAPI pattern; brought in for compatibility.
|
||||
*/
|
||||
private static final Pattern PATTERN = Pattern.compile("[%]([^% ]+)[%]");
|
||||
|
||||
/**
|
||||
* Empty injectable object.
|
||||
*/
|
||||
private static final PlaceholderInjectable EMPTY_INJECTABLE = new PlaceholderInjectable() {
|
||||
public static final PlaceholderInjectable EMPTY_INJECTABLE = new PlaceholderInjectable() {
|
||||
@Override
|
||||
public void clearInjectedPlaceholders() {
|
||||
// Do nothing.
|
||||
@@ -67,11 +72,6 @@ public final class PlaceholderManager {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The default PlaceholderAPI pattern; brought in for compatibility.
|
||||
*/
|
||||
private static final Pattern PATTERN = Pattern.compile("[%]([^%]+)[%]");
|
||||
|
||||
/**
|
||||
* Register a new placeholder integration.
|
||||
*
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package com.willfp.eco.core.integrations.shop;
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -86,6 +87,11 @@ public final class Items {
|
||||
*/
|
||||
private static final TestableItem EMPTY_TESTABLE_ITEM = new EmptyTestableItem();
|
||||
|
||||
/**
|
||||
* Friendly material names (without underscores, etc.)
|
||||
*/
|
||||
private static final Map<String, Material> FRIENDLY_MATERIAL_NAMES = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Register a new custom item.
|
||||
*
|
||||
@@ -216,7 +222,7 @@ public final class Items {
|
||||
if (isWildcard) {
|
||||
itemType = itemType.substring(1);
|
||||
}
|
||||
Material material = Material.getMaterial(itemType.toUpperCase());
|
||||
Material material = FRIENDLY_MATERIAL_NAMES.get(itemType.toLowerCase());
|
||||
if (material == null || material == Material.AIR) {
|
||||
return new EmptyTestableItem();
|
||||
}
|
||||
@@ -565,4 +571,25 @@ public final class Items {
|
||||
private Items() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
|
||||
static {
|
||||
for (Material material : Material.values()) {
|
||||
FRIENDLY_MATERIAL_NAMES.put(material.name().toLowerCase(), material);
|
||||
|
||||
String oneWord = material.name().toLowerCase().replace("_", "");
|
||||
if (!FRIENDLY_MATERIAL_NAMES.containsKey(oneWord)) {
|
||||
FRIENDLY_MATERIAL_NAMES.put(oneWord, material);
|
||||
}
|
||||
|
||||
String plural = material.name().toLowerCase() + "s";
|
||||
if (!FRIENDLY_MATERIAL_NAMES.containsKey(plural)) {
|
||||
FRIENDLY_MATERIAL_NAMES.put(plural, material);
|
||||
}
|
||||
|
||||
String oneWordPlural = oneWord + "s";
|
||||
if (!FRIENDLY_MATERIAL_NAMES.containsKey(oneWordPlural)) {
|
||||
FRIENDLY_MATERIAL_NAMES.put(oneWordPlural, material);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.willfp.eco.core.math;
|
||||
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
||||
import com.willfp.eco.core.placeholder.AdditionalPlayer;
|
||||
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Represents a context to do math in.
|
||||
*
|
||||
* @param injectableContext The PlaceholderInjectable context.
|
||||
* @param player The player.
|
||||
* @param additionalPlayers The additional players.
|
||||
*/
|
||||
public record MathContext(
|
||||
@NotNull PlaceholderInjectable injectableContext,
|
||||
@Nullable Player player,
|
||||
@NotNull Collection<AdditionalPlayer> additionalPlayers
|
||||
) {
|
||||
/**
|
||||
* Empty math context.
|
||||
*/
|
||||
public static final MathContext EMPTY = new MathContext(
|
||||
PlaceholderManager.EMPTY_INJECTABLE,
|
||||
null,
|
||||
Collections.emptyList()
|
||||
);
|
||||
|
||||
/**
|
||||
* Create MathContext of a PlaceholderInjectable context.
|
||||
*
|
||||
* @param injectableContext The PlaceholderInjectable context.
|
||||
* @return The MathContext.
|
||||
*/
|
||||
public static MathContext of(@NotNull final PlaceholderInjectable injectableContext) {
|
||||
return new MathContext(
|
||||
injectableContext,
|
||||
null,
|
||||
Collections.emptyList()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.willfp.eco.core.particle;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Create particles.
|
||||
*/
|
||||
public interface ParticleFactory {
|
||||
/**
|
||||
* Get the names (how the particle looks in lookup strings).
|
||||
* <p>
|
||||
* For example, for RGB particles this would be 'rgb', 'color', etc.
|
||||
*
|
||||
* @return The allowed names.
|
||||
*/
|
||||
@NotNull List<String> getNames();
|
||||
|
||||
/**
|
||||
* Create the particle
|
||||
*
|
||||
* @param key The key.
|
||||
* @return The particle.
|
||||
*/
|
||||
@Nullable SpawnableParticle create(@NotNull String key);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.willfp.eco.core.particle;
|
||||
|
||||
import com.willfp.eco.core.particle.impl.EmptyParticle;
|
||||
import com.willfp.eco.core.particle.impl.SimpleParticle;
|
||||
import com.willfp.eco.util.StringUtils;
|
||||
import org.bukkit.Particle;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Class to manage particles.
|
||||
*/
|
||||
public final class Particles {
|
||||
/**
|
||||
* All factories.
|
||||
*/
|
||||
private static final Map<String, ParticleFactory> FACTORIES = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Register a new particle factory.
|
||||
*
|
||||
* @param factory The factory.
|
||||
*/
|
||||
public static void registerParticleFactory(@NotNull final ParticleFactory factory) {
|
||||
for (String name : factory.getNames()) {
|
||||
FACTORIES.put(name.toLowerCase(), factory);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup a particle from a string.
|
||||
* <p>
|
||||
* A particle string should look like {@code magic}, {@code rgb:00ff00}
|
||||
*
|
||||
* @param key The key.
|
||||
* @return The particle, or an {@link EmptyParticle} if invalid.
|
||||
*/
|
||||
@NotNull
|
||||
public static SpawnableParticle lookup(@NotNull final String key) {
|
||||
String[] args = StringUtils.parseTokens(key.toLowerCase());
|
||||
|
||||
if (args.length == 0) {
|
||||
return new EmptyParticle();
|
||||
}
|
||||
|
||||
SpawnableParticle spawnableParticle;
|
||||
|
||||
String[] split = args[0].split(":");
|
||||
|
||||
if (split.length == 1) {
|
||||
try {
|
||||
Particle particle = Particle.valueOf(args[0].toUpperCase());
|
||||
spawnableParticle = new SimpleParticle(particle);
|
||||
} catch (IllegalArgumentException e) {
|
||||
spawnableParticle = new EmptyParticle();
|
||||
}
|
||||
} else if (split.length == 2) {
|
||||
String name = split[0];
|
||||
String factoryKey = split[1];
|
||||
|
||||
ParticleFactory factory = FACTORIES.get(name);
|
||||
if (factory == null) {
|
||||
spawnableParticle = new EmptyParticle();
|
||||
} else {
|
||||
spawnableParticle = factory.create(factoryKey);
|
||||
}
|
||||
} else {
|
||||
return new EmptyParticle();
|
||||
}
|
||||
|
||||
if (spawnableParticle == null || spawnableParticle instanceof EmptyParticle) {
|
||||
return new EmptyParticle();
|
||||
}
|
||||
|
||||
return spawnableParticle;
|
||||
}
|
||||
|
||||
private Particles() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.willfp.eco.core.particle;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A particle that can be spawned.
|
||||
*/
|
||||
public interface SpawnableParticle {
|
||||
/**
|
||||
* Spawn the particle at a location.
|
||||
*
|
||||
* @param location The location.
|
||||
* @param amount The amount to spawn.
|
||||
*/
|
||||
void spawn(@NotNull Location location,
|
||||
int amount);
|
||||
|
||||
/**
|
||||
* Spawn the particle at a location.
|
||||
*
|
||||
* @param location The location.
|
||||
*/
|
||||
default void spawn(@NotNull Location location) {
|
||||
spawn(location, 1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.willfp.eco.core.particle.impl;
|
||||
|
||||
import com.willfp.eco.core.particle.SpawnableParticle;
|
||||
import org.bukkit.Location;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Empty (invalid) particle that is spawned when an invalid key is provided.
|
||||
*/
|
||||
public final class EmptyParticle implements SpawnableParticle {
|
||||
@Override
|
||||
public void spawn(@NotNull final Location location,
|
||||
final int amount) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.willfp.eco.core.particle.impl;
|
||||
|
||||
import com.willfp.eco.core.particle.SpawnableParticle;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.World;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Empty (invalid) particle that is spawned when an invalid key is provided.
|
||||
*/
|
||||
public final class SimpleParticle implements SpawnableParticle {
|
||||
/**
|
||||
* The particle to be spawned.
|
||||
*/
|
||||
private final Particle particle;
|
||||
|
||||
/**
|
||||
* Create a new spawnable particle.
|
||||
*
|
||||
* @param particle The particle.
|
||||
*/
|
||||
public SimpleParticle(@NotNull final Particle particle) {
|
||||
this.particle = particle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawn(@NotNull final Location location,
|
||||
final int amount) {
|
||||
World world = location.getWorld();
|
||||
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
world.spawnParticle(particle, location, amount, 0, 0, 0, null);
|
||||
}
|
||||
}
|
||||
44
eco-api/src/main/java/com/willfp/eco/core/price/Price.java
Normal file
44
eco-api/src/main/java/com/willfp/eco/core/price/Price.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package com.willfp.eco.core.price;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A price that a player should pay.
|
||||
*/
|
||||
public interface Price {
|
||||
/**
|
||||
* Get if the player can afford the price.
|
||||
*
|
||||
* @param player The player.
|
||||
* @return If the player can afford.
|
||||
*/
|
||||
boolean canAfford(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Make the player pay the price.
|
||||
* <p>
|
||||
* Only run this if the player can afford the price.
|
||||
*
|
||||
* @param player The player.
|
||||
*/
|
||||
void pay(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* If the price is backed by a value, get it here.
|
||||
*
|
||||
* @return The value.
|
||||
*/
|
||||
default double getValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the price is backed by a value, set it here.
|
||||
*
|
||||
* @param value The value.
|
||||
*/
|
||||
default void setValue(final double value) {
|
||||
// Override when needed.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.willfp.eco.core.price;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Create prices.
|
||||
*/
|
||||
public interface PriceFactory {
|
||||
/**
|
||||
* Get the names (how the price looks in lookup strings).
|
||||
* <p>
|
||||
* For example, for XP Levels this would be 'l', 'xpl', 'levels', etc.
|
||||
*
|
||||
* @return The allowed names.
|
||||
*/
|
||||
@NotNull List<String> getNames();
|
||||
|
||||
/**
|
||||
* Create the price.
|
||||
*
|
||||
* @param value The value.
|
||||
* @return The price.
|
||||
*/
|
||||
@NotNull Price create(double value);
|
||||
}
|
||||
102
eco-api/src/main/java/com/willfp/eco/core/price/Prices.java
Normal file
102
eco-api/src/main/java/com/willfp/eco/core/price/Prices.java
Normal file
@@ -0,0 +1,102 @@
|
||||
package com.willfp.eco.core.price;
|
||||
|
||||
import com.willfp.eco.core.items.Items;
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import com.willfp.eco.core.math.MathContext;
|
||||
import com.willfp.eco.core.price.impl.PriceEconomy;
|
||||
import com.willfp.eco.core.price.impl.PriceFree;
|
||||
import com.willfp.eco.core.price.impl.PriceItem;
|
||||
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
|
||||
import com.willfp.eco.util.NumberUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Class to manage prices.
|
||||
*/
|
||||
public final class Prices {
|
||||
/**
|
||||
* All factories.
|
||||
*/
|
||||
private static final Map<String, PriceFactory> FACTORIES = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Register a new price factory.
|
||||
*
|
||||
* @param factory The factory.
|
||||
*/
|
||||
public static void registerPriceFactory(@NotNull final PriceFactory factory) {
|
||||
for (String name : factory.getNames()) {
|
||||
FACTORIES.put(name.toLowerCase(), factory);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create price from an expression (representing the value),
|
||||
* and a price name.
|
||||
* <p>
|
||||
* Supports items as price names.
|
||||
*
|
||||
* @param expression The expression for the value.
|
||||
* @param priceName The price name.
|
||||
* @return The price, or free if invalid.
|
||||
*/
|
||||
@NotNull
|
||||
public static Price create(@NotNull final String expression,
|
||||
@Nullable final String priceName) {
|
||||
return create(expression, priceName, MathContext.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create price from an expression (representing the value),
|
||||
* and a price name. Uses a context to parse the expression.
|
||||
* <p>
|
||||
* Supports items as price names.
|
||||
*
|
||||
* @param expression The expression for the value.
|
||||
* @param priceName The price name.
|
||||
* @param context The math context to parse the expression.
|
||||
* @return The price, or free if invalid.
|
||||
*/
|
||||
@NotNull
|
||||
public static Price create(@NotNull final String expression,
|
||||
@Nullable final String priceName,
|
||||
@NotNull final MathContext context) {
|
||||
double value = NumberUtils.evaluateExpression(
|
||||
expression,
|
||||
context
|
||||
);
|
||||
|
||||
if (value <= 0) {
|
||||
return new PriceFree();
|
||||
}
|
||||
|
||||
// Default to economy
|
||||
if (priceName == null) {
|
||||
return new PriceEconomy(value);
|
||||
}
|
||||
|
||||
// Find price factory
|
||||
PriceFactory factory = FACTORIES.get(priceName);
|
||||
|
||||
// If no price factory, default to item price
|
||||
if (factory == null) {
|
||||
TestableItem item = Items.lookup(priceName);
|
||||
|
||||
if (item instanceof EmptyTestableItem) {
|
||||
return new PriceFree();
|
||||
}
|
||||
|
||||
return new PriceItem((int) Math.round(value), item);
|
||||
} else {
|
||||
return factory.create(value);
|
||||
}
|
||||
}
|
||||
|
||||
private Prices() {
|
||||
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.willfp.eco.core.price.impl;
|
||||
|
||||
import com.willfp.eco.core.integrations.economy.EconomyManager;
|
||||
import com.willfp.eco.core.price.Price;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Economy-based price (for Vault, Treasury, etc.)
|
||||
*/
|
||||
public final class PriceEconomy implements Price {
|
||||
/**
|
||||
* The value of the price.
|
||||
*/
|
||||
private double value;
|
||||
|
||||
/**
|
||||
* Create a new economy-based price.
|
||||
*
|
||||
* @param value The value.
|
||||
*/
|
||||
public PriceEconomy(final double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAfford(@NotNull Player player) {
|
||||
return EconomyManager.getBalance(player) >= value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pay(@NotNull Player player) {
|
||||
EconomyManager.removeMoney(player, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(final double value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.willfp.eco.core.price.impl;
|
||||
|
||||
import com.willfp.eco.core.price.Price;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Free (default) price.
|
||||
*/
|
||||
public final class PriceFree implements Price {
|
||||
/**
|
||||
* Create a new free price.
|
||||
*/
|
||||
public PriceFree() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAfford(@NotNull Player player) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pay(@NotNull Player player) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.willfp.eco.core.price.impl;
|
||||
|
||||
import com.willfp.eco.core.items.TestableItem;
|
||||
import com.willfp.eco.core.price.Price;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Item-based price.
|
||||
*/
|
||||
public final class PriceItem implements Price {
|
||||
/**
|
||||
* The amount of items.
|
||||
*/
|
||||
private final int amountToRemove;
|
||||
|
||||
/**
|
||||
* The item.
|
||||
*/
|
||||
private final TestableItem item;
|
||||
|
||||
/**
|
||||
* Create a new economy-based price.
|
||||
*
|
||||
* @param amount The amount.
|
||||
* @param item The item.
|
||||
*/
|
||||
public PriceItem(final int amount,
|
||||
@NotNull final TestableItem item) {
|
||||
this.amountToRemove = Math.max(0, amount);
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item.
|
||||
*
|
||||
* @return The item.
|
||||
*/
|
||||
public TestableItem getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAfford(@NotNull Player player) {
|
||||
if (amountToRemove == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
for (ItemStack itemStack : player.getInventory().getContents()) {
|
||||
if (item.matches(itemStack)) {
|
||||
count += itemStack.getAmount();
|
||||
}
|
||||
}
|
||||
|
||||
return count >= amountToRemove;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pay(@NotNull Player player) {
|
||||
int count = 0;
|
||||
|
||||
for (ItemStack itemStack : player.getInventory().getContents()) {
|
||||
if (count >= amountToRemove) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (item.matches(itemStack)) {
|
||||
int itemAmount = itemStack.getAmount();
|
||||
|
||||
if (itemAmount > amountToRemove) {
|
||||
itemStack.setAmount(itemAmount - amountToRemove);
|
||||
}
|
||||
|
||||
if (itemAmount <= amountToRemove) {
|
||||
itemStack.setAmount(0);
|
||||
itemStack.setType(Material.AIR);
|
||||
}
|
||||
|
||||
count += itemAmount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.willfp.eco.util;
|
||||
|
||||
import com.willfp.eco.core.Eco;
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager;
|
||||
import com.willfp.eco.core.placeholder.AdditionalPlayer;
|
||||
import com.willfp.eco.core.placeholder.InjectablePlaceholder;
|
||||
import com.willfp.eco.core.math.MathContext;
|
||||
import com.willfp.eco.core.placeholder.PlaceholderInjectable;
|
||||
import com.willfp.eco.core.placeholder.StaticPlaceholder;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -12,7 +14,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
@@ -240,7 +241,7 @@ public final class NumberUtils {
|
||||
* @return The value of the expression, or zero if invalid.
|
||||
*/
|
||||
public static double evaluateExpression(@NotNull final String expression) {
|
||||
return evaluateExpression(expression, null);
|
||||
return evaluateExpression(expression, MathContext.EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -252,18 +253,7 @@ public final class NumberUtils {
|
||||
*/
|
||||
public static double evaluateExpression(@NotNull final String expression,
|
||||
@Nullable final Player player) {
|
||||
return evaluateExpression(expression, player, new PlaceholderInjectable() {
|
||||
@Override
|
||||
public void clearInjectedPlaceholders() {
|
||||
// Nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull
|
||||
List<InjectablePlaceholder> getPlaceholderInjections() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
});
|
||||
return evaluateExpression(expression, player, PlaceholderManager.EMPTY_INJECTABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,7 +313,23 @@ public final class NumberUtils {
|
||||
@Nullable final Player player,
|
||||
@NotNull final PlaceholderInjectable context,
|
||||
@NotNull final Collection<AdditionalPlayer> additionalPlayers) {
|
||||
return Eco.get().evaluate(expression, player, context, additionalPlayers);
|
||||
return Eco.get().evaluate(expression, new MathContext(
|
||||
context,
|
||||
player,
|
||||
additionalPlayers
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate an expression with respect to a player (for placeholders).
|
||||
*
|
||||
* @param expression The expression.
|
||||
* @param context The math context.
|
||||
* @return The value of the expression, or zero if invalid.
|
||||
*/
|
||||
public static double evaluateExpression(@NotNull final String expression,
|
||||
@NotNull final MathContext context) {
|
||||
return Eco.get().evaluate(expression, context);
|
||||
}
|
||||
|
||||
private NumberUtils() {
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
package com.willfp.eco.core.config
|
||||
|
||||
import com.willfp.eco.core.config.interfaces.Config
|
||||
import org.bukkit.configuration.ConfigurationSection
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
|
||||
/** Helper class to create configs with a kotlin DSL. */
|
||||
class DSLConfig internal constructor(type: ConfigType) : TransientConfig(emptyMap(), type) {
|
||||
class DSLConfig internal constructor(type: ConfigType) : GenericConfig(type) {
|
||||
/**
|
||||
* Map a key to a value.
|
||||
*
|
||||
@@ -34,3 +37,30 @@ class DSLConfig internal constructor(type: ConfigType) : TransientConfig(emptyMa
|
||||
*/
|
||||
fun config(type: ConfigType = ConfigType.YAML, builder: DSLConfig.() -> Unit): Config =
|
||||
DSLConfig(type).apply(builder)
|
||||
|
||||
/** @see Configs.empty */
|
||||
fun emptyConfig() = Configs.empty()
|
||||
|
||||
/** @see Configs.empty */
|
||||
fun emptyConfig(type: ConfigType) = Configs.empty(type)
|
||||
|
||||
/** @see Configs.fromBukkit */
|
||||
fun ConfigurationSection?.toConfig() = Configs.fromBukkit(this)
|
||||
|
||||
/** @see Configs.fromStream */
|
||||
fun InputStream?.readConfig() = Configs.fromStream(this)
|
||||
|
||||
/** @see Configs.fromFile */
|
||||
fun File?.readConfig() = Configs.fromFile(this)
|
||||
|
||||
/** @see Configs.fromFile */
|
||||
fun File?.readConfig(type: ConfigType) = Configs.fromFile(this, type)
|
||||
|
||||
/** @see Configs.fromMap */
|
||||
fun Map<String?, Any?>.toConfig() = Configs.fromMap(this)
|
||||
|
||||
/** @see Configs.fromMap */
|
||||
fun Map<String?, Any?>.toConfig(type: ConfigType) = Configs.fromMap(this, type)
|
||||
|
||||
/** @see Configs.fromString */
|
||||
fun readConfig(contents: String, type: ConfigType) = Configs.fromString(contents, type)
|
||||
|
||||
@@ -4,9 +4,9 @@ package com.willfp.eco.core.gui
|
||||
|
||||
import com.willfp.eco.core.gui.menu.Menu
|
||||
import com.willfp.eco.core.gui.menu.MenuBuilder
|
||||
import com.willfp.eco.core.gui.menu.MenuType
|
||||
import com.willfp.eco.core.gui.menu.MenuEvent
|
||||
import com.willfp.eco.core.gui.menu.MenuEventHandler
|
||||
import com.willfp.eco.core.gui.menu.MenuType
|
||||
import com.willfp.eco.core.gui.page.Page
|
||||
import com.willfp.eco.core.gui.page.PageBuilder
|
||||
import com.willfp.eco.core.gui.slot.Slot
|
||||
|
||||
@@ -2,8 +2,8 @@ package com.willfp.eco.internal
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.PluginProps
|
||||
import com.willfp.eco.core.config.TransientConfig
|
||||
import com.willfp.eco.core.config.interfaces.Config
|
||||
import com.willfp.eco.core.config.readConfig
|
||||
|
||||
object EcoPropsParser : PluginProps.PropsParser<Config> {
|
||||
override fun parseFrom(config: Config): PluginProps {
|
||||
@@ -28,7 +28,7 @@ object EcoPropsParser : PluginProps.PropsParser<Config> {
|
||||
}
|
||||
|
||||
return PluginProps.parse(
|
||||
TransientConfig(plugin.getResourceAsStream("/eco.yml")),
|
||||
plugin.getResourceAsStream("/eco.yml").readConfig(),
|
||||
Config::class.java
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.willfp.eco.internal.extensions
|
||||
import com.google.common.collect.ImmutableSet
|
||||
import com.willfp.eco.core.Eco
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.config.TransientConfig
|
||||
import com.willfp.eco.core.config.toConfig
|
||||
import com.willfp.eco.core.extensions.Extension
|
||||
import com.willfp.eco.core.extensions.ExtensionLoader
|
||||
import com.willfp.eco.core.extensions.ExtensionMetadata
|
||||
@@ -48,7 +48,7 @@ class EcoExtensionLoader(
|
||||
val ymlIn = classLoader.getResourceAsStream("extension.yml")
|
||||
?: throw MalformedExtensionException("No extension.yml found in " + extensionJar.name)
|
||||
|
||||
val extensionYml = TransientConfig(YamlConfiguration.loadConfiguration(InputStreamReader(ymlIn)))
|
||||
val extensionYml = YamlConfiguration.loadConfiguration(InputStreamReader(ymlIn)).toConfig()
|
||||
|
||||
val mainClass = extensionYml.getStringOrNull("main")
|
||||
var name = extensionYml.getStringOrNull("name")
|
||||
|
||||
@@ -11,8 +11,8 @@ class MergedStateMenu(
|
||||
return base.getState(player) + additional.getState(player)
|
||||
}
|
||||
|
||||
override fun addState(player: Player, key: String, value: Any?) {
|
||||
base.addState(player, key, value)
|
||||
override fun setState(player: Player, key: String, value: Any?) {
|
||||
base.setState(player, key, value)
|
||||
}
|
||||
|
||||
override fun clearState(player: Player) {
|
||||
|
||||
@@ -110,7 +110,7 @@ class EcoMenu(
|
||||
this.handle(player, this@EcoMenu, event as T)
|
||||
}
|
||||
|
||||
override fun addState(player: Player, key: String, value: Any?) {
|
||||
override fun setState(player: Player, key: String, value: Any?) {
|
||||
val inventory = player.renderedInventory ?: return
|
||||
inventory.state[key] = value
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ class RenderedInventory(
|
||||
val state = mutableMapOf<String, Any?>()
|
||||
|
||||
fun render() {
|
||||
val previousCaptive = captiveItems.toMap()
|
||||
|
||||
captiveItems.clear()
|
||||
|
||||
for (row in (1..menu.rows)) {
|
||||
@@ -60,9 +62,27 @@ class RenderedInventory(
|
||||
}
|
||||
|
||||
menu.runOnRender(player)
|
||||
|
||||
// Run second render if captive items changed
|
||||
if (captiveItems != previousCaptive) {
|
||||
for (row in (1..menu.rows)) {
|
||||
for (column in (1..menu.columns)) {
|
||||
val bukkit = MenuUtils.rowColumnToSlot(row, column, menu.columns)
|
||||
|
||||
val slot = menu.getSlot(row, column, player, menu)
|
||||
val renderedItem = slot.getItemStack(player)
|
||||
|
||||
if (!slot.isCaptive(player, menu)) {
|
||||
inventory.setItem(bukkit, renderedItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun renderDefaultCaptiveItems() {
|
||||
menu.runOnRender(player)
|
||||
|
||||
for (row in (1..menu.rows)) {
|
||||
for (column in (1..menu.columns)) {
|
||||
val bukkit = MenuUtils.rowColumnToSlot(row, column, menu.columns)
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
package com.willfp.eco.internal.integrations
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||
import me.clip.placeholderapi.PlaceholderAPI
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class PlaceholderIntegrationPAPI(private val plugin: EcoPlugin) : PlaceholderExpansion(), PlaceholderIntegration {
|
||||
class PAPIExpansion(private val plugin: EcoPlugin) : PlaceholderExpansion() {
|
||||
init {
|
||||
register()
|
||||
}
|
||||
|
||||
override fun persist(): Boolean {
|
||||
return true
|
||||
}
|
||||
@@ -34,29 +36,4 @@ class PlaceholderIntegrationPAPI(private val plugin: EcoPlugin) : PlaceholderExp
|
||||
): String {
|
||||
return PlaceholderManager.getResult(player, identifier, plugin)
|
||||
}
|
||||
|
||||
override fun registerIntegration() {
|
||||
register()
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "PlaceholderAPI"
|
||||
}
|
||||
|
||||
override fun translate(
|
||||
text: String,
|
||||
player: Player?
|
||||
): String {
|
||||
return PlaceholderAPI.setPlaceholders(player, text)
|
||||
}
|
||||
|
||||
override fun findPlaceholdersIn(text: String): MutableList<String> {
|
||||
val placeholders = mutableListOf<String>()
|
||||
val matcher = PlaceholderAPI.getPlaceholderPattern().matcher(text)
|
||||
while (matcher.find()) {
|
||||
placeholders.add(matcher.group())
|
||||
}
|
||||
|
||||
return placeholders
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,10 @@ object ArgParserCustomModelData : LookupArgParser {
|
||||
return Predicate {
|
||||
val testMeta = it.itemMeta ?: return@Predicate false
|
||||
|
||||
if (!testMeta.hasCustomModelData()) {
|
||||
return@Predicate false
|
||||
}
|
||||
|
||||
testMeta.customModelData == modelData
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.willfp.eco.internal.particle
|
||||
|
||||
import com.willfp.eco.core.particle.ParticleFactory
|
||||
import com.willfp.eco.core.particle.SpawnableParticle
|
||||
import org.bukkit.Color
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.Particle
|
||||
|
||||
object ParticleFactoryRGB : ParticleFactory {
|
||||
override fun getNames() = listOf(
|
||||
"color",
|
||||
"rgb",
|
||||
"hex"
|
||||
)
|
||||
|
||||
override fun create(key: String): SpawnableParticle? {
|
||||
val hex = key.toIntOrNull(16) ?: return null
|
||||
val color = try {
|
||||
Color.fromRGB(hex)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
return null
|
||||
}
|
||||
|
||||
return SpawnableParticleRGB(Particle.DustOptions(color, 1.0f))
|
||||
}
|
||||
|
||||
private class SpawnableParticleRGB(
|
||||
private val options: Particle.DustOptions
|
||||
) : SpawnableParticle {
|
||||
override fun spawn(location: Location, amount: Int) {
|
||||
val world = location.world ?: return
|
||||
|
||||
world.spawnParticle(Particle.REDSTONE, location, amount, 0.0, 0.0, 0.0, options)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.willfp.eco.internal.price
|
||||
|
||||
import com.willfp.eco.core.price.Price
|
||||
import com.willfp.eco.core.price.PriceFactory
|
||||
import com.willfp.eco.core.price.impl.PriceEconomy
|
||||
|
||||
object PriceFactoryEconomy : PriceFactory {
|
||||
override fun getNames() = listOf(
|
||||
"coins",
|
||||
"$"
|
||||
)
|
||||
|
||||
override fun create(value: Double): Price = PriceEconomy(value)
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.willfp.eco.internal.price
|
||||
|
||||
import com.willfp.eco.core.price.Price
|
||||
import com.willfp.eco.core.price.PriceFactory
|
||||
import org.bukkit.entity.Player
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object PriceFactoryXP : PriceFactory {
|
||||
override fun getNames() = listOf(
|
||||
"xp",
|
||||
"exp",
|
||||
"experience"
|
||||
)
|
||||
|
||||
override fun create(value: Double): Price = PriceXP(value.roundToInt())
|
||||
|
||||
private class PriceXP(
|
||||
private val xp: Int
|
||||
) : Price {
|
||||
override fun canAfford(player: Player) = player.totalExperience >= xp
|
||||
|
||||
override fun pay(player: Player) {
|
||||
player.totalExperience -= xp
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.willfp.eco.internal.price
|
||||
|
||||
import com.willfp.eco.core.price.Price
|
||||
import com.willfp.eco.core.price.PriceFactory
|
||||
import org.bukkit.entity.Player
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
object PriceFactoryXPLevels : PriceFactory {
|
||||
override fun getNames() = listOf(
|
||||
"l",
|
||||
"levels",
|
||||
"xplevels",
|
||||
"explevels",
|
||||
)
|
||||
|
||||
override fun create(value: Double): Price = PriceXPLevel(value.roundToInt())
|
||||
|
||||
private class PriceXPLevel(
|
||||
private val levels: Int
|
||||
) : Price {
|
||||
override fun canAfford(player: Player) = player.level >= levels
|
||||
|
||||
override fun pay(player: Player) {
|
||||
player.level -= levels
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,27 @@ var SkullMeta.texture: String?
|
||||
setProfile.isAccessible = true
|
||||
}
|
||||
|
||||
if (base64 == null) {
|
||||
/* This length check below was lost in the conversion. For some reason the base64
|
||||
* string is length 8 when this is called pretty frequently, causing an
|
||||
* out of bounds exception.
|
||||
*
|
||||
* Could not pass event EntityPotionEffectEvent to Talismans v5.116.0
|
||||
* java.lang.StringIndexOutOfBoundsException: begin -12, end 8, length 8
|
||||
* at java.lang.String.checkBoundsBeginEnd(String.java:4604) ~[?:?]
|
||||
* at java.lang.String.substring(String.java:2707) ~[?:?]
|
||||
* at java.lang.String.substring(String.java:2680) ~[?:?]
|
||||
* at com.willfp.eco.internal.spigot.proxy.v1_19_R1.common.SkullKt.setTexture(Skull.kt:36)
|
||||
*
|
||||
if (base64.length < 20) {
|
||||
return
|
||||
}
|
||||
*
|
||||
* ^ Update to this comment: a length 8 string ("textures") was being sent
|
||||
* because the get() method wasn't working right. This has been fixed, but the
|
||||
* check needs to remain implemented.
|
||||
*/
|
||||
|
||||
if (base64 == null || base64.length < 20) {
|
||||
setProfile.invoke(this, null)
|
||||
} else {
|
||||
val uuid = UUID(
|
||||
|
||||
@@ -3,16 +3,28 @@ 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.Material
|
||||
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.inventory.ItemStack
|
||||
import org.bukkit.persistence.PersistentDataContainer
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
class ExtendedPersistentDataContainerFactory: ExtendedPersistentDataContainerFactoryProxy {
|
||||
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private val registry: CraftPersistentDataTypeRegistry =
|
||||
CraftPersistentDataContainer::class.java.getDeclaredField("registry")
|
||||
.apply { isAccessible = true }.get(null) as CraftPersistentDataTypeRegistry
|
||||
private val registry: CraftPersistentDataTypeRegistry
|
||||
|
||||
init {
|
||||
/*
|
||||
Can't grab actual instance since it's in CraftMetaItem (which is package-private)
|
||||
And getting it would mean more janky reflection
|
||||
*/
|
||||
val item = CraftItemStack.asCraftCopy(ItemStack(Material.STONE))
|
||||
val pdc = item.itemMeta!!.persistentDataContainer
|
||||
this.registry = CraftPersistentDataContainer::class.java.getDeclaredField("registry")
|
||||
.apply { isAccessible = true }.get(pdc) as CraftPersistentDataTypeRegistry
|
||||
}
|
||||
|
||||
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
|
||||
return when (pdc) {
|
||||
@@ -34,7 +46,8 @@ class ExtendedPersistentDataContainerFactory: ExtendedPersistentDataContainerFac
|
||||
.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))
|
||||
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 {
|
||||
|
||||
@@ -3,16 +3,28 @@ 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.Material
|
||||
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.inventory.ItemStack
|
||||
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
|
||||
private val registry: CraftPersistentDataTypeRegistry
|
||||
|
||||
init {
|
||||
/*
|
||||
Can't grab actual instance since it's in CraftMetaItem (which is package-private)
|
||||
And getting it would mean more janky reflection
|
||||
*/
|
||||
val item = CraftItemStack.asCraftCopy(ItemStack(Material.STONE))
|
||||
val pdc = item.itemMeta!!.persistentDataContainer
|
||||
this.registry = CraftPersistentDataContainer::class.java.getDeclaredField("registry")
|
||||
.apply { isAccessible = true }.get(pdc) as CraftPersistentDataTypeRegistry
|
||||
}
|
||||
|
||||
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
|
||||
return when (pdc) {
|
||||
|
||||
@@ -3,16 +3,28 @@ 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.Material
|
||||
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.inventory.ItemStack
|
||||
import org.bukkit.persistence.PersistentDataContainer
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
class ExtendedPersistentDataContainerFactory: ExtendedPersistentDataContainerFactoryProxy {
|
||||
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private val registry: CraftPersistentDataTypeRegistry =
|
||||
CraftPersistentDataContainer::class.java.getDeclaredField("registry")
|
||||
.apply { isAccessible = true }.get(null) as CraftPersistentDataTypeRegistry
|
||||
private val registry: CraftPersistentDataTypeRegistry
|
||||
|
||||
init {
|
||||
/*
|
||||
Can't grab actual instance since it's in CraftMetaItem (which is package-private)
|
||||
And getting it would mean more janky reflection
|
||||
*/
|
||||
val item = CraftItemStack.asCraftCopy(ItemStack(Material.STONE))
|
||||
val pdc = item.itemMeta!!.persistentDataContainer
|
||||
this.registry = CraftPersistentDataContainer::class.java.getDeclaredField("registry")
|
||||
.apply { isAccessible = true }.get(pdc) as CraftPersistentDataTypeRegistry
|
||||
}
|
||||
|
||||
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
|
||||
return when (pdc) {
|
||||
@@ -34,7 +46,8 @@ class ExtendedPersistentDataContainerFactory: ExtendedPersistentDataContainerFac
|
||||
.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))
|
||||
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 {
|
||||
|
||||
@@ -3,21 +3,33 @@ package com.willfp.eco.internal.spigot.proxy.v1_19_R1
|
||||
import com.willfp.eco.core.data.ExtendedPersistentDataContainer
|
||||
import com.willfp.eco.internal.spigot.proxy.ExtendedPersistentDataContainerFactoryProxy
|
||||
import net.minecraft.nbt.Tag
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack
|
||||
import org.bukkit.craftbukkit.v1_19_R1.persistence.CraftPersistentDataContainer
|
||||
import org.bukkit.craftbukkit.v1_19_R1.persistence.CraftPersistentDataTypeRegistry
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.persistence.PersistentDataContainer
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
class ExtendedPersistentDataContainerFactory: ExtendedPersistentDataContainerFactoryProxy {
|
||||
class ExtendedPersistentDataContainerFactory : ExtendedPersistentDataContainerFactoryProxy {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private val registry: CraftPersistentDataTypeRegistry =
|
||||
CraftPersistentDataContainer::class.java.getDeclaredField("registry")
|
||||
.apply { isAccessible = true }.get(null) as CraftPersistentDataTypeRegistry
|
||||
private val registry: CraftPersistentDataTypeRegistry
|
||||
|
||||
init {
|
||||
/*
|
||||
Can't grab actual instance since it's in CraftMetaItem (which is package-private)
|
||||
And getting it would mean more janky reflection
|
||||
*/
|
||||
val item = CraftItemStack.asCraftCopy(ItemStack(Material.STONE))
|
||||
val pdc = item.itemMeta!!.persistentDataContainer
|
||||
this.registry = CraftPersistentDataContainer::class.java.getDeclaredField("registry")
|
||||
.apply { isAccessible = true }.get(pdc) as CraftPersistentDataTypeRegistry
|
||||
}
|
||||
|
||||
override fun adapt(pdc: PersistentDataContainer): ExtendedPersistentDataContainer {
|
||||
return when (pdc) {
|
||||
is CraftPersistentDataContainer -> EcoPersistentDataContainer(pdc)
|
||||
else -> throw IllegalArgumentException("Custom PDC instance is not supported!")
|
||||
else -> throw IllegalArgumentException("Custom PDC instance ims not supported!")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +46,8 @@ class ExtendedPersistentDataContainerFactory: ExtendedPersistentDataContainerFac
|
||||
.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))
|
||||
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 {
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.willfp.eco.core.Eco
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.PluginLike
|
||||
import com.willfp.eco.core.PluginProps
|
||||
import com.willfp.eco.core.Prerequisite
|
||||
import com.willfp.eco.core.config.ConfigType
|
||||
import com.willfp.eco.core.config.interfaces.Config
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
@@ -12,8 +11,7 @@ import com.willfp.eco.core.gui.menu.Menu
|
||||
import com.willfp.eco.core.gui.menu.MenuType
|
||||
import com.willfp.eco.core.gui.slot.functional.SlotProvider
|
||||
import com.willfp.eco.core.items.Items
|
||||
import com.willfp.eco.core.placeholder.AdditionalPlayer
|
||||
import com.willfp.eco.core.placeholder.PlaceholderInjectable
|
||||
import com.willfp.eco.core.math.MathContext
|
||||
import com.willfp.eco.internal.EcoPropsParser
|
||||
import com.willfp.eco.internal.config.EcoConfigHandler
|
||||
import com.willfp.eco.internal.config.EcoConfigSection
|
||||
@@ -34,13 +32,13 @@ import com.willfp.eco.internal.gui.MergedStateMenu
|
||||
import com.willfp.eco.internal.gui.menu.EcoMenuBuilder
|
||||
import com.willfp.eco.internal.gui.menu.renderedInventory
|
||||
import com.willfp.eco.internal.gui.slot.EcoSlotBuilder
|
||||
import com.willfp.eco.internal.integrations.PlaceholderIntegrationPAPI
|
||||
import com.willfp.eco.internal.integrations.PAPIExpansion
|
||||
import com.willfp.eco.internal.logging.EcoLogger
|
||||
import com.willfp.eco.internal.proxy.EcoProxyFactory
|
||||
import com.willfp.eco.internal.scheduling.EcoScheduler
|
||||
import com.willfp.eco.internal.spigot.data.DataYml
|
||||
import com.willfp.eco.internal.spigot.data.EcoProfileHandler
|
||||
import com.willfp.eco.internal.spigot.data.KeyRegistry
|
||||
import com.willfp.eco.internal.spigot.data.ProfileHandler
|
||||
import com.willfp.eco.internal.spigot.data.storage.HandlerType
|
||||
import com.willfp.eco.internal.spigot.integrations.bstats.MetricHandler
|
||||
import com.willfp.eco.internal.spigot.math.evaluateExpression
|
||||
@@ -53,7 +51,6 @@ import com.willfp.eco.internal.spigot.proxy.MiniMessageTranslatorProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.SNBTConverterProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.SkullProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.TPSProxy
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.NamespacedKey
|
||||
import org.bukkit.configuration.ConfigurationSection
|
||||
@@ -72,7 +69,7 @@ private val loadedEcoPlugins = mutableMapOf<String, EcoPlugin>()
|
||||
class EcoImpl : EcoSpigotPlugin(), Eco {
|
||||
override val dataYml = DataYml(this)
|
||||
|
||||
override val profileHandler = EcoProfileHandler(
|
||||
override val profileHandler = ProfileHandler(
|
||||
HandlerType.valueOf(this.configYml.getString("data-handler").uppercase()),
|
||||
this
|
||||
)
|
||||
@@ -81,10 +78,6 @@ class EcoImpl : EcoSpigotPlugin(), Eco {
|
||||
getProxy(CommonsInitializerProxy::class.java).init()
|
||||
}
|
||||
|
||||
private var adventure: BukkitAudiences? = if (!Prerequisite.HAS_PAPER.isMet) {
|
||||
BukkitAudiences.create(this)
|
||||
} else null
|
||||
|
||||
@Suppress("RedundantNullableReturnType")
|
||||
private val keyFactory: InternalNamespacedKeyFactory? =
|
||||
if (this.configYml.getBool("use-safer-namespacedkey-creation"))
|
||||
@@ -114,8 +107,9 @@ class EcoImpl : EcoSpigotPlugin(), Eco {
|
||||
override fun createLogger(plugin: EcoPlugin) =
|
||||
EcoLogger(plugin)
|
||||
|
||||
override fun createPAPIIntegration(plugin: EcoPlugin) =
|
||||
PlaceholderIntegrationPAPI(plugin)
|
||||
override fun createPAPIIntegration(plugin: EcoPlugin) {
|
||||
PAPIExpansion(plugin)
|
||||
}
|
||||
|
||||
override fun getEcoPlugin(): EcoPlugin =
|
||||
this
|
||||
@@ -174,9 +168,6 @@ class EcoImpl : EcoSpigotPlugin(), Eco {
|
||||
override fun createDropQueue(player: Player) = if (this.configYml.getBool("use-fast-collated-drops"))
|
||||
EcoFastCollatedDropQueue(player) else EcoDropQueue(player)
|
||||
|
||||
override fun getPersistentDataKeyFrom(namespacedKey: NamespacedKey) =
|
||||
KeyRegistry.getKeyFrom(namespacedKey)
|
||||
|
||||
override fun getRegisteredPersistentDataKeys() =
|
||||
KeyRegistry.getRegisteredKeys()
|
||||
|
||||
@@ -235,7 +226,7 @@ class EcoImpl : EcoSpigotPlugin(), Eco {
|
||||
MetricHandler.createMetrics(plugin)
|
||||
|
||||
override fun getAdventure() =
|
||||
adventure
|
||||
bukkitAudiences
|
||||
|
||||
override fun getServerProfile() =
|
||||
profileHandler.loadServerProfile()
|
||||
@@ -243,12 +234,6 @@ class EcoImpl : EcoSpigotPlugin(), Eco {
|
||||
override fun loadPlayerProfile(uuid: UUID) =
|
||||
profileHandler.load(uuid)
|
||||
|
||||
override fun saveAllProfiles() =
|
||||
profileHandler.save()
|
||||
|
||||
override fun savePersistentDataKeysFor(uuid: UUID, keys: Set<PersistentDataKey<*>>) =
|
||||
profileHandler.saveKeysFor(uuid, keys)
|
||||
|
||||
override fun unloadPlayerProfile(uuid: UUID) =
|
||||
profileHandler.unloadPlayer(uuid)
|
||||
|
||||
@@ -292,12 +277,8 @@ class EcoImpl : EcoSpigotPlugin(), Eco {
|
||||
override fun getTPS() =
|
||||
getProxy(TPSProxy::class.java).getTPS()
|
||||
|
||||
override fun evaluate(
|
||||
expression: String,
|
||||
player: Player?,
|
||||
injectable: PlaceholderInjectable,
|
||||
additionalPlayers: MutableCollection<AdditionalPlayer>
|
||||
) = evaluateExpression(expression, player, injectable, additionalPlayers)
|
||||
override fun evaluate(expression: String, context: MathContext) =
|
||||
evaluateExpression(expression, context)
|
||||
|
||||
override fun getOpenMenu(player: Player) =
|
||||
player.renderedInventory?.menu
|
||||
|
||||
@@ -14,8 +14,11 @@ import com.willfp.eco.core.integrations.customitems.CustomItemsManager
|
||||
import com.willfp.eco.core.integrations.economy.EconomyManager
|
||||
import com.willfp.eco.core.integrations.hologram.HologramManager
|
||||
import com.willfp.eco.core.integrations.mcmmo.McmmoManager
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||
import com.willfp.eco.core.integrations.shop.ShopManager
|
||||
import com.willfp.eco.core.items.Items
|
||||
import com.willfp.eco.core.particle.Particles
|
||||
import com.willfp.eco.core.price.Prices
|
||||
import com.willfp.eco.internal.entities.EntityArgParserAdult
|
||||
import com.willfp.eco.internal.entities.EntityArgParserAttackDamage
|
||||
import com.willfp.eco.internal.entities.EntityArgParserAttackSpeed
|
||||
@@ -44,11 +47,15 @@ import com.willfp.eco.internal.items.ArgParserTexture
|
||||
import com.willfp.eco.internal.items.ArgParserUnbreakable
|
||||
import com.willfp.eco.internal.lookup.SegmentParserGroup
|
||||
import com.willfp.eco.internal.lookup.SegmentParserUseIfPresent
|
||||
import com.willfp.eco.internal.particle.ParticleFactoryRGB
|
||||
import com.willfp.eco.internal.price.PriceFactoryEconomy
|
||||
import com.willfp.eco.internal.price.PriceFactoryXP
|
||||
import com.willfp.eco.internal.price.PriceFactoryXPLevels
|
||||
import com.willfp.eco.internal.spigot.arrows.ArrowDataListener
|
||||
import com.willfp.eco.internal.spigot.data.DataListener
|
||||
import com.willfp.eco.internal.spigot.data.DataYml
|
||||
import com.willfp.eco.internal.spigot.data.EcoProfileHandler
|
||||
import com.willfp.eco.internal.spigot.data.PlayerBlockListener
|
||||
import com.willfp.eco.internal.spigot.data.ProfileHandler
|
||||
import com.willfp.eco.internal.spigot.data.storage.ProfileSaver
|
||||
import com.willfp.eco.internal.spigot.display.PacketAutoRecipe
|
||||
import com.willfp.eco.internal.spigot.display.PacketChat
|
||||
@@ -106,6 +113,7 @@ 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.mcmmo.McmmoIntegrationImpl
|
||||
import com.willfp.eco.internal.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration
|
||||
import com.willfp.eco.internal.spigot.integrations.placeholder.PlaceholderIntegrationPAPI
|
||||
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
|
||||
@@ -118,6 +126,7 @@ import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInComplex
|
||||
import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInVanilla
|
||||
import com.willfp.eco.internal.spigot.recipes.stackhandlers.ShapedCraftingRecipeStackHandler
|
||||
import com.willfp.eco.internal.spigot.recipes.stackhandlers.ShapelessCraftingRecipeStackHandler
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences
|
||||
import net.milkbowl.vault.economy.Economy
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
@@ -126,7 +135,8 @@ import org.bukkit.inventory.ItemStack
|
||||
|
||||
abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||
abstract val dataYml: DataYml
|
||||
protected abstract val profileHandler: EcoProfileHandler
|
||||
protected abstract val profileHandler: ProfileHandler
|
||||
protected var bukkitAudiences: BukkitAudiences? = null
|
||||
|
||||
init {
|
||||
Items.registerArgParser(ArgParserEnchantment)
|
||||
@@ -157,6 +167,12 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||
Entities.registerArgParser(EntityArgParserSilent)
|
||||
Entities.registerArgParser(EntityArgParserEquipment)
|
||||
|
||||
Prices.registerPriceFactory(PriceFactoryEconomy)
|
||||
Prices.registerPriceFactory(PriceFactoryXPLevels)
|
||||
Prices.registerPriceFactory(PriceFactoryXP)
|
||||
|
||||
Particles.registerParticleFactory(ParticleFactoryRGB)
|
||||
|
||||
CraftingRecipeListener.registerListener(ComplexInComplex)
|
||||
CraftingRecipeListener.registerListener(ComplexInVanilla)
|
||||
|
||||
@@ -205,6 +221,11 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||
|
||||
// Preload categorized persistent data keys
|
||||
profileHandler.initialize()
|
||||
|
||||
// Init adventure
|
||||
if (!Prerequisite.HAS_PAPER.isMet) {
|
||||
bukkitAudiences = BukkitAudiences.create(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleDisable() {
|
||||
@@ -311,6 +332,9 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||
}
|
||||
},
|
||||
|
||||
// Placeholder
|
||||
IntegrationLoader("PlaceholderAPI") { PlaceholderManager.addIntegration(PlaceholderIntegrationPAPI()) },
|
||||
|
||||
// Misc
|
||||
IntegrationLoader("mcMMO") { McmmoManager.register(McmmoIntegrationImpl()) },
|
||||
IntegrationLoader("Multiverse-Inventories") {
|
||||
|
||||
@@ -48,8 +48,4 @@ object KeyRegistry {
|
||||
else -> throw NullPointerException("Null value found!")
|
||||
}
|
||||
}
|
||||
|
||||
fun getKeyFrom(namespacedKey: NamespacedKey): PersistentDataKey<*>? {
|
||||
return registry[namespacedKey]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import java.util.UUID
|
||||
|
||||
val serverProfileUUID = UUID(0, 0)
|
||||
|
||||
class EcoProfileHandler(
|
||||
class ProfileHandler(
|
||||
private val type: HandlerType,
|
||||
private val plugin: EcoSpigotPlugin
|
||||
) {
|
||||
@@ -7,7 +7,7 @@ import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
||||
import com.willfp.eco.internal.spigot.EcoSpigotPlugin
|
||||
import com.willfp.eco.internal.spigot.data.EcoProfileHandler
|
||||
import com.willfp.eco.internal.spigot.data.ProfileHandler
|
||||
import com.willfp.eco.internal.spigot.data.serverProfileUUID
|
||||
import com.zaxxer.hikari.HikariConfig
|
||||
import com.zaxxer.hikari.HikariDataSource
|
||||
@@ -49,7 +49,7 @@ the worst bodge I've shipped in production.
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class LegacyMySQLDataHandler(
|
||||
plugin: EcoSpigotPlugin,
|
||||
handler: EcoProfileHandler
|
||||
handler: ProfileHandler
|
||||
) : DataHandler(HandlerType.LEGACY_MYSQL) {
|
||||
private val playerHandler: ImplementedMySQLHandler
|
||||
private val serverHandler: ImplementedMySQLHandler
|
||||
@@ -114,7 +114,7 @@ class LegacyMySQLDataHandler(
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private class ImplementedMySQLHandler(
|
||||
private val handler: EcoProfileHandler,
|
||||
private val handler: ProfileHandler,
|
||||
private val table: UUIDTable,
|
||||
private val plugin: EcoPlugin
|
||||
) {
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.willfp.eco.internal.spigot.data.storage
|
||||
import com.willfp.eco.core.data.Profile
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
import com.willfp.eco.internal.spigot.EcoSpigotPlugin
|
||||
import com.willfp.eco.internal.spigot.data.EcoProfileHandler
|
||||
import com.willfp.eco.internal.spigot.data.ProfileHandler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -20,7 +20,7 @@ import java.util.UUID
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class MongoDataHandler(
|
||||
plugin: EcoSpigotPlugin,
|
||||
private val handler: EcoProfileHandler
|
||||
private val handler: ProfileHandler
|
||||
) : DataHandler(HandlerType.MONGO) {
|
||||
private val client: CoroutineClient
|
||||
private val collection: CoroutineCollection<UUIDProfile>
|
||||
|
||||
@@ -3,12 +3,12 @@ package com.willfp.eco.internal.spigot.data.storage
|
||||
import com.github.benmanes.caffeine.cache.Caffeine
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder
|
||||
import com.willfp.eco.core.config.ConfigType
|
||||
import com.willfp.eco.core.config.TransientConfig
|
||||
import com.willfp.eco.core.config.interfaces.Config
|
||||
import com.willfp.eco.core.config.readConfig
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
||||
import com.willfp.eco.internal.spigot.EcoSpigotPlugin
|
||||
import com.willfp.eco.internal.spigot.data.EcoProfileHandler
|
||||
import com.willfp.eco.internal.spigot.data.ProfileHandler
|
||||
import com.zaxxer.hikari.HikariConfig
|
||||
import com.zaxxer.hikari.HikariDataSource
|
||||
import org.jetbrains.exposed.dao.id.UUIDTable
|
||||
@@ -35,7 +35,7 @@ Whatever. At least it works.
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class MySQLDataHandler(
|
||||
private val plugin: EcoSpigotPlugin,
|
||||
private val handler: EcoProfileHandler
|
||||
private val handler: ProfileHandler
|
||||
) : DataHandler(HandlerType.MYSQL) {
|
||||
private val table = UUIDTable("eco_data")
|
||||
|
||||
@@ -130,8 +130,7 @@ class MySQLDataHandler(
|
||||
row.getOrNull(dataColumn) ?: "{}"
|
||||
}
|
||||
|
||||
|
||||
return TransientConfig(plaintext, ConfigType.JSON)
|
||||
return readConfig(plaintext, ConfigType.JSON)
|
||||
}
|
||||
|
||||
private fun setData(uuid: UUID, config: Config) {
|
||||
|
||||
@@ -2,11 +2,11 @@ package com.willfp.eco.internal.spigot.data.storage
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.internal.spigot.data.EcoProfile
|
||||
import com.willfp.eco.internal.spigot.data.EcoProfileHandler
|
||||
import com.willfp.eco.internal.spigot.data.ProfileHandler
|
||||
|
||||
class ProfileSaver(
|
||||
plugin: EcoPlugin,
|
||||
handler: EcoProfileHandler
|
||||
handler: ProfileHandler
|
||||
) {
|
||||
init {
|
||||
plugin.scheduler.runTimer(1, 1) {
|
||||
|
||||
@@ -3,14 +3,14 @@ package com.willfp.eco.internal.spigot.data.storage
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKey
|
||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
||||
import com.willfp.eco.internal.spigot.EcoSpigotPlugin
|
||||
import com.willfp.eco.internal.spigot.data.EcoProfileHandler
|
||||
import com.willfp.eco.internal.spigot.data.ProfileHandler
|
||||
import org.bukkit.NamespacedKey
|
||||
import java.util.UUID
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class YamlDataHandler(
|
||||
plugin: EcoSpigotPlugin,
|
||||
private val handler: EcoProfileHandler
|
||||
private val handler: ProfileHandler
|
||||
) : DataHandler(HandlerType.YAML) {
|
||||
private val dataYml = plugin.dataYml
|
||||
|
||||
|
||||
@@ -50,6 +50,14 @@ class GUIListener(private val plugin: EcoPlugin) : Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(
|
||||
priority = EventPriority.HIGHEST
|
||||
)
|
||||
fun handleRender(event: InventoryClickEvent) {
|
||||
val player = event.whoClicked as? Player ?: return
|
||||
player.renderActiveMenu()
|
||||
}
|
||||
|
||||
@EventHandler(
|
||||
priority = EventPriority.HIGH
|
||||
)
|
||||
@@ -63,8 +71,6 @@ class GUIListener(private val plugin: EcoPlugin) : Listener {
|
||||
val (row, column) = MenuUtils.convertSlotToRowColumn(event.slot, menu.columns)
|
||||
|
||||
menu.getSlot(row, column, player, menu).handle(player, event, menu)
|
||||
|
||||
plugin.scheduler.run { rendered.render() }
|
||||
}
|
||||
|
||||
@EventHandler(
|
||||
@@ -172,7 +178,6 @@ class GUIListener(private val plugin: EcoPlugin) : Listener {
|
||||
val rendered = player.renderedInventory ?: return
|
||||
|
||||
if (rendered.menu.allowsChangingHeldItem()) {
|
||||
player.renderActiveMenu()
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,11 @@ import com.willfp.eco.core.integrations.antigrief.AntigriefIntegration
|
||||
import org.apache.commons.lang.Validate
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.block.Block
|
||||
import org.bukkit.entity.*
|
||||
import org.bukkit.entity.Animals
|
||||
import org.bukkit.entity.ArmorStand
|
||||
import org.bukkit.entity.LivingEntity
|
||||
import org.bukkit.entity.Monster
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
class AntigriefWorldGuard : AntigriefIntegration {
|
||||
override fun canBreakBlock(
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.willfp.eco.internal.spigot.integrations.placeholder
|
||||
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderIntegration
|
||||
import me.clip.placeholderapi.PlaceholderAPI
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.regex.Pattern
|
||||
|
||||
class PlaceholderIntegrationPAPI : PlaceholderIntegration {
|
||||
private val pattern = Pattern.compile("[%]([^% ]+)[%]")
|
||||
|
||||
override fun registerIntegration() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
override fun getPluginName(): String {
|
||||
return "PlaceholderAPI"
|
||||
}
|
||||
|
||||
override fun translate(
|
||||
text: String,
|
||||
player: Player?
|
||||
): String {
|
||||
return PlaceholderAPI.setPlaceholders(player, text)
|
||||
}
|
||||
|
||||
override fun findPlaceholdersIn(text: String): MutableList<String> {
|
||||
val placeholders = mutableListOf<String>()
|
||||
val matcher = pattern.matcher(text)
|
||||
while (matcher.find()) {
|
||||
placeholders.add(matcher.group())
|
||||
}
|
||||
|
||||
return placeholders
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import com.github.benmanes.caffeine.cache.Cache
|
||||
import com.github.benmanes.caffeine.cache.Caffeine
|
||||
import com.willfp.eco.core.integrations.placeholder.PlaceholderManager
|
||||
import com.willfp.eco.core.placeholder.AdditionalPlayer
|
||||
import com.willfp.eco.core.math.MathContext
|
||||
import com.willfp.eco.core.placeholder.PlaceholderInjectable
|
||||
import org.bukkit.entity.Player
|
||||
import redempt.crunch.CompiledExpression
|
||||
@@ -25,7 +26,15 @@ private val max = Function("max", 2) {
|
||||
max(it[0], it[1])
|
||||
}
|
||||
|
||||
fun evaluateExpression(expression: String, player: Player?, context: PlaceholderInjectable, additional: Collection<AdditionalPlayer>): Double {
|
||||
fun evaluateExpression(expression: String, context: MathContext) =
|
||||
evaluateExpression(expression, context.player, context.injectableContext, context.additionalPlayers)
|
||||
|
||||
private fun evaluateExpression(
|
||||
expression: String,
|
||||
player: Player?,
|
||||
context: PlaceholderInjectable,
|
||||
additional: Collection<AdditionalPlayer>
|
||||
): Double {
|
||||
val placeholderValues = PlaceholderManager.findPlaceholdersIn(expression)
|
||||
.map { PlaceholderManager.translatePlaceholders(it, player, context, additional) }
|
||||
.map { runCatching { FastNumberParsing.parseDouble(it) }.getOrDefault(0.0) }
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version = 6.43.2
|
||||
version = 6.44.0
|
||||
plugin-name = eco
|
||||
kotlin.code.style = official
|
||||
Reference in New Issue
Block a user