Compare commits

..

44 Commits
6.3.2 ... 6.6.0

Author SHA1 Message Date
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
Auxilor
5eecef83ee Merge remote-tracking branch 'origin/master' 2021-08-20 17:35:34 +01:00
Auxilor
82a02f3738 Updated to 6.4.2 2021-08-20 17:35:30 +01:00
Auxilor
804142799b Fixed NPE 2021-08-20 17:35:20 +01:00
Will FP
e1de9b9ab3 Update README.md 2021-08-18 15:15:50 +01:00
Will FP
cc56343041 Update README.md 2021-08-18 15:15:36 +01:00
Auxilor
69d28e8bc2 Updated to 6.4.1 2021-08-15 14:34:40 +01:00
Auxilor
6878a74724 Fixed NPE 2021-08-15 14:34:19 +01:00
Auxilor
ebc76bba76 Changed display 2021-08-12 16:30:15 +01:00
Auxilor
378218b7da Minor display change 2021-08-12 16:13:59 +01:00
Auxilor
e053514b94 Added mask materials option 2021-08-12 13:56:29 +01:00
Auxilor
341a30e6da Removed unused var 2021-08-12 13:40:19 +01:00
Auxilor
70eb6d4420 Removed logging 2021-08-12 13:40:01 +01:00
Auxilor
aa368909ae Finished GUI 2021-08-12 13:38:14 +01:00
Auxilor
606a54bcf8 Your brain gets smart but your head gets dumb 2021-08-12 13:17:52 +01:00
Auxilor
7f8fb3d87b Didn't make sense not to live for fun 2021-08-12 13:00:31 +01:00
Auxilor
e97d454ff6 Fed to the rules and I hit the ground running 2021-08-12 01:51:47 +01:00
Auxilor
109b9aa3f3 And the changes start coming and they don't stop coming 2021-08-12 01:46:32 +01:00
Auxilor
4a90385b27 The gui changes don't stop 2021-08-12 01:38:20 +01:00
Auxilor
0edd50832c Even more GUI 2021-08-12 01:05:47 +01:00
Auxilor
46415268b7 More GUI 2021-08-12 00:24:35 +01:00
Auxilor
b652dbad2d Added captivator slots 2021-08-11 23:56:09 +01:00
Auxilor
50550d077a Added ? syntax to recipes 2021-08-11 23:07:25 +01:00
Auxilor
60c3b58a33 Updated to 6.3.3 2021-08-10 18:19:46 +01:00
Auxilor
7216d0b09f Fixed component serialization 2021-08-10 18:18:09 +01:00
Auxilor
97eeea8d48 Updated to 6.3.2 2021-08-10 16:18:49 +01:00
Auxilor
82061ee6a3 Added get/set repair cost methods to FastItemStack 2021-08-09 17:30:09 +01:00
66 changed files with 1392 additions and 390 deletions

View File

@@ -158,8 +158,12 @@ 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/discount/Auxilor?afmc=Auxilor" target="_blank">
<img src="https://i.imgur.com/uFDpBAC.png" alt="supps banner">
</a>
<a href="https://dedimc.promo/Auxilor" target="_blank"> <a href="https://dedimc.promo/Auxilor" target="_blank">
<img src="https://i.imgur.com/zdDLhFA.png" alt="dedimc banner"> <img src="https://i.imgur.com/zdDLhFA.png" alt="dedimc banner">
</a> </a>
<br> <br>
</h1> </h1>

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

