Compare commits

..

20 Commits

Author SHA1 Message Date
Auxilor
d676be15ce Grammar 2021-12-06 13:46:27 +00:00
Auxilor
16848caec1 Fixed grammar errors 2021-12-06 13:08:45 +00:00
Auxilor
ef26fe4629 Removed legacy arg parser method bodies 2021-12-06 13:06:22 +00:00
Auxilor
29fbd785d7 Added ArgParserName 2021-12-06 12:54:28 +00:00
Auxilor
8c73676ee0 Added ArgParserUnbreakable 2021-12-06 12:50:26 +00:00
Auxilor
ebf27d28d9 Updated to 6.15.2 2021-12-06 12:49:10 +00:00
Auxilor
317bc13f65 Moved arg parsers to internals and added ArgParserFlag 2021-12-06 12:49:00 +00:00
Auxilor
b8ec0ee6fc Updated to 6.15.1 2021-12-06 10:14:14 +00:00
Auxilor
307e57c902 Display frame changes with PacketHeldWindowItems 2021-12-06 10:13:29 +00:00
Auxilor
db0d55659f Empty transient config 2021-12-06 10:10:35 +00:00
Auxilor
548529feb3 Javadoc formatting 2021-12-06 10:09:52 +00:00
Auxilor
fb56baf452 Fixed class-cast error 2021-12-06 10:02:24 +00:00
Auxilor
5d18b424d7 Added ColorArgParser 2021-12-04 15:37:29 +00:00
Auxilor
7be9a1bd10 Fixed EcoYamlConfigWrapper cast issues 2021-12-03 20:59:07 +00:00
Auxilor
97c39b56dd Updated to 6.15.0 2021-12-03 20:23:25 +00:00
Auxilor
1e5955f249 Codestyle fixes 2021-12-03 16:21:47 +00:00
Auxilor
bad076bbe9 Added kotlin.code.style = official 2021-12-03 16:18:53 +00:00
Auxilor
e219b2f33c Config additions 2021-12-03 16:13:37 +00:00
Auxilor
2f7603409e Generic variance 2021-12-03 15:58:41 +00:00
Auxilor
28cdb65176 Added Config#getSubsections 2021-12-03 15:49:00 +00:00
24 changed files with 396 additions and 175 deletions

View File

