Compare commits

..

48 Commits
6.4.2 ... 6.7.1

Author SHA1 Message Date
Auxilor
10a313bef5 Added missing javadoc 2021-09-05 11:08:05 +01:00
Auxilor
9ae40ae09e Removed redundant nullability 2021-09-05 11:07:15 +01:00
Auxilor
7b4e1d8d24 Updated to 6.7.1 2021-09-05 11:05:33 +01:00
Auxilor
7035280731 Item checks and improvements related to EmptyTestableItem 2021-09-05 11:05:23 +01:00
Auxilor
a1e3d53cd2 Janky HeadDB fix 2021-09-04 16:44:15 +01:00
Auxilor
d7885f05c3 Optimised placeholders 2021-09-04 13:59:46 +01:00
Auxilor
415c425097 Fixed bugs 2021-09-04 11:03:04 +01:00
Auxilor
cb4d992e7d Added option to create custom lang.yml and config.yml implementations 2021-09-04 10:59:49 +01:00
Auxilor
cb64d088d1 Added nullability annotations to all utility methods 2021-09-04 10:53:06 +01:00
Auxilor
61ace5c8e5 Updated to 6.7.0 2021-09-03 12:50:23 +01:00
Auxilor
94b73ef35c Improved Arg Parser javadoc 2021-09-03 12:49:59 +01:00
Auxilor
5cfc2068e7 Added arg parser lookup system 2021-09-03 12:47:23 +01:00
Auxilor
0ce7d1dd6c Added texture:<base64> to Items.lookup 2021-09-03 12:28:03 +01:00
Auxilor
19eefaf879 Improved Items.lookup javadoc 2021-09-03 11:54:48 +01:00
Auxilor
1ebf7fb875 Added Head Database integration 2021-09-03 11:45:34 +01:00
Auxilor
e8afd15d80 Updated to 6.6.4 2021-09-02 18:55:49 +01:00
Auxilor
d024c9238e Switched TestableStack display to only show recipe lore in recipes 2021-09-02 18:55:37 +01:00
Auxilor
1356bd1f26 ItemsAdder fix 2021-09-02 18:50:01 +01:00
Auxilor
407ccca5e0 TestableStack changes don't stop ever 2021-09-02 11:49:48 +01:00
Auxilor
82de602d47 Hopefully fixed crafting exploit 2021-09-02 10:53:14 +01:00
Auxilor
b0873112af Added ItemsAdder and Oraxen to plugin.yml 2021-09-02 10:50:40 +01:00
Auxilor
3a0b81b7de Updated to 6.6.3 2021-09-02 10:50:12 +01:00
Auxilor
5142b9ce92 More Items#lookup improvements 2021-09-02 10:46:25 +01:00
Auxilor
9403a1cbcb Marked item:amount system as legacy and replaced it with item amount 2021-09-02 10:42:29 +01:00
Auxilor
e4ebea354d Added ItemsAdder support 2021-09-02 10:35:03 +01:00
Auxilor
d32b31f1e5 Updated to 6.6.2 2021-09-01 15:35:57 +01:00
Auxilor
384657f1dc Fixed menu inventory registration memory leak 2021-09-01 15:35:33 +01:00
Auxilor
7c9d226bc3 Updated to 6.6.1 2021-08-31 14:52:52 +01:00
Auxilor
031401bb8e Added option to lang.yml 2021-08-31 14:52:37 +01:00
Auxilor
1a5c429b67 Fixed villager trade display with players 2021-08-31 14:51:45 +01:00
Auxilor
d028cf5bf3 Added ShopGuiPlus to softdepend 2021-08-29 16:35:16 +01:00
Auxilor
fdd1581ce3 Removed redundant code 2021-08-29 16:34:26 +01:00
Auxilor
3d07e10543 Fixed ItemFlag application 2021-08-29 16:33:31 +01:00
Auxilor
c851e35347 Added ItemFlags to FastItemStack 2021-08-29 16:32:42 +01:00
Auxilor
4cbb33b1fd More code cleanup 2021-08-29 16:03:14 +01:00
Auxilor
2ff1458772 Fixed config wrappers missing methods 2021-08-29 15:56:39 +01:00
Auxilor
e71ad9f034 Updated to 6.6.0 2021-08-29 15:51:49 +01:00
Auxilor
196a651ab3 Added ShopGuiPlus integration 2021-08-29 15:51:38 +01:00
Auxilor
253a8c24ad Improved kotlin codestyle conventions 2021-08-29 15:38:27 +01:00
Auxilor
ac265d0260 Added more formatting options 2021-08-29 15:30:25 +01:00
Auxilor
ad861b10bb Updated to 6.5.2 2021-08-23 17:14:41 +01:00
Auxilor
db5b7f89f6 Fixed null placeholder bug and improved config loading 2021-08-23 17:14:23 +01:00
Auxilor
2c33ce25c0 Merge remote-tracking branch 'origin/master' 2021-08-22 23:14:30 +01:00
Auxilor
9c3ca429c9 Fixed recipe stack bug 2021-08-22 23:14:24 +01:00
Auxilor
70e294501a Fixed enchanted books in Items.lookup modifier 2021-08-21 13:50:33 +01:00
Will FP
65a0a0ecc7 Update README.md 2021-08-21 01:22:16 +01:00
Auxilor
d4431e7569 Changes 2021-08-20 23:02:45 +01:00
Auxilor
a6191b0870 Added data read/write to menu, updated to 6.5.0, removed event deprecation 2021-08-20 22:29:25 +01:00
77 changed files with 1382 additions and 448 deletions

View File

@@ -158,7 +158,7 @@ Here's a list of some (not all) of the features of eco:
<h1 align="center"> <h1 align="center">
<br> <br>
<a href="http://gamersupps.gg?afmc=Auxilor" target="_blank"> <a href="http://gamersupps.gg/discount/Auxilor?afmc=Auxilor" target="_blank">
<img src="https://i.imgur.com/uFDpBAC.png" alt="supps banner"> <img src="https://i.imgur.com/uFDpBAC.png" alt="supps banner">
</a> </a>
<a href="https://dedimc.promo/Auxilor" target="_blank"> <a href="https://dedimc.promo/Auxilor" target="_blank">

View File