@@ -71,10 +71,6 @@ public class Display {
*/ */
public ItemStack display(@NotNull final ItemStack itemStack, public ItemStack display(@NotNull final ItemStack itemStack,
@Nullable final Player player) { @Nullable final Player player) {
if (!itemStack.hasItemMeta()) {
return itemStack; // return early if there's no customization of the item
}
Map<String, Object[]> pluginVarArgs = new HashMap<>(); Map<String, Object[]> pluginVarArgs = new HashMap<>();
for (DisplayPriority priority : DisplayPriority.values()) { for (DisplayPriority priority : DisplayPriority.values()) {
@@ -139,10 +135,6 @@ public class Display {
unfinalize(itemStack); unfinalize(itemStack);
} }
if (!itemStack.hasItemMeta()) {
return itemStack;
}
ItemMeta meta = itemStack.getItemMeta(); ItemMeta meta = itemStack.getItemMeta();
if (meta == null) { if (meta == null) {

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.
@@ -47,6 +49,51 @@ public interface FastItemStack {
*/ */
List<String> getLore(); List<String> getLore();
/**
* Set the rework penalty.
*
* @param cost The rework penalty to set.
*/
void setRepairCost(int cost);
/**
* Get the rework penalty.
* .
*
* @return The rework penalty found on the item.
*/
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,10 @@ package com.willfp.eco.core.gui;
import com.willfp.eco.core.gui.menu.MenuBuilder; import com.willfp.eco.core.gui.menu.MenuBuilder;
import com.willfp.eco.core.gui.slot.SlotBuilder; import com.willfp.eco.core.gui.slot.SlotBuilder;
import org.bukkit.entity.Player; import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.function.Function;
/** /**
* Internal component used by {@link com.willfp.eco.core.gui.menu.Menu#builder(int)} * Internal component used by {@link com.willfp.eco.core.gui.menu.Menu#builder(int)}
* and {@link com.willfp.eco.core.gui.slot.Slot#builder(ItemStack)}. * and {@link com.willfp.eco.core.gui.slot.Slot#builder(ItemStack)}.
@@ -19,7 +17,7 @@ public interface GUIFactory {
* @param provider The provider. * @param provider The provider.
* @return The builder. * @return The builder.
*/ */
SlotBuilder createSlotBuilder(@NotNull Function<Player, ItemStack> provider); SlotBuilder createSlotBuilder(@NotNull SlotProvider provider);
/** /**
* Create menu builder. * Create menu builder.

View File

@@ -0,0 +1,19 @@
package com.willfp.eco.core.gui.menu;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.jetbrains.annotations.NotNull;
/**
* Interface to run on menu close.
*/
@FunctionalInterface
public interface CloseHandler {
/**
* Performs this operation on the given arguments.
*
* @param event The close event.
* @param menu The menu.
*/
void handle(@NotNull InventoryCloseEvent event,
@NotNull Menu menu);
}

View File

@@ -2,9 +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.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Set;
/** /**
* GUI version of {@link Inventory}. * GUI version of {@link Inventory}.
@@ -44,6 +51,51 @@ public interface Menu {
*/ */
Inventory open(@NotNull Player player); Inventory open(@NotNull Player player);
/**
* Get captive items.
*
* @param player The player.
* @return The items.
*/
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

@@ -31,6 +31,14 @@ public interface MenuBuilder {
int column, int column,
@NotNull Slot slot); @NotNull Slot slot);
/**
* Run function to modify the builder.
*
* @param modifier The modifier.
* @return The builder.
*/
MenuBuilder modfiy(@NotNull Consumer<MenuBuilder> modifier);
/** /**
* Set the menu mask. * Set the menu mask.
* *
@@ -45,7 +53,18 @@ public interface MenuBuilder {
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
MenuBuilder onClose(@NotNull Consumer<InventoryCloseEvent> action); default MenuBuilder onClose(@NotNull Consumer<InventoryCloseEvent> action) {
onClose((event, menu) -> action.accept(event));
return this;
}
/**
* Set the menu close handler.
*
* @param action The handler.
* @return The builder.
*/
MenuBuilder onClose(@NotNull CloseHandler action);
/** /**
* Build the menu. * Build the menu.

View File

@@ -7,6 +7,7 @@ import org.bukkit.Material;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@@ -39,35 +40,46 @@ public class FillerMask {
*/ */
public FillerMask(@NotNull final Material material, public FillerMask(@NotNull final Material material,
@NotNull final String... pattern) { @NotNull final String... pattern) {
if (material == Material.AIR) { this(new MaskMaterials(material), pattern);
throw new IllegalArgumentException("Material cannot be air!"); }
/**
* Create a new filler mask.
*
* @param materials The mask materials.
* @param pattern The pattern.
*/
public FillerMask(@NotNull final MaskMaterials materials,
@NotNull final String... pattern) {
if (Arrays.stream(materials.materials()).anyMatch(material -> material == Material.AIR)) {
throw new IllegalArgumentException("Materials cannot be air!");
} }
mask = ListUtils.create2DList(6, 9); mask = ListUtils.create2DList(6, 9);
ItemStack itemStack = new ItemStackBuilder(material) for (int i = 0; i < materials.materials().length; i++) {
.setDisplayName("&r") ItemStack itemStack = new ItemStackBuilder(materials.materials()[i])
.build(); .setDisplayName("&r")
.build();
int row = 0; int row = 0;
for (String patternRow : pattern) { for (String patternRow : pattern) {
int column = 0; int column = 0;
if (patternRow.length() != 9) { if (patternRow.length() != 9) {
throw new IllegalArgumentException("Invalid amount of columns in pattern!"); throw new IllegalArgumentException("Invalid amount of columns in pattern!");
}
for (char c : patternRow.toCharArray()) {
if (c == '0') {
mask.get(row).set(column, null);
} else if (c == '1') {
mask.get(row).set(column, new FillerSlot(itemStack));
} else {
throw new IllegalArgumentException("Invalid character in pattern! (Must only be 0 and 1)");
} }
for (char c : patternRow.toCharArray()) {
if (c == '0') {
mask.get(row).set(column, null);
} else if (c == Character.forDigit(i + 1, 10)) {
mask.get(row).set(column, new FillerSlot(itemStack));
}
column++; column++;
}
row++;
} }
row++;
} }
} }
} }

View File

@@ -30,4 +30,9 @@ public class FillerSlot implements Slot {
public ItemStack getItemStack(@NotNull final Player player) { public ItemStack getItemStack(@NotNull final Player player) {
return itemStack; return itemStack;
} }
@Override
public boolean isCaptive() {
return false;
}
} }

View File

@@ -0,0 +1,14 @@
package com.willfp.eco.core.gui.slot;
import org.bukkit.Material;
import org.jetbrains.annotations.NotNull;
/**
* Mask materials store a set of materials which can be accessed by
* a filler mask.
*
* @param materials The materials.
*/
public record MaskMaterials(@NotNull Material... materials) {
}

View File

@@ -1,6 +1,8 @@
package com.willfp.eco.core.gui.slot; package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.Eco; import com.willfp.eco.core.Eco;
import com.willfp.eco.core.gui.slot.functional.SlotProvider;
import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -19,6 +21,22 @@ public interface Slot {
*/ */
ItemStack getItemStack(@NotNull Player player); ItemStack getItemStack(@NotNull Player player);
/**
* If the slot is captive. (Can items be placed in it).
*
* @return If captive.
*/
boolean isCaptive();
/**
* Create a builder for an ItemStack.
*
* @return The builder.
*/
static SlotBuilder builder() {
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> new ItemStack(Material.AIR));
}
/** /**
* Create a builder for an ItemStack. * Create a builder for an ItemStack.
* *
@@ -26,7 +44,7 @@ public interface Slot {
* @return The builder. * @return The builder.
*/ */
static SlotBuilder builder(@NotNull final ItemStack itemStack) { static SlotBuilder builder(@NotNull final ItemStack itemStack) {
return Eco.getHandler().getGUIFactory().createSlotBuilder(player -> itemStack); return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> itemStack);
} }
/** /**
@@ -36,6 +54,16 @@ public interface Slot {
* @return The builder. * @return The builder.
*/ */
static SlotBuilder builder(@NotNull final Function<Player, ItemStack> provider) { static SlotBuilder builder(@NotNull final Function<Player, ItemStack> provider) {
return Eco.getHandler().getGUIFactory().createSlotBuilder((player, menu) -> provider.apply(player));
}
/**
* Create a builder for a player-specific ItemStack.
*
* @param provider The provider.
* @return The builder.
*/
static SlotBuilder builder(@NotNull final SlotProvider provider) {
return Eco.getHandler().getGUIFactory().createSlotBuilder(provider); return Eco.getHandler().getGUIFactory().createSlotBuilder(provider);
} }
} }

View File