@@ -524,6 +524,25 @@ public interface Config extends Cloneable {
@Nullable
List<Double> getDoublesOrNull(@NotNull String path);
/**
* Get a list of subsections from config.
*
* @param path The key to fetch the value from.
* @return The found value, or a blank {@link java.util.ArrayList} if not found.
*/
@NotNull
List<? extends Config> getSubsections(@NotNull String path);
/**
* Get a list of subsections from config.
*
* @param path The key to fetch the value from.
* @return The found value, or null if not found.
*/
@Nullable
List<? extends Config> getSubsectionsOrNull(@NotNull String path);
/**
* Clone the config.
*

View File

@@ -173,6 +173,16 @@ public abstract class ConfigWrapper<T extends Config> implements Config {
return handle.getDoublesOrNull(path);
}
@Override
public @NotNull List<? extends Config> getSubsections(@NotNull final String path) {
return handle.getSubsections(path);
}
@Override
public @Nullable List<? extends Config> getSubsectionsOrNull(@NotNull final String path) {
return handle.getSubsectionsOrNull(path);
}
@Override
public Config clone() {
return handle.clone();

View File

@@ -14,16 +14,23 @@ import java.io.StringReader;
*/
public class YamlTransientConfig extends YamlConfigWrapper {
/**
* @param config The YamlConfiguration handle.
* @param config The YamlConfiguration handle.
*/
public YamlTransientConfig(@NotNull final YamlConfiguration config) {
super(Eco.getHandler().getConfigFactory().createYamlConfig(config));
}
/**
* @param contents The contents of the config.
* @param contents The contents of the config.
*/
public YamlTransientConfig(@NotNull final String contents) {
super(Eco.getHandler().getConfigFactory().createYamlConfig(YamlConfiguration.loadConfiguration(new StringReader(contents))));
}
/**
* Create a new empty transient config.
*/
public YamlTransientConfig() {
super(Eco.getHandler().getConfigFactory().createYamlConfig(YamlConfiguration.loadConfiguration(new StringReader(""))));
}
}

View File

@@ -84,7 +84,7 @@ public final class Items {
/**
* This is the backbone of the entire eco item system.
* <p>
* You can lookup a TestableItem for any material, custom item,
* You can look up a TestableItem for any material, custom item,
* or item in general, and it will return it with any modifiers
* passed as parameters. This includes stack size (item amount)
* and enchantments that should be present on the item.
@@ -94,8 +94,8 @@ public final class Items {
* <p>
* The advantages of the testable item system are that there is the inbuilt
* {@link TestableItem#matches(ItemStack)} - this allows to check if any item
* is that testable item; which may sound negligible but actually it allows for
* much more power an flexibility. For example, you can have an item with an
* is that testable item; which may sound negligible, but actually it allows for
* much more power and flexibility. For example, you can have an item with an
* extra metadata tag, extra lore lines, different display name - and it
* will still work as long as the test passes. This is very important
* for custom crafting recipes where other plugins may add metadata

View File

@@ -0,0 +1,22 @@
package com.willfp.eco.core.items.args;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
/**
* Parse leather armor colors.
*
* @deprecated Moved to internals.
*/
@Deprecated(forRemoval = true)
public class ColorArgParser implements LookupArgParser {
@Override
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
@NotNull final ItemMeta meta) {
return null;
}
}

View File

@@ -9,49 +9,14 @@ import java.util.function.Predicate;
/**
* Parse custom model data.
*
* @deprecated Moved to internals.
*/
@Deprecated(forRemoval = true)
public class CustomModelDataArgParser implements LookupArgParser {
@Override
public @Nullable Predicate<ItemStack> parseArguments(@NotNull final String[] args,
@NotNull final ItemMeta meta) {
Integer modelData = null;
for (String arg : args) {
String[] argSplit = arg.split(":");
if (!argSplit[0].equalsIgnoreCase("custom-model-data")) {
continue;
}
if (argSplit.length < 2) {
continue;
}
String asString = argSplit[1];
try {
modelData = Integer.parseInt(asString);
} catch (NumberFormatException e) {
modelData = null;
}
}
if (modelData == null) {
return null;
}
meta.setCustomModelData(modelData);
int finalModelData = modelData;
return test -> {
if (!test.hasItemMeta()) {
return false;
}
ItemMeta testMeta = test.getItemMeta();
assert testMeta != null;
return testMeta.getCustomModelData() == finalModelData;
};
return null;
}
}

View File

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

View File

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

View File

@@ -1,7 +1,6 @@
package com.willfp.eco.util;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
@@ -21,8 +20,8 @@ public final class ListUtils {
* @return The list, filled will null objects.
*/
@NotNull
public static <@Nullable T> List<List<T>> create2DList(final int rows,
final int columns) {
public static <T> List<List<T>> create2DList(final int rows,
final int columns) {
List<List<T>> list = new ArrayList<>(rows);
while (list.size() < rows) {
List<T> row = new ArrayList<>(columns);

View File

@@ -5,12 +5,11 @@ import com.willfp.eco.util.StringUtils
import org.bukkit.configuration.ConfigurationSection
import org.bukkit.configuration.file.YamlConfiguration
import java.io.StringReader
import java.util.concurrent.ConcurrentHashMap
@Suppress("UNCHECKED_CAST")
open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
lateinit var handle: T
private val cache = ConcurrentHashMap<String, Any?>()
private val cache = mutableMapOf<String, Any?>()
protected fun init(config: T): Config {
handle = config
@@ -70,9 +69,9 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
override fun getInt(path: String): Int {
return if (cache.containsKey(path)) {
cache[path] as Int
(cache[path] as Number).toInt()
} else {
cache[path] = handle.getInt(path, 0)
cache[path] = handle.getDouble(path, 0.0).toInt()
getInt(path)
}
}
@@ -90,9 +89,9 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
def: Int
): Int {
return if (cache.containsKey(path)) {
cache[path] as Int
(cache[path] as Number).toInt()
} else {
cache[path] = handle.getInt(path, def)
cache[path] = handle.getDouble(path, def.toDouble()).toInt()
getInt(path)
}
}
@@ -262,6 +261,31 @@ open class EcoYamlConfigWrapper<T : ConfigurationSection> : Config {
}
}
override fun getSubsections(path: String): MutableList<out Config> {
return if (cache.containsKey(path)) {
(cache[path] as Collection<Config>).toMutableList()
} else {
val mapList = ArrayList(handle.getMapList(path)) as List<Map<String, Any?>>
val configList = mutableListOf<Config>()
for (map in mapList) {
val temp = YamlConfiguration.loadConfiguration(StringReader(""))
temp.createSection("a", map)
configList.add(EcoYamlConfigSection(temp.getConfigurationSection("a")!!))
}
cache[path] = if (has(path)) configList else emptyList()
getSubsections(path)
}
}
override fun getSubsectionsOrNull(path: String): MutableList<out Config>? {
return if (has(path)) {
getSubsections(path)
} else {
null
}
}
override fun clone(): Config {
return EcoYamlConfigSection(
YamlConfiguration.loadConfiguration(

View File

@@ -0,0 +1,44 @@
package com.willfp.eco.internal.items
import com.willfp.eco.core.items.args.LookupArgParser
import org.bukkit.Color
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import org.bukkit.inventory.meta.LeatherArmorMeta
import java.util.function.Predicate
class ArgParserColor : LookupArgParser {
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
if (meta !is LeatherArmorMeta) {
return null
}
var color: String? = null
for (arg in args) {
val argSplit = arg.split(":")
if (!argSplit[0].equals("color", ignoreCase = true)) {
continue
}
if (argSplit.size < 2) {
continue
}
color = argSplit[1]
}
color ?: return null
meta.setColor(Color.fromRGB(Integer.parseInt(color, 16)))
return Predicate {
val testMeta = it.itemMeta as? LeatherArmorMeta ?: return@Predicate false
color.equals(
Integer.toHexString(testMeta.color.red)
+ Integer.toHexString(testMeta.color.green)
+ Integer.toHexString(testMeta.color.blue),
ignoreCase = true
)
}
}
}

View File

@@ -0,0 +1,33 @@
package com.willfp.eco.internal.items
import com.willfp.eco.core.items.args.LookupArgParser
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate
class ArgParserCustomModelData : LookupArgParser {
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
var modelData: Int? = null
for (arg in args) {
val argSplit = arg.split(":")
if (!argSplit[0].equals("custom-model-data", ignoreCase = true)) {
continue
}
if (argSplit.size < 2) {
continue
}
modelData = argSplit[1].toIntOrNull()
}
modelData ?: return null
meta.setCustomModelData(modelData)
return Predicate {
val testMeta = it.itemMeta ?: return@Predicate false
testMeta.customModelData == modelData
}
}
}

View File

@@ -0,0 +1,51 @@
package com.willfp.eco.internal.items
import com.willfp.eco.core.fast.FastItemStack
import com.willfp.eco.core.items.args.LookupArgParser
import org.bukkit.NamespacedKey
import org.bukkit.enchantments.Enchantment
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.EnchantmentStorageMeta
import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate
class ArgParserEnchantment : LookupArgParser {
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
val enchants = mutableMapOf<Enchantment, Int>()
for (arg in args) {
val argSplit = arg.split(":")
if (argSplit.size < 2) {
continue
}
val enchant = Enchantment.getByKey(NamespacedKey.minecraft(argSplit[0].lowercase()))
val level = argSplit[1].toIntOrNull()
if (enchant != null && level != null) {
enchants[enchant] = level
}
}
for ((enchant, level) in enchants) {
if (meta is EnchantmentStorageMeta) {
meta.addStoredEnchant(enchant, level, true)
} else {
meta.addEnchant(enchant, level, true)
}
}
return Predicate {
val onItem = FastItemStack.wrap(it).getEnchantmentsOnItem(true)
for ((enchant, level) in enchants) {
if ((onItem[enchant] ?: 0) < level) {
return@Predicate false
}
}
true
}
}
}

View File

@@ -0,0 +1,35 @@
package com.willfp.eco.internal.items
import com.willfp.eco.core.items.args.LookupArgParser
import org.bukkit.inventory.ItemFlag
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate
class ArgParserFlag : LookupArgParser {
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
val flags = mutableSetOf<ItemFlag>()
for (arg in args) {
val flag = try {
ItemFlag.valueOf(arg.uppercase())
} catch (e: Exception) {
null
} ?: continue
flags.add(flag)
}
if (flags.isEmpty()) {
return null
}
meta.addItemFlags(*flags.toTypedArray())
return Predicate {
val testMeta = it.itemMeta ?: return@Predicate false
testMeta.itemFlags.containsAll(flags)
}
}
}

View File

@@ -0,0 +1,36 @@
package com.willfp.eco.internal.items
import com.willfp.eco.core.items.args.LookupArgParser
import com.willfp.eco.util.StringUtils
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate
class ArgParserName : LookupArgParser {
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
var name: String? = null
for (arg in args) {
val argSplit = arg.split(":")
if (!argSplit[0].equals("name", ignoreCase = true)) {
continue
}
if (argSplit.size < 2) {
continue
}
name = argSplit[1].replace("_", "")
}
name ?: return null
val formatted = StringUtils.format(name)
meta.setDisplayName(formatted)
return Predicate {
val testMeta = it.itemMeta ?: return@Predicate false
testMeta.displayName == formatted
}
}
}

View File

@@ -0,0 +1,39 @@
package com.willfp.eco.internal.items
import com.willfp.eco.core.items.args.LookupArgParser
import com.willfp.eco.util.SkullUtils
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import org.bukkit.inventory.meta.SkullMeta
import java.util.function.Predicate
class ArgParserTexture : LookupArgParser {
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
if (meta !is SkullMeta) {
return null
}
var texture: String? = null
for (arg in args) {
val argSplit = arg.split(":")
if (!argSplit[0].equals("texture", ignoreCase = true)) {
continue
}
if (argSplit.size < 2) {
continue
}
texture = argSplit[1]
}
texture ?: return null
SkullUtils.setSkullTexture(meta, texture)
return Predicate {
val testMeta = it.itemMeta as? SkullMeta ?: return@Predicate false
texture == SkullUtils.getSkullTexture(testMeta)
}
}
}

View File

@@ -0,0 +1,30 @@
package com.willfp.eco.internal.items
import com.willfp.eco.core.items.args.LookupArgParser
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import java.util.function.Predicate
class ArgParserUnbreakable : LookupArgParser {
override fun parseArguments(args: Array<out String>, meta: ItemMeta): Predicate<ItemStack>? {
var unbreakable = false
for (arg in args) {
if (arg.equals("unbreakable", true)) {
unbreakable = true
}
}
if (!unbreakable) {
return null
}
meta.isUnbreakable = true
return Predicate {
val testMeta = it.itemMeta ?: return@Predicate false
testMeta.isUnbreakable
}
}
}

View File

@@ -15,6 +15,6 @@ class RequirementPlaceholderGreaterThan : Requirement() {
val placeholder = args[0]
val equals = args[1].toDoubleOrNull() ?: return false
return PlaceholderManager.translatePlaceholders(placeholder, player).toDoubleOrNull() ?: 0.0 >= equals
return (PlaceholderManager.translatePlaceholders(placeholder, player).toDoubleOrNull() ?: 0.0) >= equals
}
}