@@ -51,6 +51,9 @@ allprojects {
// CombatLogX // CombatLogX
maven { url 'https://nexus.sirblobman.xyz/repository/public/' } maven { url 'https://nexus.sirblobman.xyz/repository/public/' }
// Head Database
maven { url 'https://mvn.intellectualsites.com/content/groups/public/' }
} }
dependencies { dependencies {

View File

@@ -305,10 +305,27 @@ public abstract class EcoPlugin extends JavaPlugin {
this.logger = Eco.getHandler().createLogger(this); this.logger = Eco.getHandler().createLogger(this);
this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.getHandler().createProxyFactory(this); this.proxyFactory = this.proxyPackage.equalsIgnoreCase("") ? null : Eco.getHandler().createProxyFactory(this);
this.langYml = new LangYml(this); this.langYml = this.createLangYml();
this.configYml = new ConfigYml(this); this.configYml = this.createConfigYml();
Eco.getHandler().addNewPlugin(this); Eco.getHandler().addNewPlugin(this);
/*
The minimum eco version check was moved here because it's very common
to add a lot of code in the constructor of plugins; meaning that the plugin
can throw errors without it being obvious to the user that the reason is
because they have an outdated version of eco installed.
*/
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().getEcoPlugin().getDescription().getVersion());
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion());
if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) {
this.getLogger().severe("You are running an outdated version of eco!");
this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion());
this.getLogger().severe("Download the newest version here:");
this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW");
Bukkit.getPluginManager().disablePlugin(this);
}
} }
/** /**
@@ -336,16 +353,6 @@ public abstract class EcoPlugin extends JavaPlugin {
}); });
} }
DefaultArtifactVersion runningVersion = new DefaultArtifactVersion(Eco.getHandler().getEcoPlugin().getDescription().getVersion());
DefaultArtifactVersion requiredVersion = new DefaultArtifactVersion(this.getMinimumEcoVersion());
if (!(runningVersion.compareTo(requiredVersion) > 0 || runningVersion.equals(requiredVersion))) {
this.getLogger().severe("You are running an outdated version of eco!");
this.getLogger().severe("You must be on at least" + this.getMinimumEcoVersion());
this.getLogger().severe("Download the newest version here:");
this.getLogger().severe("https://polymart.org/download/773/recent/JSpprMspkuyecf5y1wQ2Jn8OoLQSQ_IW");
Bukkit.getPluginManager().disablePlugin(this);
}
if (this.getBStatsId() != 0) { if (this.getBStatsId() != 0) {
Eco.getHandler().registerBStats(this); Eco.getHandler().registerBStats(this);
} }
@@ -571,6 +578,28 @@ public abstract class EcoPlugin extends JavaPlugin {
*/ */
protected abstract List<Listener> loadListeners(); protected abstract List<Listener> loadListeners();
/**
* Useful for custom LangYml implementations.
* <p>
* Override if needed.
*
* @return lang.yml.
*/
protected LangYml createLangYml() {
return new LangYml(this);
}
/**
* Useful for custom ConfigYml implementations.
* <p>
* Override if needed.
*
* @return config.yml.
*/
protected ConfigYml createConfigYml() {
return new ConfigYml(this);
}
/** /**
* Create the display module for the plugin. * Create the display module for the plugin.
* *

View File

@@ -16,6 +16,7 @@ import com.willfp.eco.core.proxy.ProxyFactory;
import com.willfp.eco.core.scheduling.Scheduler; import com.willfp.eco.core.scheduling.Scheduler;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
@@ -30,6 +31,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The scheduler. * @return The scheduler.
*/ */
@NotNull
Scheduler createScheduler(@NotNull EcoPlugin plugin); Scheduler createScheduler(@NotNull EcoPlugin plugin);
/** /**
@@ -38,6 +40,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The event manager. * @return The event manager.
*/ */
@NotNull
EventManager createEventManager(@NotNull EcoPlugin plugin); EventManager createEventManager(@NotNull EcoPlugin plugin);
/** /**
@@ -46,6 +49,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The factory. * @return The factory.
*/ */
@NotNull
NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin); NamespacedKeyFactory createNamespacedKeyFactory(@NotNull EcoPlugin plugin);
/** /**
@@ -54,6 +58,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The factory. * @return The factory.
*/ */
@NotNull
MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin); MetadataValueFactory createMetadataValueFactory(@NotNull EcoPlugin plugin);
/** /**
@@ -62,6 +67,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The factory. * @return The factory.
*/ */
@NotNull
RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin); RunnableFactory createRunnableFactory(@NotNull EcoPlugin plugin);
/** /**
@@ -70,6 +76,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The factory. * @return The factory.
*/ */
@NotNull
ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin); ExtensionLoader createExtensionLoader(@NotNull EcoPlugin plugin);
/** /**
@@ -78,6 +85,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The handler. * @return The handler.
*/ */
@NotNull
ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin); ConfigHandler createConfigHandler(@NotNull EcoPlugin plugin);
/** /**
@@ -86,6 +94,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The logger. * @return The logger.
*/ */
@NotNull
Logger createLogger(@NotNull EcoPlugin plugin); Logger createLogger(@NotNull EcoPlugin plugin);
/** /**
@@ -94,6 +103,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The integration. * @return The integration.
*/ */
@NotNull
PlaceholderIntegration createPAPIIntegration(@NotNull EcoPlugin plugin); PlaceholderIntegration createPAPIIntegration(@NotNull EcoPlugin plugin);
/** /**
@@ -102,6 +112,7 @@ public interface Handler {
* @param plugin The plugin. * @param plugin The plugin.
* @return The factory. * @return The factory.
*/ */
@NotNull
ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin); ProxyFactory createProxyFactory(@NotNull EcoPlugin plugin);
/** /**
@@ -109,6 +120,7 @@ public interface Handler {
* *
* @return The plugin. * @return The plugin.
*/ */
@NotNull
EcoPlugin getEcoPlugin(); EcoPlugin getEcoPlugin();
/** /**
@@ -116,6 +128,7 @@ public interface Handler {
* *
* @return The factory. * @return The factory.
*/ */
@NotNull
ConfigFactory getConfigFactory(); ConfigFactory getConfigFactory();
/** /**
@@ -123,6 +136,7 @@ public interface Handler {
* *
* @return The factory. * @return The factory.
*/ */
@NotNull
DropQueueFactory getDropQueueFactory(); DropQueueFactory getDropQueueFactory();
/** /**
@@ -130,6 +144,7 @@ public interface Handler {
* *
* @return The factory. * @return The factory.
*/ */
@NotNull
GUIFactory getGUIFactory(); GUIFactory getGUIFactory();
/** /**
@@ -137,6 +152,7 @@ public interface Handler {
* *
* @return The cleaner. * @return The cleaner.
*/ */
@NotNull
Cleaner getCleaner(); Cleaner getCleaner();
/** /**
@@ -152,6 +168,7 @@ public interface Handler {
* @param name The name. * @param name The name.
* @return The plugin. * @return The plugin.
*/ */
@Nullable
EcoPlugin getPluginByName(@NotNull String name); EcoPlugin getPluginByName(@NotNull String name);
/** /**
@@ -159,6 +176,7 @@ public interface Handler {
* *
* @return A list of plugin names in lowercase. * @return A list of plugin names in lowercase.
*/ */
@NotNull
List<String> getLoadedPlugins(); List<String> getLoadedPlugins();
/** /**
@@ -167,6 +185,7 @@ public interface Handler {
* @param itemStack The base ItemStack. * @param itemStack The base ItemStack.
* @return The FastItemStack. * @return The FastItemStack.
*/ */
@NotNull
FastItemStack createFastItemStack(@NotNull ItemStack itemStack); FastItemStack createFastItemStack(@NotNull ItemStack itemStack);
/** /**

View File

@@ -9,11 +9,12 @@ import org.jetbrains.annotations.NotNull;
* *
* @param <T> The eco plugin type. * @param <T> The eco plugin type.
*/ */
public abstract class PluginDependent<T extends EcoPlugin> { public abstract class PluginDependent<@NotNull T extends EcoPlugin> {
/** /**
* The {@link EcoPlugin} that is stored. * The {@link EcoPlugin} that is stored.
*/ */
@Getter(AccessLevel.PROTECTED) @Getter(AccessLevel.PROTECTED)
@NotNull
private final T plugin; private final T plugin;
/** /**

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.config.base;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.config.yaml.YamlBaseConfig; import com.willfp.eco.core.config.yaml.YamlBaseConfig;
import com.willfp.eco.util.StringUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
/** /**
@@ -42,6 +43,18 @@ public class LangYml extends YamlBaseConfig {
* @return The message with a prefix appended. * @return The message with a prefix appended.
*/ */
public String getMessage(@NotNull final String message) { public String getMessage(@NotNull final String message) {
return getPrefix() + this.getString("messages." + message); return getMessage(message, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a chat message.
*
* @param message The key of the message.
* @param option The format options.
* @return The message with a prefix appended.
*/
public String getMessage(@NotNull final String message,
@NotNull final StringUtils.FormatOption option) {
return getPrefix() + this.getString("messages." + message, option);
} }
} }

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.core.config.interfaces; package com.willfp.eco.core.config.interfaces;
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;
@@ -165,7 +166,9 @@ public interface Config extends Cloneable {
* @return The found value, or an empty string if not found. * @return The found value, or an empty string if not found.
*/ */
@NotNull @NotNull
String getString(@NotNull String path); default String getString(@NotNull String path) {
return getString(path, true);
}
/** /**
* Get a string from config. * Get a string from config.
@@ -175,8 +178,36 @@ public interface Config extends Cloneable {
* @return The found value, or an empty string if not found. * @return The found value, or an empty string if not found.
*/ */
@NotNull @NotNull
default String getString(@NotNull String path,
boolean format) {
return this.getString(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or an empty string if not found.
*/
@NotNull
default String getString(@NotNull String path,
@NotNull final StringUtils.FormatOption option) {
return this.getString(path, true, option);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param format If the string should be formatted.
* @param option The format option.
* @return The found value, or an empty string if not found.
*/
@NotNull
String getString(@NotNull String path, String getString(@NotNull String path,
boolean format); boolean format,
@NotNull StringUtils.FormatOption option);
/** /**
* Get a string from config. * Get a string from config.
@@ -185,7 +216,9 @@ public interface Config extends Cloneable {
* @return The found value, or null if not found. * @return The found value, or null if not found.
*/ */
@Nullable @Nullable
String getStringOrNull(@NotNull String path); default String getStringOrNull(@NotNull String path) {
return getStringOrNull(path, true);
}
/** /**
* Get a string from config. * Get a string from config.
@@ -195,8 +228,36 @@ public interface Config extends Cloneable {
* @return The found value, or null if not found. * @return The found value, or null if not found.
*/ */
@Nullable @Nullable
default String getStringOrNull(@NotNull String path,
boolean format) {
return this.getStringOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or null if not found.
*/
@Nullable
default String getStringOrNull(@NotNull String path,
@NotNull StringUtils.FormatOption option) {
return this.getStringOrNull(path, true, option);
}
/**
* Get a string from config.
*
* @param path The key to fetch the value from.
* @param format If the string should be formatted.
* @param option The format option.
* @return The found value, or null if not found.
*/
@Nullable
String getStringOrNull(@NotNull String path, String getStringOrNull(@NotNull String path,
boolean format); boolean format,
@NotNull StringUtils.FormatOption option);
/** /**
* Get a list of strings from config. * Get a list of strings from config.
@@ -207,7 +268,9 @@ public interface Config extends Cloneable {
* @return The found value, or a blank {@link java.util.ArrayList} if not found. * @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/ */
@NotNull @NotNull
List<String> getStrings(@NotNull String path); default List<String> getStrings(@NotNull String path) {
return getStrings(path, true);
}
/** /**
* Get a list of strings from config. * Get a list of strings from config.
@@ -217,8 +280,36 @@ public interface Config extends Cloneable {
* @return The found value, or a blank {@link java.util.ArrayList} if not found. * @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/ */
@NotNull @NotNull
default List<String> getStrings(@NotNull String path,
boolean format) {
return this.getStrings(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@Nullable
default List<String> getStrings(@NotNull String path,
@NotNull StringUtils.FormatOption option) {
return getStrings(path, true, option);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param format If the strings should be formatted.
* @param option The option.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
List<String> getStrings(@NotNull String path, List<String> getStrings(@NotNull String path,
boolean format); boolean format,
@NotNull StringUtils.FormatOption option);
/** /**
* Get a list of strings from config. * Get a list of strings from config.
@@ -227,7 +318,9 @@ public interface Config extends Cloneable {
* @return The found value, or null if not found. * @return The found value, or null if not found.
*/ */
@Nullable @Nullable
List<String> getStringsOrNull(@NotNull String path); default List<String> getStringsOrNull(@NotNull String path) {
return getStringsOrNull(path, true);
}
/** /**
* Get a list of strings from config. * Get a list of strings from config.
@@ -237,8 +330,36 @@ public interface Config extends Cloneable {
* @return The found value, or null if not found. * @return The found value, or null if not found.
*/ */
@Nullable @Nullable
default List<String> getStringsOrNull(@NotNull String path,
boolean format) {
return getStringsOrNull(path, format, StringUtils.FormatOption.WITH_PLACEHOLDERS);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param option The format option.
* @return The found value, or null if not found.
*/
@Nullable
default List<String> getStringsOrNull(@NotNull String path,
@NotNull StringUtils.FormatOption option) {
return getStringsOrNull(path, true, option);
}
/**
* Get a list of strings from config.
*
* @param path The key to fetch the value from.
* @param format If the strings should be formatted.
* @param option The format option.
* @return The found value, or null if not found.
*/
@Nullable
List<String> getStringsOrNull(@NotNull String path, List<String> getStringsOrNull(@NotNull String path,
boolean format); boolean format,
@NotNull StringUtils.FormatOption option);
/** /**
* Get a decimal from config. * Get a decimal from config.

View File

@@ -1,6 +1,7 @@
package com.willfp.eco.core.config.wrapper; package com.willfp.eco.core.config.wrapper;
import com.willfp.eco.core.config.interfaces.Config; import com.willfp.eco.core.config.interfaces.Config;
import com.willfp.eco.util.StringUtils;
import lombok.Getter; import lombok.Getter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -125,48 +126,33 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
return handle.getBoolsOrNull(path); return handle.getBoolsOrNull(path);
} }
@Override
public @NotNull String getString(@NotNull final String path) {
return handle.getString(path);
}
@Override @Override
public @NotNull String getString(@NotNull final String path, public @NotNull String getString(@NotNull final String path,
final boolean format) { final boolean format,
return handle.getString(path, format); @NotNull final StringUtils.FormatOption option) {
} return handle.getString(path, format, option);
@Override
public @Nullable String getStringOrNull(@NotNull final String path) {
return handle.getStringOrNull(path);
} }
@Override @Override
public @Nullable String getStringOrNull(@NotNull final String path, public @Nullable String getStringOrNull(@NotNull final String path,
final boolean format) { final boolean format,
return handle.getStringOrNull(path, format); @NotNull final StringUtils.FormatOption option) {
} return handle.getStringOrNull(path, format, option);
@Override
public @NotNull List<String> getStrings(@NotNull final String path) {
return handle.getStrings(path);
} }
@Override @Override
public @NotNull List<String> getStrings(@NotNull final String path, public @NotNull List<String> getStrings(@NotNull final String path,
final boolean format) { final boolean format,
return handle.getStrings(path, format); @NotNull final StringUtils.FormatOption option) {
} return handle.getStrings(path, format, option);
@Override
public @Nullable List<String> getStringsOrNull(@NotNull final String path) {
return handle.getStringsOrNull(path);
} }
@Override @Override
public @Nullable List<String> getStringsOrNull(@NotNull final String path, public @Nullable List<String> getStringsOrNull(@NotNull final String path,
final boolean format) { final boolean format,
return handle.getStringsOrNull(path, format); @NotNull final StringUtils.FormatOption option) {
return handle.getStringsOrNull(path, format, option);
} }
@Override @Override

View File

@@ -16,7 +16,6 @@ import org.jetbrains.annotations.NotNull;
* *
* @see ArmorChangeEvent * @see ArmorChangeEvent
*/ */
@Deprecated
public class ArmorEquipEvent extends PlayerEvent { public class ArmorEquipEvent extends PlayerEvent {
/** /**
* Bukkit parity. * Bukkit parity.

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.core.fast;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
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.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -10,6 +11,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
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.
@@ -51,17 +53,47 @@ public interface FastItemStack {
/** /**
* Set the rework penalty. * Set the rework penalty.
* *
* @param cost The rework penalty to set. * @param cost The rework penalty to set.
*/ */
void setRepairCost(int cost); void setRepairCost(int cost);
/** /**
* Get the rework penalty. * Get the rework penalty.
*. * .
*
* @return The rework penalty found on the item. * @return The rework penalty found on the item.
*/ */
int getRepairCost(); int getRepairCost();
/**
* Add ItemFlags.
*
* @param hideFlags The flags.
*/
void addItemFlags(ItemFlag... hideFlags);
/**
* Remove ItemFlags.
*
* @param hideFlags The flags.
*/
void removeItemFlags(ItemFlag... hideFlags);
/**
* Get the ItemFlags.
*
* @return The flags.
*/
Set<ItemFlag> getItemFlags();
/**
* Test the item for a flag.
*
* @param flag The flag.
* @return If the flag is present.
*/
boolean hasItemFlag(ItemFlag flag);
/** /**
* Get the Bukkit ItemStack again. * Get the Bukkit ItemStack again.
* *

View File

@@ -2,12 +2,16 @@ package com.willfp.eco.core.gui.menu;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.slot.Slot; import com.willfp.eco.core.gui.slot.Slot;
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;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* GUI version of {@link Inventory}. * GUI version of {@link Inventory}.
@@ -55,6 +59,43 @@ public interface Menu {
*/ */
List<ItemStack> getCaptiveItems(@NotNull Player player); List<ItemStack> getCaptiveItems(@NotNull Player player);
/**
* Write data.
*
* @param player The player.
* @param key The key.
* @param type The type.
* @param value The value.
* @param <T> The type.
* @param <Z> The type.
*/
<T, Z> void writeData(@NotNull Player player,
@NotNull NamespacedKey key,
@NotNull PersistentDataType<T, Z> type,
@NotNull Z value);
/**
* Read data.
*
* @param player The player.
* @param key The key.
* @param type The type.
* @param <T> The type.
* @param <Z> The type.
* @return The data.
*/
@Nullable <T, Z> T readData(@NotNull Player player,
@NotNull NamespacedKey key,
@NotNull PersistentDataType<T, Z> type);
/**
* Get all data keys for a player.
*
* @param player The player.
* @return The keys.
*/
Set<NamespacedKey> getKeys(@NotNull Player player);
/** /**
* Create a builder with a given amount of rows. * Create a builder with a given amount of rows.
* *

View File

@@ -1,9 +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.
*/ */
public interface CustomItemsWrapper { public interface CustomItemsWrapper extends Integration {
/** /**
* Register all the custom items for a specific plugin into eco. * Register all the custom items for a specific plugin into eco.
* *

View File

@@ -16,7 +16,7 @@ public class McmmoManager {
/** /**
* A set of all registered integrations. * A set of all registered integrations.
*/ */
private final Set<McmmoWrapper> regsistered = new HashSet<>(); private final Set<McmmoWrapper> registered = new HashSet<>();
/** /**
* Register a new integration. * Register a new integration.
@@ -24,7 +24,7 @@ public class McmmoManager {
* @param integration The integration to register. * @param integration The integration to register.
*/ */
public void register(@NotNull final McmmoWrapper integration) { public void register(@NotNull final McmmoWrapper integration) {
regsistered.add(integration); registered.add(integration);
} }
/** /**
@@ -34,7 +34,7 @@ public class McmmoManager {
* @return The bonus drop count. * @return The bonus drop count.
*/ */
public int getBonusDropCount(@NotNull final Block block) { public int getBonusDropCount(@NotNull final Block block) {
for (McmmoWrapper mcmmoWrapper : regsistered) { for (McmmoWrapper mcmmoWrapper : registered) {
return mcmmoWrapper.getBonusDropCount(block); return mcmmoWrapper.getBonusDropCount(block);
} }
return 0; return 0;
@@ -47,7 +47,7 @@ public class McmmoManager {
* @return If the event is fake. * @return If the event is fake.
*/ */
public boolean isFake(@NotNull final Event event) { public boolean isFake(@NotNull final Event event) {
for (McmmoWrapper mcmmoWrapper : regsistered) { for (McmmoWrapper mcmmoWrapper : registered) {
return mcmmoWrapper.isFake(event); return mcmmoWrapper.isFake(event);
} }
return false; return false;

View File

@@ -5,7 +5,9 @@ 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;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@@ -18,7 +20,7 @@ public class PlaceholderManager {
/** /**
* All registered placeholders. * All registered placeholders.
*/ */
private static final Set<PlaceholderEntry> REGISTERED_PLACEHOLDERS = new HashSet<>(); private static final Map<String, PlaceholderEntry> REGISTERED_PLACEHOLDERS = new HashMap<>();
/** /**
* All registered placeholder integrations. * All registered placeholder integrations.
@@ -41,8 +43,8 @@ public class PlaceholderManager {
* @param expansion The {@link PlaceholderEntry} to register. * @param expansion The {@link PlaceholderEntry} to register.
*/ */
public static void registerPlaceholder(@NotNull final PlaceholderEntry expansion) { public static void registerPlaceholder(@NotNull final PlaceholderEntry expansion) {
REGISTERED_PLACEHOLDERS.removeIf(placeholderEntry -> placeholderEntry.getIdentifier().equalsIgnoreCase(expansion.getIdentifier())); REGISTERED_PLACEHOLDERS.remove(expansion.getIdentifier());
REGISTERED_PLACEHOLDERS.add(expansion); REGISTERED_PLACEHOLDERS.put(expansion.getIdentifier(), expansion);
} }
/** /**
@@ -54,14 +56,15 @@ public class PlaceholderManager {
*/ */
public static String getResult(@Nullable final Player player, public static String getResult(@Nullable final Player player,
@NotNull final String identifier) { @NotNull final String identifier) {
Optional<PlaceholderEntry> matching = REGISTERED_PLACEHOLDERS.stream().filter(expansion -> expansion.getIdentifier().equalsIgnoreCase(identifier)).findFirst(); PlaceholderEntry entry = REGISTERED_PLACEHOLDERS.get(identifier.toLowerCase());
if (matching.isEmpty()) { if (entry == null) {
return null; return "";
} }
PlaceholderEntry entry = matching.get();
if (player == null && entry.requiresPlayer()) { if (player == null && entry.requiresPlayer()) {
return ""; return "";
} }
return entry.getResult(player); return entry.getResult(player);
} }
@@ -74,8 +77,10 @@ public 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) {
AtomicReference<String> translatedReference = new AtomicReference<>(text); String processed = text;
REGISTERED_INTEGRATIONS.forEach(placeholderIntegration -> translatedReference.set(placeholderIntegration.translate(translatedReference.get(), player))); for (PlaceholderIntegration integration : REGISTERED_INTEGRATIONS) {
return translatedReference.get(); processed = integration.translate(processed, player);
}
return processed;
} }
} }

View File

@@ -0,0 +1,36 @@
package com.willfp.eco.core.integrations.shop;
import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
/**
* Class to handle shop integrations.
*/
@UtilityClass
public class ShopManager {
/**
* A set of all registered integrations.
*/
private final Set<ShopWrapper> registered = new HashSet<>();
/**
* Register a new integration.
*
* @param integration The integration to register.
*/
public void register(@NotNull final ShopWrapper integration) {
registered.add(integration);
}
/**
* Register eco item provider for shop plugins.
*/
public void registerEcoProvider() {
for (ShopWrapper shopWrapper : registered) {
shopWrapper.registerEcoProvider();
}
}
}

View File

@@ -0,0 +1,11 @@
package com.willfp.eco.core.integrations.shop;
/**
* Wrapper class for shop integrations.
*/
public interface ShopWrapper {
/**
* Register eco item provider for shop plugins.
*/
void registerEcoProvider();
}

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.core.items; package com.willfp.eco.core.items;
import com.willfp.eco.core.items.builder.ItemBuilder; import com.willfp.eco.core.items.args.LookupArgParser;
import com.willfp.eco.core.items.builder.ItemStackBuilder;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem; import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
import com.willfp.eco.core.recipe.parts.MaterialTestableItem; import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
import com.willfp.eco.core.recipe.parts.ModifiedTestableItem; import com.willfp.eco.core.recipe.parts.ModifiedTestableItem;
@@ -10,16 +9,19 @@ import com.willfp.eco.util.NamespacedKeyUtils;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
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.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
/** /**
* Class to manage all custom and vanilla items. * Class to manage all custom and vanilla items.
@@ -29,19 +31,33 @@ public final class Items {
/** /**
* All recipe parts. * All recipe parts.
*/ */
private static final Map<NamespacedKey, CustomItem> REGISTRY = new HashMap<>(); private static final Map<NamespacedKey, CustomItem> REGISTRY = new ConcurrentHashMap<>();
/** /**
* Register a new recipe part. * All recipe parts.
*/
private static final List<LookupArgParser> ARG_PARSERS = new ArrayList<>();
/**
* Register a new custom item.
* *
* @param key The key of the recipe part. * @param key The key of the item.
* @param part The recipe part. * @param part The item.
*/ */
public void registerCustomItem(@NotNull final NamespacedKey key, public void registerCustomItem(@NotNull final NamespacedKey key,
@NotNull final CustomItem part) { @NotNull final CustomItem part) {
REGISTRY.put(key, part); REGISTRY.put(key, part);
} }
/**
* Register a new arg parser.
*
* @param parser The parser.
*/
public void registerArgParser(@NotNull final LookupArgParser parser) {
ARG_PARSERS.add(parser);
}
/** /**
* Remove an item. * Remove an item.
* *
@@ -52,12 +68,27 @@ public final class Items {
} }
/** /**
* Lookup item from string. * This is the backbone of the entire eco item system.
* <p> * <p>
* Used for recipes. * You can lookup a TestableItem for any material, custom item,
* or item in general, and it will return it with any modifiers
* passed as parameters. This includes stack size (item amount)
* and enchantments that should be present on the item.
* <p>
* If you want to get an ItemStack instance from this, then just call
* {@link TestableItem#getItem()}.
* <p>
* The advantages of the testable item system are that there is the inbuilt
* {@link TestableItem#matches(ItemStack)} - this allows to check if any item
* is that testable item; which may sound negligible but actually it allows for
* much more power an flexibility. For example, you can have an item with an
* extra metadata tag, extra lore lines, different display name - and it
* will still work as long as the test passes. This is very important
* for custom crafting recipes where other plugins may add metadata
* values or the play may rename the item.
* *
* @param key The string to test. * @param key The lookup string.
* @return The found testable item, or an empty item if not found. * @return The testable item, or an {@link EmptyTestableItem}.
*/ */
public TestableItem lookup(@NotNull final String key) { public TestableItem lookup(@NotNull final String key) {
if (key.contains("?")) { if (key.contains("?")) {
@@ -79,6 +110,8 @@ public final class Items {
TestableItem item = null; TestableItem item = null;
int stackAmount = 1;
String[] split = args[0].toLowerCase().split(":"); String[] split = args[0].toLowerCase().split(":");
if (split.length == 1) { if (split.length == 1) {
@@ -92,71 +125,84 @@ public final class Items {
if (split.length == 2) { if (split.length == 2) {
CustomItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1])); CustomItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1]));
/*
Legacy id:amount format
This has been superseded by id amount
*/
if (part == null) { if (part == null) {
Material material = Material.getMaterial(split[0].toUpperCase()); Material material = Material.getMaterial(split[0].toUpperCase());
if (material == null || material == Material.AIR) { if (material == null || material == Material.AIR) {
return new EmptyTestableItem(); return new EmptyTestableItem();
} }
item = new TestableStack(new MaterialTestableItem(material), Integer.parseInt(split[1])); item = new MaterialTestableItem(material);
stackAmount = Integer.parseInt(split[1]);
} else { } else {
item = part; item = part;
} }
} }
/*
Legacy namespace:id:amount format
This has been superseded by namespace:id amount
*/
if (split.length == 3) { if (split.length == 3) {
CustomItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1])); CustomItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1]));
item = part == null ? new EmptyTestableItem() : new TestableStack(part, Integer.parseInt(split[2])); if (part == null) {
return new EmptyTestableItem();
}
item = part;
stackAmount = Integer.parseInt(split[2]);
} }
boolean usingNewStackFormat = false;
if (args.length >= 2) {
try {
stackAmount = Integer.parseInt(args[1]);
usingNewStackFormat = true;
} catch (NumberFormatException ignored) {
}
}
// Marked as redundant but i am covering all bases here
if (item == null || item instanceof EmptyTestableItem) { if (item == null || item instanceof EmptyTestableItem) {
return new EmptyTestableItem(); return new EmptyTestableItem();
} }
String[] enchantArgs = Arrays.copyOfRange(args, 1, args.length); ItemStack example = item.getItem();
ItemMeta meta = example.getItemMeta();
assert meta != null;
Map<Enchantment, Integer> requiredEnchantments = new HashMap<>(); String[] modifierArgs = Arrays.copyOfRange(args, usingNewStackFormat ? 2 : 1, args.length);
for (String enchantArg : enchantArgs) { List<Predicate<ItemStack>> predicates = new ArrayList<>();
String[] enchantArgSplit = enchantArg.split(":");
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(enchantArgSplit[0].toLowerCase())); for (LookupArgParser argParser : ARG_PARSERS) {
int level = Integer.parseInt(enchantArgSplit[1]); predicates.add(argParser.parseArguments(modifierArgs, meta));
requiredEnchantments.put(enchantment, level);
} }
if (requiredEnchantments.isEmpty()) { example.setItemMeta(meta);
if (!predicates.isEmpty()) {
item = new ModifiedTestableItem(
item,
test -> {
for (Predicate<ItemStack> predicate : predicates) {
if (!predicate.test(test)) {
return false;
}
}
return true;
},
example
);
}
if (stackAmount <= 1) {
return item; return item;
} else {
return new TestableStack(item, stackAmount);
} }
ItemBuilder builder = new ItemStackBuilder(item.getItem());
requiredEnchantments.forEach(builder::addEnchantment);
ItemStack example = builder.build();
return new ModifiedTestableItem(
item,
itemStack -> {
if (!itemStack.hasItemMeta()) {
return false;
}
ItemMeta meta = itemStack.getItemMeta();
assert meta != null;
for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
if (!meta.hasEnchant(entry.getKey())) {
return false;
}
if (meta.getEnchantLevel(entry.getKey()) < entry.getValue()) {
return false;
}
}
return true;
},
example
);
} }
/** /**
@@ -174,6 +220,22 @@ public final class Items {
return false; return false;
} }
/**
* Get custom item from item.
*
* @param itemStack The item.
* @return The custom item, or null if not exists.
*/
@Nullable
public CustomItem getCustomItem(@NotNull final ItemStack itemStack) {
for (CustomItem item : REGISTRY.values()) {
if (item.matches(itemStack)) {
return item;
}
}
return null;
}
/** /**
* Get all registered custom items. * Get all registered custom items.
* *

View File

@@ -0,0 +1,78 @@
package com.willfp.eco.core.items.args;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
/**
* Parses enchantment arguments.
*/
public class EnchantmentArgParser implements LookupArgParser {
@Override
public Predicate<ItemStack> parseArguments(@NotNull final String[] args,
@NotNull final ItemMeta meta) {
Map<Enchantment, Integer> requiredEnchantments = new HashMap<>();
for (String enchantArg : args) {
String[] enchantArgSplit = enchantArg.split(":");
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(enchantArgSplit[0].toLowerCase()));
if (enchantment == null) {
continue;
}
if (enchantArgSplit.length < 2) {
continue;
}
int level = Integer.parseInt(enchantArgSplit[1]);
requiredEnchantments.put(enchantment, level);
}
if (meta instanceof EnchantmentStorageMeta storageMeta) {
requiredEnchantments.forEach((enchantment, integer) -> storageMeta.addStoredEnchant(enchantment, integer, true));
} else {
requiredEnchantments.forEach((enchantment, integer) -> meta.addEnchant(enchantment, integer, true));
}
return test -> {
if (!test.hasItemMeta()) {
return false;
}
ItemMeta testMeta = test.getItemMeta();
assert testMeta != null;
if (testMeta instanceof EnchantmentStorageMeta storageMeta) {
for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
if (!storageMeta.hasStoredEnchant(entry.getKey())) {
return false;
}
if (storageMeta.getStoredEnchantLevel(entry.getKey()) < entry.getValue()) {
return false;
}
}
} else {
for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
if (!testMeta.hasEnchant(entry.getKey())) {
return false;
}
if (testMeta.getEnchantLevel(entry.getKey()) < entry.getValue()) {
return false;
}
}
}
return true;
};
}
}

View File

@@ -0,0 +1,24 @@
package com.willfp.eco.core.items.args;
import com.willfp.eco.core.items.TestableItem;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.function.Predicate;
/**
* An argument parser should generate the predicate as well
* as modify the ItemMeta for {@link TestableItem#getItem()}.
*/
public interface LookupArgParser {
/**
* Parse the arguments.
*
* @param args The arguments.
* @param meta The ItemMeta to modify.
* @return The predicate test to apply to the modified item.
*/
Predicate<ItemStack> parseArguments(@NotNull String[] args,
@NotNull ItemMeta meta);
}

View File

@@ -0,0 +1,54 @@
package com.willfp.eco.core.items.args;
import com.willfp.eco.util.SkullUtils;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.jetbrains.annotations.NotNull;
import java.util.function.Predicate;
/**
* Parse skull textures.
*/
public class TextureArgParser implements LookupArgParser {
@Override
public Predicate<ItemStack> parseArguments(@NotNull final String[] args,
@NotNull final ItemMeta meta) {
String skullTexture = null;
for (String arg : args) {
String[] argSplit = arg.split(":");
if (!argSplit[0].equalsIgnoreCase("texture")) {
continue;
}
if (argSplit.length < 2) {
continue;
}
skullTexture = argSplit[1];
}
if (meta instanceof SkullMeta skullMeta && skullTexture != null) {
SkullUtils.setSkullTexture(skullMeta, skullTexture);
}
String finalSkullTexture = skullTexture;
return test -> {
if (!test.hasItemMeta()) {
return false;
}
ItemMeta testMeta = test.getItemMeta();
assert testMeta != null;
if (testMeta instanceof SkullMeta skullMeta && finalSkullTexture != null) {
return finalSkullTexture.equalsIgnoreCase(SkullUtils.getSkullTexture(skullMeta));
}
return true;
};
}
}

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.core.recipe.parts;
import com.willfp.eco.core.items.TestableItem; import com.willfp.eco.core.items.TestableItem;
import lombok.Getter; import lombok.Getter;
import org.apache.commons.lang.Validate;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -23,6 +24,8 @@ public class MaterialTestableItem implements TestableItem {
* @param material The material. * @param material The material.
*/ */
public MaterialTestableItem(@NotNull final Material material) { public MaterialTestableItem(@NotNull final Material material) {
Validate.isTrue(material != Material.AIR, "You can't have air as the type!");
this.material = material; this.material = material;
} }

View File

@@ -17,6 +17,7 @@ public class ModifiedTestableItem implements TestableItem {
/** /**
* The item. * The item.
*/ */
@Getter
private final TestableItem handle; private final TestableItem handle;
/** /**

View File

@@ -1,17 +1,12 @@
package com.willfp.eco.core.recipe.parts; package com.willfp.eco.core.recipe.parts;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.items.TestableItem; import com.willfp.eco.core.items.TestableItem;
import lombok.Getter; import lombok.Getter;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/** /**
* Stacks of items. * Stacks of items.
*/ */
@@ -19,6 +14,7 @@ public class TestableStack implements TestableItem {
/** /**
* The item. * The item.
*/ */
@Getter
private final TestableItem handle; private final TestableItem handle;
/** /**
@@ -35,7 +31,8 @@ public class TestableStack implements TestableItem {
*/ */
public TestableStack(@NotNull final TestableItem item, public TestableStack(@NotNull final TestableItem item,
final int amount) { final int amount) {
Validate.isTrue(!(item instanceof TestableStack)); Validate.isTrue(!(item instanceof TestableStack), "You can't stack a stack!");
Validate.isTrue(!(item instanceof EmptyTestableItem), "You can't stack air!");
this.handle = item; this.handle = item;
this.amount = amount; this.amount = amount;
@@ -55,19 +52,7 @@ public class TestableStack implements TestableItem {
@Override @Override
public ItemStack getItem() { public ItemStack getItem() {
ItemStack temp = handle.getItem().clone(); ItemStack temp = handle.getItem().clone();
ItemMeta meta = temp.getItemMeta();
assert meta != null;
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
assert lore != null;
lore.add("");
String add = Eco.getHandler().getEcoPlugin().getLangYml().getString("multiple-in-craft");
add = add.replace("%amount%", String.valueOf(amount));
lore.add(add);
meta.setLore(lore);
temp.setItemMeta(meta);
temp.setAmount(amount); temp.setAmount(amount);
return temp; return temp;
} }
} }

View File

@@ -1,16 +1,19 @@
package com.willfp.eco.core.recipe.recipes; package com.willfp.eco.core.recipe.recipes;
import com.willfp.eco.core.Eco;
import com.willfp.eco.core.EcoPlugin; import com.willfp.eco.core.EcoPlugin;
import com.willfp.eco.core.PluginDependent; import com.willfp.eco.core.PluginDependent;
import com.willfp.eco.core.items.TestableItem; import com.willfp.eco.core.items.TestableItem;
import com.willfp.eco.core.recipe.Recipes; import com.willfp.eco.core.recipe.Recipes;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem; import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
import com.willfp.eco.core.recipe.parts.TestableStack;
import lombok.Getter; import lombok.Getter;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.RecipeChoice; import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
@@ -87,7 +90,23 @@ public final class ShapedCraftingRecipe extends PluginDependent<EcoPlugin> imple
displayedRecipe.shape("012", "345", "678"); displayedRecipe.shape("012", "345", "678");
for (int i = 0; i < 9; i++) { for (int i = 0; i < 9; i++) {
char character = String.valueOf(i).toCharArray()[0]; char character = String.valueOf(i).toCharArray()[0];
displayedRecipe.setIngredient(character, new RecipeChoice.ExactChoice(parts.get(i).getItem())); ItemStack item = parts.get(i).getItem();
if (parts.get(i) instanceof TestableStack) {
ItemMeta meta = item.getItemMeta();
assert meta != null;
List<String> lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();
assert lore != null;
lore.add("");
String add = Eco.getHandler().getEcoPlugin().getLangYml().getString("multiple-in-craft");
add = add.replace("%amount%", String.valueOf(item.getAmount()));
lore.add(add);
meta.setLore(lore);
item.setItemMeta(meta);
}
displayedRecipe.setIngredient(character, new RecipeChoice.ExactChoice(item));
} }
Bukkit.getServer().addRecipe(shapedRecipe); Bukkit.getServer().addRecipe(shapedRecipe);

View File

@@ -19,7 +19,7 @@ public class ArrowUtils {
* Get the bow from an arrow. * Get the bow from an arrow.
* *
* @param arrow The arrow. * @param arrow The arrow.
* @return The bow. * @return The bow, or null if no bow.
*/ */
@Nullable @Nullable
public ItemStack getBow(@NotNull final Arrow arrow) { public ItemStack getBow(@NotNull final Arrow arrow) {

View File

@@ -63,6 +63,7 @@ public class BlockUtils {
* @param limit The maximum size of vein to return. * @param limit The maximum size of vein to return.
* @return A set of all {@link Block}s. * @return A set of all {@link Block}s.
*/ */
@NotNull
public Set<Block> getVein(@NotNull final Block start, public Set<Block> getVein(@NotNull final Block start,
@NotNull final List<Material> allowedMaterials, @NotNull final List<Material> allowedMaterials,
final int limit) { final int limit) {

View File

@@ -1,6 +1,8 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -18,8 +20,9 @@ public class ListUtils {
* @param <T> The type of the object stored in the list. * @param <T> The type of the object stored in the list.
* @return The list, filled will null objects. * @return The list, filled will null objects.
*/ */
public <T> List<List<T>> create2DList(final int rows, @NotNull
final int columns) { public <@Nullable T> List<List<T>> create2DList(final int rows,
final int columns) {
List<List<T>> list = new ArrayList<>(rows); List<List<T>> list = new ArrayList<>(rows);
while (list.size() < rows) { while (list.size() < rows) {
List<T> row = new ArrayList<>(columns); List<T> row = new ArrayList<>(columns);

View File

@@ -2,6 +2,7 @@ package com.willfp.eco.util;
import com.willfp.eco.core.tuples.Pair; import com.willfp.eco.core.tuples.Pair;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull;
/** /**
* Utilities / API methods for menus. * Utilities / API methods for menus.
@@ -14,6 +15,7 @@ public class MenuUtils {
* @param slot The slot. * @param slot The slot.
* @return The pair of row and columns. * @return The pair of row and columns.
*/ */
@NotNull
public Pair<Integer, Integer> convertSlotToRowColumn(final int slot) { public Pair<Integer, Integer> convertSlotToRowColumn(final int slot) {
int row = Math.floorDiv(slot, 9); int row = Math.floorDiv(slot, 9);
int column = slot - row * 9; int column = slot - row * 9;

View File

@@ -17,6 +17,7 @@ public class NamespacedKeyUtils {
* @param string The string. * @param string The string.
* @return The key. * @return The key.
*/ */
@NotNull
public NamespacedKey createEcoKey(@NotNull final String string) { public NamespacedKey createEcoKey(@NotNull final String string) {
return Objects.requireNonNull(NamespacedKey.fromString("eco:" + string)); return Objects.requireNonNull(NamespacedKey.fromString("eco:" + string));
} }
@@ -28,6 +29,7 @@ public class NamespacedKeyUtils {
* @param key The key. * @param key The key.
* @return The key. * @return The key.
*/ */
@NotNull
public NamespacedKey create(@NotNull final String namespace, public NamespacedKey create(@NotNull final String namespace,
@NotNull final String key) { @NotNull final String key) {
return Objects.requireNonNull(NamespacedKey.fromString(namespace + ":" + key)); return Objects.requireNonNull(NamespacedKey.fromString(namespace + ":" + key));

View File

@@ -1,5 +1,6 @@
package com.willfp.eco.util; package com.willfp.eco.util;
import lombok.experimental.NonFinal;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -109,6 +110,7 @@ public class NumberUtils {
* @param number The number to convert. * @param number The number to convert.
* @return The number, converted to a roman numeral. * @return The number, converted to a roman numeral.
*/ */
@NotNull
public String toNumeral(final int number) { public String toNumeral(final int number) {
if (number >= 1 && number <= 4096) { if (number >= 1 && number <= 4096) {
int l = NUMERALS.floorKey(number); int l = NUMERALS.floorKey(number);
@@ -199,6 +201,7 @@ public class NumberUtils {
* @param toFormat The number to format. * @param toFormat The number to format.
* @return Formatted. * @return Formatted.
*/ */
@NotNull
public String format(final double toFormat) { public String format(final double toFormat) {
DecimalFormat df = new DecimalFormat("0.00"); DecimalFormat df = new DecimalFormat("0.00");
String formatted = df.format(toFormat); String formatted = df.format(toFormat);

View File

@@ -5,8 +5,10 @@ import org.apache.commons.lang.Validate;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
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 java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Function;
/** /**
* Utilities / API methods for player heads. * Utilities / API methods for player heads.
@@ -23,6 +25,11 @@ public class SkullUtils {
*/ */
private BiConsumer<SkullMeta, String> metaSetConsumer = null; private BiConsumer<SkullMeta, String> metaSetConsumer = null;
/**
* The meta get function.
*/
private Function<SkullMeta, String> metaGetConsumer = null;
/** /**
* Set the texture of a skull from base64. * Set the texture of a skull from base64.
* *
@@ -37,16 +44,33 @@ public class SkullUtils {
metaSetConsumer.accept(meta, base64); metaSetConsumer.accept(meta, base64);
} }
/**
* Get the texture of a skull - in base64.
*
* @param meta The meta to modify.
* @return The texture, potentially null.
*/
@Nullable
public String getSkullTexture(@NotNull final SkullMeta meta) {
Validate.isTrue(initialized, "Must be initialized!");
Validate.notNull(metaGetConsumer, "Must be initialized!");
return metaGetConsumer.apply(meta);
}
/** /**
* Initialize the skull texture function. * Initialize the skull texture function.
* *
* @param function The function. * @param function The function.
* @param function2 Get function.
*/ */
@ApiStatus.Internal @ApiStatus.Internal
public void initialize(@NotNull final BiConsumer<SkullMeta, String> function) { public void initialize(@NotNull final BiConsumer<SkullMeta, String> function,
@NotNull final Function<SkullMeta, String> function2) {
Validate.isTrue(!initialized, "Already initialized!"); Validate.isTrue(!initialized, "Already initialized!");
metaSetConsumer = function; metaSetConsumer = function;
metaGetConsumer = function2;
initialized = true; initialized = true;
} }
} }

View File

@@ -12,7 +12,7 @@ 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;
import java.awt.*; import java.awt.Color;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@@ -57,58 +57,137 @@ public class StringUtils {
.build(); .build();
/** /**
* Format a list of strings - converts Placeholders and Color codes. * Format a list of strings.
* <p>
* Converts color codes and placeholders.
*
* @param list The messages to format.
* @return The message, formatted.
*/
@NotNull
public List<String> formatList(@NotNull final List<String> list) {
return formatList(list, (Player) null);
}
/**
* Format a list of strings.
* <p>
* Coverts color codes and placeholders for a player.
* *
* @param list The messages to format. * @param list The messages to format.
* @param player The player to translate placeholders with respect to. * @param player The player to translate placeholders with respect to.
* @return The message, format. * @return The message, format.
*/ */
@NotNull
public List<String> formatList(@NotNull final List<String> list, public List<String> formatList(@NotNull final List<String> list,
@Nullable final Player player) { @Nullable final Player player) {
return formatList(list, player, FormatOption.WITH_PLACEHOLDERS);
}
/**
* Format a list of strings.
* <p>
* Converts color codes and placeholders if specified.
*
* @param list The messages to format.
* @param option The format option.
* @return The message, formatted.
*/
@NotNull
public List<String> formatList(@NotNull final List<String> list,
@NotNull final FormatOption option) {
return formatList(list, null, option);
}
/**
* Format a list of strings.
* <p>
* Coverts color codes and placeholders for a player if specified.
*
* @param list The messages to format.
* @param player The player to translate placeholders with respect to.
* @param option The options.
* @return The message, format.
*/
@NotNull
public List<String> formatList(@NotNull final List<String> list,
@Nullable final Player player,
@NotNull final FormatOption option) {
List<String> translated = new ArrayList<>(); List<String> translated = new ArrayList<>();
for (String string : list) { for (String string : list) {
translated.add(format(string, player)); translated.add(format(string, player, option));
} }
return translated; return translated;
} }
/** /**
* Format a list of strings - converts Placeholders and Color codes. * Format a string.
* * <p>
* @param list The messages to format. * Converts color codes and placeholders.
* @return The message, formatted.
*/
public List<String> formatList(@NotNull final List<String> list) {
return formatList(list, null);
}
/**
* Format a string - converts Placeholders and Color codes.
*
* @param message The message to format.
* @param player The player to translate placeholders with respect to.
* @return The message, formatted.
*/
public String format(@NotNull final String message,
@Nullable final Player player) {
String processedMessage = message;
processedMessage = translateGradients(processedMessage);
processedMessage = PlaceholderManager.translatePlaceholders(processedMessage, player);
processedMessage = translateHexColorCodes(processedMessage);
processedMessage = ChatColor.translateAlternateColorCodes('&', processedMessage);
return processedMessage;
}
/**
* Format a string without respect to a player.
* *
* @param message The message to translate. * @param message The message to translate.
* @return The message, formatted. * @return The message, formatted.
* @see StringUtils#format(String, Player) * @see StringUtils#format(String, Player)
*/ */
@NotNull
public String format(@NotNull final String message) { public String format(@NotNull final String message) {
return format(message, null); return format(message, (Player) null);
}
/**
* Format a string.
* <p>
* Converts color codes and placeholders for a player.
*
* @param message The message to format.
* @param player The player to translate placeholders with respect to.
* @return The message, formatted.
*/
@NotNull
public String format(@NotNull final String message,
@Nullable final Player player) {
return format(message, player, FormatOption.WITH_PLACEHOLDERS);
}
/**
* Format a string.
* <p>
* Converts color codes and placeholders if specified.
*
* @param message The message to translate.
* @param option The format option.
* @return The message, formatted.
* @see StringUtils#format(String, Player)
*/
@NotNull
public String format(@NotNull final String message,
@NotNull final FormatOption option) {
return format(message, null, option);
}
/**
* Format a string.
* <p>
* Coverts color codes and placeholders for a player if specified.
*
* @param message The message to format.
* @param player The player to translate placeholders with respect to.
* @param option The format options.
* @return The message, formatted.
*/
@NotNull
public String format(@NotNull final String message,
@Nullable final Player player,
@NotNull final FormatOption option) {
String processedMessage = message;
processedMessage = translateGradients(processedMessage);
if (option == FormatOption.WITH_PLACEHOLDERS) {
processedMessage = PlaceholderManager.translatePlaceholders(processedMessage, player);
}
processedMessage = translateHexColorCodes(processedMessage);
processedMessage = ChatColor.translateAlternateColorCodes('&', processedMessage);
return processedMessage;
} }
private static String translateHexColorCodes(@NotNull final String message) { private static String translateHexColorCodes(@NotNull final String message) {
@@ -213,6 +292,7 @@ public class StringUtils {
* @param object The object to convert to string. * @param object The object to convert to string.
* @return The object stringified. * @return The object stringified.
*/ */
@NotNull
public String internalToString(@Nullable final Object object) { public String internalToString(@Nullable final Object object) {
if (object == null) { if (object == null) {
return "null"; return "null";
@@ -238,6 +318,7 @@ public class StringUtils {
* @param prefix The substring to remove. * @param prefix The substring to remove.
* @return The string with the prefix removed. * @return The string with the prefix removed.
*/ */
@NotNull
public String removePrefix(@NotNull final String string, public String removePrefix(@NotNull final String string,
@NotNull final String prefix) { @NotNull final String prefix) {
if (string.startsWith(prefix)) { if (string.startsWith(prefix)) {
@@ -252,6 +333,7 @@ public class StringUtils {
* @param legacy The legacy string. * @param legacy The legacy string.
* @return The JSON String. * @return The JSON String.
*/ */
@NotNull
public String legacyToJson(@NotNull final String legacy) { public String legacyToJson(@NotNull final String legacy) {
return GsonComponentSerializer.gson().serialize( return GsonComponentSerializer.gson().serialize(
Component.empty().decoration(TextDecoration.ITALIC, false).append( Component.empty().decoration(TextDecoration.ITALIC, false).append(
@@ -266,9 +348,25 @@ public class StringUtils {
* @param json The JSON string. * @param json The JSON string.
* @return The legacy string. * @return The legacy string.
*/ */
@NotNull
public String jsonToLegacy(@NotNull final String json) { public String jsonToLegacy(@NotNull final String json) {
return LEGACY_COMPONENT_SERIALIZER.serialize( return LEGACY_COMPONENT_SERIALIZER.serialize(
GsonComponentSerializer.gson().deserialize(json) GsonComponentSerializer.gson().deserialize(json)
); );
} }
/**
* Options for formatting.
*/
public enum FormatOption {
/**
* Completely formatted.
*/
WITH_PLACEHOLDERS,
/**
* Completely formatted without placeholders.
*/
WITHOUT_PLACEHOLDERS
}
} }

View File

@@ -43,6 +43,7 @@ public class TeamUtils {
* @param color The color to find the team for. * @param color The color to find the team for.
* @return The team. * @return The team.
*/ */
@NotNull
public Team fromChatColor(@NotNull final ChatColor color) { public Team fromChatColor(@NotNull final ChatColor color) {
if (CHAT_COLOR_TEAMS.containsKey(color)) { if (CHAT_COLOR_TEAMS.containsKey(color)) {
return CHAT_COLOR_TEAMS.get(color); return CHAT_COLOR_TEAMS.get(color);
@@ -70,6 +71,7 @@ public class TeamUtils {
* @param material The material to find the team from. * @param material The material to find the team from.
* @return The team. * @return The team.
*/ */
@NotNull
public Team getMaterialColorTeam(@NotNull final Material material) { public Team getMaterialColorTeam(@NotNull final Material material) {
return fromChatColor(MATERIAL_COLORS.getOrDefault(material, ChatColor.WHITE)); return fromChatColor(MATERIAL_COLORS.getOrDefault(material, ChatColor.WHITE));
} }

View File

@@ -44,6 +44,7 @@ public class VectorUtils {
* @param vec The vector to simplify. * @param vec The vector to simplify.
* @return The vector, simplified. * @return The vector, simplified.
*/ */
@NotNull
public Vector simplifyVector(@NotNull final Vector vec) { public Vector simplifyVector(@NotNull final Vector vec) {
double x = Math.abs(vec.getX()); double x = Math.abs(vec.getX());
double y = Math.abs(vec.getY()); double y = Math.abs(vec.getY());
@@ -76,6 +77,7 @@ public class VectorUtils {
* @param radius The radius. * @param radius The radius.
* @return An array of {@link Vector}s. * @return An array of {@link Vector}s.
*/ */
@NotNull
public Vector[] getCircle(final int radius) { public Vector[] getCircle(final int radius) {
Vector[] cached = CIRCLE_CACHE.get(radius); Vector[] cached = CIRCLE_CACHE.get(radius);
if (cached != null) { if (cached != null) {
@@ -112,6 +114,7 @@ public class VectorUtils {
* @param radius The radius of the square. * @param radius The radius of the square.
* @return An array of {@link Vector}s. * @return An array of {@link Vector}s.
*/ */
@NotNull
public Vector[] getSquare(final int radius) { public Vector[] getSquare(final int radius) {
List<Vector> vectors = new ArrayList<>(); List<Vector> vectors = new ArrayList<>();
@@ -136,6 +139,7 @@ public class VectorUtils {
* @param radius The radius of the cube. * @param radius The radius of the cube.
* @return An array of {@link Vector}s. * @return An array of {@link Vector}s.
*/ */
@NotNull
public Vector[] getCube(final int radius) { public Vector[] getCube(final int radius) {
List<Vector> vectors = new ArrayList<>(); List<Vector> vectors = new ArrayList<>();

View File

@@ -11,9 +11,9 @@ import java.util.*
open class EcoJSONConfigWrapper : JSONConfig { open class EcoJSONConfigWrapper : JSONConfig {
val handle: Gson = GsonBuilder().setPrettyPrinting().create() val handle: Gson = GsonBuilder().setPrettyPrinting().create()
val values: MutableMap<String, Any?> = HashMap() val values = mutableMapOf<String, Any?>()
private val cache: MutableMap<String, Any> = HashMap() private val cache = mutableMapOf<String, Any>()
fun init(values: Map<String, Any?>) { fun init(values: Map<String, Any?>) {
this.values.clear() this.values.clear()
@@ -138,17 +138,17 @@ open class EcoJSONConfigWrapper : JSONConfig {
override fun getSubsections(path: String): List<JSONConfig> { override fun getSubsections(path: String): List<JSONConfig> {
val subsections = getSubsectionsOrNull(path) val subsections = getSubsectionsOrNull(path)
return subsections ?: ArrayList() return subsections ?: mutableListOf()
} }
override fun getSubsectionsOrNull(path: String): List<JSONConfig>? { override fun getSubsectionsOrNull(path: String): List<JSONConfig>? {
val maps = getOfKnownType(path, Any::class.java) as List<Map<String, Any>>? val maps = getOfKnownType(path, Any::class.java) as List<Map<String, Any>>?
?: return null ?: return null
val configs: MutableList<JSONConfig> = ArrayList() val configs = mutableListOf<JSONConfig>()
for (map in maps) { for (map in maps) {
configs.add(EcoJSONConfigSection(map)) configs.add(EcoJSONConfigSection(map))
} }
return configs return configs.toMutableList()
} }
override fun getInt(path: String): Int { override fun getInt(path: String): Int {
@@ -170,11 +170,11 @@ open class EcoJSONConfigWrapper : JSONConfig {
return Objects.requireNonNullElse(getOfKnownType(path, Int::class.java), def) return Objects.requireNonNullElse(getOfKnownType(path, Int::class.java), def)
} }
override fun getInts(path: String): List<Int> { override fun getInts(path: String): MutableList<Int> {
return Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), ArrayList<Any>()) as List<Int> return (Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), emptyList<Int>()) as List<Int>).toMutableList()
} }
override fun getIntsOrNull(path: String): List<Int>? { override fun getIntsOrNull(path: String): MutableList<Int>? {
return if (has(path)) { return if (has(path)) {
getInts(path) getInts(path)
} else { } else {
@@ -194,11 +194,11 @@ open class EcoJSONConfigWrapper : JSONConfig {
} }
} }
override fun getBools(path: String): List<Boolean> { override fun getBools(path: String): MutableList<Boolean> {
return Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), ArrayList<Any>()) as List<Boolean> return (Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), emptyList<Boolean>()) as List<Boolean>).toMutableList()
} }
override fun getBoolsOrNull(path: String): List<Boolean>? { override fun getBoolsOrNull(path: String): MutableList<Boolean>? {
return if (has(path)) { return if (has(path)) {
getBools(path) getBools(path)
} else { } else {
@@ -206,64 +206,44 @@ open class EcoJSONConfigWrapper : JSONConfig {
} }
} }
override fun getString(path: String): String {
return getString(path, true)
}
override fun getString( override fun getString(
path: String, path: String,
format: Boolean format: Boolean,
option: StringUtils.FormatOption
): String { ): String {
val string = getOfKnownType(path, String::class.java) ?: "" val string = getOfKnownType(path, String::class.java) ?: ""
return if (format) StringUtils.format(string) else string return if (format) StringUtils.format(string, option) else string
}
override fun getStringOrNull(path: String): String? {
return if (has(path)) {
getString(path)
} else {
null
}
} }
override fun getStringOrNull( override fun getStringOrNull(
path: String, path: String,
format: Boolean format: Boolean,
option: StringUtils.FormatOption
): String? { ): String? {
return if (has(path)) { return if (has(path)) {
getString(path, format) getString(path, format, option)
} else { } else {
null null
} }
} }
override fun getStrings(path: String): List<String> {
return getStrings(path, true)
}
override fun getStrings( override fun getStrings(
path: String, path: String,
format: Boolean format: Boolean,
): List<String> { option: StringUtils.FormatOption
): MutableList<String> {
val strings = val strings =
Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), ArrayList<Any>()) as List<String> (Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), emptyList<String>()) as List<String>).toMutableList()
return if (format) StringUtils.formatList(strings) else strings return if (format) StringUtils.formatList(strings, option) else strings
}
override fun getStringsOrNull(path: String): List<String>? {
return if (has(path)) {
getStrings(path)
} else {
null
}
} }
override fun getStringsOrNull( override fun getStringsOrNull(
path: String, path: String,
format: Boolean format: Boolean,
): List<String>? { option: StringUtils.FormatOption
): MutableList<String>? {
return if (has(path)) { return if (has(path)) {
getStrings(path, format) getStrings(path, format, option)
} else { } else {
null null
} }
@@ -281,11 +261,11 @@ open class EcoJSONConfigWrapper : JSONConfig {
} }
} }
override fun getDoubles(path: String): List<Double> { override fun getDoubles(path: String): MutableList<Double> {
return Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), ArrayList<Any>()) as List<Double> return (Objects.requireNonNullElse(getOfKnownType(path, Any::class.java), emptyList<Double>()) as List<Double>).toMutableList()
} }
override fun getDoublesOrNull(path: String): List<Double>? { override fun getDoublesOrNull(path: String): MutableList<Double>? {
return if (has(path)) { return if (has(path)) {
getDoubles(path) getDoubles(path)
} else { } else {

View File

@@ -27,7 +27,6 @@ class EcoLoadableJSONConfig(
} }
override fun createFile() { override fun createFile() {
val resourcePath = resourcePath
val inputStream = source.getResourceAsStream(resourcePath)!! val inputStream = source.getResourceAsStream(resourcePath)!!
val outFile = File(this.plugin.dataFolder, resourcePath) val outFile = File(this.plugin.dataFolder, resourcePath)
val lastIndex = resourcePath.lastIndexOf('/') val lastIndex = resourcePath.lastIndexOf('/')
@@ -37,11 +36,7 @@ class EcoLoadableJSONConfig(
} }
if (!outFile.exists()) { if (!outFile.exists()) {
val out: OutputStream = FileOutputStream(outFile) val out: OutputStream = FileOutputStream(outFile)
val buf = ByteArray(1024) inputStream.copyTo(out, 1024)
var len: Int
while (inputStream.read(buf).also { len = it } > 0) {
out.write(buf, 0, len)
}
out.close() out.close()
inputStream.close() inputStream.close()
} }

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.internal.config.updating package com.willfp.eco.internal.config.updating
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginDependent
import com.willfp.eco.core.config.interfaces.LoadableConfig import com.willfp.eco.core.config.interfaces.LoadableConfig
import com.willfp.eco.core.config.updating.ConfigHandler import com.willfp.eco.core.config.updating.ConfigHandler
import com.willfp.eco.core.config.updating.ConfigUpdater import com.willfp.eco.core.config.updating.ConfigUpdater
@@ -14,14 +13,14 @@ import org.reflections.scanners.MethodAnnotationsScanner
import java.lang.reflect.Modifier import java.lang.reflect.Modifier
class EcoConfigHandler( class EcoConfigHandler(
plugin: EcoPlugin private val plugin: EcoPlugin
) : PluginDependent<EcoPlugin>(plugin), ConfigHandler { ) : ConfigHandler {
private val reflections: Reflections = Reflections( private val reflections: Reflections = Reflections(
this.plugin::class.java.classLoader, this.plugin::class.java.classLoader,
MethodAnnotationsScanner() MethodAnnotationsScanner()
) )
private val configs: MutableList<LoadableConfig> = ArrayList() private val configs = mutableListOf<LoadableConfig>()
override fun callUpdate() { override fun callUpdate() {
for (method in reflections.getMethodsAnnotatedWith(ConfigUpdater::class.java)) { for (method in reflections.getMethodsAnnotatedWith(ConfigUpdater::class.java)) {

View File

@@ -31,7 +31,6 @@ open class EcoLoadableYamlConfig(
} }
final override fun createFile() { final override fun createFile() {
val resourcePath = resourcePath
val inputStream = source.getResourceAsStream(resourcePath)!! val inputStream = source.getResourceAsStream(resourcePath)!!
val outFile = File(this.plugin.dataFolder, resourcePath) val outFile = File(this.plugin.dataFolder, resourcePath)
val lastIndex = resourcePath.lastIndexOf('/') val lastIndex = resourcePath.lastIndexOf('/')
@@ -41,11 +40,7 @@ open class EcoLoadableYamlConfig(
} }
if (!outFile.exists()) { if (!outFile.exists()) {
val out: OutputStream = FileOutputStream(outFile) val out: OutputStream = FileOutputStream(outFile)
val buf = ByteArray(1024) inputStream.copyTo(out, 1024)
var len: Int
while (inputStream.read(buf).also { len = it } > 0) {
out.write(buf, 0, len)
}
out.close() out.close()
inputStream.close() inputStream.close()
} }

View File

@@ -10,7 +10,7 @@ import java.io.StringReader
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config { open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
lateinit var handle: T lateinit var handle: T
private val cache: MutableMap<String, Any?> = HashMap() private val cache = mutableMapOf<String, Any?>()
protected fun init(config: T): Config { protected fun init(config: T): Config {
handle = config handle = config
@@ -98,16 +98,16 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
} }
} }
override fun getInts(path: String): List<Int> { override fun getInts(path: String): MutableList<Int> {
return if (cache.containsKey(path)) { return if (cache.containsKey(path)) {
cache[path] as List<Int> (cache[path] as MutableList<Int>).toMutableList()
} else { } else {
cache[path] = if (has(path)) ArrayList(handle.getIntegerList(path)) else ArrayList<Any>() cache[path] = if (has(path)) ArrayList(handle.getIntegerList(path)) else mutableListOf<Int>()
getInts(path) getInts(path)
} }
} }
override fun getIntsOrNull(path: String): List<Int>? { override fun getIntsOrNull(path: String): MutableList<Int>? {
return if (has(path)) { return if (has(path)) {
getInts(path) getInts(path)
} else { } else {
@@ -132,17 +132,17 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
} }
} }
override fun getBools(path: String): List<Boolean> { override fun getBools(path: String): MutableList<Boolean> {
return if (cache.containsKey(path)) { return if (cache.containsKey(path)) {
cache[path] as List<Boolean> (cache[path] as MutableList<Boolean>).toMutableList()
} else { } else {
cache[path] = cache[path] =
if (has(path)) ArrayList(handle.getBooleanList(path)) else ArrayList<Any>() if (has(path)) ArrayList(handle.getBooleanList(path)) else mutableListOf<Boolean>()
getBools(path) getBools(path)
} }
} }
override fun getBoolsOrNull(path: String): List<Boolean>? { override fun getBoolsOrNull(path: String): MutableList<Boolean>? {
return if (has(path)) { return if (has(path)) {
getBools(path) getBools(path)
} else { } else {
@@ -150,92 +150,80 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
} }
} }
override fun getString(path: String): String {
return getString(path, true)
}
override fun getString( override fun getString(
path: String, path: String,
format: Boolean format: Boolean,
option: StringUtils.FormatOption
): String { ): String {
if (format) { if (format && option == StringUtils.FormatOption.WITHOUT_PLACEHOLDERS) {
return if (cache.containsKey("$path\$FMT")) { return if (cache.containsKey("$path\$FMT")) {
cache["$path\$FMT"] as String cache["$path\$FMT"] as String
} else { } else {
val string: String = handle.getString(path, "")!! val string: String = handle.getString(path, "")!!
cache["$path\$FMT"] = StringUtils.format(string) cache["$path\$FMT"] = StringUtils.format(string, option)
getString(path, format) getString(path, format, option)
} }
} else { } else {
return if (cache.containsKey(path)) { val string = if (cache.containsKey(path)) {
cache[path] as String cache[path] as String
} else { } else {
cache[path] = handle.getString(path, "")!! cache[path] = handle.getString(path, "")!!
getString(path) getString(path, format, option)
} }
}
}
override fun getStringOrNull(path: String): String? { return if (format) StringUtils.format(string) else string
return if (has(path)) {
getString(path)
} else {
null
} }
} }
override fun getStringOrNull( override fun getStringOrNull(
path: String, path: String,
format: Boolean format: Boolean,
option: StringUtils.FormatOption
): String? { ): String? {
return if (has(path)) { return if (has(path)) {
getString(path, format) getString(path, format, option)
} else { } else {
null null
} }
} }
override fun getStrings(path: String): List<String> {
return getStrings(path, true)
}
override fun getStrings( override fun getStrings(
path: String, path: String,
format: Boolean format: Boolean,
): List<String> { option: StringUtils.FormatOption
if (format) { ): MutableList<String> {
if (format && option == StringUtils.FormatOption.WITHOUT_PLACEHOLDERS) {
return if (cache.containsKey("$path\$FMT")) { return if (cache.containsKey("$path\$FMT")) {
cache["$path\$FMT"] as List<String> (cache["$path\$FMT"] as MutableList<String>).toMutableList()
} else { } else {
val list = if (has(path)) handle.getStringList(path) else ArrayList() val list = if (has(path)) handle.getStringList(path) else mutableListOf<String>()
cache["$path\$FMT"] = StringUtils.formatList(list); cache["$path\$FMT"] = StringUtils.formatList(list, option)
getStrings(path, true) getStrings(path, true, option)
} }
} else { } else {
return if (cache.containsKey(path)) { val strings = if (cache.containsKey(path)) {
cache[path] as List<String> (cache[path] as MutableList<String>).toMutableList()
} else { } else {
cache[path] = cache[path] =
if (has(path)) ArrayList(handle.getStringList(path)) else ArrayList<Any>() if (has(path)) ArrayList(handle.getStringList(path)) else mutableListOf<String>()
getStrings(path, false) getStrings(path, false, option)
} }
}
}
override fun getStringsOrNull(path: String): List<String>? { return if (format) {
return if (has(path)) { StringUtils.formatList(strings, StringUtils.FormatOption.WITH_PLACEHOLDERS)
getStrings(path) } else {
} else { strings
null }
} }
} }
override fun getStringsOrNull( override fun getStringsOrNull(
path: String, path: String,
format: Boolean format: Boolean,
): List<String>? { option: StringUtils.FormatOption
): MutableList<String>? {
return if (has(path)) { return if (has(path)) {
getStrings(path, format) getStrings(path, format, option)
} else { } else {
null null
} }
@@ -258,16 +246,16 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
} }
} }
override fun getDoubles(path: String): List<Double> { override fun getDoubles(path: String): MutableList<Double> {
return if (cache.containsKey(path)) { return if (cache.containsKey(path)) {
cache[path] as List<Double> (cache[path] as MutableList<Double>).toMutableList()
} else { } else {
cache[path] = if (has(path)) ArrayList(handle.getDoubleList(path)) else ArrayList<Any>() cache[path] = if (has(path)) ArrayList(handle.getDoubleList(path)) else emptyList<Double>()
getDoubles(path) getDoubles(path)
} }
} }
override fun getDoublesOrNull(path: String): List<Double>? { override fun getDoublesOrNull(path: String): MutableList<Double>? {
return if (has(path)) { return if (has(path)) {
getDoubles(path) getDoubles(path)
} else { } else {

View File

@@ -13,8 +13,8 @@ import org.bukkit.inventory.ItemStack
import org.bukkit.util.Vector import org.bukkit.util.Vector
open class EcoDropQueue(player: Player) : InternalDropQueue { open class EcoDropQueue(player: Player) : InternalDropQueue {
val items: MutableList<ItemStack> val items = mutableListOf<ItemStack>()
var xp: Int var xp: Int = 0
val player: Player val player: Player
var loc: Location var loc: Location
var hasTelekinesis = false var hasTelekinesis = false
@@ -79,8 +79,6 @@ open class EcoDropQueue(player: Player) : InternalDropQueue {
} }
init { init {
items = ArrayList()
xp = 0
this.player = player this.player = player
loc = player.location loc = player.location
} }

View File

@@ -1,13 +1,12 @@
package com.willfp.eco.internal.events package com.willfp.eco.internal.events
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginDependent
import com.willfp.eco.core.events.EventManager import com.willfp.eco.core.events.EventManager
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.event.HandlerList import org.bukkit.event.HandlerList
import org.bukkit.event.Listener import org.bukkit.event.Listener
class EcoEventManager constructor(plugin: EcoPlugin) : PluginDependent<EcoPlugin>(plugin), EventManager { class EcoEventManager (private val plugin: EcoPlugin) : EventManager {
override fun registerListener(listener: Listener) { override fun registerListener(listener: Listener) {
Bukkit.getPluginManager().registerEvents(listener, plugin) Bukkit.getPluginManager().registerEvents(listener, plugin)
} }

View File

@@ -2,7 +2,6 @@ package com.willfp.eco.internal.extensions
import com.google.common.collect.ImmutableSet import com.google.common.collect.ImmutableSet
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginDependent
import com.willfp.eco.core.config.yaml.YamlTransientConfig import com.willfp.eco.core.config.yaml.YamlTransientConfig
import com.willfp.eco.core.extensions.Extension import com.willfp.eco.core.extensions.Extension
import com.willfp.eco.core.extensions.ExtensionLoader import com.willfp.eco.core.extensions.ExtensionLoader
@@ -16,9 +15,9 @@ import java.net.URL
import java.net.URLClassLoader import java.net.URLClassLoader
class EcoExtensionLoader( class EcoExtensionLoader(
plugin: EcoPlugin private val plugin: EcoPlugin
) : PluginDependent<EcoPlugin>(plugin), ExtensionLoader { ) : ExtensionLoader {
private val extensions: MutableMap<Extension, URLClassLoader> = HashMap() private val extensions = mutableMapOf<Extension, URLClassLoader>()
override fun loadExtensions() { override fun loadExtensions() {
val dir = File(this.plugin.dataFolder, "/extensions") val dir = File(this.plugin.dataFolder, "/extensions")
@@ -43,7 +42,7 @@ class EcoExtensionLoader(
@Throws(MalformedExtensionException::class) @Throws(MalformedExtensionException::class)
private fun loadExtension(extensionJar: File) { private fun loadExtension(extensionJar: File) {
lateinit var url : URL lateinit var url: URL
try { try {
url = extensionJar.toURI().toURL() url = extensionJar.toURI().toURL()
@@ -53,7 +52,7 @@ class EcoExtensionLoader(
val classLoader = URLClassLoader(arrayOf(url), this.plugin::class.java.classLoader) val classLoader = URLClassLoader(arrayOf(url), this.plugin::class.java.classLoader)
val ymlIn = classLoader.getResourceAsStream("extension.yml") val ymlIn = classLoader.getResourceAsStream("extension.yml")
?: throw MalformedExtensionException ("No extension.yml found in " + extensionJar.name) ?: throw MalformedExtensionException("No extension.yml found in " + extensionJar.name)
val extensionYml = YamlTransientConfig(YamlConfiguration.loadConfiguration(InputStreamReader(ymlIn))) val extensionYml = YamlTransientConfig(YamlConfiguration.loadConfiguration(InputStreamReader(ymlIn)))
@@ -64,7 +63,7 @@ class EcoExtensionLoader(
if (mainClass == null) { if (mainClass == null) {
throw MalformedExtensionException ("Invalid extension.yml found in " + extensionJar.name) throw MalformedExtensionException("Invalid extension.yml found in " + extensionJar.name)
} }
if (name == null) { if (name == null) {

View File

@@ -1,11 +1,10 @@
package com.willfp.eco.internal.factory package com.willfp.eco.internal.factory
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginDependent
import com.willfp.eco.core.factory.MetadataValueFactory import com.willfp.eco.core.factory.MetadataValueFactory
import org.bukkit.metadata.FixedMetadataValue import org.bukkit.metadata.FixedMetadataValue
class EcoMetadataValueFactory(plugin: EcoPlugin) : PluginDependent<EcoPlugin>(plugin), MetadataValueFactory { class EcoMetadataValueFactory(private val plugin: EcoPlugin) : MetadataValueFactory {
override fun create(value: Any): FixedMetadataValue { override fun create(value: Any): FixedMetadataValue {
return FixedMetadataValue(plugin, value) return FixedMetadataValue(plugin, value)
} }

View File

@@ -1,11 +1,10 @@
package com.willfp.eco.internal.factory package com.willfp.eco.internal.factory
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginDependent
import com.willfp.eco.core.factory.NamespacedKeyFactory import com.willfp.eco.core.factory.NamespacedKeyFactory
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
class EcoNamespacedKeyFactory(plugin: EcoPlugin) : PluginDependent<EcoPlugin>(plugin), NamespacedKeyFactory { class EcoNamespacedKeyFactory(private val plugin: EcoPlugin) : NamespacedKeyFactory {
override fun create(key: String): NamespacedKey { override fun create(key: String): NamespacedKey {
return NamespacedKey(plugin, key) return NamespacedKey(plugin, key)
} }

View File

@@ -1,13 +1,12 @@
package com.willfp.eco.internal.factory package com.willfp.eco.internal.factory
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginDependent
import com.willfp.eco.core.factory.RunnableFactory import com.willfp.eco.core.factory.RunnableFactory
import com.willfp.eco.core.scheduling.RunnableTask import com.willfp.eco.core.scheduling.RunnableTask
import com.willfp.eco.internal.scheduling.EcoRunnableTask import com.willfp.eco.internal.scheduling.EcoRunnableTask
import java.util.function.Consumer import java.util.function.Consumer
class EcoRunnableFactory(plugin: EcoPlugin) : PluginDependent<EcoPlugin>(plugin), RunnableFactory { class EcoRunnableFactory(private val plugin: EcoPlugin) : RunnableFactory {
override fun create(consumer: Consumer<RunnableTask>): RunnableTask { override fun create(consumer: Consumer<RunnableTask>): RunnableTask {
return object : EcoRunnableTask(plugin) { return object : EcoRunnableTask(plugin) {
override fun run() { override fun run() {

View File

@@ -1,6 +1,7 @@
package com.willfp.eco.internal.fast package com.willfp.eco.internal.fast
import com.willfp.eco.core.fast.FastItemStack import com.willfp.eco.core.fast.FastItemStack
import org.bukkit.inventory.ItemFlag
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
abstract class EcoFastItemStack<T: Any>( abstract class EcoFastItemStack<T: Any>(
@@ -10,4 +11,8 @@ abstract class EcoFastItemStack<T: Any>(
override fun unwrap(): ItemStack { override fun unwrap(): ItemStack {
return bukkit return bukkit
} }
fun getBitModifier(hideFlag: ItemFlag): Int {
return 1 shl hideFlag.ordinal
}
} }

View File

@@ -6,11 +6,14 @@ 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.StringUtils import com.willfp.eco.util.StringUtils
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.NamespacedKey
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryCloseEvent import org.bukkit.event.inventory.InventoryCloseEvent
import org.bukkit.inventory.Inventory import org.bukkit.inventory.Inventory
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataType
@Suppress("UNCHECKED_CAST")
class EcoMenu( class EcoMenu(
private val rows: Int, private val rows: Int,
val slots: List<MutableList<EcoSlot>>, val slots: List<MutableList<EcoSlot>>,
@@ -60,6 +63,7 @@ class EcoMenu(
fun handleClose(event: InventoryCloseEvent) { fun handleClose(event: InventoryCloseEvent) {
onClose.handle(event, this) onClose.handle(event, this)
MenuHandler.unregisterMenu(event.inventory)
} }
override fun getRows(): Int { override fun getRows(): Int {
@@ -72,7 +76,31 @@ class EcoMenu(
override fun getCaptiveItems(player: Player): MutableList<ItemStack> { override fun getCaptiveItems(player: Player): MutableList<ItemStack> {
val inventory = MenuHandler.getExtendedInventory(player.openInventory.topInventory) val inventory = MenuHandler.getExtendedInventory(player.openInventory.topInventory)
inventory ?: return ArrayList() inventory ?: return mutableListOf()
return inventory.captiveItems return inventory.captiveItems
} }
override fun <T : Any, Z : Any> writeData(
player: Player,
key: NamespacedKey,
type: PersistentDataType<T, Z>,
value: Z
) {
val inventory = MenuHandler.getExtendedInventory(player.openInventory.topInventory)
inventory ?: return
inventory.data[key] = value
inventory.refresh(player)
}
override fun <T : Any, Z : Any> readData(player: Player, key: NamespacedKey, type: PersistentDataType<T, Z>): T? {
val inventory = MenuHandler.getExtendedInventory(player.openInventory.topInventory)
inventory ?: return null
return inventory.data[key] as T?
}
override fun getKeys(player: Player): MutableSet<NamespacedKey> {
val inventory = MenuHandler.getExtendedInventory(player.openInventory.topInventory)
inventory ?: return HashSet()
return inventory.data.keys
}
} }

View File

@@ -61,10 +61,10 @@ class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
} }
} }
val finalSlots: MutableList<MutableList<EcoSlot>> = ArrayList() val finalSlots = mutableListOf<MutableList<EcoSlot>>()
for (row in tempSlots) { for (row in tempSlots) {
val tempRow = ArrayList<EcoSlot>() val tempRow = mutableListOf<EcoSlot>()
for (slot in row) { for (slot in row) {
var tempSlot = slot var tempSlot = slot
if (tempSlot is FillerSlot) { if (tempSlot is FillerSlot) {

View File

@@ -3,6 +3,7 @@ package com.willfp.eco.internal.gui.menu
import com.willfp.eco.internal.gui.slot.EcoCaptivatorSlot import com.willfp.eco.internal.gui.slot.EcoCaptivatorSlot
import com.willfp.eco.util.MenuUtils import com.willfp.eco.util.MenuUtils
import com.willfp.eco.util.StringUtils import com.willfp.eco.util.StringUtils
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
@@ -11,7 +12,8 @@ class ExtendedInventory(
val inventory: Inventory, val inventory: Inventory,
private val menu: EcoMenu private val menu: EcoMenu
) { ) {
val captiveItems: MutableList<ItemStack> = ArrayList() val captiveItems = mutableListOf<ItemStack>()
val data = mutableMapOf<NamespacedKey, Any>()
fun refresh(player: Player) { fun refresh(player: Player) {
captiveItems.clear() captiveItems.clear()

View File

@@ -4,28 +4,28 @@ import com.willfp.eco.core.gui.menu.Menu
import org.bukkit.inventory.Inventory import org.bukkit.inventory.Inventory
object MenuHandler { object MenuHandler {
private val MENUS: MutableMap<ExtendedInventory, EcoMenu> = HashMap() private val menus = mutableMapOf<ExtendedInventory, EcoMenu>()
private val INVS: MutableMap<Inventory, ExtendedInventory> = HashMap() private val inventories = mutableMapOf<Inventory, ExtendedInventory>()
fun registerMenu( fun registerMenu(
inventory: Inventory, inventory: Inventory,
menu: EcoMenu menu: EcoMenu
) { ) {
val extendedInventory = ExtendedInventory(inventory, menu) val extendedInventory = ExtendedInventory(inventory, menu)
INVS[inventory] = extendedInventory inventories[inventory] = extendedInventory
MENUS[extendedInventory] = menu menus[extendedInventory] = menu
} }
fun unregisterMenu(inventory: Inventory) { fun unregisterMenu(inventory: Inventory) {
MENUS.remove(INVS[inventory]) menus.remove(inventories[inventory])
INVS.remove(inventory) inventories.remove(inventory)
} }
fun getMenu(inventory: Inventory): Menu? { fun getMenu(inventory: Inventory): Menu? {
return MENUS[INVS[inventory]] return menus[inventories[inventory]]
} }
fun getExtendedInventory(inventory: Inventory): ExtendedInventory? { fun getExtendedInventory(inventory: Inventory): ExtendedInventory? {
return INVS[inventory] return inventories[inventory]
} }
} }

View File

@@ -15,7 +15,7 @@ class EcoCaptivatorSlot : EcoSlot(
{ _, _, _ -> } { _, _, _ -> }
) { ) {
companion object { companion object {
val plugin = Eco.getHandler().ecoPlugin!! val plugin = Eco.getHandler().ecoPlugin
val allowMovingItem = SlotHandler { event, _, _ -> val allowMovingItem = SlotHandler { event, _, _ ->
event.isCancelled = false event.isCancelled = false

View File

@@ -8,7 +8,7 @@ import com.willfp.eco.core.gui.slot.functional.SlotProvider
class EcoSlotBuilder(private val provider: SlotProvider) : SlotBuilder { class EcoSlotBuilder(private val provider: SlotProvider) : SlotBuilder {
private var captive = false private var captive = false
var modifier: SlotModifier = SlotModifier{ player, menu, _ -> provider.provide(player, menu)} private var modifier: SlotModifier = SlotModifier{ player, menu, _ -> provider.provide(player, menu)}
private var onLeftClick = private var onLeftClick =
SlotHandler { _, _, _ -> run { } } SlotHandler { _, _, _ -> run { } }

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.internal.proxy; package com.willfp.eco.internal.proxy
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginDependent
import com.willfp.eco.core.proxy.AbstractProxy import com.willfp.eco.core.proxy.AbstractProxy
import com.willfp.eco.core.proxy.ProxyConstants import com.willfp.eco.core.proxy.ProxyConstants
import com.willfp.eco.core.proxy.ProxyFactory import com.willfp.eco.core.proxy.ProxyFactory
@@ -11,8 +10,8 @@ import java.net.URLClassLoader
import java.util.* import java.util.*
class EcoProxyFactory( class EcoProxyFactory(
plugin: EcoPlugin private val plugin: EcoPlugin
) : PluginDependent<EcoPlugin>(plugin), ProxyFactory { ) : ProxyFactory {
private val proxyClassLoader: ClassLoader = plugin::class.java.classLoader private val proxyClassLoader: ClassLoader = plugin::class.java.classLoader
private val cache: MutableMap<Class<out AbstractProxy>, AbstractProxy> = IdentityHashMap() private val cache: MutableMap<Class<out AbstractProxy>, AbstractProxy> = IdentityHashMap()

View File

@@ -1,12 +1,11 @@
package com.willfp.eco.internal.scheduling package com.willfp.eco.internal.scheduling
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginDependent
import com.willfp.eco.core.scheduling.Scheduler import com.willfp.eco.core.scheduling.Scheduler
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.scheduler.BukkitTask import org.bukkit.scheduler.BukkitTask
class EcoScheduler(plugin: EcoPlugin) : PluginDependent<EcoPlugin>(plugin), Scheduler { class EcoScheduler(private val plugin: EcoPlugin) : Scheduler {
override fun runLater( override fun runLater(
runnable: Runnable, runnable: Runnable,
ticksLater: Long ticksLater: Long

View File

@@ -1,32 +1,43 @@
package com.willfp.eco.proxy.v1_16_R3 package com.willfp.eco.proxy.v1_16_R3
import com.mojang.authlib.GameProfile import com.mojang.authlib.GameProfile
import com.mojang.authlib.properties.Property import com.mojang.authlib.properties.Property
import org.bukkit.inventory.meta.SkullMeta
import com.willfp.eco.proxy.SkullProxy import com.willfp.eco.proxy.SkullProxy
import org.bukkit.inventory.meta.SkullMeta
import java.lang.reflect.Field
import java.lang.reflect.Method import java.lang.reflect.Method
import java.util.* import java.util.*
class Skull : SkullProxy { class Skull : SkullProxy {
private lateinit var setProfile: Method private lateinit var setProfile: Method
private lateinit var profile: Field
override fun setSkullTexture( override fun setSkullTexture(
meta: SkullMeta, meta: SkullMeta,
base64: String base64: String
) { ) {
try { if (!this::setProfile.isInitialized) {
if (!this::setProfile.isInitialized) { setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java) setProfile.isAccessible = true
setProfile.isAccessible = true
}
val uuid = UUID(
base64.substring(base64.length - 20).hashCode().toLong(),
base64.substring(base64.length - 10).hashCode().toLong()
)
val profile = GameProfile(uuid, "eco")
profile.properties.put("textures", Property("textures", base64))
setProfile.invoke(meta, profile)
} catch (e: ReflectiveOperationException) {
e.printStackTrace()
} }
val uuid = UUID(
base64.substring(base64.length - 20).hashCode().toLong(),
base64.substring(base64.length - 10).hashCode().toLong()
)
val profile = GameProfile(uuid, "eco")
profile.properties.put("textures", Property("textures", base64))
setProfile.invoke(meta, profile)
}
override fun getSkullTexture(
meta: SkullMeta
): String? {
if (!this::profile.isInitialized) {
profile = meta.javaClass.getDeclaredField("profile")
profile.isAccessible = true
}
val profile = profile[meta] as GameProfile?
val property = profile?.properties?.get("textures") as Property?
return property?.value
} }
} }

View File

@@ -1,9 +1,9 @@
package com.willfp.eco.proxy.v1_16_R3 package com.willfp.eco.proxy.v1_16_R3
import com.willfp.eco.core.display.Display import com.willfp.eco.core.display.Display
import com.willfp.eco.proxy.VillagerTradeProxy
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftMerchantRecipe import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftMerchantRecipe
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.MerchantRecipe import org.bukkit.inventory.MerchantRecipe
import com.willfp.eco.proxy.VillagerTradeProxy
import java.lang.reflect.Field import java.lang.reflect.Field
class VillagerTrade : VillagerTradeProxy { class VillagerTrade : VillagerTradeProxy {
@@ -15,7 +15,7 @@ class VillagerTrade : VillagerTradeProxy {
): MerchantRecipe { ): MerchantRecipe {
val oldRecipe = recipe as CraftMerchantRecipe val oldRecipe = recipe as CraftMerchantRecipe
val newRecipe = CraftMerchantRecipe( val newRecipe = CraftMerchantRecipe(
Display.display(recipe.getResult().clone()), Display.display(recipe.getResult().clone(), player),
recipe.getUses(), recipe.getUses(),
recipe.getMaxUses(), recipe.getMaxUses(),
recipe.hasExperienceReward(), recipe.hasExperienceReward(),

View File

@@ -8,7 +8,7 @@ import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack
import org.bukkit.craftbukkit.v1_16_R3.util.CraftMagicNumbers import org.bukkit.craftbukkit.v1_16_R3.util.CraftMagicNumbers
import org.bukkit.craftbukkit.v1_16_R3.util.CraftNamespacedKey import org.bukkit.craftbukkit.v1_16_R3.util.CraftNamespacedKey
import org.bukkit.enchantments.Enchantment import org.bukkit.enchantments.Enchantment
import java.lang.reflect.Field import org.bukkit.inventory.ItemFlag
import kotlin.experimental.and import kotlin.experimental.and
class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>( class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>(
@@ -96,12 +96,59 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
} }
} }
override fun addItemFlags(vararg hideFlags: ItemFlag) {
for (flag in hideFlags) {
this.flagBits = this.flagBits or getBitModifier(flag)
}
apply()
}
override fun removeItemFlags(vararg hideFlags: ItemFlag) {
for (flag in hideFlags) {
this.flagBits = this.flagBits and getBitModifier(flag)
}
apply()
}
override fun getItemFlags(): MutableSet<ItemFlag> {
val flags = mutableSetOf<ItemFlag>()
var flagArr: Array<ItemFlag>
val size = ItemFlag.values().also { flagArr = it }.size
for (i in 0 until size) {
val flag = flagArr[i]
if (this.hasItemFlag(flag)) {
flags.add(flag)
}
}
return flags
}
override fun hasItemFlag(flag: ItemFlag): Boolean {
val bitModifier = getBitModifier(flag)
return this.flagBits and bitModifier == bitModifier
}
private var flagBits: Int
get() =
if (handle.hasTag() && handle.tag!!.hasKeyOfType(
"HideFlags",
99
)
) handle.tag!!.getInt("HideFlags") else 0
set(value) =
handle.orCreateTag.setInt("HideFlags", value)
override fun getRepairCost(): Int { override fun getRepairCost(): Int {
return handle.repairCost; return handle.repairCost
} }
override fun setRepairCost(cost: Int) { override fun setRepairCost(cost: Int) {
handle.repairCost = cost; handle.repairCost = cost
} }
private fun apply() { private fun apply() {
@@ -109,28 +156,4 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta
} }
} }
companion object {
private var field: Field
init {
lateinit var temp: Field
try {
val handleField = CraftItemStack::class.java.getDeclaredField("handle")
handleField.isAccessible = true
temp = handleField
} catch (e: ReflectiveOperationException) {
e.printStackTrace()
}
field = temp
}
fun getNMSStack(itemStack: org.bukkit.inventory.ItemStack): ItemStack? {
return if (itemStack !is CraftItemStack) {
CraftItemStack.asNMSCopy(itemStack)
} else {
field.get(itemStack) as ItemStack
}
}
}
} }

View File

@@ -4,30 +4,40 @@ import com.mojang.authlib.GameProfile
import com.mojang.authlib.properties.Property import com.mojang.authlib.properties.Property
import com.willfp.eco.proxy.SkullProxy import com.willfp.eco.proxy.SkullProxy
import org.bukkit.inventory.meta.SkullMeta import org.bukkit.inventory.meta.SkullMeta
import java.lang.reflect.Field
import java.lang.reflect.Method import java.lang.reflect.Method
import java.util.* import java.util.*
class Skull : SkullProxy { class Skull : SkullProxy {
private lateinit var setProfile: Method private lateinit var setProfile: Method
private lateinit var profile: Field
override fun setSkullTexture( override fun setSkullTexture(
meta: SkullMeta, meta: SkullMeta,
base64: String base64: String
) { ) {
try { if (!this::setProfile.isInitialized) {
if (!this::setProfile.isInitialized) { setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java)
setProfile = meta.javaClass.getDeclaredMethod("setProfile", GameProfile::class.java) setProfile.isAccessible = true
setProfile.isAccessible = true
}
val uuid = UUID(
base64.substring(base64.length - 20).hashCode().toLong(),
base64.substring(base64.length - 10).hashCode().toLong()
)
val profile = GameProfile(uuid, "eco")
profile.properties.put("textures", Property("textures", base64))
setProfile.invoke(meta, profile)
} catch (e: ReflectiveOperationException) {
e.printStackTrace()
} }
val uuid = UUID(
base64.substring(base64.length - 20).hashCode().toLong(),
base64.substring(base64.length - 10).hashCode().toLong()
)
val profile = GameProfile(uuid, "eco")
profile.properties.put("textures", Property("textures", base64))
setProfile.invoke(meta, profile)
}
override fun getSkullTexture(
meta: SkullMeta
): String? {
if (!this::profile.isInitialized) {
profile = meta.javaClass.getDeclaredField("profile")
profile.isAccessible = true
}
val profile = profile[meta] as GameProfile?
val property = profile?.properties?.get("textures") as Property?
return property?.value
} }
} }

View File

@@ -1,15 +1,15 @@
package com.willfp.eco.proxy.v1_17_R1 package com.willfp.eco.proxy.v1_17_R1
import com.willfp.eco.core.display.Display import com.willfp.eco.core.display.Display
import com.willfp.eco.proxy.VillagerTradeProxy
import net.minecraft.world.item.trading.MerchantOffer import net.minecraft.world.item.trading.MerchantOffer
import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftMerchantRecipe import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftMerchantRecipe
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.MerchantRecipe import org.bukkit.inventory.MerchantRecipe
import com.willfp.eco.proxy.VillagerTradeProxy
import java.lang.reflect.Field import java.lang.reflect.Field
class VillagerTrade : VillagerTradeProxy { class VillagerTrade : VillagerTradeProxy {
private var handle: Field private val handle: Field = CraftMerchantRecipe::class.java.getDeclaredField("handle")
override fun displayTrade( override fun displayTrade(
recipe: MerchantRecipe, recipe: MerchantRecipe,
@@ -17,7 +17,7 @@ class VillagerTrade : VillagerTradeProxy {
): MerchantRecipe { ): MerchantRecipe {
val oldRecipe = recipe as CraftMerchantRecipe val oldRecipe = recipe as CraftMerchantRecipe
val newRecipe = CraftMerchantRecipe( val newRecipe = CraftMerchantRecipe(
Display.display(recipe.getResult().clone()), Display.display(recipe.getResult().clone(), player),
recipe.getUses(), recipe.getUses(),
recipe.getMaxUses(), recipe.getMaxUses(),
recipe.hasExperienceReward(), recipe.hasExperienceReward(),
@@ -32,21 +32,10 @@ class VillagerTrade : VillagerTradeProxy {
} }
private fun getHandle(recipe: CraftMerchantRecipe): MerchantOffer { private fun getHandle(recipe: CraftMerchantRecipe): MerchantOffer {
try { return handle[recipe] as MerchantOffer
return handle[recipe] as MerchantOffer
} catch (e: IllegalAccessException) {
e.printStackTrace()
}
throw IllegalArgumentException("Not CMR")
} }
init { init {
try { handle.isAccessible = true
handle = CraftMerchantRecipe::class.java.getDeclaredField("handle")
handle.isAccessible = true
} catch (e: NoSuchFieldException) {
e.printStackTrace()
throw RuntimeException("Error!")
}
} }
} }

View File

@@ -13,6 +13,7 @@ import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack
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.enchantments.Enchantment import org.bukkit.enchantments.Enchantment
import org.bukkit.inventory.ItemFlag
import kotlin.experimental.and import kotlin.experimental.and
class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>( class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemStack<ItemStack>(
@@ -115,12 +116,59 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
} }
} }
override fun addItemFlags(vararg hideFlags: ItemFlag) {
for (flag in hideFlags) {
this.flagBits = this.flagBits or getBitModifier(flag)
}
apply()
}
override fun removeItemFlags(vararg hideFlags: ItemFlag) {
for (flag in hideFlags) {
this.flagBits = this.flagBits and getBitModifier(flag)
}
apply()
}
override fun getItemFlags(): MutableSet<ItemFlag> {
val flags = mutableSetOf<ItemFlag>()
var flagArr: Array<ItemFlag>
val size = ItemFlag.values().also { flagArr = it }.size
for (i in 0 until size) {
val flag = flagArr[i]
if (this.hasItemFlag(flag)) {
flags.add(flag)
}
}
return flags
}
override fun hasItemFlag(flag: ItemFlag): Boolean {
val bitModifier = getBitModifier(flag)
return this.flagBits and bitModifier == bitModifier
}
private var flagBits: Int
get() =
if (handle.hasTag() && handle.tag!!.contains(
"HideFlags",
99
)
) handle.tag!!.getInt("HideFlags") else 0
set(value) =
handle.orCreateTag.putInt("HideFlags", value)
override fun getRepairCost(): Int { override fun getRepairCost(): Int {
return handle.baseRepairCost; return handle.baseRepairCost
} }
override fun setRepairCost(cost: Int) { override fun setRepairCost(cost: Int) {
handle.setRepairCost(cost); handle.setRepairCost(cost)
} }
private fun apply() { private fun apply() {

View File

@@ -20,8 +20,9 @@ dependencies {
compileOnly 'com.gmail.nossr50.mcMMO:mcMMO:2.1.157' compileOnly 'com.gmail.nossr50.mcMMO:mcMMO:2.1.157'
compileOnly 'me.clip:placeholderapi:2.10.9' compileOnly 'me.clip:placeholderapi:2.10.9'
compileOnly 'com.willfp:Oraxen:e1f4003d8d' compileOnly 'com.willfp:Oraxen:e1f4003d8d'
compileOnly 'com.github.brcdev-minecraft:shopgui-api:2.2.0'
compileOnly 'com.github.LoneDev6:API-ItemsAdder:2.3.8' compileOnly 'com.github.LoneDev6:API-ItemsAdder:2.4.7'
compileOnly 'me.arcaniax:HeadDatabase-API:1.2.0'
// CombatLogX V10 + NewbieHelper Expansion // 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'

View File

@@ -6,6 +6,7 @@ import com.willfp.eco.core.items.Items;
import com.willfp.eco.core.items.TestableItem; import com.willfp.eco.core.items.TestableItem;
import com.willfp.eco.core.recipe.Recipes; import com.willfp.eco.core.recipe.Recipes;
import com.willfp.eco.core.recipe.parts.MaterialTestableItem; import com.willfp.eco.core.recipe.parts.MaterialTestableItem;
import com.willfp.eco.core.recipe.parts.ModifiedTestableItem;
import com.willfp.eco.core.recipe.parts.TestableStack; import com.willfp.eco.core.recipe.parts.TestableStack;
import com.willfp.eco.core.recipe.recipes.CraftingRecipe; import com.willfp.eco.core.recipe.recipes.CraftingRecipe;
import com.willfp.eco.core.recipe.recipes.ShapedCraftingRecipe; import com.willfp.eco.core.recipe.recipes.ShapedCraftingRecipe;
@@ -97,16 +98,65 @@ public class ShapedRecipeListener extends PluginDependent<EcoPlugin> implements
return; return;
} }
this.getPlugin().getScheduler().runLater(() -> { boolean isStackedRecipe = false;
for (int i = 0; i < 9; i++) {
ItemStack inMatrix = event.getInventory().getMatrix()[i];
TestableItem inRecipe = matched.getParts().get(i);
if (inRecipe instanceof TestableStack testableStack) { int upperBound = 64;
for (int i = 0; i < 9; i++) {
ItemStack inMatrix = event.getInventory().getMatrix()[i];
TestableItem inRecipe = matched.getParts().get(i);
if (inRecipe instanceof TestableStack testableStack) {
int max = Math.floorDiv(inMatrix.getAmount(), testableStack.getAmount());
if (max < upperBound) {
upperBound = max;
}
isStackedRecipe = true;
} else if (inMatrix != null) {
int max = inMatrix.getAmount();
if (max < upperBound) {
upperBound = max;
}
}
}
if (!isStackedRecipe) {
return;
}
int toGivePerRecipe = event.getRecipe().getResult().getAmount();
int maxStackSize = event.getRecipe().getResult().getMaxStackSize();
while (toGivePerRecipe * upperBound > maxStackSize) {
upperBound--;
}
for (int i = 0; i < 9; i++) {
ItemStack inMatrix = event.getInventory().getMatrix()[i];
TestableItem inRecipe = matched.getParts().get(i);
if (inRecipe instanceof TestableStack testableStack) {
if (event.isShiftClick()) {
int amount = inMatrix.getAmount() + 1;
for (int j = 0; j < upperBound; j++) {
amount -= testableStack.getAmount();
}
inMatrix.setAmount(amount);
} else {
inMatrix.setAmount(inMatrix.getAmount() - (testableStack.getAmount() - 1)); inMatrix.setAmount(inMatrix.getAmount() - (testableStack.getAmount() - 1));
} }
} }
}, 1); }
int finalUpperBound = upperBound;
if (event.isShiftClick()) {
ItemStack result = event.getInventory().getResult();
if (result == null) {
return;
}
result.setAmount(result.getAmount() * finalUpperBound);
event.getInventory().setResult(result);
}
} }
@EventHandler @EventHandler
@@ -130,6 +180,22 @@ public class ShapedRecipeListener extends PluginDependent<EcoPlugin> implements
return; return;
} }
} }
if (part instanceof ModifiedTestableItem modified) {
if (modified.getHandle() instanceof MaterialTestableItem) {
if (Items.isCustomItem(itemStack)) {
event.getInventory().setResult(new ItemStack(Material.AIR));
return;
}
}
}
if (part instanceof TestableStack modified) {
if (modified.getHandle() instanceof MaterialTestableItem) {
if (Items.isCustomItem(itemStack)) {
event.getInventory().setResult(new ItemStack(Material.AIR));
return;
}
}
}
} }
} }
@@ -156,6 +222,24 @@ public class ShapedRecipeListener extends PluginDependent<EcoPlugin> implements
return; return;
} }
} }
if (part instanceof ModifiedTestableItem modified) {
if (modified.getHandle() instanceof MaterialTestableItem) {
if (Items.isCustomItem(itemStack)) {
event.getInventory().setResult(new ItemStack(Material.AIR));
event.setResult(Event.Result.DENY);
event.setCancelled(true);
return;
}
}
}
if (part instanceof TestableStack modified) {
if (modified.getHandle() instanceof MaterialTestableItem) {
if (Items.isCustomItem(itemStack)) {
event.getInventory().setResult(new ItemStack(Material.AIR));
return;
}
}
}
} }
} }

View File

@@ -31,9 +31,9 @@ import com.willfp.eco.internal.integrations.PlaceholderIntegrationPAPI
import com.willfp.eco.internal.logging.EcoLogger import com.willfp.eco.internal.logging.EcoLogger
import com.willfp.eco.internal.proxy.EcoProxyFactory import com.willfp.eco.internal.proxy.EcoProxyFactory
import com.willfp.eco.internal.scheduling.EcoScheduler import com.willfp.eco.internal.scheduling.EcoScheduler
import com.willfp.eco.proxy.FastItemStackFactoryProxy
import com.willfp.eco.spigot.integrations.bstats.MetricHandler import com.willfp.eco.spigot.integrations.bstats.MetricHandler
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import com.willfp.eco.proxy.FastItemStackFactoryProxy
import java.util.logging.Logger import java.util.logging.Logger
@Suppress("UNUSED") @Suppress("UNUSED")
@@ -105,7 +105,7 @@ class EcoHandler : EcoSpigotPlugin(), Handler {
} }
override fun getLoadedPlugins(): List<String> { override fun getLoadedPlugins(): List<String> {
return ArrayList(Plugins.LOADED_ECO_PLUGINS.keys) return Plugins.LOADED_ECO_PLUGINS.keys.toMutableList()
} }
override fun getPluginByName(name: String): EcoPlugin? { override fun getPluginByName(name: String): EcoPlugin? {

View File

@@ -8,6 +8,10 @@ import com.willfp.eco.core.integrations.anticheat.AnticheatManager
import com.willfp.eco.core.integrations.antigrief.AntigriefManager import com.willfp.eco.core.integrations.antigrief.AntigriefManager
import com.willfp.eco.core.integrations.customitems.CustomItemsManager import com.willfp.eco.core.integrations.customitems.CustomItemsManager
import com.willfp.eco.core.integrations.mcmmo.McmmoManager import com.willfp.eco.core.integrations.mcmmo.McmmoManager
import com.willfp.eco.core.integrations.shop.ShopManager
import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.args.EnchantmentArgParser
import com.willfp.eco.core.items.args.TextureArgParser
import com.willfp.eco.internal.drops.DropManager import com.willfp.eco.internal.drops.DropManager
import com.willfp.eco.proxy.BlockBreakProxy import com.willfp.eco.proxy.BlockBreakProxy
import com.willfp.eco.proxy.FastItemStackFactoryProxy import com.willfp.eco.proxy.FastItemStackFactoryProxy
@@ -19,8 +23,11 @@ import com.willfp.eco.spigot.eventlisteners.*
import com.willfp.eco.spigot.gui.GUIListener import com.willfp.eco.spigot.gui.GUIListener
import com.willfp.eco.spigot.integrations.anticheat.* import com.willfp.eco.spigot.integrations.anticheat.*
import com.willfp.eco.spigot.integrations.antigrief.* import com.willfp.eco.spigot.integrations.antigrief.*
import com.willfp.eco.spigot.integrations.customitems.CustomItemsHeadDatabase
import com.willfp.eco.spigot.integrations.customitems.CustomItemsItemsAdder
import com.willfp.eco.spigot.integrations.customitems.CustomItemsOraxen import com.willfp.eco.spigot.integrations.customitems.CustomItemsOraxen
import com.willfp.eco.spigot.integrations.mcmmo.McmmoIntegrationImpl import com.willfp.eco.spigot.integrations.mcmmo.McmmoIntegrationImpl
import com.willfp.eco.spigot.integrations.shop.ShopShopGuiPlus
import com.willfp.eco.spigot.recipes.ShapedRecipeListener import com.willfp.eco.spigot.recipes.ShapedRecipeListener
import com.willfp.eco.util.BlockUtils import com.willfp.eco.util.BlockUtils
import com.willfp.eco.util.SkullUtils import com.willfp.eco.util.SkullUtils
@@ -41,8 +48,14 @@ abstract class EcoSpigotPlugin : EcoPlugin(
init { init {
Display.setFinalizeKey(namespacedKeyFactory.create("finalized")) Display.setFinalizeKey(namespacedKeyFactory.create("finalized"))
Items.registerArgParser(EnchantmentArgParser())
Items.registerArgParser(TextureArgParser())
val skullProxy = getProxy(SkullProxy::class.java) val skullProxy = getProxy(SkullProxy::class.java)
SkullUtils.initialize { meta: SkullMeta, base64: String -> skullProxy.setSkullTexture(meta, base64) } SkullUtils.initialize(
{ meta: SkullMeta, base64: String -> skullProxy.setSkullTexture(meta, base64) },
{ meta: SkullMeta -> skullProxy.getSkullTexture(meta) }
)
val blockBreakProxy = getProxy(BlockBreakProxy::class.java) val blockBreakProxy = getProxy(BlockBreakProxy::class.java)
BlockUtils.initialize { player: Player, block: Block -> blockBreakProxy.breakBlock(player, block) } BlockUtils.initialize { player: Player, block: Block -> blockBreakProxy.breakBlock(player, block) }
@@ -109,6 +122,11 @@ abstract class EcoSpigotPlugin : EcoPlugin(
// Custom Items // Custom Items
IntegrationLoader("Oraxen") { CustomItemsManager.register(CustomItemsOraxen()) }, IntegrationLoader("Oraxen") { CustomItemsManager.register(CustomItemsOraxen()) },
IntegrationLoader("ItemsAdder") { CustomItemsManager.register(CustomItemsItemsAdder(this)) },
IntegrationLoader("HeadDatabase") { CustomItemsManager.register(CustomItemsHeadDatabase()) },
// Shop
IntegrationLoader("ShopGuiPlus") { ShopManager.register(ShopShopGuiPlus()) },
// Misc // Misc
IntegrationLoader("mcMMO") { McmmoManager.register(McmmoIntegrationImpl()) } IntegrationLoader("mcMMO") { McmmoManager.register(McmmoIntegrationImpl()) }
@@ -116,19 +134,14 @@ abstract class EcoSpigotPlugin : EcoPlugin(
} }
override fun loadPacketAdapters(): List<AbstractPacketAdapter> { override fun loadPacketAdapters(): List<AbstractPacketAdapter> {
val adapters = mutableListOf( return listOf(
PacketAutoRecipe(this), PacketAutoRecipe(this),
PacketChat(this), PacketChat(this),
PacketSetCreativeSlot(this), PacketSetCreativeSlot(this),
PacketSetSlot(this), PacketSetSlot(this),
PacketWindowItems(this) PacketWindowItems(this),
PacketOpenWindowMerchant(this)
) )
if (!configYml.getBool("disable-display-on-villagers")) {
adapters.add(PacketOpenWindowMerchant(this))
}
return adapters
} }
override fun loadListeners(): List<Listener> { override fun loadListeners(): List<Listener> {

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.spigot.arrows package com.willfp.eco.spigot.arrows
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginDependent
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.entity.Arrow import org.bukkit.entity.Arrow
import org.bukkit.entity.LivingEntity import org.bukkit.entity.LivingEntity
@@ -11,8 +10,8 @@ import org.bukkit.event.Listener
import org.bukkit.event.entity.ProjectileLaunchEvent import org.bukkit.event.entity.ProjectileLaunchEvent
class ArrowDataListener( class ArrowDataListener(
plugin: EcoPlugin private val plugin: EcoPlugin
) : PluginDependent<EcoPlugin>(plugin), Listener { ) : Listener {
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
fun onLaunch(event:ProjectileLaunchEvent) { fun onLaunch(event:ProjectileLaunchEvent) {

View File

@@ -19,7 +19,7 @@ class PacketOpenWindowMerchant(plugin: EcoPlugin) :
player: Player, player: Player,
event: PacketEvent event: PacketEvent
) { ) {
val recipes: MutableList<MerchantRecipe> = ArrayList() val recipes = mutableListOf<MerchantRecipe>()
/* /*

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.spigot.eventlisteners package com.willfp.eco.spigot.eventlisteners
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginDependent
import org.bukkit.entity.LivingEntity import org.bukkit.entity.LivingEntity
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.EventPriority import org.bukkit.event.EventPriority
@@ -11,8 +10,8 @@ import org.bukkit.event.entity.EntityDeathEvent
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
class EntityDeathByEntityListeners( class EntityDeathByEntityListeners(
plugin: EcoPlugin private val plugin: EcoPlugin
) : PluginDependent<EcoPlugin>(plugin), Listener { ) : Listener {
private val events = HashSet<EntityDeathByEntityBuilder>() private val events = HashSet<EntityDeathByEntityBuilder>()
@EventHandler(priority = EventPriority.HIGH) @EventHandler(priority = EventPriority.HIGH)

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.spigot.gui package com.willfp.eco.spigot.gui
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginDependent
import com.willfp.eco.core.drops.DropQueue import com.willfp.eco.core.drops.DropQueue
import com.willfp.eco.internal.gui.menu.EcoMenu import com.willfp.eco.internal.gui.menu.EcoMenu
import com.willfp.eco.internal.gui.menu.MenuHandler import com.willfp.eco.internal.gui.menu.MenuHandler
@@ -16,7 +15,7 @@ import org.bukkit.event.inventory.ClickType
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.InventoryCloseEvent import org.bukkit.event.inventory.InventoryCloseEvent
class GUIListener(plugin: EcoPlugin) : PluginDependent<EcoPlugin>(plugin), Listener { class GUIListener(private val plugin: EcoPlugin) : Listener {
@EventHandler @EventHandler
fun handleSlotClick(event: InventoryClickEvent) { fun handleSlotClick(event: InventoryClickEvent) {
val player = event.whoClicked val player = event.whoClicked
@@ -39,7 +38,7 @@ class GUIListener(plugin: EcoPlugin) : PluginDependent<EcoPlugin>(plugin), Liste
val extendedInventory = MenuHandler.getExtendedInventory(event.clickedInventory!!) ?: return val extendedInventory = MenuHandler.getExtendedInventory(event.clickedInventory!!) ?: return
plugin.scheduler.run{ extendedInventory.refresh(player) } plugin.scheduler.run { extendedInventory.refresh(player) }
} }
@EventHandler @EventHandler
@@ -52,7 +51,7 @@ class GUIListener(plugin: EcoPlugin) : PluginDependent<EcoPlugin>(plugin), Liste
MenuHandler.getMenu(player.openInventory.topInventory) ?: return MenuHandler.getMenu(player.openInventory.topInventory) ?: return
MenuHandler.getExtendedInventory(player.openInventory.topInventory) ?: return MenuHandler.getExtendedInventory(player.openInventory.topInventory) ?: return
plugin.scheduler.run{ MenuHandler.getExtendedInventory(player.openInventory.topInventory)?.refresh(player) } plugin.scheduler.run { MenuHandler.getExtendedInventory(player.openInventory.topInventory)?.refresh(player) }
} }
@EventHandler @EventHandler

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.spigot.integrations.antigrief package com.willfp.eco.spigot.integrations.antigrief
import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.PluginDependent
import com.willfp.eco.core.integrations.antigrief.AntigriefWrapper import com.willfp.eco.core.integrations.antigrief.AntigriefWrapper
import me.angeschossen.lands.api.integration.LandsIntegration import me.angeschossen.lands.api.integration.LandsIntegration
import me.angeschossen.lands.api.role.enums.RoleSetting import me.angeschossen.lands.api.role.enums.RoleSetting
@@ -10,8 +9,8 @@ import org.bukkit.block.Block
import org.bukkit.entity.LivingEntity import org.bukkit.entity.LivingEntity
import org.bukkit.entity.Player import org.bukkit.entity.Player
class AntigriefLands(plugin: EcoPlugin) : PluginDependent<EcoPlugin?>(plugin), AntigriefWrapper { class AntigriefLands(private val plugin: EcoPlugin) : AntigriefWrapper {
private val landsIntegration = LandsIntegration(this.plugin!!) private val landsIntegration = LandsIntegration(this.plugin)
override fun canBreakBlock( override fun canBreakBlock(
player: Player, player: Player,
block: Block block: Block

View File

@@ -0,0 +1,34 @@
package com.willfp.eco.spigot.integrations.customitems
import com.willfp.eco.core.integrations.customitems.CustomItemsWrapper
import com.willfp.eco.core.items.CustomItem
import com.willfp.eco.util.NamespacedKeyUtils
import me.arcaniax.hdb.api.HeadDatabaseAPI
import me.arcaniax.hdb.enums.CategoryEnum
import java.util.function.Predicate
class CustomItemsHeadDatabase : CustomItemsWrapper {
private val api = HeadDatabaseAPI()
override fun registerAllItems() {
for (categoryEnum in CategoryEnum.values()) {
for (head in api.getHeads(categoryEnum).toList()) {
val stack = head.head
val id = head.id
val key = NamespacedKeyUtils.create("headdb", id.lowercase());
CustomItem(
key,
Predicate { test ->
val headId = api.getItemID(test) ?: return@Predicate false
headId.equals(id, ignoreCase = true)
},
stack
).register()
}
}
}
override fun getPluginName(): String {
return "HeadDatabase"
}
}

View File

@@ -0,0 +1,36 @@
package com.willfp.eco.spigot.integrations.customitems
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.integrations.customitems.CustomItemsWrapper
import com.willfp.eco.core.items.CustomItem
import com.willfp.eco.util.NamespacedKeyUtils
import dev.lone.itemsadder.api.CustomStack
import dev.lone.itemsadder.api.ItemsAdder
import org.bukkit.inventory.ItemStack
import java.util.function.Predicate
class CustomItemsItemsAdder(
private val plugin: EcoPlugin
) : CustomItemsWrapper {
override fun registerAllItems() {
plugin.scheduler.runLater({
for (item in ItemsAdder.getAllItems()) {
val stack = item.itemStack
val id = item.id
val key = NamespacedKeyUtils.create("itemsadder", id.lowercase())
CustomItem(
key,
Predicate { test: ItemStack ->
val customStack = CustomStack.byItemStack(test) ?: return@Predicate false
customStack.id.equals(id, ignoreCase = true)
},
stack
).register()
}
}, 2)
}
override fun getPluginName(): String {
return "ItemsAdder"
}
}

View File

@@ -23,4 +23,8 @@ class CustomItemsOraxen : CustomItemsWrapper {
).register() ).register()
} }
} }
override fun getPluginName(): String {
return "Oraxen"
}
} }

View File

@@ -0,0 +1,31 @@
package com.willfp.eco.spigot.integrations.shop
import com.willfp.eco.core.integrations.shop.ShopWrapper
import com.willfp.eco.core.items.Items
import net.brcdev.shopgui.ShopGuiPlusApi
import net.brcdev.shopgui.provider.item.ItemProvider
import org.bukkit.configuration.ConfigurationSection
import org.bukkit.inventory.ItemStack
class ShopShopGuiPlus : ShopWrapper {
override fun registerEcoProvider() {
ShopGuiPlusApi.registerItemProvider(EcoShopGuiPlusProvider())
}
class EcoShopGuiPlusProvider : ItemProvider("eco") {
override fun isValidItem(itemStack: ItemStack?): Boolean {
itemStack ?: return false
return Items.isCustomItem(itemStack)
}
override fun loadItem(configurationSection: ConfigurationSection): ItemStack? {
val id = configurationSection.getString("eco")
return if (id == null) null else Items.lookup(id)?.item
}
override fun compare(itemStack1: ItemStack, itemStack2: ItemStack): Boolean {
return Items.getCustomItem(itemStack1)?.key == Items.getCustomItem(itemStack2)?.key
}
}
}

View File

@@ -5,7 +5,6 @@
# Options to fix villager bugs left behind from old (buggy) versions. # Options to fix villager bugs left behind from old (buggy) versions.
disable-display-on-villagers: false
villager-display-fix: false villager-display-fix: false
# DropQueue by default uses a faster collated queue system where all drops # DropQueue by default uses a faster collated queue system where all drops

View File

@@ -4,6 +4,7 @@ main: com.willfp.eco.spigot.EcoHandler
api-version: 1.16 api-version: 1.16
authors: [Auxilor] authors: [Auxilor]
website: willfp.com website: willfp.com
load: STARTUP
depend: depend:
- ProtocolLib - ProtocolLib
softdepend: softdepend:
@@ -20,6 +21,10 @@ softdepend:
- PlaceholderAPI - PlaceholderAPI
- mcMMO - mcMMO
- CombatLogX - CombatLogX
- ShopGuiPlus
- ItemsAdder
- Oraxen
- HeadDatabase
libraries: libraries:
- org.reflections:reflections:0.9.12 - org.reflections:reflections:0.9.12
- org.apache.maven:maven-artifact:3.0.3 - org.apache.maven:maven-artifact:3.0.3

View File

@@ -8,4 +8,8 @@ interface SkullProxy : AbstractProxy {
meta: SkullMeta, meta: SkullMeta,
base64: String base64: String
) )
fun getSkullTexture(
meta: SkullMeta
): String?
} }

View File

@@ -1,2 +1,2 @@
version = 6.4.2 version = 6.7.1
plugin-name = eco plugin-name = eco