@@ -1,5 +1,7 @@
package com.willfp.eco.core.gui.slot; package com.willfp.eco.core.gui.slot;
import com.willfp.eco.core.gui.slot.functional.SlotHandler;
import com.willfp.eco.core.gui.slot.functional.SlotModifier;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -15,7 +17,17 @@ public interface SlotBuilder {
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onLeftClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action); default SlotBuilder onLeftClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action) {
return onLeftClick((event, slot, menu) -> action.accept(event, slot));
}
/**
* Set click handler.
*
* @param handler The handler.
* @return The builder.
*/
SlotBuilder onLeftClick(@NotNull SlotHandler handler);
/** /**
* Set click handler. * Set click handler.
@@ -23,7 +35,17 @@ public interface SlotBuilder {
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onRightClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action); default SlotBuilder onRightClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action) {
return onRightClick((event, slot, menu) -> action.accept(event, slot));
}
/**
* Set click handler.
*
* @param handler The handler.
* @return The builder.
*/
SlotBuilder onRightClick(@NotNull SlotHandler handler);
/** /**
* Set click handler. * Set click handler.
@@ -31,7 +53,17 @@ public interface SlotBuilder {
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onShiftLeftClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action); default SlotBuilder onShiftLeftClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action) {
return onShiftLeftClick((event, slot, menu) -> action.accept(event, slot));
}
/**
* Set click handler.
*
* @param handler The handler.
* @return The builder.
*/
SlotBuilder onShiftLeftClick(@NotNull SlotHandler handler);
/** /**
* Set click handler. * Set click handler.
@@ -39,7 +71,17 @@ public interface SlotBuilder {
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onShiftRightClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action); default SlotBuilder onShiftRightClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action) {
return onShiftRightClick((event, slot, menu) -> action.accept(event, slot));
}
/**
* Set click handler.
*
* @param handler The handler.
* @return The builder.
*/
SlotBuilder onShiftRightClick(@NotNull SlotHandler handler);
/** /**
* Set click handler. * Set click handler.
@@ -47,7 +89,32 @@ public interface SlotBuilder {
* @param action The handler. * @param action The handler.
* @return The builder. * @return The builder.
*/ */
SlotBuilder onMiddleClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action); default SlotBuilder onMiddleClick(@NotNull BiConsumer<InventoryClickEvent, Slot> action) {
return onMiddleClick((event, slot, menu) -> action.accept(event, slot));
}
/**
* Set click handler.
*
* @param handler The handler.
* @return The builder.
*/
SlotBuilder onMiddleClick(@NotNull SlotHandler handler);
/**
* Modify the ItemStack.
*
* @param modifier The modifier.
* @return The builder.
*/
SlotBuilder setModifier(@NotNull SlotModifier modifier);
/**
* Set slot to be a captive slot.
*
* @return The builder.
*/
SlotBuilder setCaptive();
/** /**
* Build the slot. * Build the slot.

View File

@@ -0,0 +1,23 @@
package com.willfp.eco.core.gui.slot.functional;
import com.willfp.eco.core.gui.menu.Menu;
import com.willfp.eco.core.gui.slot.Slot;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull;
/**
* Interface to run on slot click.
*/
@FunctionalInterface
public interface SlotHandler {
/**
* Performs this operation on the given arguments.
*
* @param event The click event.
* @param slot The slot
* @param menu The menu.
*/
void handle(@NotNull InventoryClickEvent event,
@NotNull Slot slot,
@NotNull Menu menu);
}

View File

@@ -0,0 +1,23 @@
package com.willfp.eco.core.gui.slot.functional;
import com.willfp.eco.core.gui.menu.Menu;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Interface to run on slot modify.
*/
@FunctionalInterface
public interface SlotModifier {
/**
* Performs this operation on the given arguments.
*
* @param player The player.
* @param menu The menu.
* @param previous The previous ItemStack.
*/
void modify(@NotNull Player player,
@NotNull Menu menu,
@NotNull ItemStack previous);
}

View File

@@ -0,0 +1,22 @@
package com.willfp.eco.core.gui.slot.functional;
import com.willfp.eco.core.gui.menu.Menu;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* Interface to run on slot display.
*/
@FunctionalInterface
public interface SlotProvider {
/**
* Performs this operation on the given arguments.
*
* @param player The player.
* @param menu The menu.
* @return The ItemStack.
*/
ItemStack provide(@NotNull Player player,
@NotNull Menu menu);
}

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