View File

@@ -15,6 +15,6 @@ class RequirementPlaceholderLessThan : Requirement() {
val placeholder = args[0]
val equals = args[1].toDoubleOrNull() ?: return false
return PlaceholderManager.translatePlaceholders(placeholder, player).toDoubleOrNull() ?: 0.0 < equals
return (PlaceholderManager.translatePlaceholders(placeholder, player).toDoubleOrNull() ?: 0.0) < equals
}
}

View File

@@ -165,7 +165,7 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
}
override fun hashCode(): Int {
return handle.tag?.hashCode() ?: 0b00010101 * 31 + Item.getId(handle.item)
return handle.tag?.hashCode() ?: (0b00010101 * 31 + Item.getId(handle.item))
}
private fun apply() {

View File

@@ -180,7 +180,7 @@ class NMSFastItemStack(itemStack: org.bukkit.inventory.ItemStack) : EcoFastItemS
}
override fun hashCode(): Int {
return handle.tag?.hashCode() ?: 0b00010101 * 31 + Item.getId(handle.item)
return handle.tag?.hashCode() ?: (0b00010101 * 31 + Item.getId(handle.item))
}
private fun apply() {

View File

@@ -15,11 +15,15 @@ import com.willfp.eco.core.integrations.hologram.HologramManager
import com.willfp.eco.core.integrations.mcmmo.McmmoManager
import com.willfp.eco.core.integrations.shop.ShopManager
import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.args.CustomModelDataArgParser
import com.willfp.eco.core.items.args.EnchantmentArgParser
import com.willfp.eco.core.items.args.TextureArgParser
import com.willfp.eco.internal.display.EcoDisplayHandler
import com.willfp.eco.internal.drops.DropManager
import com.willfp.eco.internal.items.ArgParserColor
import com.willfp.eco.internal.items.ArgParserCustomModelData
import com.willfp.eco.internal.items.ArgParserEnchantment
import com.willfp.eco.internal.items.ArgParserFlag
import com.willfp.eco.internal.items.ArgParserName
import com.willfp.eco.internal.items.ArgParserTexture
import com.willfp.eco.internal.items.ArgParserUnbreakable
import com.willfp.eco.internal.spigot.arrows.ArrowDataListener
import com.willfp.eco.internal.spigot.data.DataListener
import com.willfp.eco.internal.spigot.data.PlayerBlockListener
@@ -91,9 +95,13 @@ abstract class EcoSpigotPlugin : EcoPlugin(
"&a"
) {
init {
Items.registerArgParser(EnchantmentArgParser())
Items.registerArgParser(TextureArgParser())
Items.registerArgParser(CustomModelDataArgParser())
Items.registerArgParser(ArgParserEnchantment())
Items.registerArgParser(ArgParserColor())
Items.registerArgParser(ArgParserTexture())
Items.registerArgParser(ArgParserCustomModelData())
Items.registerArgParser(ArgParserFlag())
Items.registerArgParser(ArgParserUnbreakable())
Items.registerArgParser(ArgParserName())
val skullProxy = getProxy(SkullProxy::class.java)
SkullUtils.initialize(

View File

@@ -7,8 +7,6 @@ import com.willfp.eco.core.AbstractPacketAdapter
import com.willfp.eco.core.EcoPlugin
import com.willfp.eco.core.Prerequisite
import com.willfp.eco.core.display.Display
import com.willfp.eco.internal.spigot.display.frame.DisplayFrame
import com.willfp.eco.internal.spigot.display.frame.lastDisplayFrame
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
@@ -27,7 +25,5 @@ class PacketHeldWindowItems(plugin: EcoPlugin) : AbstractPacketAdapter(plugin, P
item!!, player
)
}
player.lastDisplayFrame = DisplayFrame.EMPTY
}
}

View File

@@ -1,2 +1,3 @@
version = 6.14.1
plugin-name = eco
version = 6.15.2
plugin-name = eco
kotlin.code.style = official