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

This commit is contained in:
nossr50 2024-07-13 14:47:42 -07:00
parent 99d8b64589
commit ce8464fcfe
2 changed files with 42 additions and 20 deletions

View File

@ -1,4 +1,5 @@
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)
Fixed a bug with Mace permissions (thanks SrBedrock)
Updated zh_CN locale (thanks libook)

View File

@ -23,12 +23,29 @@ import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
// TODO: Update to use McMMOPlayer
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")
public static boolean isValidBrew(Player player, ItemStack[] contents) {
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) {
boolean success = false;
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;
}
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)) {
return false;
@ -271,8 +293,8 @@ public final class AlchemyPotionBrewer {
}
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;
}
@ -283,16 +305,15 @@ public final class AlchemyPotionBrewer {
/**
* 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)) {
return false;
} 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;
} else if (from.isSimilar(to)) {
int fromAmount = from.getAmount();
@ -303,17 +324,17 @@ public final class AlchemyPotionBrewer {
int left = fromAmount + toAmount - maxSize;
to.setAmount(maxSize);
view.setItem(Alchemy.INGREDIENT_SLOT, to);
setItem.invoke(view, Alchemy.INGREDIENT_SLOT, to);
from.setAmount(left);
view.setItem(fromSlot, from);
setItem.invoke(view, fromSlot, from);
return true;
}
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;
}