@@ -56,7 +56,7 @@ public class PlaceholderManager {
@NotNull final String identifier) { @NotNull final String identifier) {
Optional<PlaceholderEntry> matching = REGISTERED_PLACEHOLDERS.stream().filter(expansion -> expansion.getIdentifier().equalsIgnoreCase(identifier)).findFirst(); Optional<PlaceholderEntry> matching = REGISTERED_PLACEHOLDERS.stream().filter(expansion -> expansion.getIdentifier().equalsIgnoreCase(identifier)).findFirst();
if (matching.isEmpty()) { if (matching.isEmpty()) {
return null; return "";
} }
PlaceholderEntry entry = matching.get(); PlaceholderEntry entry = matching.get();
if (player == null && entry.requiresPlayer()) { if (player == null && entry.requiresPlayer()) {

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,5 @@
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.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;
@@ -12,8 +10,10 @@ import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
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.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@@ -60,6 +60,18 @@ public final class Items {
* @return The found testable item, or an empty item if not found. * @return The found testable item, or an empty item if not found.
*/ */
public TestableItem lookup(@NotNull final String key) { public TestableItem lookup(@NotNull final String key) {
if (key.contains("?")) {
String[] options = key.split("\\?");
for (String option : options) {
TestableItem lookup = lookup(option);
if (!(lookup instanceof EmptyTestableItem)) {
return lookup;
}
}
return new EmptyTestableItem();
}
String[] args = key.split(" "); String[] args = key.split(" ");
if (args.length == 0) { if (args.length == 0) {
return new EmptyTestableItem(); return new EmptyTestableItem();
@@ -117,9 +129,17 @@ public final class Items {
return item; return item;
} }
ItemBuilder builder = new ItemStackBuilder(item.getItem()); ItemStack example = item.getItem();
requiredEnchantments.forEach(builder::addEnchantment);
ItemStack example = builder.build(); if (example.getItemMeta() instanceof EnchantmentStorageMeta storageMeta) {
requiredEnchantments.forEach((enchantment, integer) -> storageMeta.addStoredEnchant(enchantment, integer, true));
example.setItemMeta(storageMeta);
} else {
ItemMeta meta = example.getItemMeta();
assert meta != null;
requiredEnchantments.forEach((enchantment, integer) -> meta.addEnchant(enchantment, integer, true));
example.setItemMeta(meta);
}
return new ModifiedTestableItem( return new ModifiedTestableItem(
item, item,
@@ -132,12 +152,23 @@ public final class Items {
assert meta != null; assert meta != null;
for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) { if (meta instanceof EnchantmentStorageMeta storageMeta) {
if (!meta.hasEnchant(entry.getKey())) { for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
return false; if (!storageMeta.hasStoredEnchant(entry.getKey())) {
return false;
}
if (storageMeta.getStoredEnchantLevel(entry.getKey()) < entry.getValue()) {
return false;
}
} }
if (meta.getEnchantLevel(entry.getKey()) < entry.getValue()) { } else {
return false; for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
if (!meta.hasEnchant(entry.getKey())) {
return false;
}
if (meta.getEnchantLevel(entry.getKey()) < entry.getValue()) {
return false;
}
} }
} }
@@ -162,6 +193,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

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

View File

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

View File

@@ -0,0 +1,22 @@
package com.willfp.eco.util;
import com.willfp.eco.core.tuples.Pair;
import lombok.experimental.UtilityClass;
/**
* Utilities / API methods for menus.
*/
@UtilityClass
public class MenuUtils {
/**
* Convert 0-53 slot to row and column pair.
*
* @param slot The slot.
* @return The pair of row and columns.
*/
public Pair<Integer, Integer> convertSlotToRowColumn(final int slot) {
int row = Math.floorDiv(slot, 9);
int column = slot - row * 9;
return new Pair<>(row + 1, column + 1);
}
}

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;
@@ -48,7 +48,30 @@ public class StringUtils {
.build(); .build();
/** /**
* Format a list of strings - converts Placeholders and Color codes. * Legacy serializer.
*/
private static final LegacyComponentSerializer LEGACY_COMPONENT_SERIALIZER = LegacyComponentSerializer.builder()
.character('\u00a7')
.useUnusualXRepeatedCharacterHexFormat()
.hexColors()
.build();
/**
* Format a list of strings.
* <p>
* Converts color codes and placeholders.
*
* @param list The messages to format.
* @return The message, formatted.
*/
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.
@@ -56,26 +79,61 @@ public class StringUtils {
*/ */
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.
*/
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.
*/
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>
* Converts color codes and placeholders.
* *
* @param list The messages to format. * @param message The message to translate.
* @return The message, formatted. * @return The message, formatted.
* @see StringUtils#format(String, Player)
*/ */
public List<String> formatList(@NotNull final List<String> list) { public String format(@NotNull final String message) {
return formatList(list, null); return format(message, (Player) null);
} }
/** /**
* Format a string - converts Placeholders and Color codes. * Format a string.
* <p>
* Converts color codes and placeholders for a player.
* *
* @param message The message to format. * @param message The message to format.
* @param player The player to translate placeholders with respect to. * @param player The player to translate placeholders with respect to.
@@ -83,23 +141,45 @@ public class StringUtils {
*/ */
public String format(@NotNull final String message, public String format(@NotNull final String message,
@Nullable final Player player) { @Nullable final Player player) {
String processedMessage = message; return format(message, player, FormatOption.WITH_PLACEHOLDERS);
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. * Format a string.
* <p>
* Converts color codes and placeholders if specified.
* *
* @param message The message to translate. * @param message The message to translate.
* @param option The format option.
* @return The message, formatted. * @return The message, formatted.
* @see StringUtils#format(String, Player) * @see StringUtils#format(String, Player)
*/ */
public String format(@NotNull final String message) { public String format(@NotNull final String message,
return format(message, null); @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.
*/
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) {
@@ -246,7 +326,7 @@ public class StringUtils {
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(
LegacyComponentSerializer.legacySection().deserialize(legacy) LEGACY_COMPONENT_SERIALIZER.deserialize(legacy)
) )
); );
} }
@@ -258,8 +338,23 @@ public class StringUtils {
* @return The legacy string. * @return The legacy string.
*/ */
public String jsonToLegacy(@NotNull final String json) { public String jsonToLegacy(@NotNull final String json) {
return LegacyComponentSerializer.legacySection().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

@@ -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,91 +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 {
cache["$path\$FMT"] = StringUtils.formatList(if (has(path)) ArrayList(handle.getStringList(path)) else ArrayList<String>()) val list = if (has(path)) handle.getStringList(path) else mutableListOf<String>()
getStrings(path, true) cache["$path\$FMT"] = StringUtils.formatList(list, option)
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
} }
@@ -257,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,12 +13,12 @@ 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
private var hasTelekinesis = false
override fun addItem(item: ItemStack): InternalDropQueue { override fun addItem(item: ItemStack): InternalDropQueue {
items.add(item) items.add(item)
return this return this
@@ -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

@@ -10,11 +10,14 @@ class EcoFastCollatedDropQueue(player: Player) : EcoDropQueue(player) {
val fetched = COLLATED_MAP[player] val fetched = COLLATED_MAP[player]
if (fetched == null) { if (fetched == null) {
COLLATED_MAP[player] = CollatedDrops(items, loc, xp) COLLATED_MAP[player] = CollatedDrops(items, loc, xp, hasTelekinesis)
} else { } else {
fetched.addDrops(items) fetched.addDrops(items)
fetched.location = loc fetched.location = loc
fetched.addXp(xp) fetched.addXp(xp)
if (this.hasTelekinesis) {
fetched.forceTelekinesis()
}
COLLATED_MAP[player] = fetched COLLATED_MAP[player] = fetched
} }
@@ -23,8 +26,10 @@ class EcoFastCollatedDropQueue(player: Player) : EcoDropQueue(player) {
class CollatedDrops( class CollatedDrops(
val drops: MutableList<ItemStack>, val drops: MutableList<ItemStack>,
var location: Location, var location: Location,
var xp: Int var xp: Int,
var telekinetic: Boolean
) { ) {
fun addDrops(toAdd: List<ItemStack>): CollatedDrops { fun addDrops(toAdd: List<ItemStack>): CollatedDrops {
drops.addAll(toAdd) drops.addAll(toAdd)
return this return this
@@ -34,6 +39,10 @@ class EcoFastCollatedDropQueue(player: Player) : EcoDropQueue(player) {
this.xp += xp this.xp += xp
return this return this
} }
fun forceTelekinesis() {
telekinetic = true
}
} }
companion object { companion object {

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 constructor(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

@@ -3,14 +3,12 @@ package com.willfp.eco.internal.gui
import com.willfp.eco.core.gui.GUIFactory import com.willfp.eco.core.gui.GUIFactory
import com.willfp.eco.core.gui.menu.MenuBuilder import com.willfp.eco.core.gui.menu.MenuBuilder
import com.willfp.eco.core.gui.slot.SlotBuilder import com.willfp.eco.core.gui.slot.SlotBuilder
import com.willfp.eco.core.gui.slot.functional.SlotProvider
import com.willfp.eco.internal.gui.menu.EcoMenuBuilder import com.willfp.eco.internal.gui.menu.EcoMenuBuilder
import com.willfp.eco.internal.gui.slot.EcoSlotBuilder import com.willfp.eco.internal.gui.slot.EcoSlotBuilder
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
import java.util.function.Function
class EcoGUIFactory : GUIFactory { class EcoGUIFactory : GUIFactory {
override fun createSlotBuilder(provider: Function<Player, ItemStack>): SlotBuilder { override fun createSlotBuilder(provider: SlotProvider): SlotBuilder {
return EcoSlotBuilder(provider) return EcoSlotBuilder(provider)
} }

View File

@@ -1,23 +1,25 @@
package com.willfp.eco.internal.gui.menu package com.willfp.eco.internal.gui.menu
import com.willfp.eco.core.gui.menu.CloseHandler
import com.willfp.eco.core.gui.menu.Menu import com.willfp.eco.core.gui.menu.Menu
import com.willfp.eco.core.gui.slot.FillerSlot
import com.willfp.eco.core.gui.slot.Slot import com.willfp.eco.core.gui.slot.Slot
import com.willfp.eco.internal.gui.slot.EcoFillerSlot 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 java.util.function.Consumer 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,
private val slots: List<MutableList<Slot>>, val slots: List<MutableList<EcoSlot>>,
private val title: String, private val title: String,
private val onClose: Consumer<InventoryCloseEvent> private val onClose: CloseHandler
): Menu { ): Menu {
override fun getSlot(row: Int, column: Int): Slot { override fun getSlot(row: Int, column: Int): Slot {
if (row < 1 || row > this.rows) { if (row < 1 || row > this.rows) {
throw IllegalArgumentException("Invalid row number!") throw IllegalArgumentException("Invalid row number!")
@@ -27,14 +29,7 @@ class EcoMenu(
throw IllegalArgumentException("Invalid column number!") throw IllegalArgumentException("Invalid column number!")
} }
val slot = slots[row - 1][column - 1] return slots[row - 1][column - 1]
if (slot is FillerSlot) {
slots[row - 1][column - 1] = EcoFillerSlot(slot.itemStack)
return getSlot(row, column)
}
return slot
} }
override fun open(player: Player): Inventory { override fun open(player: Player): Inventory {
@@ -46,7 +41,7 @@ class EcoMenu(
if (i == rows * 9) { if (i == rows * 9) {
break break
} }
val slotItem = item.getItemStack(player) val slotItem = item.getItemStack(player, this)
val meta = slotItem.itemMeta val meta = slotItem.itemMeta
if (meta != null) { if (meta != null) {
val lore = meta.lore val lore = meta.lore
@@ -67,7 +62,7 @@ class EcoMenu(
} }
fun handleClose(event: InventoryCloseEvent) { fun handleClose(event: InventoryCloseEvent) {
onClose.accept(event) onClose.handle(event, this)
} }
override fun getRows(): Int { override fun getRows(): Int {
@@ -77,4 +72,34 @@ class EcoMenu(
override fun getTitle(): String { override fun getTitle(): String {
return title return title
} }
override fun getCaptiveItems(player: Player): MutableList<ItemStack> {
val inventory = MenuHandler.getExtendedInventory(player.openInventory.topInventory)
inventory ?: return mutableListOf()
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

@@ -1,22 +1,24 @@
package com.willfp.eco.internal.gui.menu package com.willfp.eco.internal.gui.menu
import com.willfp.eco.core.gui.menu.CloseHandler
import com.willfp.eco.core.gui.menu.Menu import com.willfp.eco.core.gui.menu.Menu
import com.willfp.eco.core.gui.menu.MenuBuilder import com.willfp.eco.core.gui.menu.MenuBuilder
import com.willfp.eco.core.gui.slot.FillerMask import com.willfp.eco.core.gui.slot.FillerMask
import com.willfp.eco.core.gui.slot.FillerSlot
import com.willfp.eco.core.gui.slot.Slot import com.willfp.eco.core.gui.slot.Slot
import com.willfp.eco.internal.gui.slot.EcoFillerSlot import com.willfp.eco.internal.gui.slot.EcoFillerSlot
import com.willfp.eco.internal.gui.slot.EcoSlot
import com.willfp.eco.util.ListUtils import com.willfp.eco.util.ListUtils
import com.willfp.eco.util.StringUtils import com.willfp.eco.util.StringUtils
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.event.inventory.InventoryCloseEvent
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import java.util.function.Consumer import java.util.function.Consumer
class EcoMenuBuilder(private val rows: Int) : MenuBuilder { class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
private var title = "Menu" private var title = "Menu"
private var maskSlots: List<MutableList<Slot?>> private var maskSlots: List<MutableList<Slot?>>
private val slots: List<MutableList<Slot>> = ListUtils.create2DList(rows, 9) private val slots: List<MutableList<Slot?>> = ListUtils.create2DList(rows, 9)
private var onClose = Consumer { _: InventoryCloseEvent -> } private var onClose = CloseHandler { _, _ -> }
override fun setTitle(title: String): MenuBuilder { override fun setTitle(title: String): MenuBuilder {
this.title = StringUtils.format(title) this.title = StringUtils.format(title)
@@ -34,35 +36,45 @@ class EcoMenuBuilder(private val rows: Int) : MenuBuilder {
return this return this
} }
override fun modfiy(modifier: Consumer<MenuBuilder>): MenuBuilder {
modifier.accept(this)
return this
}
override fun setMask(mask: FillerMask): MenuBuilder { override fun setMask(mask: FillerMask): MenuBuilder {
maskSlots = mask.mask maskSlots = mask.mask
return this return this
} }
override fun onClose(action: Consumer<InventoryCloseEvent>): MenuBuilder { override fun onClose(action: CloseHandler): MenuBuilder {
onClose = action onClose = action
return this return this
} }
override fun build(): Menu { override fun build(): Menu {
val finalSlots: MutableList<MutableList<Slot>> = ArrayList() val tempSlots: MutableList<MutableList<Slot?>> = ArrayList(maskSlots)
for (maskRow in maskSlots) {
val row = ArrayList<Slot>()
for (slot in maskRow) {
row.add(slot ?: EcoFillerSlot(ItemStack(Material.AIR)))
}
finalSlots.add(ArrayList())
finalSlots.add(row)
}
for (i in slots.indices) { for (i in slots.indices) {
for (j in slots[i].indices) { for (j in slots[i].indices) {
val slot = slots[i][j] val slot = slots[i][j] ?: continue
finalSlots[i][j] = slot tempSlots[i][j] = slot
} }
} }
val finalSlots = mutableListOf<MutableList<EcoSlot>>()
for (row in tempSlots) {
val tempRow = mutableListOf<EcoSlot>()
for (slot in row) {
var tempSlot = slot
if (tempSlot is FillerSlot) {
tempSlot = EcoFillerSlot(tempSlot.itemStack)
}
tempRow.add((tempSlot ?: EcoFillerSlot(ItemStack(Material.AIR))) as EcoSlot)
}
finalSlots.add(tempRow)
}
return EcoMenu(rows, finalSlots, title, onClose) return EcoMenu(rows, finalSlots, title, onClose)
} }

View File

@@ -0,0 +1,57 @@
package com.willfp.eco.internal.gui.menu
import com.willfp.eco.internal.gui.slot.EcoCaptivatorSlot
import com.willfp.eco.util.MenuUtils
import com.willfp.eco.util.StringUtils
import org.bukkit.NamespacedKey
import org.bukkit.entity.Player
import org.bukkit.inventory.Inventory
import org.bukkit.inventory.ItemStack
class ExtendedInventory(
val inventory: Inventory,
private val menu: EcoMenu
) {
val captiveItems = mutableListOf<ItemStack>()
val data = mutableMapOf<NamespacedKey, Any>()
fun refresh(player: Player) {
captiveItems.clear()
for (i in 0 until inventory.size) {
val pair = MenuUtils.convertSlotToRowColumn(i)
val row = pair.first!!
val column = pair.second!!
val slot = menu.getSlot(row, column)
if (slot is EcoCaptivatorSlot) {
val defaultItem = slot.getItemStack(player)
val item = inventory.getItem(i) ?: continue
if (item != defaultItem) {
captiveItems.add(item)
}
}
}
var i = 0
for (row in menu.slots) {
for (slot in row) {
if (i == menu.rows * 9) {
break
}
val slotItem = slot.getItemStack(player, menu)
val meta = slotItem.itemMeta
if (meta != null) {
val lore = meta.lore
if (lore != null) {
lore.replaceAll{ s -> StringUtils.format(s, player) }
meta.lore = lore
}
slotItem.itemMeta = meta
}
if (!slot.isCaptive) {
inventory.setItem(i, slotItem)
}
i++
}
}
}
}

View File

@@ -4,20 +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<Inventory, Menu> = HashMap() private val menus = mutableMapOf<ExtendedInventory, EcoMenu>()
private val inventories = mutableMapOf<Inventory, ExtendedInventory>()
fun registerMenu( fun registerMenu(
inventory: Inventory, inventory: Inventory,
menu: Menu menu: EcoMenu
) { ) {
MENUS[inventory] = menu val extendedInventory = ExtendedInventory(inventory, menu)
inventories[inventory] = extendedInventory
menus[extendedInventory] = menu
} }
fun unregisterMenu(inventory: Inventory) { fun unregisterMenu(inventory: Inventory) {
MENUS.remove(inventory) menus.remove(inventories[inventory])
inventories.remove(inventory)
} }
fun getMenu(inventory: Inventory): Menu? { fun getMenu(inventory: Inventory): Menu? {
return MENUS[inventory] return menus[inventories[inventory]]
}
fun getExtendedInventory(inventory: Inventory): ExtendedInventory? {
return inventories[inventory]
} }
} }

View File

@@ -0,0 +1,28 @@
package com.willfp.eco.internal.gui.slot
import com.willfp.eco.core.Eco
import com.willfp.eco.core.gui.slot.functional.SlotHandler
import org.bukkit.Material
import org.bukkit.inventory.ItemStack
class EcoCaptivatorSlot : EcoSlot(
{ _, _ -> ItemStack(Material.AIR) },
allowMovingItem,
allowMovingItem,
allowMovingItem,
allowMovingItem,
allowMovingItem,
{ _, _, _ -> }
) {
companion object {
val plugin = Eco.getHandler().ecoPlugin!!
val allowMovingItem = SlotHandler { event, _, _ ->
event.isCancelled = false
}
}
override fun isCaptive(): Boolean {
return true
}
}

View File

@@ -1,13 +1,13 @@
package com.willfp.eco.internal.gui.slot package com.willfp.eco.internal.gui.slot
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import java.util.function.Function
class EcoFillerSlot(itemStack: ItemStack) : EcoSlot( class EcoFillerSlot(itemStack: ItemStack) : EcoSlot(
Function { itemStack }, { _, _ -> itemStack },
{ _, _ -> }, { _, _, _ -> },
{ _, _ -> }, { _, _, _ -> },
{ _, _ -> }, { _, _, _ -> },
{ _, _ -> }, { _, _, _ -> },
{ _, _ -> } { _, _, _ -> },
{ _, _, _ -> }
) )

View File

@@ -1,34 +1,58 @@
package com.willfp.eco.internal.gui.slot package com.willfp.eco.internal.gui.slot
import com.willfp.eco.core.gui.menu.Menu
import com.willfp.eco.core.gui.slot.Slot import com.willfp.eco.core.gui.slot.Slot
import com.willfp.eco.core.gui.slot.functional.SlotHandler
import com.willfp.eco.core.gui.slot.functional.SlotModifier
import com.willfp.eco.core.gui.slot.functional.SlotProvider
import com.willfp.eco.internal.gui.menu.MenuHandler
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.inventory.ClickType import org.bukkit.event.inventory.ClickType
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import java.util.function.BiConsumer
import java.util.function.Function
open class EcoSlot( open class EcoSlot(
private val provider: Function<Player, ItemStack>, private val provider: SlotProvider,
private val onLeftClick: BiConsumer<InventoryClickEvent, Slot>, private val onLeftClick: SlotHandler,
private val onRightClick: BiConsumer<InventoryClickEvent, Slot>, private val onRightClick: SlotHandler,
private val onShiftLeftClick: BiConsumer<InventoryClickEvent, Slot>, private val onShiftLeftClick: SlotHandler,
private val onShiftRightClick: BiConsumer<InventoryClickEvent, Slot>, private val onShiftRightClick: SlotHandler,
private val onMiddleClick: BiConsumer<InventoryClickEvent, Slot> private val onMiddleClick: SlotHandler,
private val modifier: SlotModifier
) : Slot { ) : Slot {
fun handleInventoryClick(event: InventoryClickEvent) { fun handleInventoryClick(
event: InventoryClickEvent,
menu: Menu
) {
when (event.click) { when (event.click) {
ClickType.LEFT -> this.onLeftClick.accept(event, this) ClickType.LEFT -> this.onLeftClick.handle(event, this, menu)
ClickType.RIGHT -> this.onRightClick.accept(event, this) ClickType.RIGHT -> this.onRightClick.handle(event, this, menu)
ClickType.SHIFT_LEFT -> this.onShiftLeftClick.accept(event, this) ClickType.SHIFT_LEFT -> this.onShiftLeftClick.handle(event, this, menu)
ClickType.SHIFT_RIGHT -> this.onShiftRightClick.accept(event, this) ClickType.SHIFT_RIGHT -> this.onShiftRightClick.handle(event, this, menu)
ClickType.MIDDLE -> this.onMiddleClick.accept(event, this) ClickType.MIDDLE -> this.onMiddleClick.handle(event, this, menu)
else -> { } else -> {
}
} }
} }
override fun getItemStack(player: Player): ItemStack { override fun getItemStack(player: Player): ItemStack {
return provider.apply(player) val menu = MenuHandler.getMenu(player.openInventory.topInventory)!!
val prev = provider.provide(player, menu)
modifier.modify(player, menu, prev)
return prev
}
fun getItemStack(
player: Player,
menu: Menu
): ItemStack {
val prev = provider.provide(player, menu)
modifier.modify(player, menu, prev)
return prev
}
override fun isCaptive(): Boolean {
return false
} }
} }

View File

@@ -2,45 +2,65 @@ package com.willfp.eco.internal.gui.slot
import com.willfp.eco.core.gui.slot.Slot import com.willfp.eco.core.gui.slot.Slot
import com.willfp.eco.core.gui.slot.SlotBuilder import com.willfp.eco.core.gui.slot.SlotBuilder
import org.bukkit.entity.Player import com.willfp.eco.core.gui.slot.functional.SlotHandler
import org.bukkit.event.inventory.InventoryClickEvent import com.willfp.eco.core.gui.slot.functional.SlotModifier
import org.bukkit.inventory.ItemStack import com.willfp.eco.core.gui.slot.functional.SlotProvider
import java.util.function.BiConsumer
import java.util.function.Function
class EcoSlotBuilder(private val provider: Function<Player, ItemStack>) : SlotBuilder { class EcoSlotBuilder(private val provider: SlotProvider) : SlotBuilder {
private var onLeftClick: BiConsumer<InventoryClickEvent, Slot> = BiConsumer { _, _ -> run { } } private var captive = false
private var onRightClick: BiConsumer<InventoryClickEvent, Slot> = BiConsumer { _, _ -> run { } } private var modifier: SlotModifier = SlotModifier{ player, menu, _ -> provider.provide(player, menu)}
private var onShiftLeftClick: BiConsumer<InventoryClickEvent, Slot> = BiConsumer { _, _ -> run { } }
private var onShiftRightClick: BiConsumer<InventoryClickEvent, Slot> = BiConsumer { _, _ -> run { } }
private var onMiddleClick: BiConsumer<InventoryClickEvent, Slot> = BiConsumer { _, _ -> run { } }
override fun onLeftClick(action: BiConsumer<InventoryClickEvent, Slot>): SlotBuilder { private var onLeftClick =
SlotHandler { _, _, _ -> run { } }
private var onRightClick =
SlotHandler { _, _, _ -> run { } }
private var onShiftLeftClick =
SlotHandler { _, _, _ -> run { } }
private var onShiftRightClick =
SlotHandler { _, _, _ -> run { } }
private var onMiddleClick =
SlotHandler { _, _, _ -> run { } }
override fun onLeftClick(action: SlotHandler): SlotBuilder {
onLeftClick = action onLeftClick = action
return this return this
} }
override fun onRightClick(action: BiConsumer<InventoryClickEvent, Slot>): SlotBuilder { override fun onRightClick(action: SlotHandler): SlotBuilder {
onRightClick = action onRightClick = action
return this return this
} }
override fun onShiftLeftClick(action: BiConsumer<InventoryClickEvent, Slot>): SlotBuilder { override fun onShiftLeftClick(action: SlotHandler): SlotBuilder {
onShiftLeftClick = action onShiftLeftClick = action
return this return this
} }
override fun onShiftRightClick(action: BiConsumer<InventoryClickEvent, Slot>): SlotBuilder { override fun onShiftRightClick(action: SlotHandler): SlotBuilder {
onShiftRightClick = action onShiftRightClick = action
return this return this
} }
override fun onMiddleClick(action: BiConsumer<InventoryClickEvent, Slot>): SlotBuilder { override fun onMiddleClick(action: SlotHandler): SlotBuilder {
onMiddleClick = action onMiddleClick = action
return this return this
} }
override fun setCaptive(): SlotBuilder {
captive = true
return this
}
override fun setModifier(modifier: SlotModifier): SlotBuilder {
this.modifier = modifier
return this
}
override fun build(): Slot { override fun build(): Slot {
return EcoSlot(provider, onLeftClick, onRightClick, onShiftLeftClick, onShiftRightClick, onMiddleClick) return if (captive) {
EcoCaptivatorSlot()
} else {
EcoSlot(provider, onLeftClick, onRightClick, onShiftLeftClick, onShiftRightClick, onMiddleClick, modifier)
}
} }
} }

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

@@ -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,33 +96,64 @@ 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 {
return handle.repairCost
}
override fun setRepairCost(cost: Int) {
handle.repairCost = cost
}
private fun apply() { private fun apply() {
if (bukkit !is CraftItemStack) { if (bukkit !is CraftItemStack) {
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

@@ -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,6 +116,61 @@ 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 {
return handle.baseRepairCost
}
override fun setRepairCost(cost: Int) {
handle.setRepairCost(cost)
}
private fun apply() { private fun apply() {
if (bukkit !is CraftItemStack) { if (bukkit !is CraftItemStack) {
bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta bukkit.itemMeta = CraftItemStack.asCraftMirror(handle).itemMeta

View File

@@ -20,6 +20,7 @@ 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.3.8'

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;
@@ -130,6 +131,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 +173,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,7 @@ 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.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
@@ -21,6 +22,7 @@ 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.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
@@ -110,6 +112,9 @@ abstract class EcoSpigotPlugin : EcoPlugin(
// Custom Items // Custom Items
IntegrationLoader("Oraxen") { CustomItemsManager.register(CustomItemsOraxen()) }, IntegrationLoader("Oraxen") { CustomItemsManager.register(CustomItemsOraxen()) },
// Shop
IntegrationLoader("ShopGuiPlus") { ShopManager.register(ShopShopGuiPlus()) },
// Misc // Misc
IntegrationLoader("mcMMO") { McmmoManager.register(McmmoIntegrationImpl()) } IntegrationLoader("mcMMO") { McmmoManager.register(McmmoIntegrationImpl()) }
) )

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

@@ -8,11 +8,17 @@ class CollatedRunnable(plugin: EcoPlugin) {
init { init {
plugin.scheduler.runTimer({ plugin.scheduler.runTimer({
for ((key, value) in EcoFastCollatedDropQueue.COLLATED_MAP) { for ((key, value) in EcoFastCollatedDropQueue.COLLATED_MAP) {
EcoDropQueue(key) val queue = EcoDropQueue(key)
.setLocation(value.location) .setLocation(value.location)
.addItems(value.drops) .addItems(value.drops)
.addXP(value.xp) .addXP(value.xp)
.push()
if (value.telekinetic) {
queue.forceTelekinesis()
}
queue.push()
EcoFastCollatedDropQueue.COLLATED_MAP.remove(key) EcoFastCollatedDropQueue.COLLATED_MAP.remove(key)
} }
EcoFastCollatedDropQueue.COLLATED_MAP.clear() EcoFastCollatedDropQueue.COLLATED_MAP.clear()

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,45 +1,105 @@
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.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
import com.willfp.eco.internal.gui.slot.EcoSlot import com.willfp.eco.internal.gui.slot.EcoSlot
import com.willfp.eco.util.MenuUtils
import org.apache.commons.lang.Validate import org.apache.commons.lang.Validate
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.EventPriority
import org.bukkit.event.Listener import org.bukkit.event.Listener
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) {
if (event.whoClicked !is Player) { val player = event.whoClicked
if (player !is Player) {
return return
} }
if (event.clickedInventory == null) { val menu = MenuHandler.getMenu(event.clickedInventory ?: return) ?: return
return val rowColumn = MenuUtils.convertSlotToRowColumn(event.slot)
} val row = rowColumn.first!!
val menu = MenuHandler.getMenu(event.clickedInventory!!) ?: return val column = rowColumn.second!!
val row = Math.floorDiv(event.slot, 9)
val column = event.slot - row * 9
val slot = menu.getSlot(row, column) val slot = menu.getSlot(row, column)
Validate.isTrue(slot is EcoSlot, "Slot not instance of EcoSlot!") Validate.isTrue(slot is EcoSlot, "Slot not instance of EcoSlot!")
val ecoSlot = menu.getSlot(row, column) as EcoSlot val ecoSlot = menu.getSlot(row, column) as EcoSlot
event.isCancelled = true event.isCancelled = true
ecoSlot.handleInventoryClick(event) ecoSlot.handleInventoryClick(event, menu)
if (event.clickedInventory == null) {
return
}
val extendedInventory = MenuHandler.getExtendedInventory(event.clickedInventory!!) ?: return
plugin.scheduler.run { extendedInventory.refresh(player) }
} }
@EventHandler @EventHandler
fun handleCaptivatorSlots(event: InventoryClickEvent) {
val player = event.whoClicked
if (player !is Player) {
return
}
MenuHandler.getMenu(player.openInventory.topInventory) ?: return
MenuHandler.getExtendedInventory(player.openInventory.topInventory) ?: return
plugin.scheduler.run { MenuHandler.getExtendedInventory(player.openInventory.topInventory)?.refresh(player) }
}
@EventHandler
fun handleShiftClick(event: InventoryClickEvent) {
if (!(event.click == ClickType.SHIFT_RIGHT || event.click == ClickType.SHIFT_LEFT)) {
return
}
val player = event.whoClicked
if (player !is Player) {
return
}
val inv = player.openInventory.topInventory
if (inv == event.clickedInventory) {
return
}
val menu = MenuHandler.getMenu(inv) ?: return
val rowColumn = MenuUtils.convertSlotToRowColumn(inv.firstEmpty())
val row = rowColumn.first!!
val column = rowColumn.second!!
val slot = menu.getSlot(row, column)
if (!slot.isCaptive) {
event.isCancelled = true
}
}
@EventHandler(priority = EventPriority.HIGH)
fun handleClose(event: InventoryCloseEvent) { fun handleClose(event: InventoryCloseEvent) {
if (event.player !is Player) { val player = event.player
if (player !is Player) {
return return
} }
val menu = MenuHandler.getMenu(event.inventory) ?: return val menu = MenuHandler.getMenu(event.inventory) ?: return
Validate.isTrue(menu is EcoMenu, "Menu not instance of EcoMenu!") Validate.isTrue(menu is EcoMenu, "Menu not instance of EcoMenu!")
val ecoMenu = menu as EcoMenu val ecoMenu = menu as EcoMenu
ecoMenu.handleClose(event) ecoMenu.handleClose(event)
DropQueue(player)
.addItems(ecoMenu.getCaptiveItems(player))
.setLocation(player.location)
.forceTelekinesis()
.push()
plugin.scheduler.run { MenuHandler.unregisterMenu(event.inventory) } plugin.scheduler.run { MenuHandler.unregisterMenu(event.inventory) }
} }
} }

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,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

@@ -20,6 +20,7 @@ softdepend:
- PlaceholderAPI - PlaceholderAPI
- mcMMO - mcMMO
- CombatLogX - CombatLogX
- ShopGuiPlus
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

@@ -1,2 +1,2 @@
version = 6.3.1 version = 6.6.0
plugin-name = eco plugin-name = eco