2
0
Эх сурвалжийг харах

Fixed alchemy shift-click exceptions on older MC versions Fixes #5046 Fixes #5039

nossr50 1 жил өмнө
parent
commit
ce8464fcfe

+ 1 - 0
Changelog.txt

@@ -1,4 +1,5 @@
 Version 2.2.017
 Version 2.2.017
+    Fixed shift-clicking ingredients into the brewing stand not working on older versions of Minecraft
     Added a setting in advanced.yml to ignore attack cooldowns (see notes)
     Added a setting in advanced.yml to ignore attack cooldowns (see notes)
     Fixed a bug with Mace permissions (thanks SrBedrock)
     Fixed a bug with Mace permissions (thanks SrBedrock)
     Updated zh_CN locale (thanks libook)
     Updated zh_CN locale (thanks libook)

+ 41 - 20
src/main/java/com/gmail/nossr50/skills/alchemy/AlchemyPotionBrewer.java

@@ -23,12 +23,29 @@ import org.bukkit.inventory.ItemStack;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.annotations.Nullable;
 
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Collections;
 import java.util.List;
 import java.util.List;
 
 
 // TODO: Update to use McMMOPlayer
 // TODO: Update to use McMMOPlayer
 public final class AlchemyPotionBrewer {
 public final class AlchemyPotionBrewer {
+    /*
+     * Compatibility with older versions where InventoryView used to be an abstract class and became an interface.
+     * This was introduced in Minecraft 1.21 if we drop support for versions older than 1.21 this can be removed.
+     */
+    private static final Method getItem, setItem;
+    static {
+        try {
+            final Class<?> clazz = Class.forName("org.bukkit.inventory.InventoryView");
+            getItem = clazz.getDeclaredMethod("getItem", int.class);
+            setItem = clazz.getDeclaredMethod("setItem", int.class, ItemStack.class);
+        } catch (NoSuchMethodException | ClassNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     @Deprecated(forRemoval = true, since = "2.2.010")
     @Deprecated(forRemoval = true, since = "2.2.010")
     public static boolean isValidBrew(Player player, ItemStack[] contents) {
     public static boolean isValidBrew(Player player, ItemStack[] contents) {
         if (!isValidIngredientByPlayer(player, contents[Alchemy.INGREDIENT_SLOT])) {
         if (!isValidIngredientByPlayer(player, contents[Alchemy.INGREDIENT_SLOT])) {
@@ -240,18 +257,23 @@ public final class AlchemyPotionBrewer {
     public static boolean transferItems(InventoryView view, int fromSlot, ClickType click) {
     public static boolean transferItems(InventoryView view, int fromSlot, ClickType click) {
         boolean success = false;
         boolean success = false;
 
 
-        if (click.isLeftClick()) {
-            success = transferItems(view, fromSlot);
-        } else if (click.isRightClick()) {
-            success = transferOneItem(view, fromSlot);
+        try {
+            if (click.isLeftClick()) {
+                success = transferItems(view, fromSlot);
+            } else if (click.isRightClick()) {
+                success = transferOneItem(view, fromSlot);
+            }
+        } catch (InvocationTargetException | IllegalAccessException e) {
+            throw new RuntimeException(e);
         }
         }
 
 
         return success;
         return success;
     }
     }
 
 
-    private static boolean transferOneItem(InventoryView view, int fromSlot) {
-        ItemStack from = view.getItem(fromSlot).clone();
-        ItemStack to = view.getItem(Alchemy.INGREDIENT_SLOT).clone();
+    private static boolean transferOneItem(InventoryView view, int fromSlot)
+            throws InvocationTargetException, IllegalAccessException {
+        final ItemStack from = ((ItemStack) getItem.invoke(view, fromSlot)).clone();
+        ItemStack to = ((ItemStack) getItem.invoke(view, Alchemy.INGREDIENT_SLOT)).clone();
 
 
         if (isEmpty(from)) {
         if (isEmpty(from)) {
             return false;
             return false;
@@ -271,8 +293,8 @@ public final class AlchemyPotionBrewer {
             }
             }
 
 
             from.setAmount(fromAmount - 1);
             from.setAmount(fromAmount - 1);
-            view.setItem(Alchemy.INGREDIENT_SLOT, to);
-            view.setItem(fromSlot, from);
+            setItem.invoke(view, Alchemy.INGREDIENT_SLOT, to);
+            setItem.invoke(view, fromSlot, from);
 
 
             return true;
             return true;
         }
         }
@@ -283,16 +305,15 @@ public final class AlchemyPotionBrewer {
     /**
     /**
      * Transfer items between two ItemStacks, returning the leftover status
      * Transfer items between two ItemStacks, returning the leftover status
      */
      */
-    private static boolean transferItems(InventoryView view, int fromSlot) {
-        ItemStack from = view.getItem(fromSlot).clone();
-        ItemStack to = view.getItem(Alchemy.INGREDIENT_SLOT).clone();
-
+    private static boolean transferItems(InventoryView view, int fromSlot)
+            throws InvocationTargetException, IllegalAccessException {
+        final ItemStack from = ((ItemStack) getItem.invoke(view, fromSlot)).clone();
+        final ItemStack to = ((ItemStack) getItem.invoke(view, Alchemy.INGREDIENT_SLOT)).clone();
         if (isEmpty(from)) {
         if (isEmpty(from)) {
             return false;
             return false;
         } else if (isEmpty(to)) {
         } else if (isEmpty(to)) {
-            view.setItem(Alchemy.INGREDIENT_SLOT, from);
-            view.setItem(fromSlot, null);
-
+            setItem.invoke(view, Alchemy.INGREDIENT_SLOT, from);
+            setItem.invoke(view, fromSlot, null);
             return true;
             return true;
         } else if (from.isSimilar(to)) {
         } else if (from.isSimilar(to)) {
             int fromAmount = from.getAmount();
             int fromAmount = from.getAmount();
@@ -303,17 +324,17 @@ public final class AlchemyPotionBrewer {
                 int left = fromAmount + toAmount - maxSize;
                 int left = fromAmount + toAmount - maxSize;
 
 
                 to.setAmount(maxSize);
                 to.setAmount(maxSize);
-                view.setItem(Alchemy.INGREDIENT_SLOT, to);
+                setItem.invoke(view, Alchemy.INGREDIENT_SLOT, to);
 
 
                 from.setAmount(left);
                 from.setAmount(left);
-                view.setItem(fromSlot, from);
+                setItem.invoke(view, fromSlot, from);
 
 
                 return true;
                 return true;
             }
             }
 
 
             to.setAmount(fromAmount + toAmount);
             to.setAmount(fromAmount + toAmount);
-            view.setItem(fromSlot, null);
-            view.setItem(Alchemy.INGREDIENT_SLOT, to);
+            setItem.invoke(view, fromSlot, null);
+            setItem.invoke(view, Alchemy.INGREDIENT_SLOT, to);
 
 
             return true;
             return true;
         }
         }