From 574ffa99bd822c983c2ae6e805197cae7c4bd601 Mon Sep 17 00:00:00 2001 From: Krakenied Date: Mon, 19 Jan 2026 11:24:06 +0100 Subject: Prepare for Mojang version mess New API to be used in server version detection and version specific handlers --- .../quests/bukkit/BukkitQuestsPlugin.java | 100 ++++----- .../versionspecific/VersionSpecificHandler.java | 44 +++- .../versionspecific/VersionSpecificHandler11.java | 93 -------- .../versionspecific/VersionSpecificHandler12.java | 18 -- .../versionspecific/VersionSpecificHandler14.java | 16 -- .../versionspecific/VersionSpecificHandler16.java | 45 ---- .../versionspecific/VersionSpecificHandler17.java | 31 --- .../versionspecific/VersionSpecificHandler20.java | 90 -------- .../versionspecific/VersionSpecificHandler21.java | 48 ---- .../versionspecific/VersionSpecificHandler8.java | 249 --------------------- .../versionspecific/VersionSpecificHandler9.java | 79 ------- .../VersionSpecificHandler_V1_11.java | 65 ++++++ .../VersionSpecificHandler_V1_11_2.java | 19 ++ .../VersionSpecificHandler_V1_14.java | 17 ++ .../VersionSpecificHandler_V1_15_2.java | 19 ++ .../VersionSpecificHandler_V1_16.java | 34 +++ .../VersionSpecificHandler_V1_17.java | 33 +++ .../VersionSpecificHandler_V1_19_2.java | 18 ++ .../VersionSpecificHandler_V1_20.java | 44 ++++ .../VersionSpecificHandler_V1_20_4.java | 42 ++++ .../VersionSpecificHandler_V1_21_11.java | 24 ++ .../VersionSpecificHandler_V1_21_6.java | 18 ++ .../VersionSpecificHandler_V1_8.java | 239 ++++++++++++++++++++ .../VersionSpecificHandler_V1_9.java | 69 ++++++ .../bukkit/tasktype/type/SmithingTaskType.java | 3 +- 25 files changed, 732 insertions(+), 725 deletions(-) delete mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler11.java delete mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler12.java delete mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler14.java delete mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler16.java delete mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler17.java delete mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler20.java delete mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler21.java delete mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler8.java delete mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler9.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_11.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_11_2.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_14.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_15_2.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_16.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_17.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_19_2.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_20.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_20_4.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_21_11.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_21_6.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_8.java create mode 100644 bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_9.java (limited to 'bukkit/src/main/java') diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java index 434b0752..c79a2e4b 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/BukkitQuestsPlugin.java @@ -37,15 +37,6 @@ import com.leonardobishop.quests.bukkit.hook.title.Title_Nothing; import com.leonardobishop.quests.bukkit.hook.vault.AbstractVaultHook; import com.leonardobishop.quests.bukkit.hook.vault.VaultHook; import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler; -import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler11; -import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler12; -import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler14; -import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler16; -import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler17; -import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler20; -import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler21; -import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler8; -import com.leonardobishop.quests.bukkit.hook.versionspecific.VersionSpecificHandler9; import com.leonardobishop.quests.bukkit.hook.wildstacker.AbstractWildStackerHook; import com.leonardobishop.quests.bukkit.hook.wildstacker.WildStackerHook; import com.leonardobishop.quests.bukkit.item.ParsedQuestItem; @@ -163,6 +154,7 @@ import com.leonardobishop.quests.common.storage.StorageProvider; import com.leonardobishop.quests.common.tasktype.TaskType; import com.leonardobishop.quests.common.tasktype.TaskTypeManager; import com.leonardobishop.quests.common.updater.Updater; +import com.leonardobishop.quests.common.versioning.Version; import com.mojang.authlib.GameProfile; import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.BaseComponent; @@ -191,6 +183,9 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.NavigableSet; +import java.util.Objects; +import java.util.TreeSet; import java.util.function.BiFunction; import java.util.function.BooleanSupplier; import java.util.logging.Level; @@ -198,6 +193,22 @@ import java.util.regex.Pattern; public class BukkitQuestsPlugin extends JavaPlugin implements Quests { + private static final NavigableSet VSH_SET = new TreeSet<>() {{ + this.add(Version.V1_8); + this.add(Version.V1_9); + this.add(Version.V1_11); + this.add(Version.V1_11_2); + this.add(Version.V1_14); + this.add(Version.V1_15_2); + this.add(Version.V1_16); + this.add(Version.V1_17); + this.add(Version.V1_19_2); + this.add(Version.V1_20); + this.add(Version.V1_20_4); + this.add(Version.V1_21_6); + this.add(Version.V1_21_11); + }}; + private QuestsLogger questsLogger; private QuestManager questManager; private TaskTypeManager taskTypeManager; @@ -328,20 +339,6 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { e.printStackTrace(); } - // Setup version specific compatibility layers - int version; - try { - version = this.getServerVersion(); - this.questsLogger.info("Your server is running version 1." + version); - } catch (final IllegalArgumentException e) { - // all server supported versions by Quests fulfill this format, - // so we assume that some future version can possibly break it, - // and we want to load the latest and not the oldest handler - version = Integer.MAX_VALUE; - - this.questsLogger.warning("Failed to resolve server version - some features may not work! (" + e.getMessage() + ")"); - } - // (titles) this.setTitleHandle(); @@ -357,22 +354,23 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { // (skulls) this.setSkullGetter(); - // (version specific handler) - if (version <= 8) { - this.versionSpecificHandler = new VersionSpecificHandler8(); - } else { - this.versionSpecificHandler = switch (version) { - case 9, 10 -> new VersionSpecificHandler9(); - case 11 -> new VersionSpecificHandler11(); - case 12, 13 -> new VersionSpecificHandler12(); - case 14, 15 -> new VersionSpecificHandler14(); - case 16 -> new VersionSpecificHandler16(); - case 17, 18, 19 -> new VersionSpecificHandler17(); - case 20 -> new VersionSpecificHandler20(); - default -> new VersionSpecificHandler21(); - }; + // Resolve server version + Version serverVersion; + try { + serverVersion = Version.fromString(Bukkit.getBukkitVersion()); + this.questsLogger.info("Your server is running version " + serverVersion); + } catch (final IllegalArgumentException e) { + // all server versions supported by Quests fulfill this format, + // so we assume that some future version can possibly break it, + // and we want to load the latest and not the oldest handler + serverVersion = Version.UNKNOWN; + this.questsLogger.warning("Failed to resolve server version - some features may not work! (" + e.getMessage() + ")"); } + // Set the latest supported version specific handler + this.versionSpecificHandler = constructVSH(serverVersion); + this.questsLogger.info("Using " + this.versionSpecificHandler.getClass().getSimpleName() + " for version compatibility!"); + // Instantiate Projectile to ItemStack cache this.projectile2ItemCache = new Projectile2ItemCache(); this.projectile2ItemCache.registerEvents(this); @@ -574,25 +572,21 @@ public class BukkitQuestsPlugin extends JavaPlugin implements Quests { }); } - /** - * Gets the server minor version. - * - * @return the server minor version - * @throws IllegalArgumentException with message set to the bukkit version if it could not be parsed successfully. - */ - private int getServerVersion() throws IllegalArgumentException { - final String bukkitVersion = this.getServer().getBukkitVersion(); + private static VersionSpecificHandler constructVSH(final Version serverVersion) { + final Version vshVersion = Objects.requireNonNullElseGet( + VSH_SET.floor(serverVersion), + VSH_SET::first + ); - final String[] bukkitVersionParts = bukkitVersion.split("\\.", 3); - if (bukkitVersionParts.length < 2) { - throw new IllegalArgumentException(bukkitVersion, new ArrayIndexOutOfBoundsException(bukkitVersionParts.length)); - } + final String vshClazzName = String.format("%s_%s", + VersionSpecificHandler.class.getCanonicalName(), + vshVersion.toClassNameString() + ); - final String minorVersionPart = bukkitVersionParts[1].split("-")[0]; try { - return Integer.parseInt(minorVersionPart); - } catch (final NumberFormatException e) { - throw new IllegalArgumentException(bukkitVersion, e); + return (VersionSpecificHandler) Class.forName(vshClazzName).getConstructor().newInstance(); + } catch (final ReflectiveOperationException e) { + throw new IllegalStateException("Failed to construct version specific handler", e); } } diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler.java index 48189513..2bf7da48 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler.java @@ -1,5 +1,6 @@ package com.leonardobishop.quests.bukkit.hook.versionspecific; +import com.leonardobishop.quests.common.versioning.Version; import org.bukkit.Keyed; import org.bukkit.Material; import org.bukkit.Tag; @@ -9,6 +10,7 @@ import org.bukkit.block.data.type.CaveVinesPlant; import org.bukkit.damage.DamageSource; import org.bukkit.entity.AbstractHorse; import org.bukkit.entity.Camel; +import org.bukkit.entity.CamelHusk; import org.bukkit.entity.Donkey; import org.bukkit.entity.Entity; import org.bukkit.entity.Goat; @@ -36,6 +38,7 @@ import org.bukkit.inventory.SmithingTransformRecipe; import org.bukkit.inventory.SmithingTrimRecipe; import org.jspecify.annotations.Nullable; +import java.util.HashMap; import java.util.List; /** @@ -46,7 +49,7 @@ import java.util.List; public interface VersionSpecificHandler { @SuppressWarnings("unused") - int getMinecraftVersion(); + Version getMinecraftVersion(); /** * Elytra were introduced in {@code 1.9}. @@ -62,6 +65,13 @@ public interface VersionSpecificHandler { */ boolean isPlayerOnCamel(Player player); + /** + * Camel Husks were introduced in {@code 1.21.11}. + * + * @see CamelHusk + */ + boolean isPlayerOnCamelHusk(Player player); + /** * Donkeys were introduced in {@code 1.6.1}. * @@ -162,6 +172,36 @@ public interface VersionSpecificHandler { */ boolean isOffHandEmpty(Player player); + /** + * Initially, the proper method to get an inventory contents except armor and other extra slots + * (not allowing player to store results of crafting actions) was {@link PlayerInventory#getContents()}. + * In {@code 1.9} {@link PlayerInventory#getStorageContents()} method was introduced superseding the old + * one. In newer versions {@link PlayerInventory#getContents()} method returns all the items including + * the extra slots of player inventories. + * + * @apiNote This method is intended to be used as a check for item crafting related task types. + * @see VersionSpecificHandler#getStorageContents(PlayerInventory) + */ + default int getAvailableSpace(Player player, ItemStack item) { + PlayerInventory inventory = player.getInventory(); + HashMap itemsOfType = inventory.all(item.getType()); + int availableSpace = 0; + + for (ItemStack existingItem : itemsOfType.values()) { + if (item.isSimilar(existingItem)) { + availableSpace += (item.getMaxStackSize() - existingItem.getAmount()); + } + } + + for (ItemStack existingItem : this.getStorageContents(inventory)) { + if (existingItem == null) { + availableSpace += item.getMaxStackSize(); + } + } + + return availableSpace; + } + /** * Initially, the proper method to get an inventory contents except armor and other extra slots * (not allowing player to store results of crafting actions) was {@link PlayerInventory#getContents()}. @@ -171,7 +211,7 @@ public interface VersionSpecificHandler { * * @apiNote This method is intended to be used as a check for item crafting related task types. */ - int getAvailableSpace(Player player, ItemStack newItemStack); + @Nullable ItemStack[] getStorageContents(PlayerInventory inventory); /** * Initially, clicking with a number key on a crafting result made the item go to the selected slot. diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler11.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler11.java deleted file mode 100644 index 53e0c86a..00000000 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler11.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.leonardobishop.quests.bukkit.hook.versionspecific; - -import org.bukkit.entity.Donkey; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Horse; -import org.bukkit.entity.Llama; -import org.bukkit.entity.Mule; -import org.bukkit.entity.Player; -import org.bukkit.entity.SkeletonHorse; -import org.bukkit.entity.ZombieHorse; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.List; - -public class VersionSpecificHandler11 extends VersionSpecificHandler9 implements VersionSpecificHandler { - - private static Method getPassengersMethod; - - static { - try { - getPassengersMethod = Entity.class.getMethod("getPassengers"); - } catch (final NoSuchMethodException e) { - // server version cannot support the method (doesn't work on 1.11, 1.11.1) - } - } - - @Override - public int getMinecraftVersion() { - return 11; - } - - @Override - public boolean isPlayerOnDonkey(Player player) { - return player.getVehicle() instanceof Donkey; - } - - @Override - public boolean isPlayerOnHorse(Player player) { - return player.getVehicle() instanceof Horse; - } - - @Override - public boolean isPlayerOnLlama(Player player) { - return player.getVehicle() instanceof Llama; - } - - @Override - public boolean isPlayerOnMule(Player player) { - return player.getVehicle() instanceof Mule; - } - - @Override - public boolean isPlayerOnSkeletonHorse(Player player) { - return player.getVehicle() instanceof SkeletonHorse; - } - - @Override - public boolean isPlayerOnZombieHorse(Player player) { - return player.getVehicle() instanceof ZombieHorse; - } - - @Override - public int removeItem(Inventory inventory, int slot, int amountToRemove) { - ItemStack item = inventory.getItem(slot); - - if (item == null) { - return 0; - } - - int amountInStack = item.getAmount(); - int newAmountInStack = Math.max(0, amountInStack - amountToRemove); - item.setAmount(newAmountInStack); - - return amountInStack - newAmountInStack; - } - - @SuppressWarnings("unchecked") - @Override - public List getPassengers(Entity entity) { - if (getPassengersMethod == null) { - return super.getPassengers(entity); - } - - try { - return (List) getPassengersMethod.invoke(entity); - } catch (InvocationTargetException | IllegalAccessException e) { - throw new IllegalStateException("Entity#getPassengers invocation failed", e); - } - } -} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler12.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler12.java deleted file mode 100644 index b887c01c..00000000 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler12.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.leonardobishop.quests.bukkit.hook.versionspecific; - -import org.bukkit.entity.Entity; - -import java.util.List; - -public class VersionSpecificHandler12 extends VersionSpecificHandler11 implements VersionSpecificHandler { - - @Override - public int getMinecraftVersion() { - return 12; - } - - @Override - public List getPassengers(Entity entity) { - return entity.getPassengers(); - } -} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler14.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler14.java deleted file mode 100644 index 6ebf1810..00000000 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler14.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.leonardobishop.quests.bukkit.hook.versionspecific; - -import org.bukkit.block.Biome; - -public class VersionSpecificHandler14 extends VersionSpecificHandler12 implements VersionSpecificHandler { - - @Override - public int getMinecraftVersion() { - return 14; - } - - @Override - public String getBiomeKey(Biome biome) { - return biome.getKey().toString(); - } -} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler16.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler16.java deleted file mode 100644 index bb4eb6b8..00000000 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler16.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.leonardobishop.quests.bukkit.hook.versionspecific; - -import org.bukkit.entity.Player; -import org.bukkit.entity.Strider; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.event.inventory.SmithItemEvent; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; - -public class VersionSpecificHandler16 extends VersionSpecificHandler14 implements VersionSpecificHandler { - - @Override - public int getMinecraftVersion() { - return 16; - } - - @Override - public boolean isPlayerOnStrider(Player player) { - return player.getVehicle() instanceof Strider; - } - - @Override - public boolean isOffHandSwap(ClickType clickType) { - return clickType == ClickType.SWAP_OFFHAND; - } - - @Override - public boolean isOffHandEmpty(Player player) { - return player.getInventory().getItemInOffHand().getAmount() == 0; - } - - @Override - public ItemStack getItemInEquipmentSlot(PlayerInventory inventory, EquipmentSlot slot) { - return inventory.getItem(slot); - } - - @Override - public ItemStack[] getSmithItems(SmithItemEvent event) { - return new ItemStack[]{ - event.getInventory().getInputEquipment(), - event.getInventory().getInputMineral() - }; - } -} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler17.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler17.java deleted file mode 100644 index 471e6a74..00000000 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler17.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.leonardobishop.quests.bukkit.hook.versionspecific; - -import org.bukkit.Material; -import org.bukkit.Tag; -import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.type.CaveVinesPlant; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Goat; - -public class VersionSpecificHandler17 extends VersionSpecificHandler16 implements VersionSpecificHandler { - - @Override - public int getMinecraftVersion() { - return 17; - } - - @Override - public boolean isCaveVinesPlantWithBerries(BlockData blockData) { - return blockData instanceof CaveVinesPlant caveVinesPlant && caveVinesPlant.isBerries(); - } - - @Override - public boolean isGoat(Entity entity) { - return entity instanceof Goat; - } - - @Override - public boolean isCake(Material type) { - return super.isCake(type) || Tag.CANDLE_CAKES.isTagged(type); - } -} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler20.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler20.java deleted file mode 100644 index 687da6fa..00000000 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler20.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.leonardobishop.quests.bukkit.hook.versionspecific; - -import com.leonardobishop.quests.bukkit.util.CompatUtils; -import org.bukkit.damage.DamageSource; -import org.bukkit.entity.Camel; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.inventory.SmithItemEvent; -import org.bukkit.event.player.PlayerBucketEmptyEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.Recipe; -import org.bukkit.inventory.SmithingTransformRecipe; -import org.bukkit.inventory.SmithingTrimRecipe; -import org.jspecify.annotations.Nullable; - -public class VersionSpecificHandler20 extends VersionSpecificHandler17 implements VersionSpecificHandler { - - private static final boolean DAMAGE_SOURCE_API = CompatUtils.classExists("org.bukkit.damage.DamageSource"); - - @Override - public int getMinecraftVersion() { - return 20; - } - - @Override - public boolean isPlayerOnCamel(Player player) { - return player.getVehicle() instanceof Camel; - } - - @Override - public ItemStack getItem(PlayerBucketEmptyEvent event) { - return event.getPlayer().getInventory().getItem(event.getHand()); - } - - @Override - public ItemStack[] getSmithItems(SmithItemEvent event) { - return new ItemStack[]{ - event.getInventory().getInputEquipment(), - event.getInventory().getInputMineral(), - event.getInventory().getInputTemplate() - }; - } - - @Override - public String getSmithMode(SmithItemEvent event) { - Recipe recipe = event.getInventory().getRecipe(); - if (recipe instanceof SmithingTransformRecipe) { - return "transform"; - } else if (recipe instanceof SmithingTrimRecipe) { - return "trim"; - } else { - return null; - } - } - - @Override - public @Nullable Player getDamager(@Nullable EntityDamageEvent event) { - if (!DAMAGE_SOURCE_API) { - return super.getDamager(event); - } - - if (event == null) { - return null; - } - - DamageSource source = event.getDamageSource(); - Entity causingEntity = source.getCausingEntity(); - - if (causingEntity instanceof Player) { - return (Player) causingEntity; - } - - return null; - } - - @Override - public @Nullable Entity getDirectSource(@Nullable EntityDamageEvent event) { - if (!DAMAGE_SOURCE_API) { - return super.getDamager(event); - } - - if (event == null) { - return null; - } - - DamageSource source = event.getDamageSource(); - return source.getDirectEntity(); - } -} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler21.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler21.java deleted file mode 100644 index 6cb5e9e7..00000000 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler21.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.leonardobishop.quests.bukkit.hook.versionspecific; - -import com.leonardobishop.quests.bukkit.util.CompatUtils; -import org.bukkit.entity.HappyGhast; -import org.bukkit.entity.Nautilus; -import org.bukkit.entity.Player; - -import java.util.function.Predicate; - -public class VersionSpecificHandler21 extends VersionSpecificHandler20 implements VersionSpecificHandler { - - // Introduced in 1.21.6 - private static final Predicate HAPPY_GHAST_PREDICATE; - - // Introduced in 1.21.11 - private static final Predicate NAUTILUS_PREDICATE; - - static { - if (CompatUtils.classExists("org.bukkit.entity.HappyGhast")) { - HAPPY_GHAST_PREDICATE = player -> player.getVehicle() instanceof HappyGhast; - } else { - HAPPY_GHAST_PREDICATE = player -> Boolean.FALSE; - } - } - - static { - if (CompatUtils.classExists("org.bukkit.entity.Nautilus")) { - NAUTILUS_PREDICATE = player -> player.getVehicle() instanceof Nautilus; - } else { - NAUTILUS_PREDICATE = player -> Boolean.FALSE; - } - } - - @Override - public int getMinecraftVersion() { - return 21; - } - - @Override - public boolean isPlayerOnHappyGhast(Player player) { - return HAPPY_GHAST_PREDICATE.test(player); - } - - @Override - public boolean isPlayerOnNautilus(Player player) { - return NAUTILUS_PREDICATE.test(player); - } -} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler8.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler8.java deleted file mode 100644 index 06657cb4..00000000 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler8.java +++ /dev/null @@ -1,249 +0,0 @@ -package com.leonardobishop.quests.bukkit.hook.versionspecific; - -import org.bukkit.Material; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Horse; -import org.bukkit.entity.Player; -import org.bukkit.entity.Projectile; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.event.inventory.SmithItemEvent; -import org.bukkit.event.player.PlayerBucketEmptyEvent; -import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -import org.bukkit.projectiles.ProjectileSource; -import org.jspecify.annotations.Nullable; - -import java.util.HashMap; -import java.util.List; - -public class VersionSpecificHandler8 implements VersionSpecificHandler { - - @Override - public int getMinecraftVersion() { - return 8; - } - - @Override - public boolean isPlayerGliding(Player player) { - return false; - } - - @Override - public boolean isPlayerOnCamel(Player player) { - return false; - } - - @SuppressWarnings("deprecation") - @Override - public boolean isPlayerOnDonkey(Player player) { - return player.getVehicle() instanceof Horse horse && horse.getVariant() == Horse.Variant.DONKEY; - } - - @Override - public boolean isPlayerOnHappyGhast(Player player) { - return false; - } - - @SuppressWarnings("deprecation") - @Override - public boolean isPlayerOnHorse(Player player) { - return player.getVehicle() instanceof Horse horse && horse.getVariant() == Horse.Variant.HORSE; - } - - @Override - public boolean isPlayerOnLlama(Player player) { - return false; - } - - @SuppressWarnings("deprecation") - @Override - public boolean isPlayerOnMule(Player player) { - return player.getVehicle() instanceof Horse horse && horse.getVariant() == Horse.Variant.MULE; - } - - @Override - public boolean isPlayerOnNautilus(Player player) { - return false; - } - - @SuppressWarnings("deprecation") - @Override - public boolean isPlayerOnSkeletonHorse(Player player) { - return player.getVehicle() instanceof Horse horse && horse.getVariant() == Horse.Variant.SKELETON_HORSE; - } - - @Override - public boolean isPlayerOnStrider(Player player) { - return false; - } - - @SuppressWarnings("deprecation") - @Override - public boolean isPlayerOnZombieHorse(Player player) { - return player.getVehicle() instanceof Horse horse && horse.getVariant() == Horse.Variant.UNDEAD_HORSE; - } - - @Override - public boolean isOffHandSwap(ClickType clickType) { - return false; - } - - @Override - public boolean isOffHandEmpty(Player player) { - return false; - } - - @Override - public int getAvailableSpace(Player player, ItemStack newItemStack) { - int availableSpace = 0; - PlayerInventory inventory = player.getInventory(); - HashMap itemStacksWithSameMaterial = inventory.all(newItemStack.getType()); - for (ItemStack existingItemStack : itemStacksWithSameMaterial.values()) { - if (newItemStack.isSimilar(existingItemStack)) { - availableSpace += (newItemStack.getMaxStackSize() - existingItemStack.getAmount()); - } - } - - for (ItemStack existingItemStack : inventory.getContents()) { - if (existingItemStack == null) { - availableSpace += newItemStack.getMaxStackSize(); - } - } - - return availableSpace; - } - - @Override - public boolean isHotbarMoveAndReaddSupported() { - return true; - } - - @Override - public boolean isCaveVinesPlantWithBerries(BlockData blockData) { - return false; - } - - @SuppressWarnings("deprecation") - @Override - public ItemStack getItemInMainHand(Player player) { - return player.getItemInHand(); - } - - @SuppressWarnings("deprecation") - @Override - public ItemStack getItemInEquipmentSlot(PlayerInventory inventory, EquipmentSlot slot) { - return switch (slot) { - case CHEST -> inventory.getChestplate(); - case FEET -> inventory.getBoots(); - case HAND -> inventory.getItemInHand(); - case HEAD -> inventory.getHelmet(); - case LEGS -> inventory.getLeggings(); - - // there are 5 equipment slots on 1.8 - default -> null; - }; - } - - @Override - public ItemStack getItem(PlayerBucketEmptyEvent event) { - return new ItemStack(event.getBucket(), 1); - } - - @Override - public EquipmentSlot getHand(PlayerInteractEvent event) { - return EquipmentSlot.HAND; - } - - @Override - public EquipmentSlot getHand(PlayerInteractEntityEvent event) { - return EquipmentSlot.HAND; - } - - @Override - public ItemStack[] getSmithItems(SmithItemEvent event) { - return new ItemStack[0]; - } - - @Override - public String getSmithMode(SmithItemEvent event) { - return null; - } - - @Override - public boolean isGoat(Entity entity) { - return false; - } - - @Override - public int removeItem(Inventory inventory, int slot, int amountToRemove) { - ItemStack item = inventory.getItem(slot); - - if (item == null) { - return 0; - } - - int amountInStack = item.getAmount(); - int newAmountInStack = Math.max(0, amountInStack - amountToRemove); - item.setAmount(newAmountInStack); - - // It's needed in older versions - // https://github.com/LMBishop/Quests/issues/787 - inventory.setItem(slot, item); - - return amountInStack - newAmountInStack; - } - - @SuppressWarnings("deprecation") - @Override - public List getPassengers(Entity entity) { - Entity passenger = entity.getPassenger(); - return passenger != null ? List.of(passenger) : List.of(); - } - - @Override - public @Nullable Player getDamager(@Nullable EntityDamageEvent event) { - if (!(event instanceof EntityDamageByEntityEvent byEntityEvent)) { - return null; - } - - Entity damager = byEntityEvent.getDamager(); - - if (damager instanceof Player) { - return (Player) damager; - } - - if (damager instanceof Projectile projectile) { - ProjectileSource shooter = projectile.getShooter(); - - if (shooter instanceof Player) { - return (Player) shooter; - } - } - - return null; - } - - @Override - public @Nullable Entity getDirectSource(@Nullable EntityDamageEvent lastDamageCause) { - return null; - } - - @Override - public boolean isCake(Material type) { - return type == Material.CAKE; - } - - @SuppressWarnings({"removal", "UnstableApiUsage"}) - @Override - public String getBiomeKey(Biome biome) { - return biome.name(); - } -} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler9.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler9.java deleted file mode 100644 index cf2f0a9c..00000000 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler9.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.leonardobishop.quests.bukkit.hook.versionspecific; - -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerInteractEntityEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; - -import java.util.HashMap; - -public class VersionSpecificHandler9 extends VersionSpecificHandler8 implements VersionSpecificHandler { - - @Override - public int getMinecraftVersion() { - return 9; - } - - @Override - public boolean isPlayerGliding(Player player) { - return player.isGliding(); - } - - @Override - public int getAvailableSpace(Player player, ItemStack newItemStack) { - int availableSpace = 0; - PlayerInventory inventory = player.getInventory(); - HashMap itemStacksWithSameMaterial = inventory.all(newItemStack.getType()); - for (ItemStack existingItemStack : itemStacksWithSameMaterial.values()) { - if (newItemStack.isSimilar(existingItemStack)) { - availableSpace += (newItemStack.getMaxStackSize() - existingItemStack.getAmount()); - } - } - - for (ItemStack existingItemStack : inventory.getStorageContents()) { - if (existingItemStack == null) { - availableSpace += newItemStack.getMaxStackSize(); - } - } - - return availableSpace; - } - - @Override - public boolean isHotbarMoveAndReaddSupported() { - return false; - } - - @Override - public ItemStack getItemInMainHand(Player player) { - return player.getInventory().getItemInMainHand(); - } - - @SuppressWarnings("deprecation") - @Override - public ItemStack getItemInEquipmentSlot(PlayerInventory inventory, EquipmentSlot slot) { - return switch (slot) { - case CHEST -> inventory.getChestplate(); - case FEET -> inventory.getBoots(); - case HAND -> inventory.getItemInHand(); - case HEAD -> inventory.getHelmet(); - case LEGS -> inventory.getLeggings(); - case OFF_HAND -> inventory.getItemInOffHand(); - - // there are 6 equipment slots on 1.9 - default -> null; - }; - } - - @Override - public EquipmentSlot getHand(PlayerInteractEvent event) { - return event.getHand(); - } - - @Override - public EquipmentSlot getHand(PlayerInteractEntityEvent event) { - return event.getHand(); - } -} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_11.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_11.java new file mode 100644 index 00000000..0e525c38 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_11.java @@ -0,0 +1,65 @@ +package com.leonardobishop.quests.bukkit.hook.versionspecific; + +import com.leonardobishop.quests.common.versioning.Version; +import org.bukkit.entity.Donkey; +import org.bukkit.entity.Horse; +import org.bukkit.entity.Llama; +import org.bukkit.entity.Mule; +import org.bukkit.entity.Player; +import org.bukkit.entity.SkeletonHorse; +import org.bukkit.entity.ZombieHorse; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +public class VersionSpecificHandler_V1_11 extends VersionSpecificHandler_V1_9 { + + @Override + public Version getMinecraftVersion() { + return Version.V1_11; + } + + @Override + public boolean isPlayerOnDonkey(Player player) { + return player.getVehicle() instanceof Donkey; + } + + @Override + public boolean isPlayerOnHorse(Player player) { + return player.getVehicle() instanceof Horse; + } + + @Override + public boolean isPlayerOnLlama(Player player) { + return player.getVehicle() instanceof Llama; + } + + @Override + public boolean isPlayerOnMule(Player player) { + return player.getVehicle() instanceof Mule; + } + + @Override + public boolean isPlayerOnSkeletonHorse(Player player) { + return player.getVehicle() instanceof SkeletonHorse; + } + + @Override + public boolean isPlayerOnZombieHorse(Player player) { + return player.getVehicle() instanceof ZombieHorse; + } + + @Override + public int removeItem(Inventory inventory, int slot, int amountToRemove) { + ItemStack item = inventory.getItem(slot); + + if (item == null) { + return 0; + } + + int amountInStack = item.getAmount(); + int newAmountInStack = Math.max(0, amountInStack - amountToRemove); + item.setAmount(newAmountInStack); + + return amountInStack - newAmountInStack; + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_11_2.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_11_2.java new file mode 100644 index 00000000..61514ddd --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_11_2.java @@ -0,0 +1,19 @@ +package com.leonardobishop.quests.bukkit.hook.versionspecific; + +import com.leonardobishop.quests.common.versioning.Version; +import org.bukkit.entity.Entity; + +import java.util.List; + +public class VersionSpecificHandler_V1_11_2 extends VersionSpecificHandler_V1_11 { + + @Override + public Version getMinecraftVersion() { + return Version.V1_11_2; + } + + @Override + public List getPassengers(Entity entity) { + return entity.getPassengers(); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_14.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_14.java new file mode 100644 index 00000000..d8864715 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_14.java @@ -0,0 +1,17 @@ +package com.leonardobishop.quests.bukkit.hook.versionspecific; + +import com.leonardobishop.quests.common.versioning.Version; +import org.bukkit.block.Biome; + +public class VersionSpecificHandler_V1_14 extends VersionSpecificHandler_V1_11_2 { + + @Override + public Version getMinecraftVersion() { + return Version.V1_14; + } + + @Override + public String getBiomeKey(Biome biome) { + return biome.getKey().toString(); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_15_2.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_15_2.java new file mode 100644 index 00000000..2ea95950 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_15_2.java @@ -0,0 +1,19 @@ +package com.leonardobishop.quests.bukkit.hook.versionspecific; + +import com.leonardobishop.quests.common.versioning.Version; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +public class VersionSpecificHandler_V1_15_2 extends VersionSpecificHandler_V1_14 { + + @Override + public Version getMinecraftVersion() { + return Version.V1_15_2; + } + + @Override + public ItemStack getItemInEquipmentSlot(PlayerInventory inventory, EquipmentSlot slot) { + return inventory.getItem(slot); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_16.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_16.java new file mode 100644 index 00000000..6cd4a34a --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_16.java @@ -0,0 +1,34 @@ +package com.leonardobishop.quests.bukkit.hook.versionspecific; + +import com.leonardobishop.quests.common.versioning.Version; +import org.bukkit.entity.Player; +import org.bukkit.entity.Strider; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.SmithItemEvent; +import org.bukkit.inventory.ItemStack; + +public class VersionSpecificHandler_V1_16 extends VersionSpecificHandler_V1_15_2 { + + @Override + public Version getMinecraftVersion() { + return Version.V1_16; + } + + @Override + public boolean isPlayerOnStrider(Player player) { + return player.getVehicle() instanceof Strider; + } + + @Override + public boolean isOffHandSwap(ClickType clickType) { + return clickType == ClickType.SWAP_OFFHAND; + } + + @Override + public ItemStack[] getSmithItems(SmithItemEvent event) { + return new ItemStack[]{ + event.getInventory().getInputEquipment(), + event.getInventory().getInputMineral() + }; + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_17.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_17.java new file mode 100644 index 00000000..e9f53565 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_17.java @@ -0,0 +1,33 @@ +package com.leonardobishop.quests.bukkit.hook.versionspecific; + +import com.leonardobishop.quests.common.versioning.Version; +import org.bukkit.Material; +import org.bukkit.Tag; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.type.CaveVinesPlant; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Goat; + +public class VersionSpecificHandler_V1_17 extends VersionSpecificHandler_V1_16 { + + @Override + public Version getMinecraftVersion() { + return Version.V1_17; + } + + @SuppressWarnings("deprecation") + @Override + public boolean isCaveVinesPlantWithBerries(BlockData blockData) { + return blockData instanceof CaveVinesPlant caveVinesPlant && caveVinesPlant.isBerries(); + } + + @Override + public boolean isGoat(Entity entity) { + return entity instanceof Goat; + } + + @Override + public boolean isCake(Material type) { + return super.isCake(type) || Tag.CANDLE_CAKES.isTagged(type); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_19_2.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_19_2.java new file mode 100644 index 00000000..fdf19c48 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_19_2.java @@ -0,0 +1,18 @@ +package com.leonardobishop.quests.bukkit.hook.versionspecific; + +import com.leonardobishop.quests.common.versioning.Version; +import org.bukkit.event.player.PlayerBucketEmptyEvent; +import org.bukkit.inventory.ItemStack; + +public class VersionSpecificHandler_V1_19_2 extends VersionSpecificHandler_V1_17 { + + @Override + public Version getMinecraftVersion() { + return Version.V1_19_2; + } + + @Override + public ItemStack getItem(PlayerBucketEmptyEvent event) { + return this.getItemInEquipmentSlot(event.getPlayer().getInventory(), event.getHand()); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_20.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_20.java new file mode 100644 index 00000000..d62df255 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_20.java @@ -0,0 +1,44 @@ +package com.leonardobishop.quests.bukkit.hook.versionspecific; + +import com.leonardobishop.quests.common.versioning.Version; +import org.bukkit.entity.Camel; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.SmithItemEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.Recipe; +import org.bukkit.inventory.SmithingTransformRecipe; +import org.bukkit.inventory.SmithingTrimRecipe; + +public class VersionSpecificHandler_V1_20 extends VersionSpecificHandler_V1_19_2 { + + @Override + public Version getMinecraftVersion() { + return Version.V1_20; + } + + @Override + public boolean isPlayerOnCamel(Player player) { + return player.getVehicle() instanceof Camel; + } + + @Override + public ItemStack[] getSmithItems(SmithItemEvent event) { + return new ItemStack[]{ + event.getInventory().getInputEquipment(), + event.getInventory().getInputMineral(), + event.getInventory().getInputTemplate() + }; + } + + @Override + public String getSmithMode(SmithItemEvent event) { + Recipe recipe = event.getInventory().getRecipe(); + if (recipe instanceof SmithingTransformRecipe) { + return "transform"; + } else if (recipe instanceof SmithingTrimRecipe) { + return "trim"; + } else { + return null; + } + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_20_4.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_20_4.java new file mode 100644 index 00000000..042c7fbe --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_20_4.java @@ -0,0 +1,42 @@ +package com.leonardobishop.quests.bukkit.hook.versionspecific; + +import com.leonardobishop.quests.common.versioning.Version; +import org.bukkit.damage.DamageSource; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityDamageEvent; +import org.jspecify.annotations.Nullable; + +public class VersionSpecificHandler_V1_20_4 extends VersionSpecificHandler_V1_20 { + + @Override + public Version getMinecraftVersion() { + return Version.V1_20_4; + } + + @Override + public @Nullable Player getDamager(@Nullable EntityDamageEvent event) { + if (event == null) { + return null; + } + + DamageSource source = event.getDamageSource(); + Entity causingEntity = source.getCausingEntity(); + + if (causingEntity instanceof Player) { + return (Player) causingEntity; + } + + return null; + } + + @Override + public @Nullable Entity getDirectSource(@Nullable EntityDamageEvent event) { + if (event == null) { + return null; + } + + DamageSource source = event.getDamageSource(); + return source.getDirectEntity(); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_21_11.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_21_11.java new file mode 100644 index 00000000..e64e2a42 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_21_11.java @@ -0,0 +1,24 @@ +package com.leonardobishop.quests.bukkit.hook.versionspecific; + +import com.leonardobishop.quests.common.versioning.Version; +import org.bukkit.entity.CamelHusk; +import org.bukkit.entity.Nautilus; +import org.bukkit.entity.Player; + +public class VersionSpecificHandler_V1_21_11 extends VersionSpecificHandler_V1_21_6 { + + @Override + public Version getMinecraftVersion() { + return Version.V1_21_11; + } + + @Override + public boolean isPlayerOnCamelHusk(Player player) { + return player.getVehicle() instanceof CamelHusk; + } + + @Override + public boolean isPlayerOnNautilus(Player player) { + return player.getVehicle() instanceof Nautilus; + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_21_6.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_21_6.java new file mode 100644 index 00000000..4eaae85f --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_21_6.java @@ -0,0 +1,18 @@ +package com.leonardobishop.quests.bukkit.hook.versionspecific; + +import com.leonardobishop.quests.common.versioning.Version; +import org.bukkit.entity.HappyGhast; +import org.bukkit.entity.Player; + +public class VersionSpecificHandler_V1_21_6 extends VersionSpecificHandler_V1_20_4 { + + @Override + public Version getMinecraftVersion() { + return Version.V1_21_6; + } + + @Override + public boolean isPlayerOnHappyGhast(Player player) { + return player.getVehicle() instanceof HappyGhast; + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_8.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_8.java new file mode 100644 index 00000000..4567f548 --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_8.java @@ -0,0 +1,239 @@ +package com.leonardobishop.quests.bukkit.hook.versionspecific; + +import com.leonardobishop.quests.common.versioning.Version; +import org.bukkit.Material; +import org.bukkit.block.Biome; +import org.bukkit.block.data.BlockData; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Horse; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.SmithItemEvent; +import org.bukkit.event.player.PlayerBucketEmptyEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.projectiles.ProjectileSource; +import org.jspecify.annotations.Nullable; + +import java.util.List; + +public class VersionSpecificHandler_V1_8 implements VersionSpecificHandler { + + @Override + public Version getMinecraftVersion() { + return Version.V1_8; + } + + @Override + public boolean isPlayerGliding(Player player) { + return false; + } + + @Override + public boolean isPlayerOnCamel(Player player) { + return false; + } + + @Override + public boolean isPlayerOnCamelHusk(Player player) { + return false; + } + + @SuppressWarnings({"deprecation", "removal"}) + @Override + public boolean isPlayerOnDonkey(Player player) { + return player.getVehicle() instanceof Horse horse && horse.getVariant() == Horse.Variant.DONKEY; + } + + @Override + public boolean isPlayerOnHappyGhast(Player player) { + return false; + } + + @SuppressWarnings({"deprecation", "removal"}) + @Override + public boolean isPlayerOnHorse(Player player) { + return player.getVehicle() instanceof Horse horse && horse.getVariant() == Horse.Variant.HORSE; + } + + @Override + public boolean isPlayerOnLlama(Player player) { + return false; + } + + @SuppressWarnings({"deprecation", "removal"}) + @Override + public boolean isPlayerOnMule(Player player) { + return player.getVehicle() instanceof Horse horse && horse.getVariant() == Horse.Variant.MULE; + } + + @Override + public boolean isPlayerOnNautilus(Player player) { + return false; + } + + @SuppressWarnings({"deprecation", "removal"}) + @Override + public boolean isPlayerOnSkeletonHorse(Player player) { + return player.getVehicle() instanceof Horse horse && horse.getVariant() == Horse.Variant.SKELETON_HORSE; + } + + @Override + public boolean isPlayerOnStrider(Player player) { + return false; + } + + @SuppressWarnings({"deprecation", "removal"}) + @Override + public boolean isPlayerOnZombieHorse(Player player) { + return player.getVehicle() instanceof Horse horse && horse.getVariant() == Horse.Variant.UNDEAD_HORSE; + } + + @Override + public boolean isOffHandSwap(ClickType clickType) { + return false; + } + + @Override + public boolean isOffHandEmpty(Player player) { + return false; + } + + @Override + public @Nullable ItemStack[] getStorageContents(PlayerInventory inventory) { + return inventory.getContents(); + } + + @Override + public boolean isHotbarMoveAndReaddSupported() { + return true; + } + + @Override + public boolean isCaveVinesPlantWithBerries(BlockData blockData) { + return false; + } + + @SuppressWarnings("deprecation") + @Override + public ItemStack getItemInMainHand(Player player) { + return player.getItemInHand(); + } + + @SuppressWarnings("deprecation") + @Override + public ItemStack getItemInEquipmentSlot(PlayerInventory inventory, EquipmentSlot slot) { + return switch (slot) { + case CHEST -> inventory.getChestplate(); + case FEET -> inventory.getBoots(); + case HAND -> inventory.getItemInHand(); + case HEAD -> inventory.getHelmet(); + case LEGS -> inventory.getLeggings(); + + // there are 5 equipment slots on 1.8 + default -> null; + }; + } + + @Override + public ItemStack getItem(PlayerBucketEmptyEvent event) { + return new ItemStack(event.getBucket(), 1); + } + + @Override + public EquipmentSlot getHand(PlayerInteractEvent event) { + return EquipmentSlot.HAND; + } + + @Override + public EquipmentSlot getHand(PlayerInteractEntityEvent event) { + return EquipmentSlot.HAND; + } + + @Override + public ItemStack[] getSmithItems(SmithItemEvent event) { + return new ItemStack[0]; + } + + @Override + public String getSmithMode(SmithItemEvent event) { + return null; + } + + @Override + public boolean isGoat(Entity entity) { + return false; + } + + @Override + public int removeItem(Inventory inventory, int slot, int amountToRemove) { + ItemStack item = inventory.getItem(slot); + + if (item == null) { + return 0; + } + + int amountInStack = item.getAmount(); + int newAmountInStack = Math.max(0, amountInStack - amountToRemove); + item.setAmount(newAmountInStack); + + // It's needed in older versions + // https://github.com/LMBishop/Quests/issues/787 + inventory.setItem(slot, item); + + return amountInStack - newAmountInStack; + } + + @SuppressWarnings("deprecation") + @Override + public List getPassengers(Entity entity) { + Entity passenger = entity.getPassenger(); + return passenger != null ? List.of(passenger) : List.of(); + } + + @Override + public @Nullable Player getDamager(@Nullable EntityDamageEvent event) { + if (!(event instanceof EntityDamageByEntityEvent byEntityEvent)) { + return null; + } + + Entity damager = byEntityEvent.getDamager(); + + if (damager instanceof Player) { + return (Player) damager; + } + + if (damager instanceof Projectile projectile) { + ProjectileSource shooter = projectile.getShooter(); + + if (shooter instanceof Player) { + return (Player) shooter; + } + } + + return null; + } + + @Override + public @Nullable Entity getDirectSource(@Nullable EntityDamageEvent lastDamageCause) { + return null; + } + + @Override + public boolean isCake(Material type) { + return type == Material.CAKE; + } + + @SuppressWarnings({"removal", "UnstableApiUsage"}) + @Override + public String getBiomeKey(Biome biome) { + return biome.name(); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_9.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_9.java new file mode 100644 index 00000000..ae90569a --- /dev/null +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/hook/versionspecific/VersionSpecificHandler_V1_9.java @@ -0,0 +1,69 @@ +package com.leonardobishop.quests.bukkit.hook.versionspecific; + +import com.leonardobishop.quests.common.versioning.Version; +import org.bukkit.entity.Player; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.jspecify.annotations.Nullable; + +public class VersionSpecificHandler_V1_9 extends VersionSpecificHandler_V1_8 { + + @Override + public Version getMinecraftVersion() { + return Version.V1_9; + } + + @Override + public boolean isPlayerGliding(Player player) { + return player.isGliding(); + } + + @Override + public boolean isOffHandEmpty(Player player) { + return player.getInventory().getItemInOffHand().getAmount() == 0; + } + + @Override + public @Nullable ItemStack[] getStorageContents(PlayerInventory inventory) { + return inventory.getStorageContents(); + } + + @Override + public boolean isHotbarMoveAndReaddSupported() { + return false; + } + + @Override + public ItemStack getItemInMainHand(Player player) { + return player.getInventory().getItemInMainHand(); + } + + @SuppressWarnings("deprecation") + @Override + public ItemStack getItemInEquipmentSlot(PlayerInventory inventory, EquipmentSlot slot) { + return switch (slot) { + case CHEST -> inventory.getChestplate(); + case FEET -> inventory.getBoots(); + case HAND -> inventory.getItemInHand(); + case HEAD -> inventory.getHelmet(); + case LEGS -> inventory.getLeggings(); + case OFF_HAND -> inventory.getItemInOffHand(); + + // there are 6 equipment slots on 1.9 + default -> null; + }; + } + + @Override + public EquipmentSlot getHand(PlayerInteractEvent event) { + return event.getHand(); + } + + @Override + public EquipmentSlot getHand(PlayerInteractEntityEvent event) { + return event.getHand(); + } +} diff --git a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/SmithingTaskType.java b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/SmithingTaskType.java index 3af221d3..fcc1540a 100644 --- a/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/SmithingTaskType.java +++ b/bukkit/src/main/java/com/leonardobishop/quests/bukkit/tasktype/type/SmithingTaskType.java @@ -11,6 +11,7 @@ import com.leonardobishop.quests.common.player.QPlayer; import com.leonardobishop.quests.common.player.questprogressfile.TaskProgress; import com.leonardobishop.quests.common.quest.Quest; import com.leonardobishop.quests.common.quest.Task; +import com.leonardobishop.quests.common.versioning.Version; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -37,7 +38,7 @@ public final class SmithingTaskType extends BukkitTaskType { super.addConfigValidator(TaskUtils.useIntegerConfigValidator(this, "data")); super.addConfigValidator(TaskUtils.useBooleanConfigValidator(this, "exact-match")); - if (plugin.getVersionSpecificHandler().getMinecraftVersion() < 20) { + if (plugin.getVersionSpecificHandler().getMinecraftVersion().isLowerThan(Version.V1_20)) { return; } -- cgit v1.2.3-70-g09d2