From 836f26bad887b28dad56f39f0012f88e8071acdc Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Sun, 12 Apr 2026 17:07:10 +0200 Subject: [PATCH 01/24] fix: handle inventory closure for VInventory on player quit --- .../java/fr/maxlego08/menu/inventory/VInventoryManager.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/fr/maxlego08/menu/inventory/VInventoryManager.java b/src/main/java/fr/maxlego08/menu/inventory/VInventoryManager.java index 46bd716b..3c965693 100644 --- a/src/main/java/fr/maxlego08/menu/inventory/VInventoryManager.java +++ b/src/main/java/fr/maxlego08/menu/inventory/VInventoryManager.java @@ -266,6 +266,10 @@ protected void onConnect(PlayerJoinEvent event, Player player) { @Override protected void onQuit(PlayerQuitEvent event, Player player) { + Inventory topInventory = CompatibilityUtil.getTopInventory(player); + if (topInventory != null && topInventory.getHolder() instanceof VInventory vInventory) { + vInventory.onPreClose(null, this.plugin, player); + } this.cooldownClick.remove(player.getUniqueId()); this.plugin.getInventoryManager().getPaginationManager().removePlayerStates(player.getUniqueId()); } From deba6b61c926f601627e9d3bd6a58c39777ba4d4 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Sun, 12 Apr 2026 17:40:12 +0200 Subject: [PATCH 02/24] refactor: rename and reorganize item component loaders for max stack size and attack range --- .../components/AttackRangeComponent.java | 38 +++--------- .../components/MaxStackSizeComponent.java | 21 +------ .../SpigotAttackRangeItemComponentLoader.java | 35 +++++++++++ ...bstractAttackRangeItemComponentLoader.java | 61 ++++++++++--------- .../paper/PaperAttackRangeComponent.java | 25 ++++++++ .../paper/PaperMaxStackSizeComponent.java | 21 +++++++ .../PaperAttackRangeItemComponentLoader.java | 34 +++++++++++ .../fr/maxlego08/menu/ZComponentsManager.java | 5 +- ...a => MaxStackSizeItemComponentLoader.java} | 15 +++-- 9 files changed, 170 insertions(+), 85 deletions(-) create mode 100644 Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotAttackRangeItemComponentLoader.java rename src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotAttackRangeItemComponentLoader.java => Common/src/main/java/fr/maxlego08/menu/loader/components/AbstractAttackRangeItemComponentLoader.java (58%) create mode 100644 Hooks/Paper/src/main/java/fr/maxlego08/menu/itemstack/components/paper/PaperAttackRangeComponent.java create mode 100644 Hooks/Paper/src/main/java/fr/maxlego08/menu/itemstack/components/paper/PaperMaxStackSizeComponent.java create mode 100644 Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperAttackRangeItemComponentLoader.java rename src/main/java/fr/maxlego08/menu/loader/components/spigot/{SpigotMaxStackSizeItemComponentLoader.java => MaxStackSizeItemComponentLoader.java} (56%) diff --git a/API/src/main/java/fr/maxlego08/menu/api/itemstack/components/AttackRangeComponent.java b/API/src/main/java/fr/maxlego08/menu/api/itemstack/components/AttackRangeComponent.java index c8ead34f..bdc139eb 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/itemstack/components/AttackRangeComponent.java +++ b/API/src/main/java/fr/maxlego08/menu/api/itemstack/components/AttackRangeComponent.java @@ -1,24 +1,17 @@ package fr.maxlego08.menu.api.itemstack.components; -import fr.maxlego08.menu.api.context.BuildContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -@SuppressWarnings("unused") -public class AttackRangeComponent extends ItemComponent { +public abstract class AttackRangeComponent extends ItemComponent { + protected final float minReach; + protected final float maxReach; + protected final float minCreativeReach; + protected final float maxCreativeReach; + protected final float hitboxMargin; + protected final float mobFactor; - private final float minReach; - private final float maxReach; - private final float minCreativeReach; - private final float maxCreativeReach; - private final float hitboxMargin; - private final float mobFactor; - public AttackRangeComponent(float minReach, float maxReach, float minCreativeReach, float maxCreativeReach, float hitboxMargin, float mobFactor) { + protected AttackRangeComponent(float minReach, float maxReach, float minCreativeReach, float maxCreativeReach, float hitboxMargin, float mobFactor) { this.minReach = minReach; this.maxReach = maxReach; this.minCreativeReach = minCreativeReach; @@ -50,19 +43,4 @@ public float getHitboxMargin() { public float getMobFactor() { return this.mobFactor; } - - @Override - public void apply(@NotNull BuildContext context, @NotNull ItemStack itemStack, @Nullable Player player) { - ItemMeta itemMeta = itemStack.getItemMeta(); - if (itemMeta == null) return; - org.bukkit.inventory.meta.components.AttackRangeComponent attackRange = itemMeta.getAttackRange(); - attackRange.setMinReach(this.minReach); - attackRange.setMaxReach(this.maxReach); - attackRange.setMinCreativeReach(this.minCreativeReach); - attackRange.setMaxCreativeReach(this.maxCreativeReach); - attackRange.setHitboxMargin(this.hitboxMargin); - attackRange.setMobFactor(this.mobFactor); - itemStack.setItemMeta(itemMeta); - } - } diff --git a/API/src/main/java/fr/maxlego08/menu/api/itemstack/components/MaxStackSizeComponent.java b/API/src/main/java/fr/maxlego08/menu/api/itemstack/components/MaxStackSizeComponent.java index 55f612f7..b019a9d5 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/itemstack/components/MaxStackSizeComponent.java +++ b/API/src/main/java/fr/maxlego08/menu/api/itemstack/components/MaxStackSizeComponent.java @@ -1,16 +1,9 @@ package fr.maxlego08.menu.api.itemstack.components; -import fr.maxlego08.menu.api.context.BuildContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -@SuppressWarnings("unused") -public class MaxStackSizeComponent extends ItemComponent { - private final int maxStackSize; +public abstract class MaxStackSizeComponent extends ItemComponent { + protected final int maxStackSize; public MaxStackSizeComponent(int maxStackSize) { this.maxStackSize = maxStackSize; @@ -19,14 +12,4 @@ public MaxStackSizeComponent(int maxStackSize) { public int getMaxStackSize() { return this.maxStackSize; } - - @Override - public void apply(@NotNull BuildContext context, @NotNull ItemStack itemStack, @Nullable Player player) { - ItemMeta itemMeta = itemStack.getItemMeta(); - if (itemMeta != null) { - itemMeta.setMaxStackSize(this.maxStackSize); - itemStack.setItemMeta(itemMeta); - } - } } - diff --git a/Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotAttackRangeItemComponentLoader.java b/Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotAttackRangeItemComponentLoader.java new file mode 100644 index 00000000..f75044db --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotAttackRangeItemComponentLoader.java @@ -0,0 +1,35 @@ +package fr.maxlego08.menu.itemstack.components.spigot; + +import fr.maxlego08.menu.api.context.MenuItemStackContext; +import fr.maxlego08.menu.api.itemstack.ItemComponent; +import fr.maxlego08.menu.loader.components.AbstractAttackRangeItemComponentLoader; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +public class SpigotAttackRangeItemComponentLoader extends AbstractAttackRangeItemComponentLoader { + + @Override + public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { + if (componentSection == null) { + return null; + } + float minReach = getMinReach(componentSection, path); + float maxReach = getMaxReach(componentSection, path); + float minCreativeReach = getMinCreativeReach(componentSection, path); + float maxCreativeReach = getMaxCreativeReach(componentSection, path); + float hitboxMargin = getHitboxMargin(componentSection, path); + float mobFactor = getMobFactor(componentSection, path); + return new SpigotAttackRangeComponent( + minReach, + maxReach, + minCreativeReach, + maxCreativeReach, + hitboxMargin, + mobFactor + ); + } +} diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotAttackRangeItemComponentLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/AbstractAttackRangeItemComponentLoader.java similarity index 58% rename from src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotAttackRangeItemComponentLoader.java rename to Common/src/main/java/fr/maxlego08/menu/loader/components/AbstractAttackRangeItemComponentLoader.java index 00f75342..4a469a33 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotAttackRangeItemComponentLoader.java +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/AbstractAttackRangeItemComponentLoader.java @@ -1,72 +1,73 @@ -package fr.maxlego08.menu.loader.components.spigot; +package fr.maxlego08.menu.loader.components; import fr.maxlego08.menu.api.configuration.Configuration; -import fr.maxlego08.menu.api.context.MenuItemStackContext; -import fr.maxlego08.menu.api.itemstack.ItemComponent; -import fr.maxlego08.menu.api.itemstack.components.AttackRangeComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; import fr.maxlego08.menu.zcore.logger.Logger; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.io.File; +public abstract class AbstractAttackRangeItemComponentLoader extends ItemComponentLoader { -public class SpigotAttackRangeItemComponentLoader extends ItemComponentLoader { - - public SpigotAttackRangeItemComponentLoader() { + public AbstractAttackRangeItemComponentLoader() { super("attack-range"); } - @Override - public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { - if (componentSection == null) { - return null; - } - double minReach = componentSection.getDouble("min-reach", 0f); + protected float getMinReach(ConfigurationSection section, String path) { + double minReach = section.getDouble("min-reach", 0f); if (minReach > 64f || minReach < 0f) { if (Configuration.enableDebug) Logger.info("Invalid min-reach value in attack-range component at path: " + path + ". Value: " + minReach + ". It must be between 0 and 64. Using default value 0f."); minReach = 0f; } - double maxReach = componentSection.getDouble("max-reach", 3f); + return (float) minReach; + } + + protected float getMaxReach(ConfigurationSection section, String path) { + double maxReach = section.getDouble("max-reach", 3f); if (maxReach > 64f || maxReach < 0f) { if (Configuration.enableDebug) Logger.info("Invalid max-reach value in attack-range component at path: " + path + ". Value: " + maxReach + ". It must be between 0 and 64. Using default value 3f."); maxReach = 3f; } - double minCreativeReach = componentSection.getDouble("min-creative-reach", 0f); + return (float) maxReach; + } + + protected float getMinCreativeReach(ConfigurationSection section, String path) { + double minCreativeReach = section.getDouble("min-creative-reach", 0f); if (minCreativeReach > 64f || minCreativeReach < 0f) { if (Configuration.enableDebug) Logger.info("Invalid min-creative-reach value in attack-range component at path: " + path + ". Value: " + minCreativeReach + ". It must be between 0 and 64. Using default value 0f."); minCreativeReach = 0f; } - double maxCreativeReach = componentSection.getDouble("max-creative-reach", 5f); + return (float) minCreativeReach; + } + + protected float getMaxCreativeReach(ConfigurationSection section, String path) { + double maxCreativeReach = section.getDouble("max-creative-reach", 5f); if (maxCreativeReach > 64f || maxCreativeReach < 0f) { if (Configuration.enableDebug) Logger.info("Invalid max-creative-reach value in attack-range component at path: " + path + ". Value: " + maxCreativeReach + ". It must be between 0 and 64. Using default value 5f."); maxCreativeReach = 5f; } - double hitboxMargin = componentSection.getDouble("hitbox-margin", 0.3f); + return (float) maxCreativeReach; + } + + protected float getHitboxMargin(ConfigurationSection section, String path) { + double hitboxMargin = section.getDouble("hitbox-margin", 0.3f); if (hitboxMargin < 0f || hitboxMargin > 1f) { if (Configuration.enableDebug) Logger.info("Invalid hitbox-margin value in attack-range component at path: " + path + ". Value: " + hitboxMargin + ". It must be between 0 and 1. Using default value 0.3f."); hitboxMargin = 0.3f; } - double mobFactor = componentSection.getDouble("mob-factor", 1f); + return (float) hitboxMargin; + } + + protected float getMobFactor(ConfigurationSection section, String path) { + double mobFactor = section.getDouble("mob-factor", 1f); if (mobFactor < 0f || mobFactor > 2f) { if (Configuration.enableDebug) Logger.info("Invalid mob-factor value in attack-range component at path: " + path + ". Value: " + mobFactor + ". It must be between 0 and 2. Using default value 1f."); mobFactor = 1f; } - return new AttackRangeComponent( - (float) minReach, - (float) maxReach, - (float) minCreativeReach, - (float) maxCreativeReach, - (float) hitboxMargin, - (float) mobFactor - ); + return (float) mobFactor; } } diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/itemstack/components/paper/PaperAttackRangeComponent.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/itemstack/components/paper/PaperAttackRangeComponent.java new file mode 100644 index 00000000..136bc2c6 --- /dev/null +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/itemstack/components/paper/PaperAttackRangeComponent.java @@ -0,0 +1,25 @@ +package fr.maxlego08.menu.itemstack.components.paper; + +import fr.maxlego08.menu.api.context.BuildContext; +import fr.maxlego08.menu.api.itemstack.components.AttackRangeComponent; +import io.papermc.paper.datacomponent.DataComponentTypes; +import io.papermc.paper.datacomponent.item.AttackRange; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class PaperAttackRangeComponent extends AttackRangeComponent { + private final AttackRange attackRange; + + public PaperAttackRangeComponent(AttackRange attackRange) { + super(attackRange.minReach(), attackRange.maxReach(), attackRange.minCreativeReach(), attackRange.maxCreativeReach(), attackRange.hitboxMargin(), attackRange.mobFactor()); + this.attackRange = attackRange; + } + + + @Override + public void apply(@NotNull BuildContext context, @NotNull ItemStack itemStack, @Nullable Player player) { + itemStack.setData(DataComponentTypes.ATTACK_RANGE, this.attackRange); + } +} diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/itemstack/components/paper/PaperMaxStackSizeComponent.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/itemstack/components/paper/PaperMaxStackSizeComponent.java new file mode 100644 index 00000000..8c588c2a --- /dev/null +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/itemstack/components/paper/PaperMaxStackSizeComponent.java @@ -0,0 +1,21 @@ +package fr.maxlego08.menu.itemstack.components.paper; + +import fr.maxlego08.menu.api.context.BuildContext; +import fr.maxlego08.menu.api.itemstack.components.MaxStackSizeComponent; +import io.papermc.paper.datacomponent.DataComponentTypes; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class PaperMaxStackSizeComponent extends MaxStackSizeComponent { + + public PaperMaxStackSizeComponent(int maxStackSize) { + super(maxStackSize); + } + + @Override + public void apply(@NotNull BuildContext context, @NotNull ItemStack itemStack, @Nullable Player player) { + itemStack.setData(DataComponentTypes.MAX_STACK_SIZE, this.maxStackSize); + } +} diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperAttackRangeItemComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperAttackRangeItemComponentLoader.java new file mode 100644 index 00000000..6d411edc --- /dev/null +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperAttackRangeItemComponentLoader.java @@ -0,0 +1,34 @@ +package fr.maxlego08.menu.loader.components.paper; + +import fr.maxlego08.menu.api.context.MenuItemStackContext; +import fr.maxlego08.menu.api.itemstack.ItemComponent; +import fr.maxlego08.menu.itemstack.components.paper.PaperAttackRangeComponent; +import fr.maxlego08.menu.loader.components.AbstractAttackRangeItemComponentLoader; +import io.papermc.paper.datacomponent.item.AttackRange; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +public class PaperAttackRangeItemComponentLoader extends AbstractAttackRangeItemComponentLoader { + + @Override + public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { + if (componentSection == null) { + return null; + } + + AttackRange.Builder builder = AttackRange.attackRange(); + + builder.minReach(getMinReach(componentSection, path)); + builder.maxReach(getMaxReach(componentSection, path)); + builder.minCreativeReach(getMinCreativeReach(componentSection, path)); + builder.maxCreativeReach(getMaxCreativeReach(componentSection, path)); + builder.hitboxMargin(getHitboxMargin(componentSection, path)); + builder.mobFactor(getMobFactor(componentSection, path)); + + return new PaperAttackRangeComponent(builder.build()); + } +} diff --git a/src/main/java/fr/maxlego08/menu/ZComponentsManager.java b/src/main/java/fr/maxlego08/menu/ZComponentsManager.java index 57cb8ff1..7449050d 100644 --- a/src/main/java/fr/maxlego08/menu/ZComponentsManager.java +++ b/src/main/java/fr/maxlego08/menu/ZComponentsManager.java @@ -8,6 +8,7 @@ import fr.maxlego08.menu.common.factory.VariantItemComponentLoaderFactory; import fr.maxlego08.menu.common.utils.nms.NmsVersion; import fr.maxlego08.menu.itemstack.components.paper.PaperVariantComponent; +import fr.maxlego08.menu.itemstack.components.spigot.SpigotAttackRangeItemComponentLoader; import fr.maxlego08.menu.itemstack.components.spigot.SpigotVariantComponent; import fr.maxlego08.menu.loader.components.paper.*; import fr.maxlego08.menu.loader.components.spigot.*; @@ -63,7 +64,7 @@ public void initializeDefaultComponents(MenuPlugin plugin) { this.registerComponent(new SpigotMapColorItemComponentLoader()); this.registerComponent(new SpigotMapIdItemComponentLoader()); this.registerComponent(new SpigotMaxDamageItemComponentLoader()); - this.registerComponent(new SpigotMaxStackSizeItemComponentLoader()); + this.registerComponent(new MaxStackSizeItemComponentLoader(plugin)); this.registerComponent(new SpigotOminousBottleAmplifierItemComponentLoader()); this.registerComponent(new SpigotPotionContentsItemComponentLoader()); this.registerComponent(new SpigotRarityItemComponentLoader()); @@ -123,7 +124,7 @@ public void initializeDefaultComponents(MenuPlugin plugin) { this.registerComponent(new SpigotProfileItemComponentLoader()); if (currentVersion.is1_21_11OrNewer()){ // 1.21.11+ - this.registerComponent(new SpigotAttackRangeItemComponentLoader()); + this.registerComponent(plugin.isPaperOrFolia() ? new PaperAttackRangeItemComponentLoader() : new SpigotAttackRangeItemComponentLoader()); this.registerComponent(new SpigotDamageTypeItemComponentLoader()); this.registerComponent(new SpigotKineticWeaponItemComponentLoader()); this.registerComponent(new SpigotMinimumAttackChargeItemComponentLoader()); diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMaxStackSizeItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/MaxStackSizeItemComponentLoader.java similarity index 56% rename from src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMaxStackSizeItemComponentLoader.java rename to src/main/java/fr/maxlego08/menu/loader/components/spigot/MaxStackSizeItemComponentLoader.java index 66ba4a62..fb234e1c 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMaxStackSizeItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/MaxStackSizeItemComponentLoader.java @@ -1,9 +1,11 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.MenuPlugin; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; -import fr.maxlego08.menu.api.itemstack.components.MaxStackSizeComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; +import fr.maxlego08.menu.itemstack.components.paper.PaperMaxStackSizeComponent; +import fr.maxlego08.menu.itemstack.components.spigot.SpigotMaxStackSizeComponent; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.jetbrains.annotations.NotNull; @@ -11,16 +13,21 @@ import java.io.File; -public class SpigotMaxStackSizeItemComponentLoader extends ItemComponentLoader { +public class MaxStackSizeItemComponentLoader extends ItemComponentLoader { + private final MenuPlugin plugin; - public SpigotMaxStackSizeItemComponentLoader(){ + public MaxStackSizeItemComponentLoader(MenuPlugin plugin){ super("max-stack-size"); + this.plugin = plugin; } @Override public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { path = normalizePath(path); int maxStackSize = configuration.getInt(path); - return maxStackSize > 0 ? new MaxStackSizeComponent(maxStackSize) : null; + if (maxStackSize > 0) { + return this.plugin.isPaperOrFolia() ? new PaperMaxStackSizeComponent(maxStackSize) : new SpigotMaxStackSizeComponent(maxStackSize); + } + return null; } } From 4fb52e6a6b6822eae4875826f826833edcc23325 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Sun, 12 Apr 2026 18:04:24 +0200 Subject: [PATCH 03/24] feat: add Spigot components for attack range + fix maxstacksize parse after setAmount --- .../fr/maxlego08/menu/ZMenuItemStack.java | 11 +++++-- .../spigot/SpigotAttackRangeComponent.java | 32 +++++++++++++++++++ .../spigot/SpigotMaxStackSizeComponent.java | 27 ++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotAttackRangeComponent.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotMaxStackSizeComponent.java diff --git a/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java b/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java index 11db451b..9f60350a 100644 --- a/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java +++ b/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java @@ -144,7 +144,8 @@ public ItemStack build(BuildContext context) { performanceDebug.end(); performanceDebug.start("build.createItemStack"); - ItemStack itemStack = this.applySpecialItemStack(player, offlinePlayer, placeholders, amount, context.getItemStack() != null ? context.getItemStack() : this.createItemStack(player, placeholders, offlinePlayer, amount)); + boolean editContextItem = context.getItemStack() != null; + ItemStack itemStack = this.applySpecialItemStack(player, offlinePlayer, placeholders, amount, editContextItem ? context.getItemStack() : this.createItemStack(player, placeholders, offlinePlayer, amount)); performanceDebug.end(); performanceDebug.start("build.applyItemMeta"); @@ -172,6 +173,13 @@ public ItemStack build(BuildContext context) { } performanceDebug.end(); + performanceDebug.start("build.setStackSize"); + if (!editContextItem) { + itemStack.setAmount(Math.max(1 , amount)); + } + performanceDebug.end(); + + if (!this.needPlaceholderAPI && Configuration.enableCacheItemStack) { this.cacheItemStack = itemStack; } @@ -278,7 +286,6 @@ private ItemStack applySpecialItemStack(Player player, OfflinePlayer offlinePlay if (this.leatherArmor != null) { itemStack = this.leatherArmor.toItemStack(amount); } - itemStack.setAmount(Math.max(1 , amount)); if (this.durability != null) { int dura = this.parseDura(offlinePlayer == null ? player : offlinePlayer, placeholders); diff --git a/Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotAttackRangeComponent.java b/Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotAttackRangeComponent.java new file mode 100644 index 00000000..549b605f --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotAttackRangeComponent.java @@ -0,0 +1,32 @@ +package fr.maxlego08.menu.itemstack.components.spigot; + +import fr.maxlego08.menu.api.context.BuildContext; +import fr.maxlego08.menu.api.itemstack.components.AttackRangeComponent; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@SuppressWarnings("unused") +public class SpigotAttackRangeComponent extends AttackRangeComponent { + + public SpigotAttackRangeComponent(float minReach, float maxReach, float minCreativeReach, float maxCreativeReach, float hitboxMargin, float mobFactor) { + super(minReach, maxReach, minCreativeReach, maxCreativeReach, hitboxMargin, mobFactor); + } + + @Override + public void apply(@NotNull BuildContext context, @NotNull ItemStack itemStack, @Nullable Player player) { + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta == null) return; + org.bukkit.inventory.meta.components.AttackRangeComponent attackRange = itemMeta.getAttackRange(); + attackRange.setMinReach(this.minReach); + attackRange.setMaxReach(this.maxReach); + attackRange.setMinCreativeReach(this.minCreativeReach); + attackRange.setMaxCreativeReach(this.maxCreativeReach); + attackRange.setHitboxMargin(this.hitboxMargin); + attackRange.setMobFactor(this.mobFactor); + itemStack.setItemMeta(itemMeta); + } + +} diff --git a/Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotMaxStackSizeComponent.java b/Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotMaxStackSizeComponent.java new file mode 100644 index 00000000..d4aff75d --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotMaxStackSizeComponent.java @@ -0,0 +1,27 @@ +package fr.maxlego08.menu.itemstack.components.spigot; + +import fr.maxlego08.menu.api.context.BuildContext; +import fr.maxlego08.menu.api.itemstack.components.MaxStackSizeComponent; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@SuppressWarnings("unused") +public class SpigotMaxStackSizeComponent extends MaxStackSizeComponent { + + public SpigotMaxStackSizeComponent(int maxStackSize) { + super(maxStackSize); + } + + @Override + public void apply(@NotNull BuildContext context, @NotNull ItemStack itemStack, @Nullable Player player) { + ItemMeta itemMeta = itemStack.getItemMeta(); + if (itemMeta != null) { + itemMeta.setMaxStackSize(this.maxStackSize); + itemStack.setItemMeta(itemMeta); + } + } +} + From d7e43e1fd8ca22d41300927663d87ac48d3d034a Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Tue, 28 Apr 2026 15:14:15 +0200 Subject: [PATCH 04/24] chore: update Gradle wrapper to version 9.3.0 (support java 25)) --- gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 46175 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 13 ++++++------- gradlew.bat | 5 +++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..61285a659d17295f1de7c53e24fdf13ad755c379 100644 GIT binary patch delta 38026 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ca025c83..19a6bdeb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index b740cf13..adff685a 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 25da30db..c4bdd3ab 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell From 96b5dd0665494da3ebccae98652318a0cc6a344a Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Tue, 28 Apr 2026 15:15:25 +0200 Subject: [PATCH 05/24] chore: update Gradle wrapper to version 9.4.0 --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 19a6bdeb..dbc3ce4a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 5f5bc3d929bac8854a5edd2084ea57b31cad089d Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Tue, 28 Apr 2026 17:30:44 +0200 Subject: [PATCH 06/24] feat: add new annotations for component loaders and update plugin.yml dependencies + use Reflexion to load ItemComponentLoader --- .../menu/api/annotations/ComponentLoader.java | 11 ++ .../menu/api/annotations/PaperOnly.java | 11 ++ .../menu/api/annotations/SinceVersion.java | 15 ++ .../menu/api/annotations/SpigotOnly.java | 12 ++ .../menu/api/annotations/UntilVersion.java | 16 ++ .../fr/maxlego08/menu/api/utils/Message.java | 2 +- .../menu/api/utils/PlatformType.java | 60 ++++++++ .../menu/api/utils/ReflectionsCache.java | 51 +++++++ .../menu/api/utils/cuboid/Cuboid.java | 2 +- .../menu/common/MinecraftVersion.java | 101 ++++++++++++ .../maxlego08/menu/common/VersionFilter.java | 58 +++++++ .../common/utils/nms/ItemStackCompound.java | 2 +- .../menu/common/utils/nms/NMSUtils.java | 28 ++-- .../menu/common/utils/nms/NmsVersion.java | 41 ++--- .../SpigotAttackRangeItemComponentLoader.java | 6 + ...gotCustomModelDataItemComponentLoader.java | 6 + .../PaperAttackRangeItemComponentLoader.java | 6 + .../PaperCustomModelDataComponentLoader.java | 6 + .../PaperCustomNameItemComponentLoader.java | 6 + ...perDeathProtectionItemComponentLoader.java | 6 + ...tangibleProjectileItemComponentLoader.java | 6 + ...aperMapDecorationsItemComponentLoader.java | 6 + ...aperNoteBlockSoundItemComponentLoader.java | 6 + ...aperPotDecorationsItemComponentLoader.java | 6 + ...idesBannerPatternsItemComponentLoader.java | 6 + ...ovidesTrimMaterialItemComponentLoader.java | 6 + .../PaperRepairableItemComponentLoader.java | 6 + ...aperTooltipDisplayItemComponentLoader.java | 6 + build.gradle.kts | 1 + .../fr/maxlego08/menu/ZComponentsManager.java | 144 +++++------------- .../MaxStackSizeItemComponentLoader.java | 4 + ...AttributeModifiersItemComponentLoader.java | 4 + ...igotBannerPatternsItemComponentLoader.java | 4 + .../SpigotBaseColorItemComponentLoader.java | 4 + .../SpigotBlockStateItemComponentLoader.java | 4 + ...pigotBlocksAttacksItemComponentLoader.java | 4 + .../SpigotBreakSoundItemComponentLoader.java | 4 + ...igotBundleContentsItemComponentLoader.java | 4 + ...ChargedProjectilesItemComponentLoader.java | 4 + .../SpigotConsumableItemComponentLoader.java | 4 + .../SpigotContainerItemComponentLoader.java | 4 + ...pigotContainerLootItemComponentLoader.java | 4 + .../SpigotCustomDataItemComponentLoader.java | 4 + .../SpigotDamageItemComponentLoader.java | 4 + ...gotDamageResistantItemComponentLoader.java | 4 + .../SpigotDamageTypeItemComponentLoader.java | 4 + .../SpigotDyedColorItemComponentLoader.java | 4 + .../SpigotEnchantableItemComponentLoader.java | 4 + ...tmentGlintOverrideItemComponentLoader.java | 4 + ...SpigotEnchantmentsItemComponentLoader.java | 4 + .../SpigotEquippableItemComponentLoader.java | 4 + ...tFireworkExplosionItemComponentLoader.java | 4 + .../SpigotFireworksItemComponentLoader.java | 4 + .../spigot/SpigotFoodItemComponentLoader.java | 4 + .../SpigotGliderItemComponentLoader.java | 4 + .../SpigotInstrumentItemComponentLoader.java | 4 + .../SpigotItemModelItemComponentLoader.java | 4 + .../SpigotItemNameItemComponentLoader.java | 4 + ...gotJukeboxPlayableItemComponentLoader.java | 4 + ...pigotKineticWeaponItemComponentLoader.java | 4 + ...otLodestoneTrackerItemComponentLoader.java | 4 + .../spigot/SpigotLoreItemComponentLoader.java | 4 + .../SpigotMapColorItemComponentLoader.java | 4 + .../SpigotMapIdItemComponentLoader.java | 4 + .../SpigotMaxDamageItemComponentLoader.java | 4 + ...inimumAttackChargeItemComponentLoader.java | 4 + ...ousBottleAmplifierItemComponentLoader.java | 4 + ...igotPiercingWeaponItemComponentLoader.java | 4 + ...igotPotionContentsItemComponentLoader.java | 4 + ...otionDurationScaleItemComponentLoader.java | 4 + .../SpigotProfileItemComponentLoader.java | 4 + .../SpigotRarityItemComponentLoader.java | 4 + .../SpigotRecipesItemComponentLoader.java | 4 + .../SpigotRepairCostItemComponentLoader.java | 4 + ...pigotStoredEnchantItemComponentLoader.java | 4 + ...piciousStewEffectsItemComponentLoader.java | 4 + ...igotSwingAnimationItemComponentLoader.java | 4 + .../spigot/SpigotToolItemComponentLoader.java | 4 + .../SpigotTooltipDisplayComponentLoader.java | 6 + ...SpigotTooltipStyleItemComponentLoader.java | 4 + .../spigot/SpigotTrimItemComponentLoader.java | 4 + .../SpigotUnbreakableItemComponentLoader.java | 4 + .../SpigotUseCooldownItemComponentLoader.java | 4 + .../SpigotUseEffectsItemComponentLoader.java | 4 + ...SpigotUseRemainderItemComponentLoader.java | 4 + .../SpigotWeaponItemComponentLoader.java | 4 + ...ritableBookContentItemComponentLoader.java | 4 + ...WrittenBookContentItemComponentLoader.java | 4 + .../menu/zcore/utils/meta/ClassicMeta.java | 2 +- .../menu/zcore/utils/plugins/Metrics.java | 12 +- .../zcore/utils/plugins/VersionChecker.java | 6 +- .../zcore/utils/toast/AdvancementHandler.java | 2 +- src/main/resources/commands/commands.yml | 2 +- src/main/resources/commands/punish/punish.yml | 2 +- .../resources/inventories/example_punish.yml | 2 +- .../resources/patterns/pattern_example.yml | 2 +- src/main/resources/plugin.yml | 3 +- 97 files changed, 749 insertions(+), 157 deletions(-) create mode 100644 API/src/main/java/fr/maxlego08/menu/api/annotations/ComponentLoader.java create mode 100644 API/src/main/java/fr/maxlego08/menu/api/annotations/PaperOnly.java create mode 100644 API/src/main/java/fr/maxlego08/menu/api/annotations/SinceVersion.java create mode 100644 API/src/main/java/fr/maxlego08/menu/api/annotations/SpigotOnly.java create mode 100644 API/src/main/java/fr/maxlego08/menu/api/annotations/UntilVersion.java create mode 100644 API/src/main/java/fr/maxlego08/menu/api/utils/PlatformType.java create mode 100644 API/src/main/java/fr/maxlego08/menu/api/utils/ReflectionsCache.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/common/MinecraftVersion.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/common/VersionFilter.java diff --git a/API/src/main/java/fr/maxlego08/menu/api/annotations/ComponentLoader.java b/API/src/main/java/fr/maxlego08/menu/api/annotations/ComponentLoader.java new file mode 100644 index 00000000..7f3ba552 --- /dev/null +++ b/API/src/main/java/fr/maxlego08/menu/api/annotations/ComponentLoader.java @@ -0,0 +1,11 @@ +package fr.maxlego08.menu.api.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ComponentLoader { +} diff --git a/API/src/main/java/fr/maxlego08/menu/api/annotations/PaperOnly.java b/API/src/main/java/fr/maxlego08/menu/api/annotations/PaperOnly.java new file mode 100644 index 00000000..51913f3d --- /dev/null +++ b/API/src/main/java/fr/maxlego08/menu/api/annotations/PaperOnly.java @@ -0,0 +1,11 @@ +package fr.maxlego08.menu.api.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface PaperOnly { +} diff --git a/API/src/main/java/fr/maxlego08/menu/api/annotations/SinceVersion.java b/API/src/main/java/fr/maxlego08/menu/api/annotations/SinceVersion.java new file mode 100644 index 00000000..2d2a3c3c --- /dev/null +++ b/API/src/main/java/fr/maxlego08/menu/api/annotations/SinceVersion.java @@ -0,0 +1,15 @@ +package fr.maxlego08.menu.api.annotations; + +import org.jetbrains.annotations.NotNull; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface SinceVersion { + @NotNull + String value(); +} diff --git a/API/src/main/java/fr/maxlego08/menu/api/annotations/SpigotOnly.java b/API/src/main/java/fr/maxlego08/menu/api/annotations/SpigotOnly.java new file mode 100644 index 00000000..986a8f68 --- /dev/null +++ b/API/src/main/java/fr/maxlego08/menu/api/annotations/SpigotOnly.java @@ -0,0 +1,12 @@ +package fr.maxlego08.menu.api.annotations; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface SpigotOnly { +} diff --git a/API/src/main/java/fr/maxlego08/menu/api/annotations/UntilVersion.java b/API/src/main/java/fr/maxlego08/menu/api/annotations/UntilVersion.java new file mode 100644 index 00000000..b5739a7b --- /dev/null +++ b/API/src/main/java/fr/maxlego08/menu/api/annotations/UntilVersion.java @@ -0,0 +1,16 @@ +package fr.maxlego08.menu.api.annotations; + +import org.jetbrains.annotations.NotNull; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface UntilVersion { + + @NotNull + String value(); +} diff --git a/API/src/main/java/fr/maxlego08/menu/api/utils/Message.java b/API/src/main/java/fr/maxlego08/menu/api/utils/Message.java index a21e4323..d8a5a66d 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/utils/Message.java +++ b/API/src/main/java/fr/maxlego08/menu/api/utils/Message.java @@ -72,7 +72,7 @@ public enum Message implements IMessage { DESCRIPTION_OPEN("Allows you to open an inventory"), DESCRIPTION_SAVE("Allows you to save the item in your hand"), DESCRIPTION_RELOAD("Allows you to reload configuration files"), - DESCRIPTION_VERSION("Show plugin version"), + DESCRIPTION_VERSION("Show plugin value"), DESCRIPTION_LIST("Inventory list"), DESCRIPTION_TEST_DUPE("Test dupe"), DESCRIPTION_OPEN_ITEM("Give open item"), diff --git a/API/src/main/java/fr/maxlego08/menu/api/utils/PlatformType.java b/API/src/main/java/fr/maxlego08/menu/api/utils/PlatformType.java new file mode 100644 index 00000000..c6d38500 --- /dev/null +++ b/API/src/main/java/fr/maxlego08/menu/api/utils/PlatformType.java @@ -0,0 +1,60 @@ +package fr.maxlego08.menu.api.utils; + +public enum PlatformType { + /** + * Paper server with native Adventure API support. + */ + PAPER, + + /** + * Spigot server requiring Adventure Platform wrapper. + */ + SPIGOT; + + private static PlatformType detectedType; + + /** + * Detects the server platform type by checking for Paper-specific classes. + * + * @return The detected platform type + */ + public static PlatformType detect() { + if (detectedType == null) { + try { + Class.forName("io.papermc.paper.text.PaperComponents"); + detectedType = PAPER; + } catch (ClassNotFoundException e) { + detectedType = SPIGOT; + } + } + return detectedType; + } + + /** + * Gets the detected platform type. + * If detection hasn't been run yet, it will be performed. + * + * @return The platform type + */ + public static PlatformType get() { + return detect(); + } + + /** + * Checks if the current platform is Paper. + * + * @return true if running on Paper, false otherwise + */ + public static boolean isPaper() { + return get() == PAPER; + } + + /** + * Checks if the current platform is Spigot. + * + * @return true if running on Spigot, false otherwise + */ + public static boolean isSpigot() { + return get() == SPIGOT; + } +} diff --git a/API/src/main/java/fr/maxlego08/menu/api/utils/ReflectionsCache.java b/API/src/main/java/fr/maxlego08/menu/api/utils/ReflectionsCache.java new file mode 100644 index 00000000..a3ea6974 --- /dev/null +++ b/API/src/main/java/fr/maxlego08/menu/api/utils/ReflectionsCache.java @@ -0,0 +1,51 @@ +package fr.maxlego08.menu.api.utils; + +import org.bukkit.plugin.java.JavaPlugin; +import org.reflections.Reflections; +import org.reflections.scanners.Scanners; +import org.reflections.util.ConfigurationBuilder; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class ReflectionsCache { + + private static ReflectionsCache instance; + + private final Map cache; + + private ReflectionsCache() { + this.cache = new ConcurrentHashMap<>(); + } + + public static synchronized ReflectionsCache getInstance() { + if (instance == null) { + instance = new ReflectionsCache(); + } + return instance; + } + + public Reflections getOrCreate(JavaPlugin plugin, String packageName) { + if (packageName == null || packageName.trim().isEmpty()) { + throw new IllegalArgumentException("Package name cannot be null or empty"); + } + + ClassLoader classLoader = plugin.getClass().getClassLoader(); + CacheKey key = new CacheKey(packageName, classLoader); + + return cache.computeIfAbsent(key, k -> createReflections(classLoader, packageName)); + } + + private Reflections createReflections(ClassLoader classLoader, String packageName) { + return new Reflections(new ConfigurationBuilder() + .forPackage(packageName, classLoader) + .addClassLoaders(classLoader) + .setScanners(Scanners.TypesAnnotated, Scanners.SubTypes)); + } + + private record CacheKey(String packageName, int classLoaderHash) { + CacheKey(String packageName, ClassLoader classLoader) { + this(packageName, System.identityHashCode(classLoader)); + } + } +} diff --git a/API/src/main/java/fr/maxlego08/menu/api/utils/cuboid/Cuboid.java b/API/src/main/java/fr/maxlego08/menu/api/utils/cuboid/Cuboid.java index ed3426b2..0f4897e2 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/utils/cuboid/Cuboid.java +++ b/API/src/main/java/fr/maxlego08/menu/api/utils/cuboid/Cuboid.java @@ -594,7 +594,7 @@ public Block getRelativeBlock(int x, int y, int z) { /** * Get a block relative to the lower NE point of the Cuboid in the given - * World. This version of getRelativeBlock() should be used if being called + * World. This value of getRelativeBlock() should be used if being called * many times, to avoid excessive calls to getWorld(). * * @param w - The world diff --git a/Common/src/main/java/fr/maxlego08/menu/common/MinecraftVersion.java b/Common/src/main/java/fr/maxlego08/menu/common/MinecraftVersion.java new file mode 100644 index 00000000..171f2131 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/common/MinecraftVersion.java @@ -0,0 +1,101 @@ +package fr.maxlego08.menu.common; + +import fr.maxlego08.menu.zcore.logger.Logger; +import org.bukkit.Bukkit; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class MinecraftVersion implements Comparable { + + private static MinecraftVersion currentVersion; + + private final int major; + private final int minor; + private final int patch; + + private MinecraftVersion(int major, int minor, int patch) { + this.major = major; + this.minor = minor; + this.patch = patch; + } + + public static MinecraftVersion getCurrentVersion() { + if (currentVersion == null) { + currentVersion = parse(Bukkit.getBukkitVersion()); + } + return currentVersion; + } + + @NotNull + public static MinecraftVersion parse(@Nullable String rawVersion) { + if (rawVersion == null || rawVersion.isBlank()) { + return new MinecraftVersion(0, 0, 0); + } + String clean = rawVersion.contains("-") ? rawVersion.substring(0, rawVersion.indexOf('-')) : rawVersion; + String[] parts = clean.split("\\."); + try { + int major = parts.length > 0 ? Integer.parseInt(parts[0]) : 0; + int minor = parts.length > 1 ? Integer.parseInt(parts[1]) : 0; + int patch = parts.length > 2 ? Integer.parseInt(parts[2]) : 0; + return new MinecraftVersion(major, minor, patch); + } catch (NumberFormatException e) { + Logger.info("Could not parse Minecraft value '" + rawVersion + "'. Version-gated classes will be skipped. (" + e.getMessage() + ")", Logger.LogType.WARNING); + return new MinecraftVersion(0, 0, 0); + } + } + + /** + * Returns {@code true} if this value is greater than or equal to {@code other}. + */ + public boolean isAtLeast(MinecraftVersion other) { + return compareTo(other) >= 0; + } + + /** + * Returns {@code true} if this value is less than or equal to {@code other}. + */ + public boolean isAtMost(MinecraftVersion other) { + return compareTo(other) <= 0; + } + + + public int getMajor() { + return this.major; + } + + public int getMinor() { + return this.minor; + } + + public int getPatch() { + return this.patch; + } + + @Override + public int compareTo(MinecraftVersion other) { + if (this.major != other.major) { + return Integer.compare(this.major, other.major); + } + if (this.minor != other.minor) { + return Integer.compare(this.minor, other.minor); + } + return Integer.compare(this.patch, other.patch); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof MinecraftVersion other)) return false; + return this.major == other.major && this.minor == other.minor && this.patch == other.patch; + } + + @Override + public int hashCode() { + return 31 * (31 * major + minor) + patch; + } + + @Override + public String toString() { + return major + "." + minor + (patch != 0 ? "." + patch : ""); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/common/VersionFilter.java b/Common/src/main/java/fr/maxlego08/menu/common/VersionFilter.java new file mode 100644 index 00000000..9c7df306 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/common/VersionFilter.java @@ -0,0 +1,58 @@ +package fr.maxlego08.menu.common; + +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.api.annotations.SpigotOnly; +import fr.maxlego08.menu.api.annotations.UntilVersion; +import fr.maxlego08.menu.api.configuration.Configuration; +import fr.maxlego08.menu.api.utils.PlatformType; +import fr.maxlego08.menu.zcore.logger.Logger; +import org.jetbrains.annotations.NotNull; + +public class VersionFilter { + + private VersionFilter() {} + + public static boolean passes(@NotNull Class clazz) { + if (clazz.isAnnotationPresent(PaperOnly.class) && !PlatformType.isPaper()) { + if (Configuration.enableDebug) { + Logger.info("Class " + clazz.getSimpleName() + " is annotated with @PaperOnly but the server is not running Paper or Folia. Skipping.", Logger.LogType.INFO); + } + return false; + } + if (clazz.isAnnotationPresent(SpigotOnly.class) && PlatformType.isPaper()) { + if (Configuration.enableDebug) { + Logger.info("Class " + clazz.getSimpleName() + " is annotated with @SpigotOnly but the server is running Paper or Folia. Skipping.", Logger.LogType.INFO); + } + return false; + } + + MinecraftVersion serverVersion = MinecraftVersion.getCurrentVersion(); + + SinceVersion since = clazz.getAnnotation(SinceVersion.class); + if (since != null) { + MinecraftVersion minimum = MinecraftVersion.parse(since.value()); + if (!serverVersion.isAtLeast(minimum)) { + if (Configuration.enableDebug) { + Logger.info("Class " + clazz.getSimpleName() + " is annotated with @SinceVersion(" + since.value() + ") but the server value is " + serverVersion + ". Skipping.", Logger.LogType.INFO); + } + return false; + } + } + + UntilVersion until = clazz.getAnnotation(UntilVersion.class); + if (until != null) { + MinecraftVersion maximum = MinecraftVersion.parse(until.value()); + if (!serverVersion.isAtMost(maximum)) { + if (Configuration.enableDebug) { + Logger.info("Class " + clazz.getSimpleName() + " is annotated with @UntilVersion(" + until.value() + ") but the server value is " + serverVersion + ". Skipping.", Logger.LogType.INFO); + } + return false; + } + } + + return true; + + } + +} diff --git a/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/ItemStackCompound.java b/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/ItemStackCompound.java index c6e796eb..3821a093 100644 --- a/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/ItemStackCompound.java +++ b/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/ItemStackCompound.java @@ -29,7 +29,7 @@ public class ItemStackCompound { /** * Constructs an ItemStackCompound instance based on the given EnumReflectionCompound. * - * @param reflection The EnumReflectionCompound representing the NBT tag reflection version. + * @param reflection The EnumReflectionCompound representing the NBT tag reflection value. */ public ItemStackCompound(EnumReflectionCompound reflection) { super(); diff --git a/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/NMSUtils.java b/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/NMSUtils.java index df76458f..90642df9 100644 --- a/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/NMSUtils.java +++ b/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/NMSUtils.java @@ -5,9 +5,9 @@ public class NMSUtils { /** - * Get minecraft serveur version + * Get minecraft serveur value * - * @return version + * @return value */ public static double getNMSVersion() { if (version != 0) @@ -24,7 +24,7 @@ public static double getNMSVersion() { } /** - * Check if minecraft version has shulker + * Check if minecraft value has shulker * * @return boolean */ @@ -33,7 +33,7 @@ public static boolean hasShulker() { } /** - * Check if minecraft version has barrel + * Check if minecraft value has barrel * * @return booleab */ @@ -44,7 +44,7 @@ public static boolean hasBarrel() { } /** - * check if version is granther than 1.13 + * check if value is granther than 1.13 * * @return boolean */ @@ -53,7 +53,7 @@ public static boolean isNewVersion() { } /** - * Check if version has one hand + * Check if value has one hand * * @return boolean */ @@ -62,7 +62,7 @@ public static boolean isOneHand() { } /** - * Check is version is minecraft 1.7 + * Check is value is minecraft 1.7 * * @return boolean */ @@ -71,7 +71,7 @@ public static boolean isVeryOldVersion() { } public static double version = getNMSVersion(); /** - * Check if version has itemmeta unbreakable + * Check if value has itemmeta unbreakable * * @return boolean */ @@ -80,7 +80,7 @@ public static boolean isUnbreakable() { } /** - * Check if version is old version of minecraft with old material system + * Check if value is old value of minecraft with old material system * * @return boolean */ @@ -90,7 +90,7 @@ public static boolean isOldVersion() { } /** - * Check if server vesion is new version + * Check if server vesion is new value * * @return boolean */ @@ -101,7 +101,7 @@ public static boolean isNewNMSVersion() { } /** - * Allows to check if the version has the colors in hex + * Allows to check if the value has the colors in hex * * @return boolean */ @@ -111,7 +111,7 @@ public static boolean isHexColor() { } /** - * Allows to check if the version has the colors in hex + * Allows to check if the value has the colors in hex * * @return boolean */ @@ -121,7 +121,7 @@ public static boolean isComponentColor() { } /** - * Check if server version is new version + * Check if server value is new value * * @return boolean */ @@ -133,7 +133,7 @@ public static boolean isNewNBTVersion() { } /** - * Check if server version is new version + * Check if server value is new value * * @return boolean */ diff --git a/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/NmsVersion.java b/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/NmsVersion.java index 56c2cfbf..ccc0b069 100644 --- a/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/NmsVersion.java +++ b/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/NmsVersion.java @@ -72,9 +72,9 @@ public enum NmsVersion { } /** - * Gets the current version of the Bukkit server. + * Gets the current value of the Bukkit server. * - * @return The NmsVersion instance corresponding to the current version. + * @return The NmsVersion instance corresponding to the current value. */ public static NmsVersion getCurrentVersion() { return nmsVersion; @@ -93,8 +93,8 @@ private static NmsVersion getNmsVersion(){ if (currentVersion > highestSupportedVersionEnum.version) { Logger.info(String.format( - "Running Minecraft %s (newer than highest supported version %s). " + - "Please report this version to help us add support. " + + "Running Minecraft %s (newer than highest supported value %s). " + + "Please report this value to help us add support. " + "Check for plugin updates if you experience issues.", currentVersion, highestSupportedVersionEnum.name() @@ -102,6 +102,8 @@ private static NmsVersion getNmsVersion(){ return UNKNOWN; } + Logger.info(String.format("Detected Minecraft value code: %d", currentVersion)); + NmsVersion closest = V_1_12_2; int smallestDifference = Integer.MAX_VALUE; for (NmsVersion value : values()) { @@ -112,11 +114,12 @@ private static NmsVersion getNmsVersion(){ closest = value; } } + Logger.info(String.format("Detected Minecraft value: %s (value code: %d)", closest.name(), closest.version)); return closest; } /** - * Checks if the current version supports PlayerProfiles. + * Checks if the current value supports PlayerProfiles. * * @return True if PlayerProfiles are supported, else False. */ @@ -125,7 +128,7 @@ public boolean hasPlayerProfiles() { } /** - * Checks if the current version uses obfuscated names. + * Checks if the current value uses obfuscated names. * * @return True if names are obfuscated, else False. */ @@ -134,7 +137,7 @@ public boolean hasObfuscatedNames() { } /** - * Checks if the current version supports components. + * Checks if the current value supports components. * * @param isPaper True if the server uses Paper, else False. * @return True if components are supported, else False. @@ -144,16 +147,16 @@ public boolean isComponent(boolean isPaper) { } /** - * Checks if the current version is a legacy item version. + * Checks if the current value is a legacy item value. * - * @return True if the version is legacy, else False. + * @return True if the value is legacy, else False. */ public boolean isItemLegacy() { return version < NmsVersion.V_1_13.version; } /** - * Checks if the current version supports PersistentDataContainer. + * Checks if the current value supports PersistentDataContainer. * * @return True if PersistentDataContainer is supported, else False. */ @@ -162,16 +165,16 @@ public boolean isPdcVersion() { } /** - * Checks if the current version is a legacy version for Skull owners. + * Checks if the current value is a legacy value for Skull owners. * - * @return True if the version is legacy, else False. + * @return True if the value is legacy, else False. */ public boolean isSkullOwnerLegacy() { return version <= NmsVersion.V_1_12.version; } /** - * Checks if the current version supports CustomModelData. + * Checks if the current value supports CustomModelData. * * @return True if CustomModelData is supported, else False. */ @@ -180,27 +183,27 @@ public boolean isCustomModelData() { } /** - * Checks if the current version is a hexadecimal version. + * Checks if the current value is a hexadecimal value. * - * @return True if the version is hexadecimal, else False. + * @return True if the value is hexadecimal, else False. */ public boolean isHexVersion() { return version >= NmsVersion.V_1_16.version; } /** - * Checks if the current version is an Attribute version. + * Checks if the current value is an Attribute value. * - * @return True if the version is Attribute, else False. + * @return True if the value is Attribute, else False. */ public boolean isAttributeVersion() { return version != NmsVersion.V_1_8_8.version; } /** - * Gets the version number associated with the enumeration. + * Gets the value number associated with the enumeration. * - * @return The version number. + * @return The value number. */ public int getVersion() { return version; diff --git a/Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotAttackRangeItemComponentLoader.java b/Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotAttackRangeItemComponentLoader.java index f75044db..c3474b9a 100644 --- a/Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotAttackRangeItemComponentLoader.java +++ b/Common/src/main/java/fr/maxlego08/menu/itemstack/components/spigot/SpigotAttackRangeItemComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.itemstack.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.api.annotations.SpigotOnly; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.loader.components.AbstractAttackRangeItemComponentLoader; @@ -10,6 +13,9 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.11") +@SpigotOnly public class SpigotAttackRangeItemComponentLoader extends AbstractAttackRangeItemComponentLoader { @Override diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotCustomModelDataItemComponentLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotCustomModelDataItemComponentLoader.java index 58d99b64..ceecc82c 100644 --- a/Common/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotCustomModelDataItemComponentLoader.java +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotCustomModelDataItemComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.api.annotations.SpigotOnly; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.CustomModelDataComponent; @@ -14,6 +17,9 @@ import java.util.ArrayList; import java.util.List; +@ComponentLoader +@SinceVersion("1.20.5") +@SpigotOnly public class SpigotCustomModelDataItemComponentLoader extends AbstractColorItemComponentLoader { public SpigotCustomModelDataItemComponentLoader(){ diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperAttackRangeItemComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperAttackRangeItemComponentLoader.java index 6d411edc..d9b4db12 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperAttackRangeItemComponentLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperAttackRangeItemComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.loader.components.paper; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.itemstack.components.paper.PaperAttackRangeComponent; @@ -12,6 +15,9 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.11") +@PaperOnly public class PaperAttackRangeItemComponentLoader extends AbstractAttackRangeItemComponentLoader { @Override diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperCustomModelDataComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperCustomModelDataComponentLoader.java index cf6d6234..25bd83e8 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperCustomModelDataComponentLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperCustomModelDataComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.loader.components.paper; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.itemstack.components.paper.PaperCustomModelDataComponent; @@ -14,6 +17,9 @@ import java.io.File; import java.util.List; +@ComponentLoader +@SinceVersion("1.20.5") +@PaperOnly public class PaperCustomModelDataComponentLoader extends SpigotCustomModelDataItemComponentLoader { @Override diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperCustomNameItemComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperCustomNameItemComponentLoader.java index ff192b31..45444d10 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperCustomNameItemComponentLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperCustomNameItemComponentLoader.java @@ -1,6 +1,9 @@ package fr.maxlego08.menu.loader.components.paper; import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; @@ -13,6 +16,9 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") +@PaperOnly public class PaperCustomNameItemComponentLoader extends ItemComponentLoader { private final PaperMetaUpdater metaUpdater; diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperDeathProtectionItemComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperDeathProtectionItemComponentLoader.java index 39638298..8847c315 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperDeathProtectionItemComponentLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperDeathProtectionItemComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.loader.components.paper; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.common.enums.ConsumeEffectType; @@ -24,6 +27,9 @@ import java.util.List; import java.util.Map; +@ComponentLoader +@SinceVersion("1.21.2") +@PaperOnly public class PaperDeathProtectionItemComponentLoader extends AbstractEffectItemComponentLoader { public PaperDeathProtectionItemComponentLoader(){ diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperIntangibleProjectileItemComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperIntangibleProjectileItemComponentLoader.java index 2b360dc1..1cfc38ac 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperIntangibleProjectileItemComponentLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperIntangibleProjectileItemComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.loader.components.paper; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; @@ -11,6 +14,9 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") +@PaperOnly public class PaperIntangibleProjectileItemComponentLoader extends ItemComponentLoader { public PaperIntangibleProjectileItemComponentLoader(){ diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperMapDecorationsItemComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperMapDecorationsItemComponentLoader.java index 9cfd9215..456b5684 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperMapDecorationsItemComponentLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperMapDecorationsItemComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.loader.components.paper; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; @@ -18,6 +21,9 @@ import java.util.HashMap; import java.util.Map; +@ComponentLoader +@SinceVersion("1.20.5") +@PaperOnly public class PaperMapDecorationsItemComponentLoader extends ItemComponentLoader { public PaperMapDecorationsItemComponentLoader(){ diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperNoteBlockSoundItemComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperNoteBlockSoundItemComponentLoader.java index 5c203f05..9a35bc54 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperNoteBlockSoundItemComponentLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperNoteBlockSoundItemComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.loader.components.paper; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; @@ -12,6 +15,9 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") +@PaperOnly public class PaperNoteBlockSoundItemComponentLoader extends ItemComponentLoader { public PaperNoteBlockSoundItemComponentLoader(){ diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperPotDecorationsItemComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperPotDecorationsItemComponentLoader.java index bd69db50..429b8cfd 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperPotDecorationsItemComponentLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperPotDecorationsItemComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.loader.components.paper; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; @@ -16,6 +19,9 @@ import java.io.File; import java.util.List; +@ComponentLoader +@SinceVersion("1.20.5") +@PaperOnly public class PaperPotDecorationsItemComponentLoader extends ItemComponentLoader { private static final int SIDES = 4; diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperProvidesBannerPatternsItemComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperProvidesBannerPatternsItemComponentLoader.java index 119782b0..78dc0803 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperProvidesBannerPatternsItemComponentLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperProvidesBannerPatternsItemComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.loader.components.paper; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; @@ -15,6 +18,9 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.5") +@PaperOnly public class PaperProvidesBannerPatternsItemComponentLoader extends ItemComponentLoader { public PaperProvidesBannerPatternsItemComponentLoader(){ diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperProvidesTrimMaterialItemComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperProvidesTrimMaterialItemComponentLoader.java index 9e7e7bff..2c703e89 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperProvidesTrimMaterialItemComponentLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperProvidesTrimMaterialItemComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.loader.components.paper; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; @@ -14,6 +17,9 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.5") +@PaperOnly public class PaperProvidesTrimMaterialItemComponentLoader extends ItemComponentLoader { public PaperProvidesTrimMaterialItemComponentLoader(){ diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperRepairableItemComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperRepairableItemComponentLoader.java index bb3df527..4069b84f 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperRepairableItemComponentLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperRepairableItemComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.loader.components.paper; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; @@ -19,6 +22,9 @@ import java.util.ArrayList; import java.util.List; +@ComponentLoader +@SinceVersion("1.21.2") +@PaperOnly public class PaperRepairableItemComponentLoader extends ItemComponentLoader { public PaperRepairableItemComponentLoader(){ diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperTooltipDisplayItemComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperTooltipDisplayItemComponentLoader.java index bf6b1aba..6c7c63c2 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperTooltipDisplayItemComponentLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperTooltipDisplayItemComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.loader.components.paper; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; @@ -16,6 +19,9 @@ import java.io.File; import java.util.List; +@ComponentLoader +@SinceVersion("1.21.5") +@PaperOnly public class PaperTooltipDisplayItemComponentLoader extends ItemComponentLoader { public PaperTooltipDisplayItemComponentLoader(){ diff --git a/build.gradle.kts b/build.gradle.kts index ea84f30f..927097bf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -107,6 +107,7 @@ allprojects { compileOnly("org.spigotmc:spigot-api:1.21.11-R0.1-SNAPSHOT") } compileOnly("me.clip:placeholderapi:2.11.6") + compileOnly("org.reflections:reflections:0.10.2") implementation("fr.maxlego08.sarah:sarah:1.22") implementation("fr.traqueur.currencies:currenciesapi:1.0.13") diff --git a/src/main/java/fr/maxlego08/menu/ZComponentsManager.java b/src/main/java/fr/maxlego08/menu/ZComponentsManager.java index 7449050d..f885d243 100644 --- a/src/main/java/fr/maxlego08/menu/ZComponentsManager.java +++ b/src/main/java/fr/maxlego08/menu/ZComponentsManager.java @@ -2,23 +2,24 @@ import fr.maxlego08.menu.api.ComponentsManager; import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; import fr.maxlego08.menu.api.configuration.Configuration; import fr.maxlego08.menu.api.exceptions.ItemComponentAlreadyRegisterException; import fr.maxlego08.menu.api.loader.ItemComponentLoader; +import fr.maxlego08.menu.api.utils.ReflectionsCache; +import fr.maxlego08.menu.common.MinecraftVersion; +import fr.maxlego08.menu.common.VersionFilter; import fr.maxlego08.menu.common.factory.VariantItemComponentLoaderFactory; import fr.maxlego08.menu.common.utils.nms.NmsVersion; import fr.maxlego08.menu.itemstack.components.paper.PaperVariantComponent; -import fr.maxlego08.menu.itemstack.components.spigot.SpigotAttackRangeItemComponentLoader; import fr.maxlego08.menu.itemstack.components.spigot.SpigotVariantComponent; -import fr.maxlego08.menu.loader.components.paper.*; -import fr.maxlego08.menu.loader.components.spigot.*; +import fr.maxlego08.menu.loader.components.paper.PaperVariantItemComponentLoader; +import fr.maxlego08.menu.loader.components.spigot.SpigotVariantItemComponentLoader; import fr.maxlego08.menu.zcore.logger.Logger; import org.jetbrains.annotations.NotNull; +import org.reflections.Reflections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; public class ZComponentsManager implements ComponentsManager { private final Map components = new HashMap<>(); @@ -29,6 +30,37 @@ private boolean isPaperAndMiniMessageEnabled(MenuPlugin plugin){ @Override public void initializeDefaultComponents(MenuPlugin plugin) { + MinecraftVersion minecraftVersion = MinecraftVersion.getCurrentVersion(); + + Reflections reflection = ReflectionsCache.getInstance().getOrCreate((ZMenuPlugin) plugin, "fr.maxlego08.menu"); + + int count = 0; + Set> typesAnnotatedWith = reflection.getTypesAnnotatedWith(ComponentLoader.class); + for (Class clazz : typesAnnotatedWith) { + if (ItemComponentLoader.class.isAssignableFrom(clazz)) { + if (!VersionFilter.passes(clazz)) continue; + + try { + ItemComponentLoader loader; + try { + loader = (ItemComponentLoader) clazz.getDeclaredConstructor().newInstance(); + } catch (NoSuchMethodException e) { + loader = (ItemComponentLoader) clazz.getDeclaredConstructor(MenuPlugin.class).newInstance(plugin); + } + this.registerComponent(loader); + count++; + } catch (Exception e) { + if (Configuration.enableDebug) { + Logger.info("Failed to instantiate component loader: " + clazz.getName()); + e.printStackTrace(); + } + } + } + } + + Logger.info("Registered " + count + " default component loaders for Minecraft version " + minecraftVersion + "."); + + NmsVersion currentVersion = NmsVersion.getCurrentVersion(); if (currentVersion.isAttributItemStack()){ // 1.20.5+ try { @@ -39,104 +71,6 @@ public void initializeDefaultComponents(MenuPlugin plugin) { e.printStackTrace(); } } - - this.registerComponent(new SpigotBlockStateItemComponentLoader()); - this.registerComponent(new SpigotAttributeModifiersItemComponentLoader(plugin)); - this.registerComponent(new SpigotBannerPatternsItemComponentLoader()); - this.registerComponent(new SpigotBaseColorItemComponentLoader()); - this.registerComponent(new SpigotBundleContentsItemComponentLoader(plugin)); - this.registerComponent(new SpigotChargedProjectilesItemComponentLoader(plugin)); - this.registerComponent(new SpigotContainerItemComponentLoader(plugin)); - this.registerComponent(new SpigotContainerLootItemComponentLoader()); - this.registerComponent(new SpigotCustomDataItemComponentLoader()); - this.registerComponent(plugin.isPaperOrFolia() ? new PaperCustomModelDataComponentLoader() : new SpigotCustomModelDataItemComponentLoader()); - this.registerComponent(new SpigotDamageItemComponentLoader()); - this.registerComponent(new SpigotDamageResistantItemComponentLoader()); - this.registerComponent(new SpigotDyedColorItemComponentLoader()); - this.registerComponent(new SpigotEnchantmentGlintOverrideItemComponentLoader()); - this.registerComponent(new SpigotFireworkExplosionItemComponentLoader()); - this.registerComponent(new SpigotFireworksItemComponentLoader()); - this.registerComponent(new SpigotFoodItemComponentLoader()); - this.registerComponent(new SpigotInstrumentItemComponentLoader()); - this.registerComponent(new SpigotItemNameItemComponentLoader()); - this.registerComponent(new SpigotLodestoneTrackerItemComponentLoader()); - this.registerComponent(new SpigotLoreItemComponentLoader(plugin)); - this.registerComponent(new SpigotMapColorItemComponentLoader()); - this.registerComponent(new SpigotMapIdItemComponentLoader()); - this.registerComponent(new SpigotMaxDamageItemComponentLoader()); - this.registerComponent(new MaxStackSizeItemComponentLoader(plugin)); - this.registerComponent(new SpigotOminousBottleAmplifierItemComponentLoader()); - this.registerComponent(new SpigotPotionContentsItemComponentLoader()); - this.registerComponent(new SpigotRarityItemComponentLoader()); - this.registerComponent(new SpigotRecipesItemComponentLoader()); - this.registerComponent(new SpigotRepairCostItemComponentLoader()); - this.registerComponent(new SpigotStoredEnchantItemComponentLoader()); - this.registerComponent(new SpigotSuspiciousStewEffectsItemComponentLoader()); - this.registerComponent(new SpigotToolItemComponentLoader()); - this.registerComponent(new SpigotTrimItemComponentLoader()); - this.registerComponent(new SpigotUnbreakableItemComponentLoader()); - this.registerComponent(new SpigotWritableBookContentItemComponentLoader()); - this.registerComponent(new SpigotWrittenBookContentItemComponentLoader()); - this.registerComponent(new SpigotEnchantmentsItemComponentLoader()); - - if (isPaperAndMiniMessageEnabled(plugin)) { - this.registerComponent(new PaperCustomNameItemComponentLoader(plugin)); - } - if (plugin.isPaperOrFolia()) { - this.registerComponent(new PaperIntangibleProjectileItemComponentLoader()); - this.registerComponent(new PaperMapDecorationsItemComponentLoader()); - this.registerComponent(new PaperNoteBlockSoundItemComponentLoader()); - this.registerComponent(new PaperPotDecorationsItemComponentLoader()); - } - - if (currentVersion.isNewItemStackAPI()){ // 1.21+ - this.registerComponent(new SpigotJukeboxPlayableItemComponentLoader()); - - if (currentVersion.is1_21_2OrNewer()){ // 1.21.2+ - this.registerComponent(new SpigotConsumableItemComponentLoader()); - this.registerComponent(new SpigotEnchantableItemComponentLoader()); - this.registerComponent(new SpigotEquippableItemComponentLoader()); - this.registerComponent(new SpigotGliderItemComponentLoader()); - this.registerComponent(new SpigotItemModelItemComponentLoader()); - this.registerComponent(new SpigotTooltipStyleItemComponentLoader()); - this.registerComponent(new SpigotUseCooldownItemComponentLoader()); - this.registerComponent(new SpigotUseRemainderItemComponentLoader(plugin)); - - if (plugin.isPaperOrFolia()){ - this.registerComponent(new PaperDeathProtectionItemComponentLoader()); - this.registerComponent(new PaperRepairableItemComponentLoader()); - } - - if (currentVersion.is1_21_5OrNewer()){ // 1.21.5+ - this.registerComponent(new SpigotBlocksAttacksItemComponentLoader()); - this.registerComponent(new SpigotBreakSoundItemComponentLoader()); - this.registerComponent(new SpigotPotionDurationScaleItemComponentLoader()); - this.registerComponent(plugin.isPaperOrFolia() ? new PaperTooltipDisplayItemComponentLoader() : new SpigotTooltipDisplayComponentLoader()); // Bukkit does not have support for hidden components - this.registerComponent(new SpigotWeaponItemComponentLoader()); - - if (isPaperAndMiniMessageEnabled(plugin)){ - this.registerComponent(new PaperProvidesBannerPatternsItemComponentLoader()); - this.registerComponent(new PaperProvidesTrimMaterialItemComponentLoader()); - } - - if (currentVersion.is1_21_9OrNewer()){ // 1.21.9+ - - this.registerComponent(new SpigotProfileItemComponentLoader()); - - if (currentVersion.is1_21_11OrNewer()){ // 1.21.11+ - this.registerComponent(plugin.isPaperOrFolia() ? new PaperAttackRangeItemComponentLoader() : new SpigotAttackRangeItemComponentLoader()); - this.registerComponent(new SpigotDamageTypeItemComponentLoader()); - this.registerComponent(new SpigotKineticWeaponItemComponentLoader()); - this.registerComponent(new SpigotMinimumAttackChargeItemComponentLoader()); - this.registerComponent(new SpigotPiercingWeaponItemComponentLoader()); - this.registerComponent(new SpigotSwingAnimationItemComponentLoader()); - this.registerComponent(new SpigotUseEffectsItemComponentLoader()); - } - } - - } - } - } } } diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/MaxStackSizeItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/MaxStackSizeItemComponentLoader.java index fb234e1c..aaa160b5 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/MaxStackSizeItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/MaxStackSizeItemComponentLoader.java @@ -1,6 +1,8 @@ package fr.maxlego08.menu.loader.components.spigot; import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; @@ -13,6 +15,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class MaxStackSizeItemComponentLoader extends ItemComponentLoader { private final MenuPlugin plugin; diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotAttributeModifiersItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotAttributeModifiersItemComponentLoader.java index 16a86353..45ec777f 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotAttributeModifiersItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotAttributeModifiersItemComponentLoader.java @@ -1,6 +1,8 @@ package fr.maxlego08.menu.loader.components.spigot; import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.attribute.AttributeMergeStrategy; import fr.maxlego08.menu.api.attribute.AttributeWrapper; import fr.maxlego08.menu.api.configuration.Configuration; @@ -23,6 +25,8 @@ import java.util.List; import java.util.Map; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotAttributeModifiersItemComponentLoader extends ItemComponentLoader { private final MenuPlugin plugin; diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBannerPatternsItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBannerPatternsItemComponentLoader.java index 60b63491..3533b997 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBannerPatternsItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBannerPatternsItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.BannerPatternsComponent; @@ -15,6 +17,8 @@ import java.util.List; import java.util.Map; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotBannerPatternsItemComponentLoader extends ItemComponentLoader { public SpigotBannerPatternsItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBaseColorItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBaseColorItemComponentLoader.java index d5e0e50f..36fbf82d 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBaseColorItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBaseColorItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.BaseColorComponent; @@ -12,6 +14,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotBaseColorItemComponentLoader extends ItemComponentLoader { public SpigotBaseColorItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBlockStateItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBlockStateItemComponentLoader.java index 21ebfad5..06b5f8c6 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBlockStateItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBlockStateItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.BlockStateComponent; @@ -12,6 +14,8 @@ import java.io.File; import java.util.Map; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotBlockStateItemComponentLoader extends ItemComponentLoader { public SpigotBlockStateItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBlocksAttacksItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBlocksAttacksItemComponentLoader.java index 0f7b3678..fa2c107a 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBlocksAttacksItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBlocksAttacksItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.configuration.Configuration; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; @@ -21,6 +23,8 @@ import java.util.List; import java.util.Map; +@ComponentLoader +@SinceVersion("1.21.5") public class SpigotBlocksAttacksItemComponentLoader extends ItemComponentLoader { public SpigotBlocksAttacksItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBreakSoundItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBreakSoundItemComponentLoader.java index b23e8956..8e8535df 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBreakSoundItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBreakSoundItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.BreakSoundComponent; @@ -13,6 +15,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.5") public class SpigotBreakSoundItemComponentLoader extends ItemComponentLoader { public SpigotBreakSoundItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBundleContentsItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBundleContentsItemComponentLoader.java index f87d46cc..067cba75 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBundleContentsItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotBundleContentsItemComponentLoader.java @@ -2,6 +2,8 @@ import fr.maxlego08.menu.api.MenuItemStack; import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.BundleContentsComponent; @@ -15,6 +17,8 @@ import java.util.List; import java.util.Map; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotBundleContentsItemComponentLoader extends AbstractMenuItemStackListComponentLoaderBase { public SpigotBundleContentsItemComponentLoader(MenuPlugin plugin){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotChargedProjectilesItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotChargedProjectilesItemComponentLoader.java index 6a8b341a..ca63ec56 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotChargedProjectilesItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotChargedProjectilesItemComponentLoader.java @@ -2,6 +2,8 @@ import fr.maxlego08.menu.api.MenuItemStack; import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.ChargedProjectilesComponent; @@ -15,6 +17,8 @@ import java.util.List; import java.util.Map; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotChargedProjectilesItemComponentLoader extends AbstractMenuItemStackListComponentLoaderBase { public SpigotChargedProjectilesItemComponentLoader(MenuPlugin plugin){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotConsumableItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotConsumableItemComponentLoader.java index 50d1a2fe..1770661a 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotConsumableItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotConsumableItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.utils.itemstack.*; @@ -23,6 +25,8 @@ import java.util.Map; import java.util.Optional; +@ComponentLoader +@SinceVersion("1.21.2") public class SpigotConsumableItemComponentLoader extends AbstractEffectItemComponentLoader { public SpigotConsumableItemComponentLoader() { diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotContainerItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotContainerItemComponentLoader.java index 10fd14d0..15338f87 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotContainerItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotContainerItemComponentLoader.java @@ -2,6 +2,8 @@ import fr.maxlego08.menu.api.MenuItemStack; import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.ContainerComponent; @@ -17,6 +19,8 @@ import java.util.List; import java.util.Map; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotContainerItemComponentLoader extends AbstractMenuItemStackListComponentLoaderBase { public SpigotContainerItemComponentLoader(MenuPlugin plugin) { diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotContainerLootItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotContainerLootItemComponentLoader.java index bbe35637..7e303cee 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotContainerLootItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotContainerLootItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.ContainerLootComponent; @@ -12,6 +14,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotContainerLootItemComponentLoader extends ItemComponentLoader { public SpigotContainerLootItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotCustomDataItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotCustomDataItemComponentLoader.java index e8759d9a..2631d49a 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotCustomDataItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotCustomDataItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.CustomDataComponent; @@ -17,6 +19,8 @@ import java.util.List; import java.util.Optional; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotCustomDataItemComponentLoader extends ItemComponentLoader { public SpigotCustomDataItemComponentLoader() { diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDamageItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDamageItemComponentLoader.java index 758d9ec9..e072b3e7 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDamageItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDamageItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.DamageComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotDamageItemComponentLoader extends ItemComponentLoader { public SpigotDamageItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDamageResistantItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDamageResistantItemComponentLoader.java index 99e3a725..6350dace 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDamageResistantItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDamageResistantItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.DamageResistantComponent; @@ -15,6 +17,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotDamageResistantItemComponentLoader extends ItemComponentLoader { public SpigotDamageResistantItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDamageTypeItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDamageTypeItemComponentLoader.java index 1b158345..1584de3e 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDamageTypeItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDamageTypeItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.DamageTypeComponent; @@ -13,6 +15,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.11") public class SpigotDamageTypeItemComponentLoader extends ItemComponentLoader { public SpigotDamageTypeItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDyedColorItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDyedColorItemComponentLoader.java index fc18f5d3..3ed94d4e 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDyedColorItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotDyedColorItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.DyeColorComponent; @@ -12,6 +14,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotDyedColorItemComponentLoader extends AbstractColorItemComponentLoader { public SpigotDyedColorItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantableItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantableItemComponentLoader.java index a45da00f..81cd7745 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantableItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantableItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.EnchantableComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.2") public class SpigotEnchantableItemComponentLoader extends ItemComponentLoader { public SpigotEnchantableItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantmentGlintOverrideItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantmentGlintOverrideItemComponentLoader.java index f60fea69..ed5da0a4 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantmentGlintOverrideItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantmentGlintOverrideItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.EnchantmentGlintOverrideComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotEnchantmentGlintOverrideItemComponentLoader extends ItemComponentLoader { public SpigotEnchantmentGlintOverrideItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantmentsItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantmentsItemComponentLoader.java index 1a7d896a..b84c6e9f 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantmentsItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEnchantmentsItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.EnchantementsComponent; @@ -16,6 +18,8 @@ import java.util.HashMap; import java.util.Map; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotEnchantmentsItemComponentLoader extends ItemComponentLoader { public SpigotEnchantmentsItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEquippableItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEquippableItemComponentLoader.java index d03ce36d..477c5039 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEquippableItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotEquippableItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.EquippableComponent; @@ -17,6 +19,8 @@ import java.util.Collection; import java.util.Optional; +@ComponentLoader +@SinceVersion("1.21.2") public class SpigotEquippableItemComponentLoader extends ItemComponentLoader { public SpigotEquippableItemComponentLoader() { diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotFireworkExplosionItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotFireworkExplosionItemComponentLoader.java index d699a51f..1a79b3ba 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotFireworkExplosionItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotFireworkExplosionItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.FireworkExplosionComponent; @@ -13,6 +15,8 @@ import java.io.File; import java.util.Optional; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotFireworkExplosionItemComponentLoader extends AbstractFireworkItemComponentLoader { public SpigotFireworkExplosionItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotFireworksItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotFireworksItemComponentLoader.java index 7a282f40..63edc011 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotFireworksItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotFireworksItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.FireworksComponent; @@ -15,6 +17,8 @@ import java.util.List; import java.util.Map; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotFireworksItemComponentLoader extends AbstractFireworkItemComponentLoader { public SpigotFireworksItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotFoodItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotFoodItemComponentLoader.java index e2ca7ea8..2580da7f 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotFoodItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotFoodItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.FoodComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotFoodItemComponentLoader extends ItemComponentLoader { public SpigotFoodItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotGliderItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotGliderItemComponentLoader.java index 2fc7976d..f8e52e2e 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotGliderItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotGliderItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.GliderComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.2") public class SpigotGliderItemComponentLoader extends ItemComponentLoader { public SpigotGliderItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotInstrumentItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotInstrumentItemComponentLoader.java index 92ad37c1..2286b8ac 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotInstrumentItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotInstrumentItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.InstrumentComponent; @@ -16,6 +18,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotInstrumentItemComponentLoader extends ItemComponentLoader { public SpigotInstrumentItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotItemModelItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotItemModelItemComponentLoader.java index 4552d9b4..15451b4c 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotItemModelItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotItemModelItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.ItemModelComponent; @@ -12,6 +14,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.2") public class SpigotItemModelItemComponentLoader extends ItemComponentLoader { public SpigotItemModelItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotItemNameItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotItemNameItemComponentLoader.java index 1f70c398..096d14c9 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotItemNameItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotItemNameItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.ItemNameComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotItemNameItemComponentLoader extends ItemComponentLoader { public SpigotItemNameItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotJukeboxPlayableItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotJukeboxPlayableItemComponentLoader.java index 28ea59fa..4b847962 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotJukeboxPlayableItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotJukeboxPlayableItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.JukeboxPlayableComponent; @@ -15,6 +17,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21") public class SpigotJukeboxPlayableItemComponentLoader extends ItemComponentLoader { public SpigotJukeboxPlayableItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotKineticWeaponItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotKineticWeaponItemComponentLoader.java index e96107ef..a63430a4 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotKineticWeaponItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotKineticWeaponItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; @@ -14,6 +16,8 @@ import java.io.File; import java.util.Optional; +@ComponentLoader +@SinceVersion("1.21.11") public class SpigotKineticWeaponItemComponentLoader extends ItemComponentLoader { public SpigotKineticWeaponItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotLodestoneTrackerItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotLodestoneTrackerItemComponentLoader.java index 9bd41297..8eb24944 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotLodestoneTrackerItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotLodestoneTrackerItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.LodestoneTrackerComponent; @@ -15,6 +17,8 @@ import java.io.File; import java.util.List; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotLodestoneTrackerItemComponentLoader extends ItemComponentLoader { public SpigotLodestoneTrackerItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotLoreItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotLoreItemComponentLoader.java index fa9f0721..af8ad6d5 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotLoreItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotLoreItemComponentLoader.java @@ -1,6 +1,8 @@ package fr.maxlego08.menu.loader.components.spigot; import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.LoreComponent; @@ -17,6 +19,8 @@ import java.util.ArrayList; import java.util.List; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotLoreItemComponentLoader extends ItemComponentLoader { private final MetaUpdater metaUpdater; diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMapColorItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMapColorItemComponentLoader.java index 4f9b2ace..bc90f270 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMapColorItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMapColorItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.MapColorComponent; @@ -12,6 +14,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotMapColorItemComponentLoader extends AbstractColorItemComponentLoader { public SpigotMapColorItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMapIdItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMapIdItemComponentLoader.java index f7535fdd..8e991f9e 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMapIdItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMapIdItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.MapIdComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotMapIdItemComponentLoader extends ItemComponentLoader { public SpigotMapIdItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMaxDamageItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMaxDamageItemComponentLoader.java index 821c18ea..13b09725 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMaxDamageItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMaxDamageItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.MaxDamageComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotMaxDamageItemComponentLoader extends ItemComponentLoader { public SpigotMaxDamageItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMinimumAttackChargeItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMinimumAttackChargeItemComponentLoader.java index 921e4525..dea8bd2d 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMinimumAttackChargeItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotMinimumAttackChargeItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.MinimumAttackChargeComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.11") public class SpigotMinimumAttackChargeItemComponentLoader extends ItemComponentLoader { public SpigotMinimumAttackChargeItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotOminousBottleAmplifierItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotOminousBottleAmplifierItemComponentLoader.java index 825eb805..65aa0c11 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotOminousBottleAmplifierItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotOminousBottleAmplifierItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.OminousBottleAmplifierComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotOminousBottleAmplifierItemComponentLoader extends ItemComponentLoader { public SpigotOminousBottleAmplifierItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotPiercingWeaponItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotPiercingWeaponItemComponentLoader.java index ba60fe00..a3db0eb1 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotPiercingWeaponItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotPiercingWeaponItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.PiercingWeaponComponent; @@ -13,6 +15,8 @@ import java.io.File; import java.util.Optional; +@ComponentLoader +@SinceVersion("1.21.11") public class SpigotPiercingWeaponItemComponentLoader extends ItemComponentLoader { public SpigotPiercingWeaponItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotPotionContentsItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotPotionContentsItemComponentLoader.java index efed5f40..26628108 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotPotionContentsItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotPotionContentsItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.PotionContentsComponent; @@ -17,6 +19,8 @@ import java.io.File; import java.util.List; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotPotionContentsItemComponentLoader extends AbstractEffectItemComponentLoader { public SpigotPotionContentsItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotPotionDurationScaleItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotPotionDurationScaleItemComponentLoader.java index 3972730d..469d52e1 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotPotionDurationScaleItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotPotionDurationScaleItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.PotionDurationScaleComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.5") public class SpigotPotionDurationScaleItemComponentLoader extends ItemComponentLoader { public SpigotPotionDurationScaleItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotProfileItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotProfileItemComponentLoader.java index f0d55d4e..701de8b9 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotProfileItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotProfileItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.ProfileComponent; @@ -19,6 +21,8 @@ import java.net.URL; import java.util.UUID; +@ComponentLoader +@SinceVersion("1.21.9") public class SpigotProfileItemComponentLoader extends ItemComponentLoader { public SpigotProfileItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotRarityItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotRarityItemComponentLoader.java index 01bfdab4..be252c10 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotRarityItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotRarityItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.RarityComponent; @@ -12,6 +14,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotRarityItemComponentLoader extends ItemComponentLoader { public SpigotRarityItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotRecipesItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotRecipesItemComponentLoader.java index a50bca61..6b849df4 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotRecipesItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotRecipesItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.RecipesComponent; @@ -14,6 +16,8 @@ import java.util.ArrayList; import java.util.List; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotRecipesItemComponentLoader extends ItemComponentLoader { public SpigotRecipesItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotRepairCostItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotRepairCostItemComponentLoader.java index 4edf2070..e2fc4e16 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotRepairCostItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotRepairCostItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.RepairCostComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotRepairCostItemComponentLoader extends ItemComponentLoader { public SpigotRepairCostItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotStoredEnchantItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotStoredEnchantItemComponentLoader.java index b5a841c3..2001c188 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotStoredEnchantItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotStoredEnchantItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.StoredEnchantmentsComponent; @@ -16,6 +18,8 @@ import java.util.HashMap; import java.util.Map; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotStoredEnchantItemComponentLoader extends ItemComponentLoader { public SpigotStoredEnchantItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotSuspiciousStewEffectsItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotSuspiciousStewEffectsItemComponentLoader.java index 10e0f8b6..33087859 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotSuspiciousStewEffectsItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotSuspiciousStewEffectsItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.SuspiciousStewEffectsComponent; @@ -14,6 +16,8 @@ import java.util.List; import java.util.Map; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotSuspiciousStewEffectsItemComponentLoader extends AbstractEffectItemComponentLoader { public SpigotSuspiciousStewEffectsItemComponentLoader() { diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotSwingAnimationItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotSwingAnimationItemComponentLoader.java index cc11c060..1f3b18b3 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotSwingAnimationItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotSwingAnimationItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.loader.ItemComponentLoader; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.11") public class SpigotSwingAnimationItemComponentLoader extends ItemComponentLoader { public SpigotSwingAnimationItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotToolItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotToolItemComponentLoader.java index c2542ecc..936f4358 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotToolItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotToolItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.ToolComponent; @@ -14,6 +16,8 @@ import java.io.File; import java.util.*; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotToolItemComponentLoader extends ItemComponentLoader { public SpigotToolItemComponentLoader() { diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotTooltipDisplayComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotTooltipDisplayComponentLoader.java index f8de79a1..834a0eef 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotTooltipDisplayComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotTooltipDisplayComponentLoader.java @@ -1,5 +1,8 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.api.annotations.SpigotOnly; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.TooltipDisplayComponent; @@ -11,6 +14,9 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.5") +@SpigotOnly public class SpigotTooltipDisplayComponentLoader extends ItemComponentLoader { public SpigotTooltipDisplayComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotTooltipStyleItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotTooltipStyleItemComponentLoader.java index 74ad973b..cea28b56 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotTooltipStyleItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotTooltipStyleItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.TooltipStyleComponent; @@ -12,6 +14,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.2") public class SpigotTooltipStyleItemComponentLoader extends ItemComponentLoader { public SpigotTooltipStyleItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotTrimItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotTrimItemComponentLoader.java index 0a7d4df8..858cbd5c 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotTrimItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotTrimItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.TrimComponent; @@ -16,6 +18,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotTrimItemComponentLoader extends ItemComponentLoader { public SpigotTrimItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUnbreakableItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUnbreakableItemComponentLoader.java index f9609592..a9dcc640 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUnbreakableItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUnbreakableItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.UnbreakableComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotUnbreakableItemComponentLoader extends ItemComponentLoader { public SpigotUnbreakableItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUseCooldownItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUseCooldownItemComponentLoader.java index 50746948..3c7c8bf1 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUseCooldownItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUseCooldownItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.UseCooldownComponent; @@ -12,6 +14,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.2") public class SpigotUseCooldownItemComponentLoader extends ItemComponentLoader { public SpigotUseCooldownItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUseEffectsItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUseEffectsItemComponentLoader.java index 7957aaa6..09f5983a 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUseEffectsItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUseEffectsItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.UseEffectsComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.11") public class SpigotUseEffectsItemComponentLoader extends ItemComponentLoader { public SpigotUseEffectsItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUseRemainderItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUseRemainderItemComponentLoader.java index 50d0e072..bc037005 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUseRemainderItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotUseRemainderItemComponentLoader.java @@ -2,6 +2,8 @@ import fr.maxlego08.menu.api.MenuItemStack; import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.UseRemainderComponent; @@ -14,6 +16,8 @@ import java.io.File; import java.util.Map; +@ComponentLoader +@SinceVersion("1.21.2") public class SpigotUseRemainderItemComponentLoader extends AbstractMenuItemStackListComponentLoaderBase { public SpigotUseRemainderItemComponentLoader(MenuPlugin plugin){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotWeaponItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotWeaponItemComponentLoader.java index 8006a416..496a727d 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotWeaponItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotWeaponItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.WeaponComponent; @@ -11,6 +13,8 @@ import java.io.File; +@ComponentLoader +@SinceVersion("1.21.5") public class SpigotWeaponItemComponentLoader extends ItemComponentLoader { public SpigotWeaponItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotWritableBookContentItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotWritableBookContentItemComponentLoader.java index 21e8b746..00f3ac1e 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotWritableBookContentItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotWritableBookContentItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.WritableBookContentComponent; @@ -14,6 +16,8 @@ import java.util.List; import java.util.Map; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotWritableBookContentItemComponentLoader extends ItemComponentLoader { public SpigotWritableBookContentItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotWrittenBookContentItemComponentLoader.java b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotWrittenBookContentItemComponentLoader.java index 2ae18ccd..7131f845 100644 --- a/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotWrittenBookContentItemComponentLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotWrittenBookContentItemComponentLoader.java @@ -1,5 +1,7 @@ package fr.maxlego08.menu.loader.components.spigot; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.context.MenuItemStackContext; import fr.maxlego08.menu.api.itemstack.ItemComponent; import fr.maxlego08.menu.api.itemstack.components.WrittenBookContentComponent; @@ -15,6 +17,8 @@ import java.util.List; import java.util.Map; +@ComponentLoader +@SinceVersion("1.20.5") public class SpigotWrittenBookContentItemComponentLoader extends ItemComponentLoader { public SpigotWrittenBookContentItemComponentLoader(){ diff --git a/src/main/java/fr/maxlego08/menu/zcore/utils/meta/ClassicMeta.java b/src/main/java/fr/maxlego08/menu/zcore/utils/meta/ClassicMeta.java index 6af259e0..9cba1700 100644 --- a/src/main/java/fr/maxlego08/menu/zcore/utils/meta/ClassicMeta.java +++ b/src/main/java/fr/maxlego08/menu/zcore/utils/meta/ClassicMeta.java @@ -78,7 +78,7 @@ public void sendMessage(@NonNull CommandSender sender, @NonNull String message) @Override public void openBook(@NonNull Player player, @NonNull String title, @NonNull String author, @NonNull List lines) { - player.sendMessage("§cYou cant open a book with your minecraft version !"); + player.sendMessage("§cYou cant open a book with your minecraft value !"); } @Override diff --git a/src/main/java/fr/maxlego08/menu/zcore/utils/plugins/Metrics.java b/src/main/java/fr/maxlego08/menu/zcore/utils/plugins/Metrics.java index b05c49c3..ef691a49 100644 --- a/src/main/java/fr/maxlego08/menu/zcore/utils/plugins/Metrics.java +++ b/src/main/java/fr/maxlego08/menu/zcore/utils/plugins/Metrics.java @@ -30,7 +30,7 @@ */ public class Metrics { - // The version of this bStats class + // The value of this bStats class public static final int B_STATS_VERSION = 1; // The url to which the data is sent private static final String URL = "https://bStats.org/submitData/bukkit"; @@ -266,7 +266,7 @@ public JsonObject getPluginData() { data.addProperty("pluginName", pluginName); // Append the name of the plugin data.addProperty("id", pluginId); // Append the id of the plugin - data.addProperty("pluginVersion", pluginVersion); // Append the version of the plugin + data.addProperty("pluginVersion", pluginVersion); // Append the value of the plugin JsonArray customCharts = new JsonArray(); for (CustomChart customChart : charts) { // Add the data of the custom charts @@ -304,10 +304,10 @@ private JsonObject getServerData() { String bukkitName = Bukkit.getName(); // OS/Java specific data - String javaVersion = System.getProperty("java.version"); + String javaVersion = System.getProperty("java.value"); String osName = System.getProperty("os.name"); String osArch = System.getProperty("os.arch"); - String osVersion = System.getProperty("os.version"); + String osVersion = System.getProperty("os.value"); int coreCount = Runtime.getRuntime().availableProcessors(); JsonObject data = new JsonObject(); @@ -346,7 +346,7 @@ private void submitData() { Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider()); if (plugin instanceof JsonObject) { pluginData.add((JsonObject) plugin); - } else { // old bstats version compatibility + } else { // old bstats value compatibility try { Class jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject"); if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) { @@ -357,7 +357,7 @@ private void submitData() { pluginData.add(object); } } catch (ClassNotFoundException e) { - // minecraft version 1.14+ + // minecraft value 1.14+ if (logFailedRequests) { this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception", e); } diff --git a/src/main/java/fr/maxlego08/menu/zcore/utils/plugins/VersionChecker.java b/src/main/java/fr/maxlego08/menu/zcore/utils/plugins/VersionChecker.java index 6a211629..dff9a5dc 100644 --- a/src/main/java/fr/maxlego08/menu/zcore/utils/plugins/VersionChecker.java +++ b/src/main/java/fr/maxlego08/menu/zcore/utils/plugins/VersionChecker.java @@ -37,7 +37,7 @@ public VersionChecker(ZMenuPlugin plugin, int pluginID) { } /** - * Allows to check if the plugin version is up-to-date. + * Allows to check if the plugin value is up-to-date. */ public void useLastVersion() { if (Configuration.skipUpdateCheck) { @@ -54,7 +54,7 @@ public void useLastVersion() { if (useLastVersion) { Logger.info("No update available."); } else { - Logger.info("New update available. Your version: " + pluginVersion + ", latest version: " + version); + Logger.info("New update available. Your value: " + pluginVersion + ", latest value: " + version); Logger.info("Download plugin here: " + String.format(URL_RESOURCE, this.pluginID)); } }); @@ -62,7 +62,7 @@ public void useLastVersion() { } /** - * Get version by plugin id + * Get value by plugin id * * @param consumer - Do something after */ diff --git a/src/main/java/fr/maxlego08/menu/zcore/utils/toast/AdvancementHandler.java b/src/main/java/fr/maxlego08/menu/zcore/utils/toast/AdvancementHandler.java index f1a49e6e..e54b668f 100644 --- a/src/main/java/fr/maxlego08/menu/zcore/utils/toast/AdvancementHandler.java +++ b/src/main/java/fr/maxlego08/menu/zcore/utils/toast/AdvancementHandler.java @@ -219,7 +219,7 @@ private NamespacedKey modernType(String icon, String message, ToastType style, O } /** - * Helper method to determine which advancement creation method to use based on server version + * Helper method to determine which advancement creation method to use based on server value * * @param icon The Minecraft item ID to use as the toast icon * @param message The message to display in the toast diff --git a/src/main/resources/commands/commands.yml b/src/main/resources/commands/commands.yml index 51e8f259..503b959e 100644 --- a/src/main/resources/commands/commands.yml +++ b/src/main/resources/commands/commands.yml @@ -27,7 +27,7 @@ # - /zm reload config » Reload config.json and messages.yml files - zmenu.reload # - /zm reload inventory [] » Reload inventories files - zmenu.reload # - /zm reload command [] » Reload commands files - zmenu.reload -# - /zm version » Show plugin version +# - /zm value » Show plugin value # - /zm convert » Convert other plugin to zMenu - zmenu.convert # - / » Open specific file - Custom permission # diff --git a/src/main/resources/commands/punish/punish.yml b/src/main/resources/commands/punish/punish.yml index 938e06d5..376dbf8d 100644 --- a/src/main/resources/commands/punish/punish.yml +++ b/src/main/resources/commands/punish/punish.yml @@ -27,7 +27,7 @@ # - /zm reload config » Reload config.json and messages.yml files - zmenu.reload # - /zm reload inventory [] » Reload inventories files - zmenu.reload # - /zm reload command [] » Reload commands files - zmenu.reload -# - /zm version » Show plugin version +# - /zm value » Show plugin value # - /zm convert » Convert other plugin to zMenu - zmenu.convert # - / » Open specific file - Custom permission # diff --git a/src/main/resources/inventories/example_punish.yml b/src/main/resources/inventories/example_punish.yml index 40f2ffb2..07e31a3b 100644 --- a/src/main/resources/inventories/example_punish.yml +++ b/src/main/resources/inventories/example_punish.yml @@ -28,7 +28,7 @@ # - /zm reload config » Reload config.json and messages.yml files - zmenu.reload # - /zm reload inventory [] » Reload inventories files - zmenu.reload # - /zm reload command [] » Reload commands files - zmenu.reload -# - /zm version » Show plugin version +# - /zm value » Show plugin value # - /zm convert » Convert other plugin to zMenu - zmenu.convert # - / » Open specific file - Custom permission # diff --git a/src/main/resources/patterns/pattern_example.yml b/src/main/resources/patterns/pattern_example.yml index f8aa6514..93eadc75 100644 --- a/src/main/resources/patterns/pattern_example.yml +++ b/src/main/resources/patterns/pattern_example.yml @@ -28,7 +28,7 @@ # - /zm reload config » Reload config.json and messages.yml files - zmenu.reload # - /zm reload inventory [] » Reload inventories files - zmenu.reload # - /zm reload command [] » Reload commands files - zmenu.reload -# - /zm version » Show plugin version +# - /zm value » Show plugin value # - /zm convert » Convert other plugin to zMenu - zmenu.convert # - / » Open specific file - Custom permission # diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 774e4dbf..777324ce 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -28,4 +28,5 @@ loadbefore: - SuperiorSkyblock2 libraries: - org.mariadb.jdbc:mariadb-java-client:3.5.6 - - net.kyori:adventure-text-minimessage:4.26.1 \ No newline at end of file + - net.kyori:adventure-text-minimessage:4.26.1 + - org.reflections:reflections:0.10.2 \ No newline at end of file From 59c578b1c0fd60d2d298d0a8e284d37c1c10b918 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Wed, 29 Apr 2026 12:21:30 +0200 Subject: [PATCH 07/24] feat: implement variant loaders for Axolotl, Cat, Fox, and other entities with updated component registration --- .../VariantItemComponentLoaderFactory.java | 124 ------ .../SpigotVariantItemComponentLoader.java | 411 ------------------ .../variants/AxolotlVariantLoader.java | 16 + .../variants/CatCollarVariantLoader.java | 15 + .../components/variants/CatVariantLoader.java | 17 + .../components/variants/FoxVariantLoader.java | 16 + .../variants/FrogVariantLoader.java | 17 + .../variants/HorseVariantLoader.java | 16 + .../variants/LlamaVariantLoader.java | 16 + .../variants/MushroomCowVariantLoader.java | 16 + .../variants/PaintingVariantLoader.java | 17 + .../variants/ParrotVariantLoader.java | 16 + .../variants/RabbitVariantLoader.java | 16 + .../variants/SalmonVariantLoader.java | 16 + .../variants/SheepColorVariantLoader.java | 15 + .../ShulkerBoxColorVariantLoader.java | 15 + .../variants/SpigotChickenVariantLoader.java | 19 + .../variants/SpigotCowVariantLoader.java | 19 + .../variants/SpigotPigVariantLoader.java | 19 + .../TropicalFishBaseColorVariantLoader.java | 15 + ...TropicalFishPatternColorVariantLoader.java | 15 + .../variants/VillagerVariantLoader.java | 17 + .../variants/WolfCollarVariantLoader.java | 15 + .../variants/WolfVariantLoader.java | 17 + .../variants/base/CollarColorLoader.java | 43 ++ .../variants/base/DyeColorVariantLoader.java | 35 ++ .../variants/base/EnumVariantLoader.java | 36 ++ .../variants/base/RegistryVariantLoader.java | 40 ++ .../paper/PaperChickenVariantLoader.java | 19 + .../paper/PaperCowVariantLoader.java | 19 + .../paper/PaperPigVariantLoader.java | 19 + .../PaperVariantItemComponentLoader.java | 89 ---- .../base/PaperRegistryVariantLoader.java | 42 ++ .../fr/maxlego08/menu/ZComponentsManager.java | 106 +---- 34 files changed, 623 insertions(+), 720 deletions(-) delete mode 100644 Common/src/main/java/fr/maxlego08/menu/common/factory/VariantItemComponentLoaderFactory.java delete mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotVariantItemComponentLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/AxolotlVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/CatCollarVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/CatVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/FoxVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/FrogVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/HorseVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/LlamaVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/MushroomCowVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/PaintingVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/ParrotVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/RabbitVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SalmonVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SheepColorVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/ShulkerBoxColorVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SpigotChickenVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SpigotCowVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SpigotPigVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/TropicalFishBaseColorVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/TropicalFishPatternColorVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/VillagerVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/WolfCollarVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/WolfVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/CollarColorLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/DyeColorVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/EnumVariantLoader.java create mode 100644 Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/RegistryVariantLoader.java create mode 100644 Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperChickenVariantLoader.java create mode 100644 Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperCowVariantLoader.java create mode 100644 Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperPigVariantLoader.java delete mode 100644 Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperVariantItemComponentLoader.java create mode 100644 Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/variants/base/PaperRegistryVariantLoader.java diff --git a/Common/src/main/java/fr/maxlego08/menu/common/factory/VariantItemComponentLoaderFactory.java b/Common/src/main/java/fr/maxlego08/menu/common/factory/VariantItemComponentLoaderFactory.java deleted file mode 100644 index 905d90f4..00000000 --- a/Common/src/main/java/fr/maxlego08/menu/common/factory/VariantItemComponentLoaderFactory.java +++ /dev/null @@ -1,124 +0,0 @@ -package fr.maxlego08.menu.common.factory; - -import fr.maxlego08.menu.api.loader.ItemComponentLoader; -import org.jetbrains.annotations.NotNull; - -/** - * Factory interface for platform-specific ItemComponentLoaders for all supported variants. - * Each method returns a loader for a specific entity type/variant. - * If a loader cannot be provided, it may return null but all supported loaders should be implemented in factories. - **/ -public interface VariantItemComponentLoaderFactory { - /** - * Loader for Axolotl variant. Never null if the platform supports Axolotl. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderAxolotl(); - /** - * Loader for Cat collar color. May be null if not supported. - * - * @return @Nullable ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderCatCollar(); - /** - * Loader for Cat variant. Never null if supported by the platform. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderCatVariant(); - /** - * Loader for Chicken variant (regardless of underlying Paper/Bukkit differences). - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderChicken(); - /** - * Loader for Cow variant (handles Paper/Bukkit differences). - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderCow(); - /** - * Loader for Fox variant. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderFox(); - /** - * Loader for Frog variant. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderFrog(); - /** - * Loader for Horse variant. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderHorse(); - /** - * Loader for Llama variant. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderLlama(); - /** - * Loader for MushroomCow (Mooshroom) variant. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderMushroomCow(); - /** - * Loader for Painting variant. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderPainting(); - /** - * Loader for Parrot variant. - * - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderParrot(); - /** - * Loader for Pig variant. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderPig(); - /** - * Loader for Rabbit variant. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderRabbit(); - /** - * Loader for Salmon variant. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderSalmon(); - /** - * Loader for Sheep variant (dye color). - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderSheep(); - /** - * Loader for ShulkerBox variant (dye color). - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderShulkerBox(); - /** - * Loader for TropicalFish base color. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderTropicalFishBaseColor(); - /** - * Loader for TropicalFish pattern color. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderTropicalFishPatternColor(); - /** - * Loader for Villager variant. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderVillager(); - /** - * Loader for Wolf collar color. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderWolfCollar(); - /** - * Loader for Wolf variant type. - * @return @NotNull ItemComponentLoader - */ - @NotNull ItemComponentLoader getLoaderWolfVariant(); -} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotVariantItemComponentLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotVariantItemComponentLoader.java deleted file mode 100644 index b360d8d6..00000000 --- a/Common/src/main/java/fr/maxlego08/menu/loader/components/spigot/SpigotVariantItemComponentLoader.java +++ /dev/null @@ -1,411 +0,0 @@ -package fr.maxlego08.menu.loader.components.spigot; - -import fr.maxlego08.menu.api.context.MenuItemStackContext; -import fr.maxlego08.menu.api.itemstack.ItemComponent; -import fr.maxlego08.menu.api.loader.ItemComponentLoader; -import fr.maxlego08.menu.common.factory.VariantItemComponentLoaderFactory; -import fr.maxlego08.menu.common.interfaces.VariantComponent; -import fr.maxlego08.menu.loader.components.AbstractColorItemComponentLoader; -import org.bukkit.*; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jspecify.annotations.NonNull; - -import java.io.File; -import java.util.function.Function; - -public class SpigotVariantItemComponentLoader implements VariantItemComponentLoaderFactory { - - protected final VariantComponent variantFactory; - - public SpigotVariantItemComponentLoader(VariantComponent variantFactory) { - this.variantFactory = variantFactory; - } - - @Override - public @NonNull ItemComponentLoader getLoaderAxolotl() { - return new Axolotl(); - } - - - @Override - public @NotNull ItemComponentLoader getLoaderCatCollar() { - return new Cat(this.variantFactory).new Collar(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderCatVariant() { - return new Cat(this.variantFactory).new Variant(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderChicken() { - return new Chicken(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderCow() { - return new Cow(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderFox() { - return new Fox(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderFrog() { - return new Frog(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderHorse() { - return new Horse(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderLlama() { - return new Llama(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderMushroomCow() { - return new MushroomCow(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderPainting() { - return new Painting(); - } - - - @Override - public @NotNull ItemComponentLoader getLoaderParrot() { - return new Parrot(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderPig() { - return new Pig(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderRabbit() { - return new Rabbit(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderSalmon() { - return new Salmon(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderSheep() { - return new Sheep(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderShulkerBox() { - return new ShulkerBox(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderTropicalFishBaseColor() { - return new TropicalFish(this.variantFactory).new BaseColor(); - } - - @Override - public @NonNull ItemComponentLoader getLoaderTropicalFishPatternColor() { - return new TropicalFish(this.variantFactory).new PatternColor(); - } - - @Override - public @NonNull ItemComponentLoader getLoaderVillager() { - return new Villager(); - } - - - @Override - public @NonNull ItemComponentLoader getLoaderWolfCollar() { - return new Wolf(this.variantFactory).new Collar(); - } - - @Override - public @NonNull ItemComponentLoader getLoaderWolfVariant() { - return new Wolf(this.variantFactory).new Variant(); - } - - private static abstract class EnumVariantLoader> extends ItemComponentLoader { - private final Class enumClass; - private final Function componentFactory; - - protected EnumVariantLoader(String path, Class enumClass, Function componentFactory) { - super(path); - this.enumClass = enumClass; - this.componentFactory = componentFactory; - } - - @Override - public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { - path = normalizePath(path); - String value = configuration.getString(path); - if (value == null) return null; - try { - T variant = Enum.valueOf(enumClass, value.toUpperCase()); - return componentFactory.apply(variant); - } catch (IllegalArgumentException e) { - return null; - } - } - } - - protected static abstract class RegistryVariantLoader extends ItemComponentLoader { - private final Registry registry; - private final Function componentFactory; - - protected RegistryVariantLoader(String path, Registry registry, Function componentFactory) { - super(path); - this.registry = registry; - this.componentFactory = componentFactory; - } - - @Override - public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { - path = normalizePath(path); - String value = configuration.getString(path); - if (value == null) return null; - NamespacedKey key = NamespacedKey.fromString(value.toLowerCase()); - if (key == null) return null; - try { - return componentFactory.apply(registry.getOrThrow(key)); - } catch (IllegalArgumentException e) { - return null; - } - } - } - - private static abstract class DyeColorVariantLoader extends ItemComponentLoader { - private final Function componentFactory; - - protected DyeColorVariantLoader(String path, Function componentFactory) { - super(path); - this.componentFactory = componentFactory; - } - - @Override - public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { - path = normalizePath(path); - String value = configuration.getString(path); - if (value == null) return null; - try { - DyeColor dyeColor = DyeColor.valueOf(value.toUpperCase()); - return componentFactory.apply(dyeColor); - } catch (IllegalArgumentException e) { - return null; - } - } - } - - private static abstract class CollarColorLoader extends AbstractColorItemComponentLoader { - private final Function componentFactory; - - protected CollarColorLoader(String path, Function componentFactory) { - super(path); - this.componentFactory = componentFactory; - } - - @Override - public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { - path = normalizePath(path); - Object rawColor = configuration.get(path); - if (rawColor == null) return null; - Color color = parseColor(rawColor); - DyeColor dyeColor; - if (color == null) { - try { - dyeColor = DyeColor.valueOf(rawColor.toString().toUpperCase()); - } catch (IllegalArgumentException e) { - return null; - } - } else { - dyeColor = DyeColor.getByColor(color); - } - if (dyeColor == null) return null; - return componentFactory.apply(dyeColor); - } - } - - // Specific loaders - public class Axolotl extends EnumVariantLoader { - public Axolotl() { - super("axolotl/variant", org.bukkit.entity.Axolotl.Variant.class, variantFactory::createAxolotl); - } - } - - public static class Cat { - private final VariantComponent variantFactory; - - public Cat(VariantComponent variantFactory) { - this.variantFactory = variantFactory; - } - - public class Collar extends CollarColorLoader { - public Collar() { - super("cat/collar", variantFactory::createCatCollar); - } - } - - public class Variant extends RegistryVariantLoader { - public Variant() { - super("cat/variant", Registry.CAT_VARIANT, variantFactory::createCatVariant); - } - } - } - - public class Chicken extends RegistryVariantLoader { - public Chicken() { - super("chicken/variant", Registry.CHICKEN_VARIANT, variantFactory::createChicken); - } - } - - public class Cow extends RegistryVariantLoader { - public Cow() { - super("cow/variant", Registry.COW_VARIANT, variantFactory::createCow); - } - } - - public class Fox extends EnumVariantLoader { - public Fox() { - super("fox/variant", org.bukkit.entity.Fox.Type.class, variantFactory::createFox); - } - } - - public class Frog extends RegistryVariantLoader { - public Frog() { - super("frog/variant", Registry.FROG_VARIANT, variantFactory::createFrog); - } - } - - public class Horse extends EnumVariantLoader { - public Horse() { - super("horse/variant", org.bukkit.entity.Horse.Color.class, variantFactory::createHorse); - } - } - - public class Llama extends EnumVariantLoader { - public Llama() { - super("llama/variant", org.bukkit.entity.Llama.Color.class, variantFactory::createLlama); - } - } - - public class MushroomCow extends EnumVariantLoader { - public MushroomCow() { - super("mooshroom/variant", org.bukkit.entity.MushroomCow.Variant.class, variantFactory::createMushroomCow); - } - } - - public class Painting extends RegistryVariantLoader { - public Painting() { - super("painting/variant", Registry.ART, variantFactory::createPainting); - } - } - - public class Parrot extends EnumVariantLoader { - public Parrot() { - super("parrot/variant", org.bukkit.entity.Parrot.Variant.class, variantFactory::createParrot); - } - } - - public class Pig extends RegistryVariantLoader { - public Pig() { - super("pig/variant", Registry.PIG_VARIANT, variantFactory::createPig); - } - } - - public class Rabbit extends EnumVariantLoader { - public Rabbit() { - super("rabbit/variant", org.bukkit.entity.Rabbit.Type.class, variantFactory::createRabbit); - } - } - - public class Salmon extends EnumVariantLoader { - public Salmon() { - super("salmon/size", org.bukkit.entity.Salmon.Variant.class, variantFactory::createSalmon); - } - } - - public class Sheep extends DyeColorVariantLoader { - public Sheep() { - super("sheep/color", variantFactory::createSheep); - } - } - - public class ShulkerBox extends DyeColorVariantLoader { - public ShulkerBox() { - super("shulker/color", variantFactory::createShulkerBox); - } - } - - public static class TropicalFish { - private final VariantComponent variantFactory; - - public TropicalFish(VariantComponent variantFactory) { - this.variantFactory = variantFactory; - } - - public class BaseColor extends DyeColorVariantLoader { - public BaseColor() { - super("tropical_fish/base_color", variantFactory::createTropicalFishBaseColor); - } - } - - public class PatternColor extends DyeColorVariantLoader { - public PatternColor() { - super("tropical_fish/pattern_color", variantFactory::createTropicalFishPatternColor); - } - } - } - - public class Villager extends RegistryVariantLoader { - public Villager() { - super("villager/variant", Registry.VILLAGER_TYPE, variantFactory::createVillager); - } - } - - public static class Wolf { - private final VariantComponent variantFactory; - - public Wolf(VariantComponent variantFactory) { - this.variantFactory = variantFactory; - } - - public class Collar extends CollarColorLoader { - public Collar() { - super("wolf/collar", variantFactory::createWolfCollar); - } - } - - public class Variant extends RegistryVariantLoader { - public Variant() { - super("wolf/variant", Registry.WOLF_VARIANT, variantFactory::createWolfVariant); - } - } - } -} \ No newline at end of file diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/AxolotlVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/AxolotlVariantLoader.java new file mode 100644 index 00000000..ee49cb04 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/AxolotlVariantLoader.java @@ -0,0 +1,16 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.EnumVariantLoader; +import org.bukkit.entity.Axolotl; + +@ComponentLoader +@SinceVersion("1.17") +public class AxolotlVariantLoader extends EnumVariantLoader { + public AxolotlVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("axolotl/variant", Axolotl.Variant.class, variantFactory::createAxolotl); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/CatCollarVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/CatCollarVariantLoader.java new file mode 100644 index 00000000..01260992 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/CatCollarVariantLoader.java @@ -0,0 +1,15 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.CollarColorLoader; + +@ComponentLoader +@SinceVersion("1.20.5") +public class CatCollarVariantLoader extends CollarColorLoader { + public CatCollarVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("cat/collar", variantFactory::createCatCollar); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/CatVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/CatVariantLoader.java new file mode 100644 index 00000000..db92b92b --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/CatVariantLoader.java @@ -0,0 +1,17 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.RegistryVariantLoader; +import org.bukkit.Registry; +import org.bukkit.entity.Cat; + +@ComponentLoader +@SinceVersion("1.20.5") +public class CatVariantLoader extends RegistryVariantLoader { + public CatVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("cat/variant", Registry.CAT_VARIANT, variantFactory::createCatVariant); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/FoxVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/FoxVariantLoader.java new file mode 100644 index 00000000..e496ba06 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/FoxVariantLoader.java @@ -0,0 +1,16 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.EnumVariantLoader; +import org.bukkit.entity.Fox; + +@ComponentLoader +@SinceVersion("1.13") +public class FoxVariantLoader extends EnumVariantLoader { + public FoxVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("fox/variant", Fox.Type.class, variantFactory::createFox); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/FrogVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/FrogVariantLoader.java new file mode 100644 index 00000000..4173235c --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/FrogVariantLoader.java @@ -0,0 +1,17 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.RegistryVariantLoader; +import org.bukkit.Registry; +import org.bukkit.entity.Frog; + +@ComponentLoader +@SinceVersion("1.18") +public class FrogVariantLoader extends RegistryVariantLoader { + public FrogVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("frog/variant", Registry.FROG_VARIANT, variantFactory::createFrog); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/HorseVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/HorseVariantLoader.java new file mode 100644 index 00000000..32e93935 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/HorseVariantLoader.java @@ -0,0 +1,16 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.EnumVariantLoader; +import org.bukkit.entity.Horse; + +@ComponentLoader +@SinceVersion("1.20.5") +public class HorseVariantLoader extends EnumVariantLoader { + public HorseVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("horse/variant", Horse.Color.class, variantFactory::createHorse); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/LlamaVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/LlamaVariantLoader.java new file mode 100644 index 00000000..91d8af0e --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/LlamaVariantLoader.java @@ -0,0 +1,16 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.EnumVariantLoader; +import org.bukkit.entity.Llama; + +@ComponentLoader +@SinceVersion("1.11") +public class LlamaVariantLoader extends EnumVariantLoader { + public LlamaVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("llama/variant", Llama.Color.class, variantFactory::createLlama); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/MushroomCowVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/MushroomCowVariantLoader.java new file mode 100644 index 00000000..c7a7462b --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/MushroomCowVariantLoader.java @@ -0,0 +1,16 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.EnumVariantLoader; +import org.bukkit.entity.MushroomCow; + +@ComponentLoader +@SinceVersion("1.13") +public class MushroomCowVariantLoader extends EnumVariantLoader { + public MushroomCowVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("mooshroom/variant", MushroomCow.Variant.class, variantFactory::createMushroomCow); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/PaintingVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/PaintingVariantLoader.java new file mode 100644 index 00000000..b051858c --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/PaintingVariantLoader.java @@ -0,0 +1,17 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.RegistryVariantLoader; +import org.bukkit.Art; +import org.bukkit.Registry; + +@ComponentLoader +@SinceVersion("1.20.5") +public class PaintingVariantLoader extends RegistryVariantLoader { + public PaintingVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("painting/variant", Registry.ART, variantFactory::createPainting); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/ParrotVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/ParrotVariantLoader.java new file mode 100644 index 00000000..3679f750 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/ParrotVariantLoader.java @@ -0,0 +1,16 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.EnumVariantLoader; +import org.bukkit.entity.Parrot; + +@ComponentLoader +@SinceVersion("1.12") +public class ParrotVariantLoader extends EnumVariantLoader { + public ParrotVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("parrot/variant", Parrot.Variant.class, variantFactory::createParrot); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/RabbitVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/RabbitVariantLoader.java new file mode 100644 index 00000000..0873916b --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/RabbitVariantLoader.java @@ -0,0 +1,16 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.EnumVariantLoader; +import org.bukkit.entity.Rabbit; + +@ComponentLoader +@SinceVersion("1.20.5") +public class RabbitVariantLoader extends EnumVariantLoader { + public RabbitVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("rabbit/variant", Rabbit.Type.class, variantFactory::createRabbit); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SalmonVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SalmonVariantLoader.java new file mode 100644 index 00000000..74534bdf --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SalmonVariantLoader.java @@ -0,0 +1,16 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.EnumVariantLoader; +import org.bukkit.entity.Salmon; + +@ComponentLoader +@SinceVersion("1.21.5") +public class SalmonVariantLoader extends EnumVariantLoader { + public SalmonVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("salmon/size", Salmon.Variant.class, variantFactory::createSalmon); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SheepColorVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SheepColorVariantLoader.java new file mode 100644 index 00000000..44834783 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SheepColorVariantLoader.java @@ -0,0 +1,15 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.DyeColorVariantLoader; + +@ComponentLoader +@SinceVersion("1.20.5") +public class SheepColorVariantLoader extends DyeColorVariantLoader { + public SheepColorVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("sheep/color", variantFactory::createSheep); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/ShulkerBoxColorVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/ShulkerBoxColorVariantLoader.java new file mode 100644 index 00000000..0d05701e --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/ShulkerBoxColorVariantLoader.java @@ -0,0 +1,15 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.DyeColorVariantLoader; + +@ComponentLoader +@SinceVersion("1.11") +public class ShulkerBoxColorVariantLoader extends DyeColorVariantLoader { + public ShulkerBoxColorVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("shulker/color", variantFactory::createShulkerBox); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SpigotChickenVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SpigotChickenVariantLoader.java new file mode 100644 index 00000000..c664e6c0 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SpigotChickenVariantLoader.java @@ -0,0 +1,19 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.api.annotations.SpigotOnly; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.RegistryVariantLoader; +import org.bukkit.Registry; +import org.bukkit.entity.Chicken; + +@ComponentLoader +@SpigotOnly +@SinceVersion("1.21.5") +public class SpigotChickenVariantLoader extends RegistryVariantLoader { + public SpigotChickenVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("chicken/variant", Registry.CHICKEN_VARIANT, variantFactory::createChicken); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SpigotCowVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SpigotCowVariantLoader.java new file mode 100644 index 00000000..7fbfffd3 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SpigotCowVariantLoader.java @@ -0,0 +1,19 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.api.annotations.SpigotOnly; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.RegistryVariantLoader; +import org.bukkit.Registry; +import org.bukkit.entity.Cow; + +@ComponentLoader +@SpigotOnly +@SinceVersion("1.21.5") +public class SpigotCowVariantLoader extends RegistryVariantLoader { + public SpigotCowVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("cow/variant", Registry.COW_VARIANT, variantFactory::createCow); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SpigotPigVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SpigotPigVariantLoader.java new file mode 100644 index 00000000..a7b327ee --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/SpigotPigVariantLoader.java @@ -0,0 +1,19 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.api.annotations.SpigotOnly; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.RegistryVariantLoader; +import org.bukkit.Registry; +import org.bukkit.entity.Pig; + +@ComponentLoader +@SpigotOnly +@SinceVersion("1.21.5") +public class SpigotPigVariantLoader extends RegistryVariantLoader { + public SpigotPigVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("pig/variant", Registry.PIG_VARIANT, variantFactory::createPig); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/TropicalFishBaseColorVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/TropicalFishBaseColorVariantLoader.java new file mode 100644 index 00000000..d4730bea --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/TropicalFishBaseColorVariantLoader.java @@ -0,0 +1,15 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.DyeColorVariantLoader; + +@ComponentLoader +@SinceVersion("1.20.5") +public class TropicalFishBaseColorVariantLoader extends DyeColorVariantLoader { + public TropicalFishBaseColorVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("tropical_fish/base_color", variantFactory::createTropicalFishBaseColor); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/TropicalFishPatternColorVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/TropicalFishPatternColorVariantLoader.java new file mode 100644 index 00000000..4e69c954 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/TropicalFishPatternColorVariantLoader.java @@ -0,0 +1,15 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.DyeColorVariantLoader; + +@ComponentLoader +@SinceVersion("1.20.5") +public class TropicalFishPatternColorVariantLoader extends DyeColorVariantLoader { + public TropicalFishPatternColorVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("tropical_fish/pattern_color", variantFactory::createTropicalFishPatternColor); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/VillagerVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/VillagerVariantLoader.java new file mode 100644 index 00000000..7ae6228b --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/VillagerVariantLoader.java @@ -0,0 +1,17 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.RegistryVariantLoader; +import org.bukkit.Registry; +import org.bukkit.entity.Villager; + +@ComponentLoader +@SinceVersion("1.20.5") +public class VillagerVariantLoader extends RegistryVariantLoader { + public VillagerVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("villager/variant", Registry.VILLAGER_TYPE, variantFactory::createVillager); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/WolfCollarVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/WolfCollarVariantLoader.java new file mode 100644 index 00000000..42a107a0 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/WolfCollarVariantLoader.java @@ -0,0 +1,15 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.CollarColorLoader; + +@ComponentLoader +@SinceVersion("1.20.5") +public class WolfCollarVariantLoader extends CollarColorLoader { + public WolfCollarVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("wolf/collar", variantFactory::createWolfCollar); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/WolfVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/WolfVariantLoader.java new file mode 100644 index 00000000..e3cce42f --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/WolfVariantLoader.java @@ -0,0 +1,17 @@ +package fr.maxlego08.menu.loader.components.variants; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.RegistryVariantLoader; +import org.bukkit.Registry; +import org.bukkit.entity.Wolf; + +@ComponentLoader +@SinceVersion("1.20.5") +public class WolfVariantLoader extends RegistryVariantLoader { + public WolfVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("wolf/variant", Registry.WOLF_VARIANT, variantFactory::createWolfVariant); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/CollarColorLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/CollarColorLoader.java new file mode 100644 index 00000000..0d49c8ce --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/CollarColorLoader.java @@ -0,0 +1,43 @@ +package fr.maxlego08.menu.loader.components.variants.base; + +import fr.maxlego08.menu.api.context.MenuItemStackContext; +import fr.maxlego08.menu.api.itemstack.ItemComponent; +import fr.maxlego08.menu.loader.components.AbstractColorItemComponentLoader; +import org.bukkit.Color; +import org.bukkit.DyeColor; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.util.function.Function; + +public abstract class CollarColorLoader extends AbstractColorItemComponentLoader { + private final Function componentFactory; + + protected CollarColorLoader(String path, Function componentFactory) { + super(path); + this.componentFactory = componentFactory; + } + + @Override + public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { + path = normalizePath(path); + Object rawColor = configuration.get(path); + if (rawColor == null) return null; + Color color = parseColor(rawColor); + DyeColor dyeColor; + if (color == null) { + try { + dyeColor = DyeColor.valueOf(rawColor.toString().toUpperCase()); + } catch (IllegalArgumentException e) { + return null; + } + } else { + dyeColor = DyeColor.getByColor(color); + } + if (dyeColor == null) return null; + return componentFactory.apply(dyeColor); + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/DyeColorVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/DyeColorVariantLoader.java new file mode 100644 index 00000000..5714771f --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/DyeColorVariantLoader.java @@ -0,0 +1,35 @@ +package fr.maxlego08.menu.loader.components.variants.base; + +import fr.maxlego08.menu.api.context.MenuItemStackContext; +import fr.maxlego08.menu.api.itemstack.ItemComponent; +import fr.maxlego08.menu.api.loader.ItemComponentLoader; +import org.bukkit.DyeColor; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.util.function.Function; + +public abstract class DyeColorVariantLoader extends ItemComponentLoader { + private final Function componentFactory; + + protected DyeColorVariantLoader(String path, Function componentFactory) { + super(path); + this.componentFactory = componentFactory; + } + + @Override + public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { + path = normalizePath(path); + String value = configuration.getString(path); + if (value == null) return null; + try { + DyeColor dyeColor = DyeColor.valueOf(value.toUpperCase()); + return componentFactory.apply(dyeColor); + } catch (IllegalArgumentException e) { + return null; + } + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/EnumVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/EnumVariantLoader.java new file mode 100644 index 00000000..9fdef0f3 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/EnumVariantLoader.java @@ -0,0 +1,36 @@ +package fr.maxlego08.menu.loader.components.variants.base; + +import fr.maxlego08.menu.api.context.MenuItemStackContext; +import fr.maxlego08.menu.api.itemstack.ItemComponent; +import fr.maxlego08.menu.api.loader.ItemComponentLoader; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.util.function.Function; + +public abstract class EnumVariantLoader> extends ItemComponentLoader { + private final Class enumClass; + private final Function componentFactory; + + protected EnumVariantLoader(String path, Class enumClass, Function componentFactory) { + super(path); + this.enumClass = enumClass; + this.componentFactory = componentFactory; + } + + @Override + public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { + path = normalizePath(path); + String value = configuration.getString(path); + if (value == null) return null; + try { + T variant = Enum.valueOf(enumClass, value.toUpperCase()); + return componentFactory.apply(variant); + } catch (IllegalArgumentException e) { + return null; + } + } +} diff --git a/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/RegistryVariantLoader.java b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/RegistryVariantLoader.java new file mode 100644 index 00000000..2016af75 --- /dev/null +++ b/Common/src/main/java/fr/maxlego08/menu/loader/components/variants/base/RegistryVariantLoader.java @@ -0,0 +1,40 @@ +package fr.maxlego08.menu.loader.components.variants.base; + +import fr.maxlego08.menu.api.context.MenuItemStackContext; +import fr.maxlego08.menu.api.itemstack.ItemComponent; +import fr.maxlego08.menu.api.loader.ItemComponentLoader; +import org.bukkit.Keyed; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.util.function.Function; + +public abstract class RegistryVariantLoader extends ItemComponentLoader { + private final Registry registry; + private final Function componentFactory; + + protected RegistryVariantLoader(String path, Registry registry, Function componentFactory) { + super(path); + this.registry = registry; + this.componentFactory = componentFactory; + } + + @Override + public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { + path = normalizePath(path); + String value = configuration.getString(path); + if (value == null) return null; + NamespacedKey key = NamespacedKey.fromString(value.toLowerCase()); + if (key == null) return null; + try { + return componentFactory.apply(registry.getOrThrow(key)); + } catch (IllegalArgumentException e) { + return null; + } + } +} diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperChickenVariantLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperChickenVariantLoader.java new file mode 100644 index 00000000..5dd739c0 --- /dev/null +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperChickenVariantLoader.java @@ -0,0 +1,19 @@ +package fr.maxlego08.menu.loader.components.paper; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.PaperRegistryVariantLoader; +import io.papermc.paper.registry.RegistryKey; +import org.bukkit.entity.Chicken; + +@ComponentLoader +@PaperOnly +@SinceVersion("1.21.5") +public class PaperChickenVariantLoader extends PaperRegistryVariantLoader { + public PaperChickenVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("chicken/variant", RegistryKey.CHICKEN_VARIANT, variantFactory::createChicken); + } +} diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperCowVariantLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperCowVariantLoader.java new file mode 100644 index 00000000..0713a7b7 --- /dev/null +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperCowVariantLoader.java @@ -0,0 +1,19 @@ +package fr.maxlego08.menu.loader.components.paper; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.PaperRegistryVariantLoader; +import io.papermc.paper.registry.RegistryKey; +import org.bukkit.entity.Cow; + +@ComponentLoader +@PaperOnly +@SinceVersion("1.21.5") +public class PaperCowVariantLoader extends PaperRegistryVariantLoader { + public PaperCowVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("cow/variant", RegistryKey.COW_VARIANT, variantFactory::createCow); + } +} diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperPigVariantLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperPigVariantLoader.java new file mode 100644 index 00000000..ea201743 --- /dev/null +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperPigVariantLoader.java @@ -0,0 +1,19 @@ +package fr.maxlego08.menu.loader.components.paper; + +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.ComponentLoader; +import fr.maxlego08.menu.api.annotations.PaperOnly; +import fr.maxlego08.menu.api.annotations.SinceVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; +import fr.maxlego08.menu.loader.components.variants.base.PaperRegistryVariantLoader; +import io.papermc.paper.registry.RegistryKey; +import org.bukkit.entity.Pig; + +@ComponentLoader +@PaperOnly +@SinceVersion("1.21.5") +public class PaperPigVariantLoader extends PaperRegistryVariantLoader { + public PaperPigVariantLoader(MenuPlugin plugin, VariantComponent variantFactory) { + super("pig/variant", RegistryKey.PIG_VARIANT, variantFactory::createPig); + } +} diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperVariantItemComponentLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperVariantItemComponentLoader.java deleted file mode 100644 index c36c6ff0..00000000 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/paper/PaperVariantItemComponentLoader.java +++ /dev/null @@ -1,89 +0,0 @@ -package fr.maxlego08.menu.loader.components.paper; - -import fr.maxlego08.menu.api.context.MenuItemStackContext; -import fr.maxlego08.menu.api.itemstack.ItemComponent; -import fr.maxlego08.menu.api.loader.ItemComponentLoader; -import fr.maxlego08.menu.common.factory.VariantItemComponentLoaderFactory; -import fr.maxlego08.menu.common.interfaces.VariantComponent; -import fr.maxlego08.menu.loader.components.spigot.SpigotVariantItemComponentLoader; -import io.papermc.paper.registry.RegistryAccess; -import io.papermc.paper.registry.RegistryKey; -import org.bukkit.Keyed; -import org.bukkit.NamespacedKey; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.io.File; -import java.util.function.Function; - -/** - * Paper-specific variant component loader that uses Paper's RegistryAccess API - * for better performance and compatibility. - */ -public class PaperVariantItemComponentLoader extends SpigotVariantItemComponentLoader implements VariantItemComponentLoaderFactory { - - public PaperVariantItemComponentLoader(VariantComponent variantFactory) { - super(variantFactory); - } - - @Override - public @NotNull ItemComponentLoader getLoaderChicken() { - return new Chicken(); - } - - @Override - public @NotNull ItemComponentLoader getLoaderCow() { - return new Cow(); - } - @Override - public @NotNull ItemComponentLoader getLoaderPig() { - return new Pig(); - } - - - private static abstract class PaperRegistryVariantLoader extends ItemComponentLoader { - private final RegistryKey registryKey; - private final Function componentFactory; - - protected PaperRegistryVariantLoader(String path, RegistryKey registryKey, Function componentFactory) { - super(path); - this.registryKey = registryKey; - this.componentFactory = componentFactory; - } - - @Override - public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { - path = normalizePath(path); - String value = configuration.getString(path); - if (value == null) return null; - NamespacedKey key = NamespacedKey.fromString(value); - if (key == null) return null; - try { - T registryValue = RegistryAccess.registryAccess().getRegistry(this.registryKey).getOrThrow(key); - return componentFactory.apply(registryValue); - } catch (IllegalArgumentException e) { - return null; - } - } - } - - public class Chicken extends PaperRegistryVariantLoader { - public Chicken() { - super("chicken/variant", RegistryKey.CHICKEN_VARIANT, variantFactory::createChicken); - } - } - - public class Cow extends PaperRegistryVariantLoader { - public Cow() { - super("cow/variant", RegistryKey.COW_VARIANT, variantFactory::createCow); - } - } - - public class Pig extends PaperRegistryVariantLoader { - public Pig() { - super("pig/variant", RegistryKey.PIG_VARIANT, variantFactory::createPig); - } - } -} \ No newline at end of file diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/variants/base/PaperRegistryVariantLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/variants/base/PaperRegistryVariantLoader.java new file mode 100644 index 00000000..d749a3fe --- /dev/null +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/loader/components/variants/base/PaperRegistryVariantLoader.java @@ -0,0 +1,42 @@ +package fr.maxlego08.menu.loader.components.variants.base; + +import fr.maxlego08.menu.api.context.MenuItemStackContext; +import fr.maxlego08.menu.api.itemstack.ItemComponent; +import fr.maxlego08.menu.api.loader.ItemComponentLoader; +import io.papermc.paper.registry.RegistryAccess; +import io.papermc.paper.registry.RegistryKey; +import org.bukkit.Keyed; +import org.bukkit.NamespacedKey; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.util.function.Function; + +public abstract class PaperRegistryVariantLoader extends ItemComponentLoader { + private final RegistryKey registryKey; + private final Function componentFactory; + + protected PaperRegistryVariantLoader(String path, RegistryKey registryKey, Function componentFactory) { + super(path); + this.registryKey = registryKey; + this.componentFactory = componentFactory; + } + + @Override + public @Nullable ItemComponent load(@NotNull MenuItemStackContext context, @NotNull File file, @NotNull YamlConfiguration configuration, @NotNull String path, @Nullable ConfigurationSection componentSection) { + path = normalizePath(path); + String value = configuration.getString(path); + if (value == null) return null; + NamespacedKey key = NamespacedKey.fromString(value); + if (key == null) return null; + try { + T registryValue = RegistryAccess.registryAccess().getRegistry(this.registryKey).getOrThrow(key); + return componentFactory.apply(registryValue); + } catch (IllegalArgumentException e) { + return null; + } + } +} diff --git a/src/main/java/fr/maxlego08/menu/ZComponentsManager.java b/src/main/java/fr/maxlego08/menu/ZComponentsManager.java index f885d243..4f4280ee 100644 --- a/src/main/java/fr/maxlego08/menu/ZComponentsManager.java +++ b/src/main/java/fr/maxlego08/menu/ZComponentsManager.java @@ -9,12 +9,9 @@ import fr.maxlego08.menu.api.utils.ReflectionsCache; import fr.maxlego08.menu.common.MinecraftVersion; import fr.maxlego08.menu.common.VersionFilter; -import fr.maxlego08.menu.common.factory.VariantItemComponentLoaderFactory; -import fr.maxlego08.menu.common.utils.nms.NmsVersion; +import fr.maxlego08.menu.common.interfaces.VariantComponent; import fr.maxlego08.menu.itemstack.components.paper.PaperVariantComponent; import fr.maxlego08.menu.itemstack.components.spigot.SpigotVariantComponent; -import fr.maxlego08.menu.loader.components.paper.PaperVariantItemComponentLoader; -import fr.maxlego08.menu.loader.components.spigot.SpigotVariantItemComponentLoader; import fr.maxlego08.menu.zcore.logger.Logger; import org.jetbrains.annotations.NotNull; import org.reflections.Reflections; @@ -33,6 +30,7 @@ public void initializeDefaultComponents(MenuPlugin plugin) { MinecraftVersion minecraftVersion = MinecraftVersion.getCurrentVersion(); Reflections reflection = ReflectionsCache.getInstance().getOrCreate((ZMenuPlugin) plugin, "fr.maxlego08.menu"); + VariantComponent variantComponent = plugin.isPaperOrFolia() ? new PaperVariantComponent() : new SpigotVariantComponent(); int count = 0; Set> typesAnnotatedWith = reflection.getTypesAnnotatedWith(ComponentLoader.class); @@ -43,9 +41,13 @@ public void initializeDefaultComponents(MenuPlugin plugin) { try { ItemComponentLoader loader; try { - loader = (ItemComponentLoader) clazz.getDeclaredConstructor().newInstance(); - } catch (NoSuchMethodException e) { - loader = (ItemComponentLoader) clazz.getDeclaredConstructor(MenuPlugin.class).newInstance(plugin); + loader = (ItemComponentLoader) clazz.getDeclaredConstructor(MenuPlugin.class, VariantComponent.class).newInstance(plugin, variantComponent); + } catch (NoSuchMethodException e1) { + try { + loader = (ItemComponentLoader) clazz.getDeclaredConstructor().newInstance(); + } catch (NoSuchMethodException e2) { + loader = (ItemComponentLoader) clazz.getDeclaredConstructor(MenuPlugin.class).newInstance(plugin); + } } this.registerComponent(loader); count++; @@ -58,97 +60,9 @@ public void initializeDefaultComponents(MenuPlugin plugin) { } } - Logger.info("Registered " + count + " default component loaders for Minecraft version " + minecraftVersion + "."); - - - NmsVersion currentVersion = NmsVersion.getCurrentVersion(); - if (currentVersion.isAttributItemStack()){ // 1.20.5+ - try { - this.initializeVariantComponents(plugin); - } catch (Exception e) { - if (Configuration.enableDebug) { - Logger.info("Failed to initialize variant item components:"); - e.printStackTrace(); - } - } - } - } - - private void initializeVariantComponents(MenuPlugin plugin) { - NmsVersion currentVersion = NmsVersion.getCurrentVersion(); - VariantItemComponentLoaderFactory loaderFactory = - plugin.isPaperOrFolia() ? new PaperVariantItemComponentLoader(new PaperVariantComponent()) - : new SpigotVariantItemComponentLoader(new SpigotVariantComponent()); - - this.registerComponent(loaderFactory.getLoaderCatCollar()); - this.registerComponent(loaderFactory.getLoaderCatVariant()); - this.registerComponent(loaderFactory.getLoaderHorse()); - this.registerComponent(loaderFactory.getLoaderRabbit()); - this.registerComponent(loaderFactory.getLoaderSheep()); - this.registerComponent(loaderFactory.getLoaderTropicalFishBaseColor()); - this.registerComponent(loaderFactory.getLoaderTropicalFishPatternColor()); - this.registerComponent(loaderFactory.getLoaderVillager()); - - if (currentVersion.isNewMaterial()){ // 1.13+ - this.registerComponent(loaderFactory.getLoaderFox()); - this.registerComponent(loaderFactory.getLoaderMushroomCow()); - } - if (currentVersion.isNewNMSVersion()){ // 1.17+ - this.registerComponent(loaderFactory.getLoaderAxolotl()); - } - if (currentVersion.isAttributItemStack()){ // 1.20.5+ - this.registerComponent(loaderFactory.getLoaderWolfCollar()); - this.registerComponent(loaderFactory.getLoaderWolfVariant()); - this.registerComponent(loaderFactory.getLoaderPainting()); - } - if (currentVersion.is1_21_5OrNewer()){ // 1.21.5+ - try { - this.registerComponent(loaderFactory.getLoaderChicken()); - } catch (Exception e) { - if (Configuration.enableDebug){ - Logger.info("Failed to register Chicken variant component:"); - e.printStackTrace(); - } - } - try { - this.registerComponent(loaderFactory.getLoaderCow()); - } catch (Exception e) { - if (Configuration.enableDebug){ - Logger.info("Failed to register Cow variant component:"); - e.printStackTrace(); - } - } - try { - this.registerComponent(loaderFactory.getLoaderPig()); - } catch (Exception e) { - if (Configuration.enableDebug){ - Logger.info("Failed to register Pig variant component:"); - e.printStackTrace(); - } - } - try { - this.registerComponent(loaderFactory.getLoaderSalmon()); - } catch (Exception e) { - if (Configuration.enableDebug){ - Logger.info("Failed to register Salmon variant component:"); - e.printStackTrace(); - } - } - } - if (currentVersion.isNewNBTVersion()) { // 1.18+ - this.registerComponent(loaderFactory.getLoaderFrog()); - } - if (currentVersion.is1_11OrNewer()){ // 1.11+ - this.registerComponent(loaderFactory.getLoaderLlama()); - this.registerComponent(loaderFactory.getLoaderShulkerBox()); - } - if (currentVersion.is1_12OrNewer()) { // 1.12+ - this.registerComponent(loaderFactory.getLoaderParrot()); - } - + Logger.info("Registered " + count + " default component loaders for Minecraft version " + minecraftVersion + "."); } - @Override public void registerComponent(@NotNull ItemComponentLoader loader) throws ItemComponentAlreadyRegisterException { List componentNames = loader.getComponentNames(); From 9a29afda79b42d18761818df8e6aebe6e381d5f4 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Wed, 29 Apr 2026 12:22:39 +0200 Subject: [PATCH 08/24] feat: add GEMINI.md to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 3506388e..c7cb74dc 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,4 @@ opencode.json CLAUDE.md .claude/settings.local.json build-and-deploy.sh +GEMINI.md \ No newline at end of file From 8bd49c1bedec1a824843bf214de67237c3688b41 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Wed, 29 Apr 2026 14:02:28 +0200 Subject: [PATCH 09/24] feat: implement automatic listener registration using AutoListener annotation --- .../menu/api/annotations/AutoListener.java | 11 ++++++ .../fr/maxlego08/menu/ZComponentsManager.java | 4 -- .../java/fr/maxlego08/menu/ZMenuPlugin.java | 39 +++++++++++++++++-- .../menu/listener/AdapterListener.java | 7 +++- .../menu/listener/SwapKeyListener.java | 2 + 5 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 API/src/main/java/fr/maxlego08/menu/api/annotations/AutoListener.java diff --git a/API/src/main/java/fr/maxlego08/menu/api/annotations/AutoListener.java b/API/src/main/java/fr/maxlego08/menu/api/annotations/AutoListener.java new file mode 100644 index 00000000..e3a0c549 --- /dev/null +++ b/API/src/main/java/fr/maxlego08/menu/api/annotations/AutoListener.java @@ -0,0 +1,11 @@ +package fr.maxlego08.menu.api.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface AutoListener { +} diff --git a/src/main/java/fr/maxlego08/menu/ZComponentsManager.java b/src/main/java/fr/maxlego08/menu/ZComponentsManager.java index 4f4280ee..2759a7fd 100644 --- a/src/main/java/fr/maxlego08/menu/ZComponentsManager.java +++ b/src/main/java/fr/maxlego08/menu/ZComponentsManager.java @@ -21,10 +21,6 @@ public class ZComponentsManager implements ComponentsManager { private final Map components = new HashMap<>(); - private boolean isPaperAndMiniMessageEnabled(MenuPlugin plugin){ - return plugin.isPaperOrFolia() && Configuration.enableMiniMessageFormat; - } - @Override public void initializeDefaultComponents(MenuPlugin plugin) { MinecraftVersion minecraftVersion = MinecraftVersion.getCurrentVersion(); diff --git a/src/main/java/fr/maxlego08/menu/ZMenuPlugin.java b/src/main/java/fr/maxlego08/menu/ZMenuPlugin.java index 7562b40e..49c21452 100644 --- a/src/main/java/fr/maxlego08/menu/ZMenuPlugin.java +++ b/src/main/java/fr/maxlego08/menu/ZMenuPlugin.java @@ -3,6 +3,7 @@ import com.tcoded.folialib.FoliaLib; import com.tcoded.folialib.impl.PlatformScheduler; import fr.maxlego08.menu.api.*; +import fr.maxlego08.menu.api.annotations.AutoListener; import fr.maxlego08.menu.api.attribute.ApplySpigotAttribute; import fr.maxlego08.menu.api.attribute.AttributApplier; import fr.maxlego08.menu.api.command.CommandManager; @@ -20,10 +21,12 @@ import fr.maxlego08.menu.api.storage.StorageManager; import fr.maxlego08.menu.api.utils.EnumInventory; import fr.maxlego08.menu.api.utils.MetaUpdater; +import fr.maxlego08.menu.api.utils.ReflectionsCache; import fr.maxlego08.menu.api.utils.toast.ToastHelper; import fr.maxlego08.menu.api.website.WebsiteManager; import fr.maxlego08.menu.command.VCommandManager; import fr.maxlego08.menu.command.commands.CommandMenu; +import fr.maxlego08.menu.common.VersionFilter; import fr.maxlego08.menu.common.utils.cache.YamlFileCache; import fr.maxlego08.menu.common.utils.nms.NMSUtils; import fr.maxlego08.menu.common.utils.nms.NmsVersion; @@ -48,9 +51,7 @@ import fr.maxlego08.menu.hooks.packetevents.loader.PacketEventTitleAnimationLoader; import fr.maxlego08.menu.inventory.VInventoryManager; import fr.maxlego08.menu.inventory.inventories.InventoryDefault; -import fr.maxlego08.menu.listener.AdapterListener; import fr.maxlego08.menu.listener.ItemUpdaterListener; -import fr.maxlego08.menu.listener.SwapKeyListener; import fr.maxlego08.menu.loader.materials.ArmorLoader; import fr.maxlego08.menu.loader.materials.Base64Loader; import fr.maxlego08.menu.pattern.ZPatternManager; @@ -72,9 +73,11 @@ import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; +import org.bukkit.event.Listener; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.ServicePriority; import org.bukkit.plugin.ServicesManager; +import org.reflections.Reflections; import java.io.File; import java.util.*; @@ -208,8 +211,7 @@ public void onEnable() { this.registerCommand("zmenu", this.commandMenu = new CommandMenu(this), "zm"); /* Add Listener */ - this.addListener(new SwapKeyListener()); - this.addListener(new AdapterListener(this)); + this.registerAutoListeners(); this.addListener(this.vinventoryManager); this.addListener(this.inventoriesPlayer); this.addListener(new ItemUpdaterListener(this.itemManager)); @@ -270,6 +272,35 @@ public void onEnable() { this.postEnable(); } + private void registerAutoListeners() { + Reflections reflection = ReflectionsCache.getInstance().getOrCreate(this, "fr.maxlego08.menu"); + + Set> candidates = reflection.getTypesAnnotatedWith(AutoListener.class); + + int count = 0; + for (Class clazz : candidates) { + if (!Listener.class.isAssignableFrom(clazz)) continue; + if (!VersionFilter.passes(clazz)) continue; + try { + Listener listener; + try { + listener = (Listener) clazz.getDeclaredConstructor(MenuPlugin.class).newInstance(this); + } catch (NoSuchMethodException e) { + listener = (Listener) clazz.getDeclaredConstructor().newInstance(); + } + this.addListener(listener); + count++; + } catch (Exception e) { + if (Configuration.enableDebug) { + Logger.info("Failed to instantiate auto listener: " + clazz.getName()); + e.printStackTrace(); + } + } + } + + Logger.info("Registered " + count + " auto listener(s)."); + } + /** * Registers all the hooks for the plugins that are present. * This method is called at the end of {@link #onEnable()} and it will diff --git a/src/main/java/fr/maxlego08/menu/listener/AdapterListener.java b/src/main/java/fr/maxlego08/menu/listener/AdapterListener.java index 839e43c1..7ea12ffa 100644 --- a/src/main/java/fr/maxlego08/menu/listener/AdapterListener.java +++ b/src/main/java/fr/maxlego08/menu/listener/AdapterListener.java @@ -1,6 +1,8 @@ package fr.maxlego08.menu.listener; import fr.maxlego08.menu.ZMenuPlugin; +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.annotations.AutoListener; import fr.maxlego08.menu.common.utils.ZUtils; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -13,12 +15,13 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; +@AutoListener public class AdapterListener extends ZUtils implements Listener { private final ZMenuPlugin plugin; - public AdapterListener(ZMenuPlugin template) { - this.plugin = template; + public AdapterListener(MenuPlugin plugin) { + this.plugin = (ZMenuPlugin) plugin; } @EventHandler diff --git a/src/main/java/fr/maxlego08/menu/listener/SwapKeyListener.java b/src/main/java/fr/maxlego08/menu/listener/SwapKeyListener.java index b507c5e4..8477d363 100644 --- a/src/main/java/fr/maxlego08/menu/listener/SwapKeyListener.java +++ b/src/main/java/fr/maxlego08/menu/listener/SwapKeyListener.java @@ -2,6 +2,7 @@ import fr.maxlego08.menu.ZMenuPlugin; import fr.maxlego08.menu.api.InventoryManager; +import fr.maxlego08.menu.api.annotations.AutoListener; import fr.maxlego08.menu.api.configuration.Configuration; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -11,6 +12,7 @@ /** * Allows to use the key to change item in his second hand, by default the key will be F */ +@AutoListener public class SwapKeyListener implements Listener { @EventHandler public void onPressKey(PlayerSwapHandItemsEvent event) { From 165044f843c973ba193079618f222866cd3f8fcc Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Fri, 1 May 2026 15:17:58 +0200 Subject: [PATCH 10/24] feat: support for view-requirement for CustomRender buttons --- .../inventories/InventoryDefault.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/java/fr/maxlego08/menu/inventory/inventories/InventoryDefault.java b/src/main/java/fr/maxlego08/menu/inventory/inventories/InventoryDefault.java index 1fc78027..5ab2c36a 100644 --- a/src/main/java/fr/maxlego08/menu/inventory/inventories/InventoryDefault.java +++ b/src/main/java/fr/maxlego08/menu/inventory/inventories/InventoryDefault.java @@ -197,12 +197,6 @@ public void buildButton(Button button, @NonNull Placeholders placeholders) { return; } final Player targetPlayer = getTargetPlayer(); - if (button.hasCustomRender()) { - perfDebug.start("onRender." + button.getName()); - button.onRender(targetPlayer, this); - perfDebug.end(); - return; - } perfDebug.start("getDisplayButton." + button.getName()); button = button.getDisplayButton(this, this.player); @@ -231,13 +225,25 @@ public void buildButton(Button button, @NonNull Placeholders placeholders) { } else { // If the player has the permission, the button - this.displayButton(button, placeholders); + if (button.hasCustomRender()) { + perfDebug.start("onRender." + button.getName()); + button.onRender(targetPlayer, this); + perfDebug.end(); + } else { + this.displayButton(button, placeholders); + } } } else { // If there is no permission, then the button - this.displayButton(button, placeholders); + if (button.hasCustomRender()) { + perfDebug.start("onRender." + button.getName()); + button.onRender(targetPlayer, this); + perfDebug.end(); + } else { + this.displayButton(button, placeholders); + } } } From 8102644e76ccff6f2e0fd3b3bb3e38992436feaf Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Fri, 1 May 2026 15:45:41 +0200 Subject: [PATCH 11/24] feat: replace NmsVersion with MinecraftVersion for version checks across multiple classes --- .../fr/maxlego08/menu/ZMenuItemStack.java | 8 +- .../menu/common/MinecraftVersion.java | 35 +++-- .../menu/common/utils/MessageUtils.java | 4 +- .../maxlego08/menu/common/utils/ZUtils.java | 8 +- .../itemstack/MenuItemStackFromItemStack.java | 6 +- .../common/utils/nms/ItemStackCompound.java | 11 +- .../menu/common/utils/nms/ItemStackUtils.java | 8 +- .../menu/common/utils/nms/NmsVersion.java | 147 ++++++++++++------ .../java/fr/maxlego08/menu/ZMenuPlugin.java | 9 +- .../menu/command/commands/CommandMenu.java | 4 +- .../menu/itemstack/ItemModelSimilar.java | 4 +- .../menu/loader/MenuItemStackLoader.java | 10 +- .../maxlego08/menu/loader/ZButtonLoader.java | 3 +- .../menu/website/ZWebsiteManager.java | 3 +- .../zcore/utils/loader/ItemStackLoader.java | 6 +- 15 files changed, 168 insertions(+), 98 deletions(-) diff --git a/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java b/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java index 9f60350a..3175dc16 100644 --- a/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java +++ b/Common/src/main/java/fr/maxlego08/menu/ZMenuItemStack.java @@ -19,9 +19,9 @@ import fr.maxlego08.menu.api.utils.MapConfiguration; import fr.maxlego08.menu.api.utils.OfflinePlayerCache; import fr.maxlego08.menu.api.utils.Placeholders; +import fr.maxlego08.menu.common.MinecraftVersion; import fr.maxlego08.menu.common.utils.ZUtils; import fr.maxlego08.menu.common.utils.itemstack.MenuItemStackFromItemStack; -import fr.maxlego08.menu.common.utils.nms.NmsVersion; import fr.maxlego08.menu.zcore.logger.Logger; import fr.maxlego08.menu.zcore.utils.PerformanceDebug; import org.bukkit.*; @@ -353,15 +353,15 @@ private void applyFlags(ItemMeta itemMeta) { } private void applyVersionSpecificMeta(ItemStack itemStack, ItemMeta itemMeta, Player player, Placeholders placeholders) { - if (NmsVersion.getCurrentVersion().isNewItemStackAPI()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21"))) { this.buildNewItemStackAPI(itemStack, itemMeta, player, placeholders); } - if (NmsVersion.getCurrentVersion().isNewHeadApi()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.20"))) { this.buildTrimAPI(itemStack, itemMeta, player, placeholders); } - if (this.clearDefaultAttributes && this.attributes.isEmpty() && NmsVersion.getCurrentVersion().getVersion() >= NmsVersion.V_1_20_4.getVersion()) { + if (this.clearDefaultAttributes && this.attributes.isEmpty() && MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.20.4"))) { itemMeta.setAttributeModifiers(ArrayListMultimap.create()); } } diff --git a/Common/src/main/java/fr/maxlego08/menu/common/MinecraftVersion.java b/Common/src/main/java/fr/maxlego08/menu/common/MinecraftVersion.java index 171f2131..040220f9 100644 --- a/Common/src/main/java/fr/maxlego08/menu/common/MinecraftVersion.java +++ b/Common/src/main/java/fr/maxlego08/menu/common/MinecraftVersion.java @@ -5,7 +5,11 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + public final class MinecraftVersion implements Comparable { + private static final Map PARSE_CACHE = new ConcurrentHashMap<>(); private static MinecraftVersion currentVersion; @@ -31,17 +35,19 @@ public static MinecraftVersion parse(@Nullable String rawVersion) { if (rawVersion == null || rawVersion.isBlank()) { return new MinecraftVersion(0, 0, 0); } - String clean = rawVersion.contains("-") ? rawVersion.substring(0, rawVersion.indexOf('-')) : rawVersion; - String[] parts = clean.split("\\."); - try { - int major = parts.length > 0 ? Integer.parseInt(parts[0]) : 0; - int minor = parts.length > 1 ? Integer.parseInt(parts[1]) : 0; - int patch = parts.length > 2 ? Integer.parseInt(parts[2]) : 0; - return new MinecraftVersion(major, minor, patch); - } catch (NumberFormatException e) { - Logger.info("Could not parse Minecraft value '" + rawVersion + "'. Version-gated classes will be skipped. (" + e.getMessage() + ")", Logger.LogType.WARNING); - return new MinecraftVersion(0, 0, 0); - } + return PARSE_CACHE.computeIfAbsent(rawVersion, raw -> { + String clean = raw.contains("-") ? raw.substring(0, raw.indexOf('-')) : raw; + String[] parts = clean.split("\\."); + try { + int major = parts.length > 0 ? Integer.parseInt(parts[0]) : 0; + int minor = parts.length > 1 ? Integer.parseInt(parts[1]) : 0; + int patch = parts.length > 2 ? Integer.parseInt(parts[2]) : 0; + return new MinecraftVersion(major, minor, patch); + } catch (NumberFormatException e) { + Logger.info("Could not parse Minecraft value '" + raw + "'. Version-gated classes will be skipped. (" + e.getMessage() + ")", Logger.LogType.WARNING); + return new MinecraftVersion(0, 0, 0); + } + }); } /** @@ -58,6 +64,13 @@ public boolean isAtMost(MinecraftVersion other) { return compareTo(other) <= 0; } + public boolean isBefore(MinecraftVersion other) { + return compareTo(other) < 0; + } + + public boolean isAfter(MinecraftVersion other) { + return compareTo(other) > 0; + } public int getMajor() { return this.major; diff --git a/Common/src/main/java/fr/maxlego08/menu/common/utils/MessageUtils.java b/Common/src/main/java/fr/maxlego08/menu/common/utils/MessageUtils.java index 83140edf..90526424 100644 --- a/Common/src/main/java/fr/maxlego08/menu/common/utils/MessageUtils.java +++ b/Common/src/main/java/fr/maxlego08/menu/common/utils/MessageUtils.java @@ -3,7 +3,7 @@ import fr.maxlego08.menu.api.MenuPlugin; import fr.maxlego08.menu.api.utils.IMessage; import fr.maxlego08.menu.api.utils.Message; -import fr.maxlego08.menu.common.utils.nms.NmsVersion; +import fr.maxlego08.menu.common.MinecraftVersion; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -130,7 +130,7 @@ protected final Class getNMSClass(String name) { protected void title(Player player, String title, String subtitle, int fadeInTime, int showTime, int fadeOutTime) { - if (NmsVersion.nmsVersion.isNewMaterial()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.13"))) { player.sendTitle(title, subtitle, fadeInTime, showTime, fadeOutTime); return; } diff --git a/Common/src/main/java/fr/maxlego08/menu/common/utils/ZUtils.java b/Common/src/main/java/fr/maxlego08/menu/common/utils/ZUtils.java index c2a2863c..9d5b6dd0 100644 --- a/Common/src/main/java/fr/maxlego08/menu/common/utils/ZUtils.java +++ b/Common/src/main/java/fr/maxlego08/menu/common/utils/ZUtils.java @@ -3,9 +3,9 @@ import fr.maxlego08.menu.api.MenuPlugin; import fr.maxlego08.menu.api.utils.EnumInventory; import fr.maxlego08.menu.api.utils.Message; +import fr.maxlego08.menu.common.MinecraftVersion; import fr.maxlego08.menu.common.enums.Permission; import fr.maxlego08.menu.common.utils.nms.NMSUtils; -import fr.maxlego08.menu.common.utils.nms.NmsVersion; import fr.maxlego08.menu.zcore.logger.Logger; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.ClickEvent; @@ -45,7 +45,7 @@ public abstract class ZUtils extends MessageUtils { private static Material[] byId; static { - if (!NmsVersion.nmsVersion.isNewMaterial()) { + if (!MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.13"))) { byId = new Material[0]; for (Material material : Material.values()) { if (byId.length <= material.getId()) { @@ -57,7 +57,7 @@ public abstract class ZUtils extends MessageUtils { } protected String findPlayerLocale(Player player) { - if (NmsVersion.getCurrentVersion().getVersion() >= NmsVersion.V_1_13.getVersion()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.13"))) { try { return player != null ? player.getLocale() : null; } catch (Exception exception) { @@ -452,7 +452,7 @@ private void applyTextureUrl(ItemStack itemStack, String url) { protected Object getPrivateField(Object object, String field) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException { Class clazz = object.getClass(); - Field objectField = field.equals("commandMap") ? clazz.getDeclaredField(field) : field.equals("knownCommands") ? NmsVersion.nmsVersion.isNewMaterial() ? clazz.getSuperclass().getDeclaredField(field) : clazz.getDeclaredField(field) : null; + Field objectField = field.equals("commandMap") ? clazz.getDeclaredField(field) : field.equals("knownCommands") ? MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.13")) ? clazz.getSuperclass().getDeclaredField(field) : clazz.getDeclaredField(field) : null; objectField.setAccessible(true); Object result = objectField.get(object); objectField.setAccessible(false); diff --git a/Common/src/main/java/fr/maxlego08/menu/common/utils/itemstack/MenuItemStackFromItemStack.java b/Common/src/main/java/fr/maxlego08/menu/common/utils/itemstack/MenuItemStackFromItemStack.java index 5edc1a38..d2739d16 100644 --- a/Common/src/main/java/fr/maxlego08/menu/common/utils/itemstack/MenuItemStackFromItemStack.java +++ b/Common/src/main/java/fr/maxlego08/menu/common/utils/itemstack/MenuItemStackFromItemStack.java @@ -4,8 +4,8 @@ import fr.maxlego08.menu.api.InventoryManager; import fr.maxlego08.menu.api.itemstack.Firework; import fr.maxlego08.menu.api.itemstack.Potion; +import fr.maxlego08.menu.common.MinecraftVersion; import fr.maxlego08.menu.common.utils.nms.ItemStackUtils; -import fr.maxlego08.menu.common.utils.nms.NmsVersion; import org.bukkit.FireworkEffect; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.*; @@ -24,7 +24,7 @@ public static ZMenuItemStack fromItemStack(InventoryManager manager, ItemStack i menuItemStack.setMaterial(itemStack.getType().name()); int amount = itemStack.getAmount(); if (amount > 1) menuItemStack.setAmount(String.valueOf(itemStack.getAmount())); - if (NmsVersion.getCurrentVersion().isItemLegacy()) { + if (MinecraftVersion.getCurrentVersion().isBefore(MinecraftVersion.parse("1.13"))) { int durability = itemStack.getDurability(); if (durability > 0) menuItemStack.setDurability(durability); int data = itemStack.getData().getData(); @@ -45,7 +45,7 @@ public static ZMenuItemStack fromItemStack(InventoryManager manager, ItemStack i menuItemStack.setFlags(new ArrayList<>(itemMeta.getItemFlags())); menuItemStack.setEnchantments(itemMeta.getEnchants()); - if (NmsVersion.getCurrentVersion().isCustomModelData() && itemMeta.hasCustomModelData()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.14")) && itemMeta.hasCustomModelData()) { menuItemStack.setModelID(itemMeta.getCustomModelData()); } diff --git a/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/ItemStackCompound.java b/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/ItemStackCompound.java index 3821a093..197f15dc 100644 --- a/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/ItemStackCompound.java +++ b/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/ItemStackCompound.java @@ -1,5 +1,6 @@ package fr.maxlego08.menu.common.utils.nms; +import fr.maxlego08.menu.common.MinecraftVersion; import fr.maxlego08.menu.common.utils.nms.ItemStackUtils.EnumReflectionItemStack; import org.bukkit.inventory.ItemStack; @@ -12,14 +13,14 @@ public class ItemStackCompound { // Static block to initialize the itemStackCompound based on the NmsVersion static { - fr.maxlego08.menu.common.utils.nms.NmsVersion nmsVersion = fr.maxlego08.menu.common.utils.nms.NmsVersion.nmsVersion; - if (nmsVersion == fr.maxlego08.menu.common.utils.nms.NmsVersion.V_1_18_2) { + MinecraftVersion currentVersion = MinecraftVersion.getCurrentVersion(); + if (currentVersion.equals(MinecraftVersion.parse("1.18.2"))) { itemStackCompound = new ItemStackCompound(EnumReflectionCompound.V1_18_2); - } else if (nmsVersion.getVersion() >= 1200) { + } else if (currentVersion.isAtLeast(MinecraftVersion.parse("1.12"))) { itemStackCompound = new ItemStackCompound(EnumReflectionCompound.V1_12); - } else if (nmsVersion.getVersion() >= 1190) { + } else if (currentVersion.isAtLeast(MinecraftVersion.parse("1.19"))) { itemStackCompound = new ItemStackCompound(EnumReflectionCompound.V1_19); - } else if (nmsVersion.getVersion() >= 1170) { + } else if (currentVersion.isAtLeast(MinecraftVersion.parse("1.17"))) { itemStackCompound = new ItemStackCompound(EnumReflectionCompound.V1_17); } else itemStackCompound = new ItemStackCompound(EnumReflectionCompound.V1_8_8); } diff --git a/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/ItemStackUtils.java b/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/ItemStackUtils.java index cdd70f66..be1e9cfc 100644 --- a/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/ItemStackUtils.java +++ b/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/ItemStackUtils.java @@ -1,6 +1,7 @@ package fr.maxlego08.menu.common.utils.nms; import fr.maxlego08.menu.api.configuration.Configuration; +import fr.maxlego08.menu.common.MinecraftVersion; import fr.maxlego08.menu.common.utils.Base64; import org.bukkit.Bukkit; import org.bukkit.inventory.ItemStack; @@ -15,6 +16,7 @@ public class ItemStackUtils { private static final fr.maxlego08.menu.common.utils.nms.NmsVersion NMS_VERSION = fr.maxlego08.menu.common.utils.nms.NmsVersion.nmsVersion; private static final Map itemStackSerialized = new HashMap<>(); + private static final MinecraftVersion MINECRAFT_VERSION = MinecraftVersion.getCurrentVersion(); public static String serializeItemStack(ItemStack paramItemStack) { @@ -26,7 +28,7 @@ public static String serializeItemStack(ItemStack paramItemStack) { return itemStackSerialized.get(paramItemStack); } - if (fr.maxlego08.menu.common.utils.nms.NmsVersion.getCurrentVersion().isAttributItemStack()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.20.5"))) { return Base64ItemStack.encode(paramItemStack); } @@ -67,7 +69,7 @@ public static ItemStack deserializeItemStack(String paramString) { return null; } - if (fr.maxlego08.menu.common.utils.nms.NmsVersion.getCurrentVersion().isAttributItemStack()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.20.5"))) { return Base64ItemStack.decode(paramString); } @@ -99,7 +101,7 @@ public static ItemStack deserializeItemStack(String paramString) { if (NMS_VERSION == fr.maxlego08.menu.common.utils.nms.NmsVersion.V_1_11 || NMS_VERSION == fr.maxlego08.menu.common.utils.nms.NmsVersion.V_1_12) { Constructor localConstructor = localClass2.getConstructor(localClass1); localObject2 = localConstructor.newInstance(localObject1); - } else if (!NMS_VERSION.isItemLegacy()) { + } else if (MINECRAFT_VERSION.isAtMost(MinecraftVersion.parse("1.13"))) { localObject2 = localClass2.getMethod("a", new Class[]{localClass1}).invoke(null, localObject1); } else { diff --git a/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/NmsVersion.java b/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/NmsVersion.java index ccc0b069..b2525581 100644 --- a/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/NmsVersion.java +++ b/Common/src/main/java/fr/maxlego08/menu/common/utils/nms/NmsVersion.java @@ -1,5 +1,6 @@ package fr.maxlego08.menu.common.utils.nms; +import fr.maxlego08.menu.common.MinecraftVersion; import fr.maxlego08.menu.zcore.logger.Logger; import org.bukkit.Bukkit; @@ -60,9 +61,7 @@ public enum NmsVersion { V_1_21_10(12110), V_1_21_11(12111), - UNKNOWN(Integer.MAX_VALUE) - - ; + UNKNOWN(Integer.MAX_VALUE); public static final NmsVersion nmsVersion = getNmsVersion(); private final int version; @@ -72,15 +71,17 @@ public enum NmsVersion { } /** - * Gets the current value of the Bukkit server. + * Gets the current version of the Bukkit server. * - * @return The NmsVersion instance corresponding to the current value. + * @return The NmsVersion instance corresponding to the current version. + * @deprecated Use {@link MinecraftVersion#getCurrentVersion()} instead. */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public static NmsVersion getCurrentVersion() { return nmsVersion; } - private static NmsVersion getNmsVersion(){ + private static NmsVersion getNmsVersion() { Matcher matcher = Pattern.compile("(?\\d+\\.\\d+)(?\\.\\d+)?").matcher(Bukkit.getBukkitVersion()); int currentVersion = matcher.find() ? Integer.parseInt(matcher.group("version").replace(".", "") + (matcher.group("patch") != null ? matcher.group("patch").replace(".", "") : "0")) : 0; @@ -93,17 +94,15 @@ private static NmsVersion getNmsVersion(){ if (currentVersion > highestSupportedVersionEnum.version) { Logger.info(String.format( - "Running Minecraft %s (newer than highest supported value %s). " + - "Please report this value to help us add support. " + - "Check for plugin updates if you experience issues.", - currentVersion, - highestSupportedVersionEnum.name() + "Running Minecraft %s (newer than highest supported version %s). " + + "Please report this version to help us add support. " + + "Check for plugin updates if you experience issues.", + currentVersion, + highestSupportedVersionEnum.name() ), Logger.LogType.WARNING); return UNKNOWN; } - Logger.info(String.format("Detected Minecraft value code: %d", currentVersion)); - NmsVersion closest = V_1_12_2; int smallestDifference = Integer.MAX_VALUE; for (NmsVersion value : values()) { @@ -114,166 +113,222 @@ private static NmsVersion getNmsVersion(){ closest = value; } } - Logger.info(String.format("Detected Minecraft value: %s (value code: %d)", closest.name(), closest.version)); return closest; } /** - * Checks if the current value supports PlayerProfiles. - * - * @return True if PlayerProfiles are supported, else False. + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.18.1"))} instead. */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean hasPlayerProfiles() { return version >= NmsVersion.V_1_18_1.version; } /** - * Checks if the current value uses obfuscated names. - * - * @return True if names are obfuscated, else False. + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.17"))} instead. */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean hasObfuscatedNames() { return version >= NmsVersion.V_1_17.version; } /** - * Checks if the current value supports components. - * - * @param isPaper True if the server uses Paper, else False. - * @return True if components are supported, else False. + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.16.5"))} instead (combined with your Paper check). */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isComponent(boolean isPaper) { return isPaper && version >= NmsVersion.V_1_16_5.version; } /** - * Checks if the current value is a legacy item value. - * - * @return True if the value is legacy, else False. + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isBefore(MinecraftVersion.parse("1.13"))} instead. */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isItemLegacy() { return version < NmsVersion.V_1_13.version; } /** - * Checks if the current value supports PersistentDataContainer. - * - * @return True if PersistentDataContainer is supported, else False. + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.14"))} instead. */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isPdcVersion() { return version >= NmsVersion.V_1_14.version; } /** - * Checks if the current value is a legacy value for Skull owners. - * - * @return True if the value is legacy, else False. + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtMost(MinecraftVersion.parse("1.12"))} instead. */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isSkullOwnerLegacy() { return version <= NmsVersion.V_1_12.version; } /** - * Checks if the current value supports CustomModelData. - * - * @return True if CustomModelData is supported, else False. + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.14"))} instead. */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isCustomModelData() { return version >= NmsVersion.V_1_14.version; } /** - * Checks if the current value is a hexadecimal value. - * - * @return True if the value is hexadecimal, else False. + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.16"))} instead. */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isHexVersion() { return version >= NmsVersion.V_1_16.version; } /** - * Checks if the current value is an Attribute value. - * - * @return True if the value is Attribute, else False. + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAfter(MinecraftVersion.parse("1.8.8"))} instead. */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isAttributeVersion() { return version != NmsVersion.V_1_8_8.version; } /** - * Gets the value number associated with the enumeration. - * - * @return The value number. + * @deprecated Use {@link MinecraftVersion#getMinor()} or comparisons via {@link MinecraftVersion} instead. */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public int getVersion() { return version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.20.5"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isAttributItemStack() { return version >= NmsVersion.V_1_20_5.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().equals(MinecraftVersion.parse("1.8.8"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isOneHand() { return version == NmsVersion.V_1_8_8.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.14"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isBarrel() { return version >= V_1_14.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.9"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isShulker() { return version >= V_1_9.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.13"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isNewMaterial() { return version >= V_1_13.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.18"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isNewNBTVersion() { return version >= V_1_18.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.20"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isNewHeadApi() { return version >= V_1_20.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.17"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isNewNMSVersion() { return version >= V_1_17.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.11"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean is1_11OrNewer() { return version >= V_1_11.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.12"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean is1_12OrNewer() { return version >= V_1_12.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isNewItemStackAPI() { return version >= V_1_21.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21.4"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isNewItemModelAPI() { return version >= V_1_21_4.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21.7"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean isDialogsVersion() { return version >= V_1_21_7.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21.2"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean is1_21_2OrNewer() { return version >= V_1_21_2.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21.5"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean is1_21_5OrNewer() { return version >= V_1_21_5.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21.9"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean is1_21_9OrNewer() { return version >= V_1_21_9.version; } + /** + * @deprecated Use {@code MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21.11"))} instead. + */ + @Deprecated(since = "1.1.1.4", forRemoval = true) public boolean is1_21_11OrNewer() { return version >= V_1_21_11.version; } -} +} \ No newline at end of file diff --git a/src/main/java/fr/maxlego08/menu/ZMenuPlugin.java b/src/main/java/fr/maxlego08/menu/ZMenuPlugin.java index 49c21452..dc5a20fd 100644 --- a/src/main/java/fr/maxlego08/menu/ZMenuPlugin.java +++ b/src/main/java/fr/maxlego08/menu/ZMenuPlugin.java @@ -26,10 +26,10 @@ import fr.maxlego08.menu.api.website.WebsiteManager; import fr.maxlego08.menu.command.VCommandManager; import fr.maxlego08.menu.command.commands.CommandMenu; +import fr.maxlego08.menu.common.MinecraftVersion; import fr.maxlego08.menu.common.VersionFilter; import fr.maxlego08.menu.common.utils.cache.YamlFileCache; import fr.maxlego08.menu.common.utils.nms.NMSUtils; -import fr.maxlego08.menu.common.utils.nms.NmsVersion; import fr.maxlego08.menu.config.ConfigManager; import fr.maxlego08.menu.dupe.DupeListener; import fr.maxlego08.menu.dupe.NMSDupeManager; @@ -151,7 +151,8 @@ public void onEnable() { this.scheduler = this.foliaLib.getScheduler(); - this.dupeManager = NmsVersion.nmsVersion.isPdcVersion() ? new PDCDupeManager(this) : new NMSDupeManager(); + + this.dupeManager = MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.14")) ? new PDCDupeManager(this) : new NMSDupeManager(); this.enchantments.register(); this.preEnable(); @@ -194,7 +195,7 @@ public void onEnable() { servicesManager.register(Enchantments.class, this.enchantments, this, ServicePriority.Highest); servicesManager.register(TitleAnimationManager.class, this.titleAnimationManager, this, ServicePriority.Highest); - if (this.isPaperOrFolia() && NmsVersion.getCurrentVersion().isDialogsVersion()) { + if (this.isPaperOrFolia() && MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21.7"))) { if (Configuration.enableMiniMessageFormat) { Logger.info("Paper server detected, loading Dialogs support"); ConfigManager configManager = new ConfigManager(this); @@ -425,7 +426,7 @@ private List getInventoriesFiles() { files.add("actions_patterns/default-actions.yml"); - if (isPaperOrFolia() && NmsVersion.getCurrentVersion().isDialogsVersion()) { + if (isPaperOrFolia() && MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21.7"))) { files.add("dialogs/confirmation-dialog.yml"); files.add("dialogs/default-dialog.yml"); files.add("dialogs/multi_action-dialog.yml"); diff --git a/src/main/java/fr/maxlego08/menu/command/commands/CommandMenu.java b/src/main/java/fr/maxlego08/menu/command/commands/CommandMenu.java index 317e4628..fd59dde4 100644 --- a/src/main/java/fr/maxlego08/menu/command/commands/CommandMenu.java +++ b/src/main/java/fr/maxlego08/menu/command/commands/CommandMenu.java @@ -10,8 +10,8 @@ import fr.maxlego08.menu.command.commands.website.CommandMenuDownload; import fr.maxlego08.menu.command.commands.website.CommandMenuInventories; import fr.maxlego08.menu.command.commands.website.CommandMenuLogin; +import fr.maxlego08.menu.common.MinecraftVersion; import fr.maxlego08.menu.common.enums.Permission; -import fr.maxlego08.menu.common.utils.nms.NmsVersion; import fr.maxlego08.menu.zcore.utils.commands.CommandType; public class CommandMenu extends VCommand { @@ -43,7 +43,7 @@ public CommandMenu(ZMenuPlugin plugin) { this.addSubCommand(new CommandMenuInventories(plugin)); // this.addSubCommand(new CommandMenuMarketplace(plugin)); - if (plugin.isPaperOrFolia() && NmsVersion.getCurrentVersion().isDialogsVersion() &&Configuration.enableMiniMessageFormat) { + if (plugin.isPaperOrFolia() && MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21.7")) && Configuration.enableMiniMessageFormat) { this.addSubCommand(new CommandDialog(plugin)); } } diff --git a/src/main/java/fr/maxlego08/menu/itemstack/ItemModelSimilar.java b/src/main/java/fr/maxlego08/menu/itemstack/ItemModelSimilar.java index e67951e7..bfcbe737 100644 --- a/src/main/java/fr/maxlego08/menu/itemstack/ItemModelSimilar.java +++ b/src/main/java/fr/maxlego08/menu/itemstack/ItemModelSimilar.java @@ -1,7 +1,7 @@ package fr.maxlego08.menu.itemstack; import fr.maxlego08.menu.api.itemstack.ItemStackSimilar; -import fr.maxlego08.menu.common.utils.nms.NmsVersion; +import fr.maxlego08.menu.common.MinecraftVersion; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.jspecify.annotations.NonNull; @@ -14,7 +14,7 @@ public class ItemModelSimilar implements ItemStackSimilar { @Override public boolean isSimilar(@NonNull ItemStack itemStackA, @NonNull ItemStack itemStackB) { - if (NmsVersion.getCurrentVersion().isNewItemModelAPI()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21.4"))) { ItemMeta itemMetaA = itemStackA.getItemMeta(); ItemMeta itemMetaB = itemStackB.getItemMeta(); return itemMetaA.hasItemModel() == itemMetaB.hasItemModel() && itemMetaA.getItemModel() == itemMetaB.getItemModel(); diff --git a/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java b/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java index 83c444ef..5dad3de3 100644 --- a/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/MenuItemStackLoader.java @@ -16,8 +16,8 @@ import fr.maxlego08.menu.api.loader.ItemComponentLoader; import fr.maxlego08.menu.api.utils.Loader; import fr.maxlego08.menu.api.utils.LoreType; +import fr.maxlego08.menu.common.MinecraftVersion; import fr.maxlego08.menu.common.utils.ZUtils; -import fr.maxlego08.menu.common.utils.nms.NmsVersion; import fr.maxlego08.menu.zcore.logger.Logger; import org.bukkit.*; import org.bukkit.block.banner.Pattern; @@ -107,15 +107,15 @@ public MenuItemStack load(@NonNull YamlConfiguration configuration, @NonNull Str this.loadAttributes(menuItemStack, configuration, path); - if (NmsVersion.getCurrentVersion().isNewItemStackAPI()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21"))) { this.loadNewItemStacks(menuItemStack, configuration, path, file); } - if (NmsVersion.getCurrentVersion().isNewHeadApi()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.20"))) { this.loadTrims(menuItemStack, configuration, path, file); } this.loadItemModel(configuration, menuItemStack, path, file); - if (NmsVersion.getCurrentVersion().isAttributItemStack()) { // 1.20.5+ + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.20.5"))) { // 1.20.5+ ConfigurationSection componentsSection = configuration.getConfigurationSection(path + "components."); if (componentsSection != null) { ComponentsManager componentsManager = this.manager.getPlugin().getComponentsManager(); @@ -173,7 +173,7 @@ private void loadLore(ZMenuItemStack menuItemStack, YamlConfiguration configurat } private void loadItemModel(@NonNull YamlConfiguration configuration, ZMenuItemStack menuItemStack, @NonNull String path, File file) { - if (NmsVersion.getCurrentVersion().isNewItemModelAPI()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.21.4"))) { String itemModel = configuration.getString(path + "item-model"); if (itemModel != null) { try { diff --git a/src/main/java/fr/maxlego08/menu/loader/ZButtonLoader.java b/src/main/java/fr/maxlego08/menu/loader/ZButtonLoader.java index 54b21fbb..8ae3c05e 100644 --- a/src/main/java/fr/maxlego08/menu/loader/ZButtonLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/ZButtonLoader.java @@ -29,7 +29,6 @@ import fr.maxlego08.menu.common.utils.ZUtils; import fr.maxlego08.menu.common.utils.cache.YamlFileCache; import fr.maxlego08.menu.common.utils.cache.YamlFileCacheEntry; -import fr.maxlego08.menu.common.utils.nms.NmsVersion; import fr.maxlego08.menu.common.utils.yaml.YamlParser; import fr.maxlego08.menu.loader.permissible.PlaceholderPermissibleLoader; import fr.maxlego08.menu.requirement.permissible.ZPermissionPermissible; @@ -211,7 +210,7 @@ public Button load(@NonNull YamlConfiguration configuration, @NonNull String pat String playerHead = configuration.getString(path + "playerHead", configuration.getString(path + "player-head", configuration.getString(path + "item.playerHead", configuration.getString(path + "item.player-head", defaultButtonValue.getPlayerHead())))); if (playerHead != null) { - if (NmsVersion.nmsVersion.isNewMaterial()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.13"))) { itemStack.setMaterial("PLAYER_HEAD"); } else { itemStack.setMaterial("SKULL_ITEM"); diff --git a/src/main/java/fr/maxlego08/menu/website/ZWebsiteManager.java b/src/main/java/fr/maxlego08/menu/website/ZWebsiteManager.java index ef43f1b8..82b4dbff 100644 --- a/src/main/java/fr/maxlego08/menu/website/ZWebsiteManager.java +++ b/src/main/java/fr/maxlego08/menu/website/ZWebsiteManager.java @@ -11,7 +11,6 @@ import fr.maxlego08.menu.api.utils.Message; import fr.maxlego08.menu.api.website.WebsiteManager; import fr.maxlego08.menu.common.utils.ZUtils; -import fr.maxlego08.menu.common.utils.nms.NmsVersion; import fr.maxlego08.menu.website.buttons.*; import fr.maxlego08.menu.website.request.HttpRequest; import org.bukkit.command.CommandSender; @@ -212,7 +211,7 @@ private void loadFiles() { files.add("website/inventories.yml"); files.forEach(filePath -> { - if (NmsVersion.nmsVersion.isNewMaterial()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.13"))) { if (!new File(plugin.getDataFolder(), filePath).exists()) { this.plugin.saveResource(filePath.replace("website/", "website/1_13/"), filePath, true); } diff --git a/src/main/java/fr/maxlego08/menu/zcore/utils/loader/ItemStackLoader.java b/src/main/java/fr/maxlego08/menu/zcore/utils/loader/ItemStackLoader.java index b4e1c325..a3078209 100644 --- a/src/main/java/fr/maxlego08/menu/zcore/utils/loader/ItemStackLoader.java +++ b/src/main/java/fr/maxlego08/menu/zcore/utils/loader/ItemStackLoader.java @@ -4,8 +4,8 @@ import fr.maxlego08.menu.api.exceptions.ItemFlagException; import fr.maxlego08.menu.api.itemstack.Potion; import fr.maxlego08.menu.api.utils.Loader; +import fr.maxlego08.menu.common.MinecraftVersion; import fr.maxlego08.menu.common.utils.ZUtils; -import fr.maxlego08.menu.common.utils.nms.NmsVersion; import fr.maxlego08.menu.zcore.logger.Logger; import fr.maxlego08.menu.zcore.logger.Logger.LogType; import org.bukkit.Material; @@ -171,7 +171,7 @@ public void save(ItemStack item, @NonNull YamlConfiguration configuration, @NonN configuration.set(path + "material", item.getType().name()); if (item.getAmount() != 1) configuration.set(path + "amount", item.getAmount()); - if (NmsVersion.getCurrentVersion().isItemLegacy()) { + if (MinecraftVersion.getCurrentVersion().isBefore(MinecraftVersion.parse("1.13"))) { if (item.getData().getData() != 0) configuration.set(path + "data", item.getData().getData()); if (item.getDurability() != 0) configuration.set(path + "durability", item.getDurability()); } @@ -209,7 +209,7 @@ public void save(ItemStack item, @NonNull YamlConfiguration configuration, @NonN configuration.set(path + "enchants", enchantList); } - if (NmsVersion.getCurrentVersion().isCustomModelData() && meta.hasCustomModelData()) { + if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.parse("1.14")) && meta.hasCustomModelData()) { configuration.set(path + "model-id", meta.getCustomModelData()); } } From 9b82328ab6e8e1e6a786f22cbe439bb151499402 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Tue, 5 May 2026 13:52:43 +0200 Subject: [PATCH 12/24] fix: remove debug logs --- .../menu/api/itemstack/components/ContainerComponent.java | 1 - 1 file changed, 1 deletion(-) diff --git a/API/src/main/java/fr/maxlego08/menu/api/itemstack/components/ContainerComponent.java b/API/src/main/java/fr/maxlego08/menu/api/itemstack/components/ContainerComponent.java index 29e9b0d5..9ae2dd45 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/itemstack/components/ContainerComponent.java +++ b/API/src/main/java/fr/maxlego08/menu/api/itemstack/components/ContainerComponent.java @@ -40,7 +40,6 @@ public void apply(@NotNull BuildContext context, @NotNull ItemStack itemStack, @ int slot = containerSlot.slot(); ItemStack builtItemStack = menuItemStack.build(player); inventory.setItem(slot, builtItemStack); - Logger.info("Added item to container at slot " + slot + ": " + builtItemStack.getType().name()); } container.update(); From 93ffca11a4bb81c2d878d8c0a5e2adfcd88ee8ea Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Tue, 5 May 2026 13:53:29 +0200 Subject: [PATCH 13/24] feat: add TakeItemAction and TakeItemLoader for item removal functionality --- .../fr/maxlego08/menu/ZInventoryManager.java | 3 +- .../maxlego08/menu/loader/ZButtonLoader.java | 1 + .../menu/loader/actions/TakeItemLoader.java | 32 ++++++++ .../requirement/actions/TakeItemAction.java | 82 +++++++++++++++++++ .../permissible/ZItemPermissible.java | 9 +- .../menu/website/ZWebsiteManager.java | 1 + 6 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 src/main/java/fr/maxlego08/menu/loader/actions/TakeItemLoader.java create mode 100644 src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java diff --git a/src/main/java/fr/maxlego08/menu/ZInventoryManager.java b/src/main/java/fr/maxlego08/menu/ZInventoryManager.java index 871eb014..4c7c4449 100644 --- a/src/main/java/fr/maxlego08/menu/ZInventoryManager.java +++ b/src/main/java/fr/maxlego08/menu/ZInventoryManager.java @@ -134,7 +134,7 @@ public MenuItemStack loadItemStack(YamlConfiguration configuration, String path, public MenuItemStack loadItemStack(File file, String path, Map map) { YamlConfiguration configuration = new YamlConfiguration(); configuration.set("item", map); - return new MenuItemStackLoader(this).load(configuration, "item", file); + return new MenuItemStackLoader(this).load(configuration, "item.", file); } @Override @@ -402,6 +402,7 @@ public void loadButtons() { buttonManager.registerAction(new TeleportLoader(this.plugin)); buttonManager.registerAction(new CurrencyWithdrawLoader()); buttonManager.registerAction(new CurrencyDepositLoader()); + buttonManager.registerAction(new TakeItemLoader(this.plugin)); if (this.plugin.isEnable(Plugins.LUCKPERMS)) { buttonManager.registerAction(new LuckPermissionSetLoader()); } diff --git a/src/main/java/fr/maxlego08/menu/loader/ZButtonLoader.java b/src/main/java/fr/maxlego08/menu/loader/ZButtonLoader.java index 8ae3c05e..ecfbd612 100644 --- a/src/main/java/fr/maxlego08/menu/loader/ZButtonLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/ZButtonLoader.java @@ -26,6 +26,7 @@ import fr.maxlego08.menu.api.utils.Loader; import fr.maxlego08.menu.api.utils.OpenLink; import fr.maxlego08.menu.api.utils.TypedMapAccessor; +import fr.maxlego08.menu.common.MinecraftVersion; import fr.maxlego08.menu.common.utils.ZUtils; import fr.maxlego08.menu.common.utils.cache.YamlFileCache; import fr.maxlego08.menu.common.utils.cache.YamlFileCacheEntry; diff --git a/src/main/java/fr/maxlego08/menu/loader/actions/TakeItemLoader.java b/src/main/java/fr/maxlego08/menu/loader/actions/TakeItemLoader.java new file mode 100644 index 00000000..0676cdff --- /dev/null +++ b/src/main/java/fr/maxlego08/menu/loader/actions/TakeItemLoader.java @@ -0,0 +1,32 @@ +package fr.maxlego08.menu.loader.actions; + +import fr.maxlego08.menu.ZMenuItemStack; +import fr.maxlego08.menu.api.MenuPlugin; +import fr.maxlego08.menu.api.enums.ItemVerification; +import fr.maxlego08.menu.api.loader.ActionLoader; +import fr.maxlego08.menu.api.requirement.Action; +import fr.maxlego08.menu.api.utils.TypedMapAccessor; +import fr.maxlego08.menu.requirement.actions.TakeItemAction; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +public class TakeItemLoader extends ActionLoader { + private final MenuPlugin menuPlugin; + + public TakeItemLoader(MenuPlugin menuPlugin) { + super("take_item", "take-item"); + this.menuPlugin = menuPlugin; + } + + @Override + public @Nullable Action load(@NotNull String path, @NotNull TypedMapAccessor accessor, @NotNull File file) { + ZMenuItemStack menuItemStack = new ZMenuItemStack(this.menuPlugin.getInventoryManager(), file.getPath(), path); + menuItemStack.setTypeMapAccessor(accessor); + boolean useCache = accessor.getBoolean("use-cache", false); + int amount = accessor.getInt("amount", 1); + ItemVerification itemVerification = ItemVerification.valueOf(accessor.getString("verification", ItemVerification.SIMILAR.name())); + return new TakeItemAction(menuItemStack, useCache, amount, itemVerification); + } +} diff --git a/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java b/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java new file mode 100644 index 00000000..bd08270f --- /dev/null +++ b/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java @@ -0,0 +1,82 @@ +package fr.maxlego08.menu.requirement.actions; + +import fr.maxlego08.menu.api.MenuItemStack; +import fr.maxlego08.menu.api.button.Button; +import fr.maxlego08.menu.api.engine.InventoryEngine; +import fr.maxlego08.menu.api.enums.ItemVerification; +import fr.maxlego08.menu.api.requirement.Action; +import fr.maxlego08.menu.api.utils.Placeholders; +import fr.maxlego08.menu.zcore.logger.Logger; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class TakeItemAction extends Action { + private final ItemVerification itemVerification; + private final MenuItemStack menuItemStack; + private final boolean useCache; + private final int amount; + + public TakeItemAction(MenuItemStack menuItemStack, boolean useCache, int amount, ItemVerification itemVerification) { + this.menuItemStack = menuItemStack; + this.useCache = useCache; + this.amount = amount; + this.itemVerification = itemVerification; + } + + @Override + protected void execute(@NotNull Player player, + @Nullable Button button, + @NotNull InventoryEngine inventoryEngine, + @NotNull Placeholders placeholders) { + + if (this.menuItemStack == null) { + return; + } + + ItemStack targetItem = this.menuItemStack.build(player, this.useCache, placeholders); + int remaining = this.amount; + + PlayerInventory inventory = player.getInventory(); + + for (int slot = 0; slot < 36 && remaining > 0; slot++) { + + ItemStack current = inventory.getItem(slot); + if (current == null) continue; + + if (!matches(current, targetItem)) continue; + + int removed = Math.min(remaining, current.getAmount()); + current.setAmount(current.getAmount() - removed); + remaining -= removed; + + if (current.getAmount() <= 0) { + inventory.setItem(slot, null); + } + } + + if (remaining > 0) { + Logger.info("WARNING: Could not remove full amount. Missing: " + remaining); + } + } + + private boolean matches(@NotNull ItemStack item, @NotNull ItemStack target) { + return switch (this.itemVerification) { + + case SIMILAR -> item.isSimilar(target); + + case MODELID -> { + if (!item.hasItemMeta()) yield false; + + ItemMeta meta = item.getItemMeta(); + if (meta == null || !meta.hasCustomModelData()) yield false; + + String modelID = String.valueOf(meta.getCustomModelData()); + yield modelID.equals(this.menuItemStack.getModelID()); + } + }; + } +} \ No newline at end of file diff --git a/src/main/java/fr/maxlego08/menu/requirement/permissible/ZItemPermissible.java b/src/main/java/fr/maxlego08/menu/requirement/permissible/ZItemPermissible.java index 1d62f39f..4b6f3591 100644 --- a/src/main/java/fr/maxlego08/menu/requirement/permissible/ZItemPermissible.java +++ b/src/main/java/fr/maxlego08/menu/requirement/permissible/ZItemPermissible.java @@ -1,6 +1,6 @@ package fr.maxlego08.menu.requirement.permissible; -import fr.maxlego08.menu.ZMenuItemStack; +import fr.maxlego08.menu.api.MenuItemStack; import fr.maxlego08.menu.api.button.Button; import fr.maxlego08.menu.api.engine.InventoryEngine; import fr.maxlego08.menu.api.enums.ItemVerification; @@ -19,10 +19,10 @@ public class ZItemPermissible extends ItemPermissible { private final ItemVerification itemVerification; - private final ZMenuItemStack menuItemStack; + private final MenuItemStack menuItemStack; private final int amount; - public ZItemPermissible(ZMenuItemStack menuItemStack, int amount, List denyActions, List successActions, ItemVerification itemVerification) { + public ZItemPermissible(MenuItemStack menuItemStack, int amount, List denyActions, List successActions, ItemVerification itemVerification) { super(denyActions, successActions); this.menuItemStack = menuItemStack; this.amount = amount; @@ -67,8 +67,9 @@ public boolean isValid() { return this.menuItemStack != null; } + @Override - public @Nullable ZMenuItemStack getMenuItemStack() { + public @Nullable MenuItemStack getMenuItemStack() { return this.menuItemStack; } diff --git a/src/main/java/fr/maxlego08/menu/website/ZWebsiteManager.java b/src/main/java/fr/maxlego08/menu/website/ZWebsiteManager.java index 82b4dbff..87336110 100644 --- a/src/main/java/fr/maxlego08/menu/website/ZWebsiteManager.java +++ b/src/main/java/fr/maxlego08/menu/website/ZWebsiteManager.java @@ -10,6 +10,7 @@ import fr.maxlego08.menu.api.placeholder.LocalPlaceholder; import fr.maxlego08.menu.api.utils.Message; import fr.maxlego08.menu.api.website.WebsiteManager; +import fr.maxlego08.menu.common.MinecraftVersion; import fr.maxlego08.menu.common.utils.ZUtils; import fr.maxlego08.menu.website.buttons.*; import fr.maxlego08.menu.website.request.HttpRequest; From 3ba5e95aeeda3c09ef429dcd0b35df681841396d Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Tue, 5 May 2026 13:55:02 +0200 Subject: [PATCH 14/24] refactor: remove debug logging from VersionFilter class --- .../maxlego08/menu/common/VersionFilter.java | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/Common/src/main/java/fr/maxlego08/menu/common/VersionFilter.java b/Common/src/main/java/fr/maxlego08/menu/common/VersionFilter.java index 9c7df306..3a7296b7 100644 --- a/Common/src/main/java/fr/maxlego08/menu/common/VersionFilter.java +++ b/Common/src/main/java/fr/maxlego08/menu/common/VersionFilter.java @@ -4,9 +4,7 @@ import fr.maxlego08.menu.api.annotations.SinceVersion; import fr.maxlego08.menu.api.annotations.SpigotOnly; import fr.maxlego08.menu.api.annotations.UntilVersion; -import fr.maxlego08.menu.api.configuration.Configuration; import fr.maxlego08.menu.api.utils.PlatformType; -import fr.maxlego08.menu.zcore.logger.Logger; import org.jetbrains.annotations.NotNull; public class VersionFilter { @@ -15,15 +13,9 @@ private VersionFilter() {} public static boolean passes(@NotNull Class clazz) { if (clazz.isAnnotationPresent(PaperOnly.class) && !PlatformType.isPaper()) { - if (Configuration.enableDebug) { - Logger.info("Class " + clazz.getSimpleName() + " is annotated with @PaperOnly but the server is not running Paper or Folia. Skipping.", Logger.LogType.INFO); - } return false; } if (clazz.isAnnotationPresent(SpigotOnly.class) && PlatformType.isPaper()) { - if (Configuration.enableDebug) { - Logger.info("Class " + clazz.getSimpleName() + " is annotated with @SpigotOnly but the server is running Paper or Folia. Skipping.", Logger.LogType.INFO); - } return false; } @@ -33,9 +25,6 @@ public static boolean passes(@NotNull Class clazz) { if (since != null) { MinecraftVersion minimum = MinecraftVersion.parse(since.value()); if (!serverVersion.isAtLeast(minimum)) { - if (Configuration.enableDebug) { - Logger.info("Class " + clazz.getSimpleName() + " is annotated with @SinceVersion(" + since.value() + ") but the server value is " + serverVersion + ". Skipping.", Logger.LogType.INFO); - } return false; } } @@ -43,12 +32,7 @@ public static boolean passes(@NotNull Class clazz) { UntilVersion until = clazz.getAnnotation(UntilVersion.class); if (until != null) { MinecraftVersion maximum = MinecraftVersion.parse(until.value()); - if (!serverVersion.isAtMost(maximum)) { - if (Configuration.enableDebug) { - Logger.info("Class " + clazz.getSimpleName() + " is annotated with @UntilVersion(" + until.value() + ") but the server value is " + serverVersion + ". Skipping.", Logger.LogType.INFO); - } - return false; - } + return serverVersion.isAtMost(maximum); } return true; From f7402b9ca478d2a257c170aca009c91a9c26fe21 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Wed, 6 May 2026 19:39:46 +0200 Subject: [PATCH 15/24] fix: update loadItemStack to use createSection for item map --- src/main/java/fr/maxlego08/menu/ZInventoryManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/fr/maxlego08/menu/ZInventoryManager.java b/src/main/java/fr/maxlego08/menu/ZInventoryManager.java index 4c7c4449..44e04e68 100644 --- a/src/main/java/fr/maxlego08/menu/ZInventoryManager.java +++ b/src/main/java/fr/maxlego08/menu/ZInventoryManager.java @@ -133,7 +133,7 @@ public MenuItemStack loadItemStack(YamlConfiguration configuration, String path, @Override public MenuItemStack loadItemStack(File file, String path, Map map) { YamlConfiguration configuration = new YamlConfiguration(); - configuration.set("item", map); + configuration.createSection("item", map); return new MenuItemStackLoader(this).load(configuration, "item.", file); } From 78b075b69443bdb824dc32c6267849f2c038e318 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Wed, 6 May 2026 19:42:47 +0200 Subject: [PATCH 16/24] fix: TakeItemAction and improve item loading requirement for TakeItemAction && ItemPermissibleLoader --- .../maxlego08/menu/api/utils/TypedMapAccessor.java | 5 +++++ .../menu/loader/actions/TakeItemLoader.java | 12 +++++++++--- .../loader/permissible/ItemPermissibleLoader.java | 11 ++++++++--- .../menu/requirement/actions/TakeItemAction.java | 5 +++++ 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/API/src/main/java/fr/maxlego08/menu/api/utils/TypedMapAccessor.java b/API/src/main/java/fr/maxlego08/menu/api/utils/TypedMapAccessor.java index 985c0268..a3b017ed 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/utils/TypedMapAccessor.java +++ b/API/src/main/java/fr/maxlego08/menu/api/utils/TypedMapAccessor.java @@ -25,6 +25,11 @@ public TypedMapAccessor(@NotNull Map map) { this.map = map; } + + public Map getMap() { + return map; + } + /** * Retrieves a string value from the map based on the provided key. * diff --git a/src/main/java/fr/maxlego08/menu/loader/actions/TakeItemLoader.java b/src/main/java/fr/maxlego08/menu/loader/actions/TakeItemLoader.java index 0676cdff..9950cbf8 100644 --- a/src/main/java/fr/maxlego08/menu/loader/actions/TakeItemLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/actions/TakeItemLoader.java @@ -1,6 +1,6 @@ package fr.maxlego08.menu.loader.actions; -import fr.maxlego08.menu.ZMenuItemStack; +import fr.maxlego08.menu.api.MenuItemStack; import fr.maxlego08.menu.api.MenuPlugin; import fr.maxlego08.menu.api.enums.ItemVerification; import fr.maxlego08.menu.api.loader.ActionLoader; @@ -11,6 +11,7 @@ import org.jetbrains.annotations.Nullable; import java.io.File; +import java.util.Map; public class TakeItemLoader extends ActionLoader { private final MenuPlugin menuPlugin; @@ -22,8 +23,13 @@ public TakeItemLoader(MenuPlugin menuPlugin) { @Override public @Nullable Action load(@NotNull String path, @NotNull TypedMapAccessor accessor, @NotNull File file) { - ZMenuItemStack menuItemStack = new ZMenuItemStack(this.menuPlugin.getInventoryManager(), file.getPath(), path); - menuItemStack.setTypeMapAccessor(accessor); + MenuItemStack menuItemStack; + if (accessor.contains("item")) { + menuItemStack = this.menuPlugin.getInventoryManager().loadItemStack(file, path, (Map) accessor.getObject("item")); + } else { + menuItemStack = this.menuPlugin.getInventoryManager().loadItemStack(file, path, accessor.getMap()); + } + boolean useCache = accessor.getBoolean("use-cache", false); int amount = accessor.getInt("amount", 1); ItemVerification itemVerification = ItemVerification.valueOf(accessor.getString("verification", ItemVerification.SIMILAR.name())); diff --git a/src/main/java/fr/maxlego08/menu/loader/permissible/ItemPermissibleLoader.java b/src/main/java/fr/maxlego08/menu/loader/permissible/ItemPermissibleLoader.java index dda0ba43..bfea6bf6 100644 --- a/src/main/java/fr/maxlego08/menu/loader/permissible/ItemPermissibleLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/permissible/ItemPermissibleLoader.java @@ -1,7 +1,7 @@ package fr.maxlego08.menu.loader.permissible; -import fr.maxlego08.menu.ZMenuItemStack; import fr.maxlego08.menu.api.ButtonManager; +import fr.maxlego08.menu.api.MenuItemStack; import fr.maxlego08.menu.api.MenuPlugin; import fr.maxlego08.menu.api.enums.ItemVerification; import fr.maxlego08.menu.api.loader.PermissibleLoader; @@ -13,6 +13,7 @@ import java.io.File; import java.util.List; +import java.util.Map; public class ItemPermissibleLoader extends PermissibleLoader { @@ -27,8 +28,12 @@ public ItemPermissibleLoader(MenuPlugin plugin) { public Permissible load(@NonNull String path, @NonNull TypedMapAccessor accessor, @NonNull File file) { ButtonManager buttonManager = this.plugin.getButtonManager(); - ZMenuItemStack menuItemStack = new ZMenuItemStack(this.plugin.getInventoryManager(), file.getPath(), path); - menuItemStack.setTypeMapAccessor(accessor); + MenuItemStack menuItemStack; + if (accessor.contains("item")) { + menuItemStack = this.plugin.getInventoryManager().loadItemStack(file, path, (Map) accessor.getObject("item")); + } else { + menuItemStack = this.plugin.getInventoryManager().loadItemStack(file, path, accessor.getMap()); + } int amount = accessor.getInt("amount"); ItemVerification itemVerification = ItemVerification.valueOf(accessor.getString("verification", ItemVerification.SIMILAR.name())); diff --git a/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java b/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java index bd08270f..3c10c08e 100644 --- a/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java +++ b/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java @@ -38,6 +38,10 @@ protected void execute(@NotNull Player player, } ItemStack targetItem = this.menuItemStack.build(player, this.useCache, placeholders); + if (targetItem == null) { + return; + } + Logger.info("Target item :" + targetItem); int remaining = this.amount; PlayerInventory inventory = player.getInventory(); @@ -46,6 +50,7 @@ protected void execute(@NotNull Player player, ItemStack current = inventory.getItem(slot); if (current == null) continue; + Logger.info("Current item :" + current); if (!matches(current, targetItem)) continue; From a6da9a6f0de6de2dc0dacc8e12e348f882d1c21b Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Wed, 6 May 2026 19:45:29 +0200 Subject: [PATCH 17/24] remove debug message --- .../maxlego08/menu/requirement/actions/TakeItemAction.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java b/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java index 3c10c08e..9a413e1b 100644 --- a/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java +++ b/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java @@ -41,7 +41,6 @@ protected void execute(@NotNull Player player, if (targetItem == null) { return; } - Logger.info("Target item :" + targetItem); int remaining = this.amount; PlayerInventory inventory = player.getInventory(); @@ -62,10 +61,6 @@ protected void execute(@NotNull Player player, inventory.setItem(slot, null); } } - - if (remaining > 0) { - Logger.info("WARNING: Could not remove full amount. Missing: " + remaining); - } } private boolean matches(@NotNull ItemStack item, @NotNull ItemStack target) { From 439ef385356e5d9dbb46e5a0d8e5fa269e1dae86 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Thu, 7 May 2026 16:11:27 +0200 Subject: [PATCH 18/24] fix: switch with clear-inv and packet event don't hide items in player inv --- .../players/inventory/InventoriesPlayer.java | 2 ++ .../players/inventory/InventoryPlayer.java | 3 +++ .../PacketEventPlayerInventoryManager.java | 19 +++++++++----- .../java/fr/maxlego08/menu/ZInventory.java | 2 +- .../java/fr/maxlego08/menu/ZMenuPlugin.java | 2 +- .../players/inventory/ZInventoriesPlayer.java | 11 +++++++- .../players/inventory/ZInventoryPlayer.java | 25 +++++++++++++++---- .../requirement/actions/TakeItemAction.java | 2 -- 8 files changed, 50 insertions(+), 16 deletions(-) diff --git a/API/src/main/java/fr/maxlego08/menu/api/players/inventory/InventoriesPlayer.java b/API/src/main/java/fr/maxlego08/menu/api/players/inventory/InventoriesPlayer.java index d7c9f12a..33b84acc 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/players/inventory/InventoriesPlayer.java +++ b/API/src/main/java/fr/maxlego08/menu/api/players/inventory/InventoriesPlayer.java @@ -28,6 +28,8 @@ public interface InventoriesPlayer extends Listener { */ void storeInventoryTemporary(@NonNull Player player); + void storeInventoryTemporaryOrClear(@NotNull Player player); + /** * Allows giving the inventory back to the player * diff --git a/API/src/main/java/fr/maxlego08/menu/api/players/inventory/InventoryPlayer.java b/API/src/main/java/fr/maxlego08/menu/api/players/inventory/InventoryPlayer.java index e0ba743e..5e3a7752 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/players/inventory/InventoryPlayer.java +++ b/API/src/main/java/fr/maxlego08/menu/api/players/inventory/InventoryPlayer.java @@ -3,6 +3,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.NonNull; import java.util.List; import java.util.Map; @@ -19,6 +20,8 @@ public interface InventoryPlayer { */ void storeInventory(@NotNull Player player); + void clearInventory(@NonNull Player player); + /** * Allows giving the inventory back to the player * diff --git a/Hooks/PacketEvents/src/main/java/fr/maxlego08/menu/hooks/packetevents/PacketEventPlayerInventoryManager.java b/Hooks/PacketEvents/src/main/java/fr/maxlego08/menu/hooks/packetevents/PacketEventPlayerInventoryManager.java index 91b49d76..f551dba2 100644 --- a/Hooks/PacketEvents/src/main/java/fr/maxlego08/menu/hooks/packetevents/PacketEventPlayerInventoryManager.java +++ b/Hooks/PacketEvents/src/main/java/fr/maxlego08/menu/hooks/packetevents/PacketEventPlayerInventoryManager.java @@ -3,6 +3,7 @@ import com.github.retrooper.packetevents.PacketEvents; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetPlayerInventory; import fr.maxlego08.menu.api.InventoryListener; +import fr.maxlego08.menu.api.MenuPlugin; import fr.maxlego08.menu.api.engine.BaseInventory; import fr.maxlego08.menu.api.engine.ItemButton; import fr.maxlego08.menu.api.players.inventory.InventoryPlayer; @@ -20,9 +21,11 @@ import java.util.UUID; public class PacketEventPlayerInventoryManager implements InventoryListener { + private final MenuPlugin plugin; private final Map> pendingInventoryUpdates = new HashMap<>(); - public PacketEventPlayerInventoryManager() { + public PacketEventPlayerInventoryManager(MenuPlugin plugin) { + this.plugin = plugin; ClearInvType packetEvent = ClearInvType.PACKET_EVENT; packetEvent.setOnButtonClear((player, slot)->this.addItemInstantly(player,slot,new ItemStack(Material.AIR))); packetEvent.setOnInventoryClose(((inventoriesPlayer, player) -> { @@ -56,11 +59,15 @@ public void onInventoryPreOpen(Player player, BaseInventory baseInventory, int p public void onInventoryPostOpen(Player player, BaseInventory baseInventory){ UUID playerUniqueId = player.getUniqueId(); if (this.pendingInventoryUpdates.containsKey(playerUniqueId)) { - Map wrappers = this.pendingInventoryUpdates.get(playerUniqueId); - for (WrapperPlayServerSetPlayerInventory wrapper : wrappers.values()) { - PacketEvents.getAPI().getPlayerManager().sendPacket(player, wrapper); - } - this.pendingInventoryUpdates.remove(playerUniqueId); + this.plugin.getScheduler().runAtEntityLater(player, () -> { + Map wrappers = this.pendingInventoryUpdates.get(playerUniqueId); + if (wrappers != null) { + for (WrapperPlayServerSetPlayerInventory wrapper : wrappers.values()) { + PacketEvents.getAPI().getPlayerManager().sendPacket(player, wrapper); + } + this.pendingInventoryUpdates.remove(playerUniqueId); + } + }, 1); } } diff --git a/src/main/java/fr/maxlego08/menu/ZInventory.java b/src/main/java/fr/maxlego08/menu/ZInventory.java index f8b51e64..7b60af5b 100644 --- a/src/main/java/fr/maxlego08/menu/ZInventory.java +++ b/src/main/java/fr/maxlego08/menu/ZInventory.java @@ -235,7 +235,7 @@ public InventoryResult openInventory(Player player, InventoryEngine inventoryDef if (this.clearInvType == ClearInvType.DEFAULT){ inventoriesPlayer.storeInventory(player); } else { - inventoriesPlayer.storeInventoryTemporary(player); + inventoriesPlayer.storeInventoryTemporaryOrClear(player); } } } else if (this.clearInventory) { diff --git a/src/main/java/fr/maxlego08/menu/ZMenuPlugin.java b/src/main/java/fr/maxlego08/menu/ZMenuPlugin.java index dc5a20fd..a8a2d106 100644 --- a/src/main/java/fr/maxlego08/menu/ZMenuPlugin.java +++ b/src/main/java/fr/maxlego08/menu/ZMenuPlugin.java @@ -268,7 +268,7 @@ public void onEnable() { // this.inventoryManager.registerInventoryListener(this.packetUtils); if (isActive(Plugins.PACKETEVENTS)) - this.inventoryManager.registerInventoryListener(new PacketEventPlayerInventoryManager()); + this.inventoryManager.registerInventoryListener(new PacketEventPlayerInventoryManager(this)); this.postEnable(); } diff --git a/src/main/java/fr/maxlego08/menu/players/inventory/ZInventoriesPlayer.java b/src/main/java/fr/maxlego08/menu/players/inventory/ZInventoriesPlayer.java index dc697f46..db16168b 100644 --- a/src/main/java/fr/maxlego08/menu/players/inventory/ZInventoriesPlayer.java +++ b/src/main/java/fr/maxlego08/menu/players/inventory/ZInventoriesPlayer.java @@ -10,6 +10,7 @@ import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; import org.jspecify.annotations.NonNull; import java.util.*; @@ -51,7 +52,15 @@ public void storeInventoryTemporary(@NonNull Player player) { inventories.put(player.getUniqueId(), inventoryPlayer); } - + @Override + public void storeInventoryTemporaryOrClear(@NotNull Player player) { + Optional playerInventory = this.getPlayerInventory(player.getUniqueId()); + if (playerInventory.isPresent()) { + playerInventory.get().clearInventory(player); + } else { + storeInventoryTemporary(player); + } + } private void restoreInventory(Player player, BiConsumer restoreAction) { Optional optional = this.getPlayerInventory(player.getUniqueId()); diff --git a/src/main/java/fr/maxlego08/menu/players/inventory/ZInventoryPlayer.java b/src/main/java/fr/maxlego08/menu/players/inventory/ZInventoryPlayer.java index 3736d0a5..5e920a2a 100644 --- a/src/main/java/fr/maxlego08/menu/players/inventory/ZInventoryPlayer.java +++ b/src/main/java/fr/maxlego08/menu/players/inventory/ZInventoryPlayer.java @@ -31,23 +31,38 @@ public void storeInventory(@NonNull Player player) { } public void storeInventory(@NonNull Player player, boolean temporary) { + ClearInvType clearInvType = temporary ? ClearInvType.PACKET_EVENT : ClearInvType.DEFAULT; + this.temporary = temporary; PlayerInventory playerInventory = player.getInventory(); ItemStack[] content = playerInventory.getContents(); for (int slot = 0; slot != MAX_INVENTORY_SIZE; slot++) { - clear(slot, playerInventory, content,!temporary, player); + clear(slot, playerInventory, content, player, true, clearInvType); + } + if (!NMSUtils.isOneHand()) { + clear(40, playerInventory, content, player, true, clearInvType); + } + } + + @Override + public void clearInventory(@NonNull Player player) { + ClearInvType clearInvType = ClearInvType.PACKET_EVENT; + var removeItem = clearInvType.getRemoveItem(); + + PlayerInventory playerInventory = player.getInventory(); + for (int slot = 0; slot != MAX_INVENTORY_SIZE; slot++) { + removeItem.accept(player, slot, playerInventory); } if (!NMSUtils.isOneHand()) { - clear(40, playerInventory, content,!temporary, player); + removeItem.accept(player, 40, playerInventory); } } - private void clear(int slot, PlayerInventory playerInventory, ItemStack[] content, boolean removeItem, Player player) { + private void clear(int slot, PlayerInventory playerInventory, ItemStack[] content, Player player, boolean save, ClearInvType clearInvType) { ItemStack itemStack = content[slot]; - if (itemStack != null) { + if (itemStack != null && save) { items.put(slot, ItemStackUtils.serializeItemStack(itemStack)); } - ClearInvType clearInvType = removeItem ? ClearInvType.DEFAULT : ClearInvType.PACKET_EVENT; clearInvType.getRemoveItem().accept(player, slot, playerInventory); } diff --git a/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java b/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java index 9a413e1b..403ca4af 100644 --- a/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java +++ b/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java @@ -6,7 +6,6 @@ import fr.maxlego08.menu.api.enums.ItemVerification; import fr.maxlego08.menu.api.requirement.Action; import fr.maxlego08.menu.api.utils.Placeholders; -import fr.maxlego08.menu.zcore.logger.Logger; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; @@ -49,7 +48,6 @@ protected void execute(@NotNull Player player, ItemStack current = inventory.getItem(slot); if (current == null) continue; - Logger.info("Current item :" + current); if (!matches(current, targetItem)) continue; From b1f08bc74e4a1fa23d74432256d9cfa49710ea6e Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Fri, 8 May 2026 11:05:55 +0200 Subject: [PATCH 19/24] feat: add support for command action requirements --- .../main/java/fr/maxlego08/menu/api/command/Command.java | 7 +++++++ src/main/java/fr/maxlego08/menu/ZCommand.java | 5 +++-- .../maxlego08/menu/command/commands/CommandInventory.java | 1 + src/main/java/fr/maxlego08/menu/loader/CommandLoader.java | 4 +++- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/API/src/main/java/fr/maxlego08/menu/api/command/Command.java b/API/src/main/java/fr/maxlego08/menu/api/command/Command.java index a5c081ad..7322d983 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/command/Command.java +++ b/API/src/main/java/fr/maxlego08/menu/api/command/Command.java @@ -1,6 +1,7 @@ package fr.maxlego08.menu.api.command; import fr.maxlego08.menu.api.requirement.Action; +import fr.maxlego08.menu.api.requirement.Requirement; import org.bukkit.plugin.Plugin; import java.io.File; @@ -102,6 +103,12 @@ public interface Command { */ List subCommands(); + /** + * Gets the list of requirements that must be met for the command's actions to be executed. + * @return The list of requirements that must be met for the command's actions to be executed. + */ + List actions_requirements(); + /** * Gets the message to display when the player does not have the required permission. * diff --git a/src/main/java/fr/maxlego08/menu/ZCommand.java b/src/main/java/fr/maxlego08/menu/ZCommand.java index 78b99b97..3976a91f 100644 --- a/src/main/java/fr/maxlego08/menu/ZCommand.java +++ b/src/main/java/fr/maxlego08/menu/ZCommand.java @@ -3,6 +3,7 @@ import fr.maxlego08.menu.api.command.Command; import fr.maxlego08.menu.api.command.CommandArgument; import fr.maxlego08.menu.api.requirement.Action; +import fr.maxlego08.menu.api.requirement.Requirement; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; @@ -24,11 +25,11 @@ * @param file File */ public record ZCommand(Plugin plugin, String command, List aliases, boolean consoleCanUse, String permission, String inventory, List arguments, - List actions, List subCommands, String denyMessage, String path, File file) implements Command { + List actions, List subCommands, List actions_requirements, String denyMessage, String path, File file) implements Command { @Override public @NotNull String toString() { - return "ZCommand{" + "plugin=" + plugin + ", command='" + command + '\'' + ", aliases=" + aliases + ", permission='" + permission + '\'' + ", inventory='" + inventory + '\'' + ", arguments=" + arguments + ", actions=" + actions + ", subCommands=" + subCommands + ", path='" + path + '\'' + ", file=" + file + '}'; + return "ZCommand{" + "plugin=" + plugin + ", command='" + command + '\'' + ", aliases=" + aliases + ", permission='" + permission + '\'' + ", inventory='" + inventory + '\'' + ", arguments=" + arguments + ", actions=" + actions + ", subCommands=" + subCommands + ", actions-requirements=" + actions_requirements + ", path='" + path + '\'' + ", file=" + file + '}'; } @Override diff --git a/src/main/java/fr/maxlego08/menu/command/commands/CommandInventory.java b/src/main/java/fr/maxlego08/menu/command/commands/CommandInventory.java index 58afa2ac..755380f5 100644 --- a/src/main/java/fr/maxlego08/menu/command/commands/CommandInventory.java +++ b/src/main/java/fr/maxlego08/menu/command/commands/CommandInventory.java @@ -135,6 +135,7 @@ protected CommandType perform(ZMenuPlugin plugin) { } if (performMainActions) { + this.command.actions_requirements().forEach(requirement -> requirement.execute(player, null, inventoryDefault, placeholders)); this.command.actions().forEach(action -> action.preExecute(player, null, inventoryDefault, placeholders)); optional.ifPresent(inventory -> manager.openInventory(this.player, inventory)); } diff --git a/src/main/java/fr/maxlego08/menu/loader/CommandLoader.java b/src/main/java/fr/maxlego08/menu/loader/CommandLoader.java index b97a9b81..92aa0c0a 100644 --- a/src/main/java/fr/maxlego08/menu/loader/CommandLoader.java +++ b/src/main/java/fr/maxlego08/menu/loader/CommandLoader.java @@ -7,6 +7,7 @@ import fr.maxlego08.menu.api.command.CommandArgument; import fr.maxlego08.menu.api.exceptions.InventoryException; import fr.maxlego08.menu.api.requirement.Action; +import fr.maxlego08.menu.api.requirement.Requirement; import fr.maxlego08.menu.api.utils.Loader; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; @@ -45,6 +46,7 @@ public Command load(@NonNull YamlConfiguration configuration, @NonNull String pa boolean consoleCanUse = configuration.getBoolean(path + "console-can-use", false); List commandActions = menuPlugin.getButtonManager().loadActions((List>) configuration.getList(path + "actions", new ArrayList<>()), path, file); + List requirements = this.menuPlugin.getButtonManager().loadRequirements(configuration, path + "actions-requirements", file); List arguments = new ArrayList<>(); List listValues = configuration.getList(path + "arguments", new ArrayList<>()); if (isListOfMap(listValues)) { @@ -98,7 +100,7 @@ public Command load(@NonNull YamlConfiguration configuration, @NonNull String pa } } - return new ZCommand(this.plugin, command, aliases, consoleCanUse, permission, inventory, arguments, commandActions, subCommands, denyMessage, path, file); + return new ZCommand(this.plugin, command, aliases, consoleCanUse, permission, inventory, arguments, commandActions, subCommands, requirements, denyMessage, path, file); } @Override From 8a7bf09011eea12150e0aeb640df4baa5fbb47bc Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Fri, 8 May 2026 11:26:35 +0200 Subject: [PATCH 20/24] fix: enhance error handling and debug logging in MMOItemsLoader --- .../menu/hooks/mmoitems/MMOItemsLoader.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/Hooks/MMOItems/src/main/java/fr/maxlego08/menu/hooks/mmoitems/MMOItemsLoader.java b/Hooks/MMOItems/src/main/java/fr/maxlego08/menu/hooks/mmoitems/MMOItemsLoader.java index cde9cdb6..b5be3f8e 100644 --- a/Hooks/MMOItems/src/main/java/fr/maxlego08/menu/hooks/mmoitems/MMOItemsLoader.java +++ b/Hooks/MMOItems/src/main/java/fr/maxlego08/menu/hooks/mmoitems/MMOItemsLoader.java @@ -1,6 +1,8 @@ package fr.maxlego08.menu.hooks.mmoitems; +import fr.maxlego08.menu.api.configuration.Configuration; import fr.maxlego08.menu.api.loader.MaterialLoader; +import fr.maxlego08.menu.zcore.logger.Logger; import net.Indyuce.mmoitems.MMOItems; import net.Indyuce.mmoitems.api.Type; import org.bukkit.configuration.file.YamlConfiguration; @@ -21,9 +23,21 @@ public MMOItemsLoader() { if (split.length != 2) return null; try { final Type type = MMOItems.plugin.getTypes().get(split[0]); - if (type == null) return null; - return MMOItems.plugin.getItem(type, split[1]); + if (type == null) { + if (Configuration.enableDebug) + Logger.info(String.format("Invalid MMOItems type '%s' for material '%s', available types: %s", split[0], materialString, MMOItems.plugin.getTypes().getAllTypeNames())); + return null; + } + ItemStack item = MMOItems.plugin.getItem(type, split[1]); + if (item == null) { + if (Configuration.enableDebug) + Logger.info(String.format("Invalid MMOItems item '%s' for type '%s', available items: %s", split[1], split[0], MMOItems.plugin.getTemplates().getTemplateNames(type))); + return null; + } + return item; } catch (Exception e) { + if (Configuration.enableDebug) + Logger.info(String.format("Error loading MMOItems material '%s': %s", materialString, e.getMessage())); return null; } } From 3af2842e2d2e19b2f9627962c56aa12d6b3f55a2 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Fri, 8 May 2026 11:28:28 +0200 Subject: [PATCH 21/24] feat: add debug logging functionality to TakeItemAction and Action classes --- .../menu/api/requirement/Action.java | 9 ++++ .../fr/maxlego08/menu/ZButtonManager.java | 1 + .../requirement/actions/TakeItemAction.java | 51 ++++++++++++++----- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/API/src/main/java/fr/maxlego08/menu/api/requirement/Action.java b/API/src/main/java/fr/maxlego08/menu/api/requirement/Action.java index 794457de..f3105750 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/requirement/Action.java +++ b/API/src/main/java/fr/maxlego08/menu/api/requirement/Action.java @@ -25,6 +25,7 @@ public abstract class Action { */ private int delay; private float chance; + protected boolean debug = false; /** * The type of the action. @@ -65,6 +66,14 @@ public void setDelay(int delay) { this.delay = delay; } + public boolean isDebug() { + return this.debug; + } + + public void setDebug(boolean debug) { + this.debug = debug; + } + @Contract(pure= true) public float getChance() { return chance; diff --git a/src/main/java/fr/maxlego08/menu/ZButtonManager.java b/src/main/java/fr/maxlego08/menu/ZButtonManager.java index 4f018579..b260ae04 100644 --- a/src/main/java/fr/maxlego08/menu/ZButtonManager.java +++ b/src/main/java/fr/maxlego08/menu/ZButtonManager.java @@ -185,6 +185,7 @@ public void registerAction(@NotNull ActionLoader actionLoader) { if (action != null) { action.setDelay(accessor.getInt("delay", 0)); action.setChance(accessor.getFloat("chance", 100)); + action.setDebug(accessor.getBoolean("debug", false)); action.setType(type); List> denyChanceAction = accessor.getMapList("deny-chance-actions"); if (!denyChanceAction.isEmpty()) { diff --git a/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java b/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java index 403ca4af..f476a119 100644 --- a/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java +++ b/src/main/java/fr/maxlego08/menu/requirement/actions/TakeItemAction.java @@ -6,6 +6,7 @@ import fr.maxlego08.menu.api.enums.ItemVerification; import fr.maxlego08.menu.api.requirement.Action; import fr.maxlego08.menu.api.utils.Placeholders; +import fr.maxlego08.menu.zcore.logger.Logger; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; @@ -14,6 +15,7 @@ import org.jetbrains.annotations.Nullable; public class TakeItemAction extends Action { + private final ItemVerification itemVerification; private final MenuItemStack menuItemStack; private final boolean useCache; @@ -32,33 +34,59 @@ protected void execute(@NotNull Player player, @NotNull InventoryEngine inventoryEngine, @NotNull Placeholders placeholders) { - if (this.menuItemStack == null) { - return; - } + if (this.menuItemStack == null) return; ItemStack targetItem = this.menuItemStack.build(player, this.useCache, placeholders); + if (targetItem == null) { + debugLog("Build failed — target item is null | player=%s", player.getName()); return; } - int remaining = this.amount; + debugLog("Built target item | player=%s item=%s", player.getName(), targetItem); + + int remaining = this.amount; PlayerInventory inventory = player.getInventory(); for (int slot = 0; slot < 36 && remaining > 0; slot++) { - ItemStack current = inventory.getItem(slot); if (current == null) continue; - if (!matches(current, targetItem)) continue; + boolean matches = matches(current, targetItem); + debugLog("Slot %02d | item=%-30s match=%s", slot, current, matches); + if (!matches) continue; - int removed = Math.min(remaining, current.getAmount()); - current.setAmount(current.getAmount() - removed); - remaining -= removed; + int toRemove = Math.min(remaining, current.getAmount()); + current.setAmount(current.getAmount() - toRemove); + remaining -= toRemove; if (current.getAmount() <= 0) { + debugLog("Slot %02d cleared | player=%s", slot, player.getName()); inventory.setItem(slot, null); } } + + logResult(player, remaining); + } + + private void logResult(@NotNull Player player, int remaining) { + if (!this.debug) return; + + if (remaining > 0) { + Logger.info(String.format( + "[TakeItem] Partial removal | player=%s taken=%d missing=%d", + player.getName(), this.amount - remaining, remaining + )); + } else { + Logger.info(String.format( + "[TakeItem] Success | player=%s taken=%d", + player.getName(), this.amount + )); + } + } + + private void debugLog(String format, Object... args) { + if (this.debug) Logger.info("[TakeItem] " + String.format(format, args)); } private boolean matches(@NotNull ItemStack item, @NotNull ItemStack target) { @@ -68,12 +96,9 @@ private boolean matches(@NotNull ItemStack item, @NotNull ItemStack target) { case MODELID -> { if (!item.hasItemMeta()) yield false; - ItemMeta meta = item.getItemMeta(); if (meta == null || !meta.hasCustomModelData()) yield false; - - String modelID = String.valueOf(meta.getCustomModelData()); - yield modelID.equals(this.menuItemStack.getModelID()); + yield String.valueOf(meta.getCustomModelData()).equals(this.menuItemStack.getModelID()); } }; } From a84d288dfd86c9bf66c9c675446d97f929951715 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Fri, 8 May 2026 12:05:30 +0200 Subject: [PATCH 22/24] fix: add nullable annotation import in ZInventory --- src/main/java/fr/maxlego08/menu/ZInventory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/fr/maxlego08/menu/ZInventory.java b/src/main/java/fr/maxlego08/menu/ZInventory.java index ae44e35e..504339c7 100644 --- a/src/main/java/fr/maxlego08/menu/ZInventory.java +++ b/src/main/java/fr/maxlego08/menu/ZInventory.java @@ -20,6 +20,7 @@ import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.InventoryHolder; import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.*; From 6121ce2e22935289e8b07243329cbccc9eed635d Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Fri, 8 May 2026 12:26:29 +0200 Subject: [PATCH 23/24] feat: update changelog.md --- changelog.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 19d4361f..8a4d08b8 100644 --- a/changelog.md +++ b/changelog.md @@ -44,11 +44,36 @@ ## Bug Fixes -- **Clear Inventory + BACK Button**: Fixed items being restored to the player when clicking a BACK button between two inventories with `clear-inventory: true` and `clear-inventory-type: PACKET_EVENT`. Items are now physically cleared from the player inventory during storage, ensuring container content packets don't reveal hidden items. The close handler also uses physical restoration (`giveInventory`) instead of packet-based restoration. +- **Clear Inventory + BACK Button**: Fixed items being restored to the player when clicking a BACK button between two inventories with `clear-inventory: true` and `clear-inventory-type: PACKET_EVENT`. ## Changes +- **Take Item Action**: New `take-item` action to remove a specified amount of an item from the player's inventory. +```yaml +- type: take-item + item: + material: DIAMOND + amount: 5 +``` +- **Custom Commands**: Add a new field `actions-requirements` for custom commands, allowing you to specify requirements that must be met for the command's actions to execute. This provides more control over argument conditions and enhances command functionality. - **Time Placeholders**: Changed `time_unix_timestamp`, `time_next_day_unix_timestamp`, and `time_today_start_unix_timestamp` placeholders to return values in seconds instead of milliseconds. +- **Pagination Button**: Now supports `view-requirement`. + +**Bedrock Forms Support**: + +TODO + +**Internal Changes** + +- New Minecraft version detection system `MinecraftVersion` over old `NMSVersion` enum, allowing more flexible version checks and better support for future Minecraft versions without needing to update the plugin. +- New utils annotations + - `@SinceVersion` | These annotations can be used to mark classes that should only be loaded for specific Minecraft versions, check in the `VersionFilter` class for more details. + - `@UntilVersion` | These annotations can be used to mark classes that should only be loaded for specific Minecraft versions, check in the `VersionFilter` class for more details. + - `@PaperOnly` | These annotations can be used to mark classes that should only be loaded if the server is a Paper version, check in the `VersionFilter` class for more details. + - `@SpigotOnly` | These annotations can be used to mark classes that should only be loaded if the server is a spigot version, check in the `VersionFilter` class for more details. + - `@ComponentLoader` | Allow to load dynamically all items component loader without having to register them one by one in the `ZComponentManager` class for "fr.maxlego08.zmenu" package, filtering by version and server type with the new annotations by the helper of `VersionFilter` class. + - `@AutoListener` | Allow to load dynamically all listeners who take a `MenuPlugin` in their constructor or no-arg constructor without having to register them one by one in the `ZListenerManager` class for "fr.maxlego08.zmenu" package, filtering by version and server type with the new annotations by the helper of `VersionFilter` class. + # 1.1.1.3 From 21bdc8e142248c026bf4eb4cee7a3903416b2cd5 Mon Sep 17 00:00:00 2001 From: 1robie <97293924+1robie@users.noreply.github.com> Date: Sun, 10 May 2026 20:06:49 +0200 Subject: [PATCH 24/24] feat: enhance ButtonLoader to support aliases and update dialog type references to support backward compatibility --- .../menu/api/loader/ButtonLoader.java | 17 +++++++++- .../button/loader/DialogItemBodyLoader.java | 2 +- .../loader/DialogPlainMessageBodyLoader.java | 4 +-- .../button/loader/DialogTextInputLoader.java | 2 -- .../fr/maxlego08/menu/ZButtonManager.java | 32 +++++++++++++++++-- .../resources/dialogs/confirmation-dialog.yml | 4 +-- src/main/resources/dialogs/default-dialog.yml | 4 +-- .../resources/dialogs/multi_action-dialog.yml | 4 +-- .../resources/dialogs/server_link-dialog.yml | 4 +-- 9 files changed, 56 insertions(+), 17 deletions(-) diff --git a/API/src/main/java/fr/maxlego08/menu/api/loader/ButtonLoader.java b/API/src/main/java/fr/maxlego08/menu/api/loader/ButtonLoader.java index bb2707c5..8ec07446 100644 --- a/API/src/main/java/fr/maxlego08/menu/api/loader/ButtonLoader.java +++ b/API/src/main/java/fr/maxlego08/menu/api/loader/ButtonLoader.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.stream.IntStream; @@ -31,9 +32,12 @@ public abstract class ButtonLoader { protected final Plugin plugin; protected final String name; - public ButtonLoader(@NotNull Plugin plugin,@NotNull String name) { + protected final List aliases = new ArrayList<>(); + + public ButtonLoader(@NotNull Plugin plugin,@NotNull String name, String... aliases) { this.plugin = plugin; this.name = name; + this.aliases.addAll(List.of(aliases)); } /** @@ -78,6 +82,17 @@ public String getName() { return this.name; } + /** + * Gets the list of aliases for the button. + * + * @return An unmodifiable list of aliases. + */ + @Contract(pure = true) + @NotNull + public List getAliases() { + return Collections.unmodifiableList(this.aliases); + } + /** * Gets the plugin from which the button loader originates. * diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/dialogs/button/loader/DialogItemBodyLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/dialogs/button/loader/DialogItemBodyLoader.java index d80d4212..2ec72dcf 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/dialogs/button/loader/DialogItemBodyLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/dialogs/button/loader/DialogItemBodyLoader.java @@ -13,7 +13,7 @@ public class DialogItemBodyLoader extends ButtonLoader { public DialogItemBodyLoader(Plugin plugin) { - super(plugin, "dialog_item"); + super(plugin, "dialog_item", "item"); } @Override diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/dialogs/button/loader/DialogPlainMessageBodyLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/dialogs/button/loader/DialogPlainMessageBodyLoader.java index 9814badf..914b6b13 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/dialogs/button/loader/DialogPlainMessageBodyLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/dialogs/button/loader/DialogPlainMessageBodyLoader.java @@ -2,8 +2,6 @@ import fr.maxlego08.menu.api.button.Button; import fr.maxlego08.menu.api.button.DefaultButtonValue; -import fr.maxlego08.menu.api.button.dialogs.BodyButton; -import fr.maxlego08.menu.api.enums.dialog.DialogBodyType; import fr.maxlego08.menu.api.loader.ButtonLoader; import fr.maxlego08.menu.hooks.dialogs.button.buttons.ZDialogPlainMessageBody; import org.bukkit.configuration.file.YamlConfiguration; @@ -15,7 +13,7 @@ public class DialogPlainMessageBodyLoader extends ButtonLoader { public DialogPlainMessageBodyLoader(Plugin plugin) { - super(plugin, "dialog_plain_message"); + super(plugin, "dialog_plain_message", "plain_message"); } @Override diff --git a/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/dialogs/button/loader/DialogTextInputLoader.java b/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/dialogs/button/loader/DialogTextInputLoader.java index 0de388a7..a700d02e 100644 --- a/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/dialogs/button/loader/DialogTextInputLoader.java +++ b/Hooks/Paper/src/main/java/fr/maxlego08/menu/hooks/dialogs/button/loader/DialogTextInputLoader.java @@ -2,8 +2,6 @@ import fr.maxlego08.menu.api.button.Button; import fr.maxlego08.menu.api.button.DefaultButtonValue; -import fr.maxlego08.menu.api.button.dialogs.InputButton; -import fr.maxlego08.menu.api.enums.dialog.DialogInputType; import fr.maxlego08.menu.api.loader.ButtonLoader; import fr.maxlego08.menu.hooks.dialogs.button.buttons.ZDialogTextInput; import org.bukkit.configuration.file.YamlConfiguration; diff --git a/src/main/java/fr/maxlego08/menu/ZButtonManager.java b/src/main/java/fr/maxlego08/menu/ZButtonManager.java index 75217ecb..836d6de5 100644 --- a/src/main/java/fr/maxlego08/menu/ZButtonManager.java +++ b/src/main/java/fr/maxlego08/menu/ZButtonManager.java @@ -46,18 +46,41 @@ public void register(@NonNull ButtonLoader button) { ButtonLoader existingLoader = null; for (List buttonLoaders : this.loaders.values()) { for (ButtonLoader loader : buttonLoaders) { + // Check if name matches if (loader.getName().equalsIgnoreCase(button.getName())) { existingLoader = loader; break; } + // Check if any alias matches + for (String alias : loader.getAliases()) { + if (alias.equalsIgnoreCase(button.getName())) { + existingLoader = loader; + break; + } + } + // Check if any of the new button's aliases conflict with existing loader names/aliases + for (String newAlias : button.getAliases()) { + if (loader.getName().equalsIgnoreCase(newAlias)) { + existingLoader = loader; + break; + } + for (String existingAlias : loader.getAliases()) { + if (existingAlias.equalsIgnoreCase(newAlias)) { + existingLoader = loader; + break; + } + } + } + if (existingLoader != null) { + break; + } } if (existingLoader != null) { break; } } if (existingLoader != null) { - var loader = existingLoader; - throw new ButtonAlreadyRegisterException("Button " + button.getName() + " was already register in the " + loader.getPlugin().getName()); + throw new ButtonAlreadyRegisterException("Button " + button.getName() + " was already register in the " + existingLoader.getPlugin().getName()); } Plugin plugin = button.getPlugin(); @@ -101,6 +124,11 @@ public void unregisters(@NotNull Plugin plugin) { if (loader.getName().equalsIgnoreCase(name)) { return Optional.of(loader); } + for (String alias : loader.getAliases()) { + if (alias.equalsIgnoreCase(name)) { + return Optional.of(loader); + } + } } return Optional.empty(); } diff --git a/src/main/resources/dialogs/confirmation-dialog.yml b/src/main/resources/dialogs/confirmation-dialog.yml index 1e5fbe87..50a0d33b 100644 --- a/src/main/resources/dialogs/confirmation-dialog.yml +++ b/src/main/resources/dialogs/confirmation-dialog.yml @@ -15,7 +15,7 @@ after-action: CLOSE # What to do after dialog: CLOSE, PAUSE, or NONE body: # Plain message section plain_message: - type: dialog_plain_message + type: dialog_dialog_plain_message messages: - "&6&lWelcome to our amazing server!" - "" @@ -67,7 +67,7 @@ body: # Another message section server_rules: - type: dialog_plain_message + type: dialog_dialog_plain_message messages: - "&a&l━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - "&6Server Rules" diff --git a/src/main/resources/dialogs/default-dialog.yml b/src/main/resources/dialogs/default-dialog.yml index db15b7fe..579709e0 100644 --- a/src/main/resources/dialogs/default-dialog.yml +++ b/src/main/resources/dialogs/default-dialog.yml @@ -10,7 +10,7 @@ after_action: CLOSE # What to do after dialog: CLOSE, PAUSE, or NONE # Dialog body content - can contain multiple sections body: plain_message: - type: dialog_plain_message + type: dialog_dialog_plain_message messages: - "&6&lWelcome to our amazing server!" - "" @@ -53,7 +53,7 @@ body: height: 150 # Item display height (1-256) server_rules: # Another message section - type: dialog_plain_message + type: dialog_dialog_plain_message messages: - "&a&l━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - "&6Server Rules" diff --git a/src/main/resources/dialogs/multi_action-dialog.yml b/src/main/resources/dialogs/multi_action-dialog.yml index 3423f8cf..66d83ac9 100644 --- a/src/main/resources/dialogs/multi_action-dialog.yml +++ b/src/main/resources/dialogs/multi_action-dialog.yml @@ -42,7 +42,7 @@ multi-actions: # Dialog body content - can contain multiple sections body: plain_message: - type: dialog_plain_message + type: dialog_dialog_plain_message messages: - "&6&lWelcome to our amazing server!" - "" @@ -85,7 +85,7 @@ body: height: 150 # Item display height (1-256) server_rules: # Another message section - type: dialog_plain_message + type: dialog_dialog_plain_message messages: - "&a&l━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - "&6Server Rules" diff --git a/src/main/resources/dialogs/server_link-dialog.yml b/src/main/resources/dialogs/server_link-dialog.yml index 85d76e08..e2be6752 100644 --- a/src/main/resources/dialogs/server_link-dialog.yml +++ b/src/main/resources/dialogs/server_link-dialog.yml @@ -31,7 +31,7 @@ server-links: # Dialog body content - can contain multiple sections body: plain_message: - type: dialog_plain_message + type: dialog_dialog_plain_message messages: - "&6&lWelcome to our amazing server!" - "" @@ -74,7 +74,7 @@ body: height: 150 # Item display height (1-256) server_rules: # Another message section - type: dialog_plain_message + type: dialog_dialog_plain_message messages: - "&a&l━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - "&6Server Rules"