diff --git a/api/src/main/java/net/momirealms/customcrops/api/CustomCropsPlugin.java b/api/src/main/java/net/momirealms/customcrops/api/CustomCropsPlugin.java index 042c746..78cf379 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/CustomCropsPlugin.java +++ b/api/src/main/java/net/momirealms/customcrops/api/CustomCropsPlugin.java @@ -122,4 +122,6 @@ public abstract class CustomCropsPlugin extends JavaPlugin { public abstract void reload(); public abstract boolean doesHookedPluginExist(String plugin); + + public abstract String getServerVersion(); } diff --git a/api/src/main/java/net/momirealms/customcrops/api/manager/VersionManager.java b/api/src/main/java/net/momirealms/customcrops/api/manager/VersionManager.java index 7cbe24e..3e874a6 100644 --- a/api/src/main/java/net/momirealms/customcrops/api/manager/VersionManager.java +++ b/api/src/main/java/net/momirealms/customcrops/api/manager/VersionManager.java @@ -69,12 +69,6 @@ public abstract class VersionManager { return instance.getPluginVersion(); } - public static String serverVersion() { - return instance.getServerVersion(); - } - - public abstract String getServerVersion(); - public static boolean spigot() { return instance.isSpigot(); } diff --git a/build.gradle.kts b/build.gradle.kts index ebbca19..e113982 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,7 +8,7 @@ plugins { allprojects { project.group = "net.momirealms" - project.version = "3.4.12" + project.version = "3.5.0" apply() apply(plugin = "java") diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index c236caa..3203d60 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -53,13 +53,15 @@ dependencies { implementation(project(":legacy-api")) implementation("net.kyori:adventure-api:4.17.0") - implementation("net.kyori:adventure-platform-bukkit:4.3.2") + implementation("net.kyori:adventure-platform-bukkit:4.3.3") implementation("net.kyori:adventure-text-minimessage:4.17.0") implementation("net.kyori:adventure-text-serializer-legacy:4.17.0") - implementation("de.tr7zw:item-nbt-api:2.12.4") implementation("com.github.Xiao-MoMi:AntiGriefLib:0.11") - implementation("com.github.Xiao-MoMi:BiomeAPI:0.6") + implementation("com.github.Xiao-MoMi:Sparrow-Heart:0.16") implementation("com.flowpowered:flow-nbt:2.0.2") + implementation("com.saicone.rtag:rtag:1.5.4") + implementation("com.saicone.rtag:rtag-item:1.5.4") + compileOnly("de.tr7zw:item-nbt-api-plugin:2.13.0") implementation("com.github.luben:zstd-jni:1.5.6-2") } @@ -71,9 +73,10 @@ tasks { relocate ("org.objenesis", "net.momirealms.customcrops.libraries.objenesis") relocate ("org.bstats", "net.momirealms.customcrops.libraries.bstats") relocate ("dev.dejvokep.boostedyaml", "net.momirealms.customcrops.libraries.boostedyaml") - relocate ("net.momirealms.biomeapi", "net.momirealms.customcrops.libraries.biomeapi") + relocate ("net.momirealms.sparrow.heart", "net.momirealms.customcrops.libraries.sparrow") relocate ("net.momirealms.antigrieflib", "net.momirealms.customcrops.libraries.antigrieflib") relocate ("net.objecthunter.exp4j", "net.momirealms.customcrops.libraries.exp4j") + relocate ("com.saicone.rtag", "net.momirealms.customcrops.libraries.rtag") } } diff --git a/plugin/src/main/java/net/momirealms/customcrops/CustomCropsPluginImpl.java b/plugin/src/main/java/net/momirealms/customcrops/CustomCropsPluginImpl.java index 43b2f6d..aff5ce6 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/CustomCropsPluginImpl.java +++ b/plugin/src/main/java/net/momirealms/customcrops/CustomCropsPluginImpl.java @@ -33,11 +33,11 @@ import net.momirealms.customcrops.manager.*; import net.momirealms.customcrops.mechanic.action.ActionManagerImpl; import net.momirealms.customcrops.mechanic.condition.ConditionManagerImpl; import net.momirealms.customcrops.mechanic.item.ItemManagerImpl; +import net.momirealms.customcrops.mechanic.item.factory.BukkitItemFactory; import net.momirealms.customcrops.mechanic.misc.migrator.Migration; import net.momirealms.customcrops.mechanic.requirement.RequirementManagerImpl; import net.momirealms.customcrops.mechanic.world.WorldManagerImpl; import net.momirealms.customcrops.scheduler.SchedulerImpl; -import net.momirealms.customcrops.util.NBTUtils; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -53,13 +53,14 @@ public class CustomCropsPluginImpl extends CustomCropsPlugin { @Override public void onLoad() { + this.versionManager = new VersionManagerImpl(this); this.dependencyManager = new DependencyManagerImpl(this, new ReflectionClassPathAppender(this.getClassLoader())); this.dependencyManager.loadDependencies(new ArrayList<>( List.of( Dependency.GSON, Dependency.SLF4J_API, Dependency.SLF4J_SIMPLE, - Dependency.COMMAND_API, + versionManager.isMojmap() ? Dependency.COMMAND_API_MOJMAP : Dependency.COMMAND_API, Dependency.BOOSTED_YAML, Dependency.BSTATS_BASE, Dependency.BSTATS_BUKKIT @@ -70,7 +71,6 @@ public class CustomCropsPluginImpl extends CustomCropsPlugin { @Override public void onEnable() { instance = this; - this.versionManager = new VersionManagerImpl(this); this.adventure = new AdventureManagerImpl(this); this.scheduler = new SchedulerImpl(this); this.configManager = new ConfigManagerImpl(this); @@ -93,7 +93,7 @@ public class CustomCropsPluginImpl extends CustomCropsPlugin { this.hologramManager = new HologramManager(this); this.commandManager.init(); this.integrationManager.init(); - NBTUtils.disableNBTAPILogs(); + BukkitItemFactory.create(this); Migration.tryUpdating(); this.reload(); if (ConfigManager.metrics()) new Metrics(this, 16593); @@ -164,4 +164,9 @@ public class CustomCropsPluginImpl extends CustomCropsPlugin { public boolean doesHookedPluginExist(String plugin) { return Bukkit.getPluginManager().getPlugin(plugin) != null; } + + @Override + public String getServerVersion() { + return Bukkit.getServer().getBukkitVersion().split("-")[0]; + } } diff --git a/plugin/src/main/java/net/momirealms/customcrops/compatibility/item/MMOItemsItemImpl.java b/plugin/src/main/java/net/momirealms/customcrops/compatibility/item/MMOItemsItemImpl.java index 4d9578f..8336b16 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/compatibility/item/MMOItemsItemImpl.java +++ b/plugin/src/main/java/net/momirealms/customcrops/compatibility/item/MMOItemsItemImpl.java @@ -17,7 +17,7 @@ package net.momirealms.customcrops.compatibility.item; -import de.tr7zw.changeme.nbtapi.NBTItem; +import io.lumine.mythic.lib.api.item.NBTItem; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.Type; import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem; @@ -44,7 +44,7 @@ public class MMOItemsItemImpl implements ItemLibrary { @Override public String getItemID(ItemStack itemStack) { - NBTItem nbtItem = new NBTItem(itemStack); + NBTItem nbtItem = NBTItem.get(itemStack); if (!nbtItem.hasTag("MMOITEMS_ITEM_ID")) return null; return nbtItem.getString("MMOITEMS_ITEM_TYPE") + ":" + nbtItem.getString("MMOITEMS_ITEM_ID"); } diff --git a/plugin/src/main/java/net/momirealms/customcrops/compatibility/item/MythicMobsItemImpl.java b/plugin/src/main/java/net/momirealms/customcrops/compatibility/item/MythicMobsItemImpl.java index 392ee4c..1ff645e 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/compatibility/item/MythicMobsItemImpl.java +++ b/plugin/src/main/java/net/momirealms/customcrops/compatibility/item/MythicMobsItemImpl.java @@ -17,7 +17,6 @@ package net.momirealms.customcrops.compatibility.item; -import de.tr7zw.changeme.nbtapi.NBTItem; import io.lumine.mythic.bukkit.MythicBukkit; import net.momirealms.customcrops.api.integration.ItemLibrary; import org.bukkit.entity.Player; @@ -46,7 +45,6 @@ public class MythicMobsItemImpl implements ItemLibrary { @Override public String getItemID(ItemStack itemStack) { - NBTItem nbtItem = new NBTItem(itemStack); - return nbtItem.hasTag("MYTHIC_TYPE") ? nbtItem.getString("MYTHIC_TYPE") : null; + return mythicBukkit.getItemManager().getMythicTypeFromItem(itemStack); } } \ No newline at end of file diff --git a/plugin/src/main/java/net/momirealms/customcrops/libraries/dependencies/Dependency.java b/plugin/src/main/java/net/momirealms/customcrops/libraries/dependencies/Dependency.java index 1fc5796..e1c20ff 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/libraries/dependencies/Dependency.java +++ b/plugin/src/main/java/net/momirealms/customcrops/libraries/dependencies/Dependency.java @@ -60,15 +60,22 @@ public enum Dependency { null, "jar-relocator" ), - COMMAND_API( "dev{}jorel", "commandapi-bukkit-shade", - "9.3.0", + "9.5.0", null, "commandapi-bukkit", Relocation.of("commandapi", "dev{}jorel{}commandapi") ), + COMMAND_API_MOJMAP( + "dev{}jorel", + "commandapi-bukkit-shade-mojang-mapped", + "9.5.0", + null, + "commandapi-bukkit-mojang-mapped", + Relocation.of("commandapi", "dev{}jorel{}commandapi") + ), BOOSTED_YAML( "dev{}dejvokep", "boosted-yaml", diff --git a/plugin/src/main/java/net/momirealms/customcrops/manager/VersionManagerImpl.java b/plugin/src/main/java/net/momirealms/customcrops/manager/VersionManagerImpl.java index 15e2318..4840b60 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/manager/VersionManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customcrops/manager/VersionManagerImpl.java @@ -32,55 +32,20 @@ public class VersionManagerImpl extends VersionManager { private final CustomCropsPlugin plugin; private final String pluginVersion; - private final String serverVersion; private boolean foliaScheduler; private final boolean isSpigot; - private final boolean isNewerThan1_19_R2; - private final boolean isNewerThan1_19_R3; - private final boolean isNewerThan1_20; - private final boolean isNewerThan1_20_R2; - private final boolean isNewerThan1_19; - private final boolean isNewerThan1_18; private boolean isMojmap; + private final float mcVersion; + @SuppressWarnings("deprecation") public VersionManagerImpl(CustomCropsPlugin plugin) { this.plugin = plugin; this.isSpigot = plugin.getServer().getName().equals("CraftBukkit"); this.pluginVersion = plugin.getDescription().getVersion(); - this.serverVersion = plugin.getServer().getClass().getPackage().getName().split("\\.")[3]; - String[] split = serverVersion.split("_"); - int main_ver = Integer.parseInt(split[1]); - if (main_ver >= 20) { - isNewerThan1_20_R2 = Integer.parseInt(split[2].substring(1)) >= 2; - isNewerThan1_19_R2 = true; - isNewerThan1_19_R3 = true; - isNewerThan1_20 = true; - isNewerThan1_19 = true; - isNewerThan1_18 = true; - } else if (main_ver == 19) { - isNewerThan1_19_R2 = Integer.parseInt(split[2].substring(1)) >= 2; - isNewerThan1_19_R3 = Integer.parseInt(split[2].substring(1)) >= 3; - isNewerThan1_20 = false; - isNewerThan1_20_R2 = false; - isNewerThan1_19 = true; - isNewerThan1_18 = true; - } else if (main_ver == 18) { - isNewerThan1_19_R2 = false; - isNewerThan1_19_R3 = false; - isNewerThan1_20_R2 = false; - isNewerThan1_20 = false; - isNewerThan1_19 = false; - isNewerThan1_18 = true; - } else { - isNewerThan1_19_R2 = false; - isNewerThan1_19_R3 = false; - isNewerThan1_20_R2 = false; - isNewerThan1_20 = false; - isNewerThan1_19 = false; - isNewerThan1_18 = false; - } + String[] split = plugin.getServerVersion().split("\\."); + this.mcVersion = Float.parseFloat(split[1] + "." + split[2]); try { Class.forName("io.papermc.paper.threadedregions.RegionizedServer"); @@ -98,11 +63,6 @@ public class VersionManagerImpl extends VersionManager { } } - @Override - public boolean isVersionNewerThan1_20_R2() { - return isNewerThan1_20_R2; - } - @Override public boolean hasRegionScheduler() { return foliaScheduler; @@ -113,11 +73,6 @@ public class VersionManagerImpl extends VersionManager { return pluginVersion; } - @Override - public String getServerVersion() { - return serverVersion; - } - @Override public boolean isSpigot() { return isSpigot; @@ -125,27 +80,32 @@ public class VersionManagerImpl extends VersionManager { @Override public boolean isVersionNewerThan1_19_R3() { - return isNewerThan1_19_R3; + return mcVersion >= 19.4; + } + + @Override + public boolean isVersionNewerThan1_20_R2() { + return mcVersion >= 20.2; } @Override public boolean isVersionNewerThan1_19() { - return isNewerThan1_19; + return mcVersion >= 19; } @Override public boolean isVersionNewerThan1_19_R2() { - return isNewerThan1_19_R2; + return mcVersion >= 19.3; } @Override public boolean isVersionNewerThan1_20() { - return isNewerThan1_20; + return mcVersion >= 20; } @Override public boolean isVersionNewerThan1_18() { - return isNewerThan1_18; + return mcVersion >= 18; } @Override diff --git a/plugin/src/main/java/net/momirealms/customcrops/mechanic/action/ActionManagerImpl.java b/plugin/src/main/java/net/momirealms/customcrops/mechanic/action/ActionManagerImpl.java index 0ac242c..5c25399 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/mechanic/action/ActionManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customcrops/mechanic/action/ActionManagerImpl.java @@ -65,7 +65,9 @@ import org.bukkit.block.BlockFace; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.ExperienceOrb; import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerItemDamageEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.NotNull; @@ -827,10 +829,18 @@ public class ActionManagerImpl implements ActionManager { return state -> { if (Math.random() > chance) return; ItemStack itemStack = state.getItemInHand(); + if (amount > 0) { ItemUtils.increaseDurability(itemStack, amount); } else { - if (state.getPlayer().getGameMode() == GameMode.CREATIVE) return; + if (state.getPlayer().getGameMode() == GameMode.CREATIVE || itemStack.getItemMeta().isUnbreakable()) return; + + ItemMeta previousMeta = itemStack.getItemMeta().clone(); + PlayerItemDamageEvent itemDamageEvent = new PlayerItemDamageEvent(state.getPlayer(), itemStack, amount); + Bukkit.getPluginManager().callEvent(itemDamageEvent); + if (!itemStack.getItemMeta().equals(previousMeta) || itemDamageEvent.isCancelled()) { + return; + } ItemUtils.decreaseDurability(state.getPlayer(), itemStack, -amount); } }; diff --git a/plugin/src/main/java/net/momirealms/customcrops/mechanic/condition/ConditionManagerImpl.java b/plugin/src/main/java/net/momirealms/customcrops/mechanic/condition/ConditionManagerImpl.java index feb1f74..851ce4a 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/mechanic/condition/ConditionManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customcrops/mechanic/condition/ConditionManagerImpl.java @@ -17,7 +17,6 @@ package net.momirealms.customcrops.mechanic.condition; -import net.momirealms.biomeapi.BiomeAPI; import net.momirealms.customcrops.api.CustomCropsPlugin; import net.momirealms.customcrops.api.common.Pair; import net.momirealms.customcrops.api.manager.ConditionManager; @@ -36,6 +35,7 @@ import net.momirealms.customcrops.mechanic.misc.CrowAttackAnimation; import net.momirealms.customcrops.mechanic.world.block.MemoryCrop; import net.momirealms.customcrops.util.ClassUtils; import net.momirealms.customcrops.util.ConfigUtils; +import net.momirealms.sparrow.heart.SparrowHeart; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.data.type.Farmland; @@ -203,14 +203,14 @@ public class ConditionManagerImpl implements ConditionManager { registerCondition("biome", (args) -> { HashSet biomes = new HashSet<>(ConfigUtils.stringListArgs(args)); return (block, offline) -> { - String currentBiome = BiomeAPI.getBiomeAt(block.getLocation().getBukkitLocation()); + String currentBiome = SparrowHeart.getInstance().getBiomeResourceLocation(block.getLocation().getBukkitLocation()); return biomes.contains(currentBiome); }; }); registerCondition("!biome", (args) -> { HashSet biomes = new HashSet<>(ConfigUtils.stringListArgs(args)); return (block, offline) -> { - String currentBiome = BiomeAPI.getBiomeAt(block.getLocation().getBukkitLocation()); + String currentBiome = SparrowHeart.getInstance().getBiomeResourceLocation(block.getLocation().getBukkitLocation()); return !biomes.contains(currentBiome); }; }); diff --git a/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/AbstractItem.java b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/AbstractItem.java new file mode 100644 index 0000000..4deb2c0 --- /dev/null +++ b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/AbstractItem.java @@ -0,0 +1,104 @@ +package net.momirealms.customcrops.mechanic.item.factory; + +import net.momirealms.customcrops.api.CustomCropsPlugin; + +import java.util.List; +import java.util.Optional; + +public class AbstractItem implements Item { + + private final CustomCropsPlugin plugin; + private final ItemFactory factory; + private final R item; + + AbstractItem(CustomCropsPlugin plugin, ItemFactory factory, R item) { + this.plugin = plugin; + this.factory = factory; + this.item = item; + } + + @Override + public Item customModelData(Integer data) { + factory.customModelData(item, data); + return this; + } + + @Override + public Optional customModelData() { + return factory.customModelData(item); + } + + @Override + public Item damage(Integer data) { + factory.damage(item, data); + return this; + } + + @Override + public Optional damage() { + return factory.damage(item); + } + + @Override + public Item maxDamage(Integer data) { + factory.maxDamage(item, data); + return this; + } + + @Override + public Optional maxDamage() { + return factory.maxDamage(item); + } + + @Override + public Item lore(List lore) { + factory.lore(item, lore); + return this; + } + + @Override + public Optional> lore() { + return factory.lore(item); + } + + @Override + public Optional getTag(Object... path) { + return factory.getTag(item, path); + } + + @Override + public Item setTag(Object value, Object... path) { + factory.setTag(item, value, path); + return this; + } + + @Override + public boolean hasTag(Object... path) { + return factory.hasTag(item, path); + } + + @Override + public boolean removeTag(Object... path) { + return factory.removeTag(item, path); + } + + @Override + public I getItem() { + return factory.getItem(item); + } + + @Override + public I load() { + return factory.load(item); + } + + @Override + public I loadCopy() { + return factory.loadCopy(item); + } + + @Override + public void update() { + factory.update(item); + } +} diff --git a/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/BukkitItemFactory.java b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/BukkitItemFactory.java new file mode 100644 index 0000000..efa092b --- /dev/null +++ b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/BukkitItemFactory.java @@ -0,0 +1,86 @@ +package net.momirealms.customcrops.mechanic.item.factory; + +import com.saicone.rtag.RtagItem; +import net.momirealms.customcrops.api.CustomCropsPlugin; +import net.momirealms.customcrops.mechanic.item.factory.impl.ComponentItemFactory; +import net.momirealms.customcrops.mechanic.item.factory.impl.UniversalItemFactory; +import org.bukkit.inventory.ItemStack; + +import java.util.Objects; +import java.util.Optional; + +public abstract class BukkitItemFactory extends ItemFactory { + + private static BukkitItemFactory instance; + + protected BukkitItemFactory(CustomCropsPlugin plugin) { + super(plugin); + instance = this; + } + + public static BukkitItemFactory create(CustomCropsPlugin plugin) { + Objects.requireNonNull(plugin, "plugin"); + switch (plugin.getServerVersion()) { + case "1.17", "1.17.1", + "1.18", "1.18.1", "1.18.2", + "1.19", "1.19.1", "1.19.2", "1.19.3", "1.19.4", + "1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4" -> { + return new UniversalItemFactory(plugin); + } + case "1.20.5", "1.20.6", + "1.21", "1.21.1", "1.21.2" -> { + return new ComponentItemFactory(plugin); + } + default -> throw new IllegalStateException("Unsupported server version: " + plugin.getServerVersion()); + } + } + + public static BukkitItemFactory getInstance() { + return instance; + } + + public Item wrap(ItemStack item) { + Objects.requireNonNull(item, "item"); + return wrap(new RtagItem(item)); + } + + @Override + protected void setTag(RtagItem item, Object value, Object... path) { + item.set(value, path); + } + + @Override + protected Optional getTag(RtagItem item, Object... path) { + return Optional.ofNullable(item.get(path)); + } + + @Override + protected boolean hasTag(RtagItem item, Object... path) { + return item.hasTag(path); + } + + @Override + protected boolean removeTag(RtagItem item, Object... path) { + return item.remove(path); + } + + @Override + protected void update(RtagItem item) { + item.update(); + } + + @Override + protected ItemStack load(RtagItem item) { + return item.load(); + } + + @Override + protected ItemStack getItem(RtagItem item) { + return item.getItem(); + } + + @Override + protected ItemStack loadCopy(RtagItem item) { + return item.loadCopy(); + } +} diff --git a/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/ComponentKeys.java b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/ComponentKeys.java new file mode 100644 index 0000000..32eaad2 --- /dev/null +++ b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/ComponentKeys.java @@ -0,0 +1,17 @@ +package net.momirealms.customcrops.mechanic.item.factory; + +import net.kyori.adventure.key.Key; + +public class ComponentKeys { + + public static final String CUSTOM_MODEL_DATA = Key.key("minecraft", "custom_model_data").asString(); + public static final String MAX_DAMAGE = Key.key("minecraft", "max_damage").asString(); + public static final String CUSTOM_NAME = Key.key("minecraft", "custom_name").asString(); + public static final String LORE = Key.key("minecraft", "lore").asString(); + public static final String DAMAGE = Key.key("minecraft", "damage").asString(); + public static final String ENCHANTMENT_GLINT_OVERRIDE = Key.key("minecraft", "enchantment_glint_override").asString(); + public static final String HIDE_TOOLTIP = Key.key("minecraft", "hide_tooltip").asString(); + public static final String MAX_STACK_SIZE = Key.key("minecraft", "max_stack_size").asString(); + public static final String PROFILE = Key.key("minecraft", "profile").asString(); + public static final String UNBREAKABLE = Key.key("minecraft", "unbreakable").asString(); +} diff --git a/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/Item.java b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/Item.java new file mode 100644 index 0000000..35e2233 --- /dev/null +++ b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/Item.java @@ -0,0 +1,39 @@ +package net.momirealms.customcrops.mechanic.item.factory; + +import java.util.List; +import java.util.Optional; + +public interface Item { + + Item customModelData(Integer data); + + Optional customModelData(); + + Item damage(Integer data); + + Optional damage(); + + Item maxDamage(Integer data); + + Optional maxDamage(); + + Item lore(List lore); + + Optional> lore(); + + Optional getTag(Object... path); + + Item setTag(Object value, Object... path); + + boolean hasTag(Object... path); + + boolean removeTag(Object... path); + + I getItem(); + + I load(); + + I loadCopy(); + + void update(); +} diff --git a/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/ItemFactory.java b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/ItemFactory.java new file mode 100644 index 0000000..72c62c3 --- /dev/null +++ b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/ItemFactory.java @@ -0,0 +1,53 @@ +package net.momirealms.customcrops.mechanic.item.factory; + +import net.momirealms.customcrops.api.CustomCropsPlugin; + +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +public abstract class ItemFactory

{ + + protected final P plugin; + + protected ItemFactory(P plugin) { + this.plugin = plugin; + } + + public Item wrap(R item) { + Objects.requireNonNull(item, "item"); + return new AbstractItem<>(this.plugin, this, item); + } + + protected abstract Optional getTag(R item, Object... path); + + protected abstract void setTag(R item, Object value, Object... path); + + protected abstract boolean hasTag(R item, Object... path); + + protected abstract boolean removeTag(R item, Object... path); + + protected abstract void update(R item); + + protected abstract I load(R item); + + protected abstract I getItem(R item); + + protected abstract I loadCopy(R item); + + protected abstract Optional customModelData(R item); + + protected abstract void customModelData(R item, Integer data); + + protected abstract Optional> lore(R item); + + protected abstract void lore(R item, List lore); + + protected abstract Optional maxDamage(R item); + + protected abstract void maxDamage(R item, Integer data); + + protected abstract Optional damage(R item); + + protected abstract void damage(R item, Integer data); +} diff --git a/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/impl/ComponentItemFactory.java b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/impl/ComponentItemFactory.java new file mode 100644 index 0000000..5266f84 --- /dev/null +++ b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/impl/ComponentItemFactory.java @@ -0,0 +1,99 @@ +package net.momirealms.customcrops.mechanic.item.factory.impl; + +import com.saicone.rtag.RtagItem; +import com.saicone.rtag.data.ComponentType; +import net.momirealms.customcrops.api.CustomCropsPlugin; +import net.momirealms.customcrops.mechanic.item.factory.BukkitItemFactory; +import net.momirealms.customcrops.mechanic.item.factory.ComponentKeys; + +import java.util.List; +import java.util.Optional; + +@SuppressWarnings("UnstableApiUsage") +public class ComponentItemFactory extends BukkitItemFactory { + + public ComponentItemFactory(CustomCropsPlugin plugin) { + super(plugin); + } + + @Override + protected void customModelData(RtagItem item, Integer data) { + if (data == null) { + item.removeComponent(ComponentKeys.CUSTOM_MODEL_DATA); + } else { + item.setComponent(ComponentKeys.CUSTOM_MODEL_DATA, data); + } + } + + @Override + protected Optional customModelData(RtagItem item) { + if (!item.hasComponent(ComponentKeys.CUSTOM_MODEL_DATA)) return Optional.empty(); + return Optional.ofNullable( + (Integer) ComponentType.encodeJava( + ComponentKeys.CUSTOM_MODEL_DATA, + item.getComponent(ComponentKeys.CUSTOM_MODEL_DATA) + ).orElse(null) + ); + } + + @SuppressWarnings("unchecked") + @Override + protected Optional> lore(RtagItem item) { + if (item.getComponent(ComponentKeys.LORE) == null) return Optional.empty(); + return Optional.ofNullable( + (List) ComponentType.encodeJava( + ComponentKeys.LORE, + item.getComponent(ComponentKeys.LORE) + ).orElse(null) + ); + } + + @Override + protected void lore(RtagItem item, List lore) { + if (lore == null || lore.isEmpty()) { + item.removeComponent(ComponentKeys.LORE); + } else { + item.setComponent(ComponentKeys.LORE, lore); + } + } + + @Override + protected Optional maxDamage(RtagItem item) { + if (!item.hasComponent(ComponentKeys.MAX_DAMAGE)) return Optional.of((int) item.getItem().getType().getMaxDurability()); + return Optional.ofNullable( + (Integer) ComponentType.encodeJava( + ComponentKeys.MAX_DAMAGE, + item.getComponent(ComponentKeys.MAX_DAMAGE) + ).orElse(null) + ); + } + + @Override + protected void maxDamage(RtagItem item, Integer data) { + if (data == null) { + item.removeComponent(ComponentKeys.MAX_DAMAGE); + } else { + item.setComponent(ComponentKeys.MAX_DAMAGE, data); + } + } + + @Override + protected Optional damage(RtagItem item) { + if (!item.hasComponent(ComponentKeys.DAMAGE)) return Optional.of(0); + return Optional.ofNullable( + (Integer) ComponentType.encodeJava( + ComponentKeys.DAMAGE, + item.getComponent(ComponentKeys.DAMAGE) + ).orElse(null) + ); + } + + @Override + protected void damage(RtagItem item, Integer data) { + if (data == null) { + item.removeComponent(ComponentKeys.DAMAGE); + } else { + item.setComponent(ComponentKeys.DAMAGE, data); + } + } +} \ No newline at end of file diff --git a/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/impl/UniversalItemFactory.java b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/impl/UniversalItemFactory.java new file mode 100644 index 0000000..5fb923c --- /dev/null +++ b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/factory/impl/UniversalItemFactory.java @@ -0,0 +1,67 @@ +package net.momirealms.customcrops.mechanic.item.factory.impl; + + + +import com.saicone.rtag.RtagItem; +import net.momirealms.customcrops.api.CustomCropsPlugin; +import net.momirealms.customcrops.mechanic.item.factory.BukkitItemFactory; + +import java.util.List; +import java.util.Optional; + +public class UniversalItemFactory extends BukkitItemFactory { + + public UniversalItemFactory(CustomCropsPlugin plugin) { + super(plugin); + } + + @Override + protected void customModelData(RtagItem item, Integer data) { + if (data == null) { + item.remove("CustomModelData"); + } else { + item.set(data, "CustomModelData"); + } + } + + @Override + protected Optional customModelData(RtagItem item) { + if (!item.hasTag("CustomModelData")) return Optional.empty(); + return Optional.of(item.get("CustomModelData")); + } + + @Override + protected Optional> lore(RtagItem item) { + if (!item.hasTag("display", "Lore")) return Optional.empty(); + return Optional.of(item.get("display", "Lore")); + } + + @Override + protected void lore(RtagItem item, List lore) { + if (lore == null || lore.isEmpty()) { + item.remove("display", "Lore"); + } else { + item.set(lore, "display", "Lore"); + } + } + + @Override + protected Optional maxDamage(RtagItem item) { + return Optional.of((int) item.getItem().getType().getMaxDurability()); + } + + @Override + protected void maxDamage(RtagItem item, Integer data) { + throw new RuntimeException("Unsupported operation"); + } + + @Override + protected Optional damage(RtagItem item) { + return Optional.of(item.getOptional("Damage").or(0)); + } + + @Override + protected void damage(RtagItem item, Integer data) { + item.set(data, "Damage"); + } +} diff --git a/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/impl/WateringCanConfig.java b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/impl/WateringCanConfig.java index fcd7b2a..96caabf 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/impl/WateringCanConfig.java +++ b/plugin/src/main/java/net/momirealms/customcrops/mechanic/item/impl/WateringCanConfig.java @@ -17,8 +17,7 @@ package net.momirealms.customcrops.mechanic.item.impl; -import de.tr7zw.changeme.nbtapi.NBTCompound; -import de.tr7zw.changeme.nbtapi.NBTItem; +import com.saicone.rtag.item.ItemObject; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.ScoreComponent; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; @@ -32,16 +31,15 @@ import net.momirealms.customcrops.api.mechanic.item.water.PositiveFillMethod; import net.momirealms.customcrops.api.mechanic.misc.image.WaterBar; import net.momirealms.customcrops.api.mechanic.requirement.Requirement; import net.momirealms.customcrops.mechanic.item.AbstractEventItem; +import net.momirealms.customcrops.mechanic.item.factory.BukkitItemFactory; +import net.momirealms.customcrops.mechanic.item.factory.Item; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; +import java.util.*; public class WateringCanConfig extends AbstractEventItem implements WateringCan { @@ -134,12 +132,19 @@ public class WateringCanConfig extends AbstractEventItem implements WateringCan @Override public void updateItem(Player player, ItemStack itemStack, int water, Map args) { - int maxDurability = itemStack.getType().getMaxDurability(); - NBTItem nbtItem = new NBTItem(itemStack); + Item item = BukkitItemFactory.getInstance().wrap(itemStack); + int maxDurability = item.maxDamage().orElse((int) itemStack.getType().getMaxDurability()); + if (isInfinite()) water = storage; + item.setTag(water, "WaterAmount"); + if (maxDurability != 0) { + item.setTag((int) (maxDurability * (((double) storage - water) / storage)), "Damage"); + } + if (appearanceMap.containsKey(water)) { + item.customModelData(appearanceMap.get(water)); + } if (hasDynamicLore()) { - NBTCompound displayCompound = nbtItem.getOrCreateCompound("display"); - List lore = displayCompound.getStringList("Lore"); + List lore = new ArrayList<>(item.lore().orElse(List.of())); if (ConfigManager.protectLore()) { lore.removeIf(line -> { Component component = GsonComponentSerializer.gson().deserialize(line); @@ -157,24 +162,17 @@ public class WateringCanConfig extends AbstractEventItem implements WateringCan )); lore.add(GsonComponentSerializer.gson().serialize(builder.build())); } + item.lore(lore); } - - nbtItem.setInteger("WaterAmount", water); - if (maxDurability != 0) { - nbtItem.setInteger("Damage", (int) (maxDurability * (((double) storage - water) / storage))); - } - if (appearanceMap.containsKey(water)) { - nbtItem.setInteger("CustomModelData", appearanceMap.get(water)); - } - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); + itemStack.setItemMeta(item.loadCopy().getItemMeta()); } @Override public int getCurrentWater(ItemStack itemStack) { if (itemStack == null || itemStack.getType() == Material.AIR) return 0; - NBTItem nbtItem = new NBTItem(itemStack); - return nbtItem.getInteger("WaterAmount"); + Item item = BukkitItemFactory.getInstance().wrap(itemStack); + return (int) item.getTag("WaterAmount").orElse(0); } @Override diff --git a/plugin/src/main/java/net/momirealms/customcrops/mechanic/misc/TempFakeItem.java b/plugin/src/main/java/net/momirealms/customcrops/mechanic/misc/TempFakeItem.java index a6e06d1..b5dbd41 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/mechanic/misc/TempFakeItem.java +++ b/plugin/src/main/java/net/momirealms/customcrops/mechanic/misc/TempFakeItem.java @@ -22,7 +22,6 @@ import net.momirealms.customcrops.api.CustomCropsPlugin; import net.momirealms.customcrops.api.mechanic.world.SimpleLocation; import net.momirealms.customcrops.manager.PacketManager; import net.momirealms.customcrops.util.FakeEntityUtils; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; diff --git a/plugin/src/main/java/net/momirealms/customcrops/mechanic/requirement/RequirementManagerImpl.java b/plugin/src/main/java/net/momirealms/customcrops/mechanic/requirement/RequirementManagerImpl.java index 2756161..cb8d289 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/mechanic/requirement/RequirementManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customcrops/mechanic/requirement/RequirementManagerImpl.java @@ -17,7 +17,6 @@ package net.momirealms.customcrops.mechanic.requirement; -import net.momirealms.biomeapi.BiomeAPI; import net.momirealms.customcrops.api.CustomCropsPlugin; import net.momirealms.customcrops.api.common.Pair; import net.momirealms.customcrops.api.integration.LevelInterface; @@ -39,6 +38,7 @@ import net.momirealms.customcrops.compatibility.VaultHook; import net.momirealms.customcrops.compatibility.papi.ParseUtils; import net.momirealms.customcrops.util.ClassUtils; import net.momirealms.customcrops.util.ConfigUtils; +import net.momirealms.sparrow.heart.SparrowHeart; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; @@ -368,7 +368,7 @@ public class RequirementManagerImpl implements RequirementManager { registerRequirement("biome", (args, actions, advanced) -> { HashSet biomes = new HashSet<>(ConfigUtils.stringListArgs(args)); return state -> { - String currentBiome = BiomeAPI.getBiomeAt(state.getLocation()); + String currentBiome = SparrowHeart.getInstance().getBiomeResourceLocation(state.getLocation()); if (biomes.contains(currentBiome)) return true; if (advanced) triggerActions(actions, state); @@ -378,7 +378,7 @@ public class RequirementManagerImpl implements RequirementManager { registerRequirement("!biome", (args, actions, advanced) -> { HashSet biomes = new HashSet<>(ConfigUtils.stringListArgs(args)); return state -> { - String currentBiome = BiomeAPI.getBiomeAt(state.getLocation()); + String currentBiome = SparrowHeart.getInstance().getBiomeResourceLocation(state.getLocation()); if (!biomes.contains(currentBiome)) return true; if (advanced) triggerActions(actions, state); diff --git a/plugin/src/main/java/net/momirealms/customcrops/mechanic/world/WorldManagerImpl.java b/plugin/src/main/java/net/momirealms/customcrops/mechanic/world/WorldManagerImpl.java index 4111ed7..7a96567 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/mechanic/world/WorldManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customcrops/mechanic/world/WorldManagerImpl.java @@ -39,16 +39,13 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.event.EventHandler; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; -import org.bukkit.event.world.ChunkEvent; import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.ChunkUnloadEvent; import org.bukkit.event.world.EntitiesLoadEvent; import org.jetbrains.annotations.NotNull; import java.util.*; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.TimeUnit; public class WorldManagerImpl implements WorldManager, Listener { diff --git a/plugin/src/main/java/net/momirealms/customcrops/util/ItemUtils.java b/plugin/src/main/java/net/momirealms/customcrops/util/ItemUtils.java index 175872c..89cfed4 100644 --- a/plugin/src/main/java/net/momirealms/customcrops/util/ItemUtils.java +++ b/plugin/src/main/java/net/momirealms/customcrops/util/ItemUtils.java @@ -17,7 +17,8 @@ package net.momirealms.customcrops.util; -import de.tr7zw.changeme.nbtapi.NBTItem; +import net.momirealms.customcrops.mechanic.item.factory.BukkitItemFactory; +import net.momirealms.customcrops.mechanic.item.factory.Item; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; @@ -84,20 +85,16 @@ public class ItemUtils { public static void increaseDurability(ItemStack itemStack, int amount) { if (itemStack == null || itemStack.getType() == Material.AIR) return; - NBTItem nbtItem = new NBTItem(itemStack); - if (nbtItem.getByte("Unbreakable") == 1) { - return; - } - int damage = Math.max(nbtItem.getInteger("Damage") - amount, 0); - nbtItem.setInteger("Damage", damage); - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); + Item item = BukkitItemFactory.getInstance().wrap(itemStack); + int damage = Math.max(item.damage().orElse(0) - amount, 0); + item.damage(damage); + itemStack.setItemMeta(item.load().getItemMeta()); } public static void decreaseDurability(Player player, ItemStack itemStack, int amount) { if (itemStack == null || itemStack.getType() == Material.AIR) return; - NBTItem nbtItem = new NBTItem(itemStack); - ItemMeta previousMeta = itemStack.getItemMeta().clone(); + ItemMeta previousMeta = itemStack.getItemMeta().clone(); PlayerItemDamageEvent itemDamageEvent = new PlayerItemDamageEvent(player, itemStack, amount, amount); Bukkit.getPluginManager().callEvent(itemDamageEvent); if (!itemStack.getItemMeta().equals(previousMeta) || itemDamageEvent.isCancelled()) { @@ -107,15 +104,13 @@ public class ItemUtils { if (Math.random() > (double) 1 / (unBreakingLevel + 1)) { return; } - if (nbtItem.getByte("Unbreakable") == 1) { - return; - } - int damage = nbtItem.getInteger("Damage") + amount; - if (damage > itemStack.getType().getMaxDurability()) { + Item item = BukkitItemFactory.getInstance().wrap(itemStack); + int damage = item.damage().orElse(0) + amount; + if (damage > item.maxDamage().orElse((int) itemStack.getType().getMaxDurability())) { itemStack.setAmount(0); } else { - nbtItem.setInteger("Damage", damage); - itemStack.setItemMeta(nbtItem.getItem().getItemMeta()); + item.damage(damage); + itemStack.setItemMeta(item.load().getItemMeta()); } } } diff --git a/plugin/src/main/java/net/momirealms/customcrops/util/NBTUtils.java b/plugin/src/main/java/net/momirealms/customcrops/util/NBTUtils.java deleted file mode 100644 index 7a726bb..0000000 --- a/plugin/src/main/java/net/momirealms/customcrops/util/NBTUtils.java +++ /dev/null @@ -1,61 +0,0 @@ -package net.momirealms.customcrops.util; - -import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion; -import de.tr7zw.changeme.nbtapi.utils.VersionChecker; -import net.momirealms.customcrops.api.CustomCropsPlugin; -import org.bukkit.Bukkit; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; - -public class NBTUtils { - - private NBTUtils() {} - - public static void disableNBTAPILogs() { - MinecraftVersion.disableBStats(); - MinecraftVersion.disableUpdateCheck(); - VersionChecker.hideOk = true; - try { - Field field = MinecraftVersion.class.getDeclaredField("version"); - field.setAccessible(true); - MinecraftVersion minecraftVersion; - try { - minecraftVersion = MinecraftVersion.valueOf(CustomCropsPlugin.get().getVersionManager().getServerVersion().replace("v", "MC")); - } catch (Exception ex) { - minecraftVersion = VERSION_TO_REVISION.getOrDefault(Bukkit.getServer().getBukkitVersion().split("-")[0], - MinecraftVersion.UNKNOWN); - } - field.set(MinecraftVersion.class, minecraftVersion); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException(e); - } - boolean hasGsonSupport; - try { - Class.forName("com.google.gson.Gson"); - hasGsonSupport = true; - } catch (Exception ex) { - hasGsonSupport = false; - } - try { - Field field= MinecraftVersion.class.getDeclaredField("hasGsonSupport"); - field.setAccessible(true); - field.set(Boolean.class, hasGsonSupport); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - private static final Map VERSION_TO_REVISION = new HashMap<>() { - { - this.put("1.20", MinecraftVersion.MC1_20_R1); - this.put("1.20.1", MinecraftVersion.MC1_20_R1); - this.put("1.20.2", MinecraftVersion.MC1_20_R2); - this.put("1.20.3", MinecraftVersion.MC1_20_R3); - this.put("1.20.4", MinecraftVersion.MC1_20_R3); - this.put("1.20.5", MinecraftVersion.MC1_20_R4); - this.put("1.20.6", MinecraftVersion.MC1_20_R4); - } - }; -}