From 1e956f1e5748c0c2a73657f574f8778e0640faef Mon Sep 17 00:00:00 2001 From: jhqwqmc <2110242767@qq.com> Date: Wed, 12 Feb 2025 04:38:59 +0800 Subject: [PATCH] =?UTF-8?q?refactor(bukkit):=20=E4=BC=98=E5=8C=96=E9=BC=A0?= =?UTF-8?q?=E6=A0=87=E4=B8=AD=E9=94=AE=E8=8E=B7=E5=8F=96=E7=89=A9=E5=93=81?= =?UTF-8?q?=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 ItemUtils.setItem 方法,使用反射设置玩家背包中的物品 - 在 PacketConsumers 类中使用新的 setItem 方法替换原有的直接设置物品方式 - 添加 Reflections 类中的相关字段,用于物品设置的反射操作 --- .../plugin/network/PacketConsumers.java | 28 +++++++++---------- .../craftengine/bukkit/util/ItemUtils.java | 24 ++++++++++++++++ .../craftengine/bukkit/util/Reflections.java | 13 +++++++++ 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index f6e4ed33d..51c2ed804 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -339,26 +339,26 @@ public class PacketConsumers { if (sameItemSlot < 9) { inventory.setHeldItemSlot(sameItemSlot); ItemStack previousItem = inventory.getItem(slot - 36); - BukkitCraftEngine.instance().scheduler().sync().runDelayed(() -> inventory.setItem(slot - 36, previousItem)); + BukkitCraftEngine.instance().scheduler().sync().runDelayed(() -> ItemUtils.setItem(inventory, slot - 36, previousItem)); } else { ItemStack sameItem = inventory.getItem(sameItemSlot); int finalSameItemSlot = sameItemSlot; BukkitCraftEngine.instance().scheduler().sync().runDelayed(() -> { - inventory.setItem(finalSameItemSlot, new ItemStack(Material.AIR)); - inventory.setItem(slot - 36, sameItem); + ItemUtils.setItem(inventory, finalSameItemSlot, new ItemStack(Material.AIR)); + ItemUtils.setItem(inventory, slot - 36, sameItem); }); } } else { if (item.getAmount() == 1) { if (ItemUtils.isEmpty(inventory.getItem(slot - 36))) { - BukkitCraftEngine.instance().scheduler().sync().runDelayed(() -> inventory.setItem(slot - 36, itemStack)); + BukkitCraftEngine.instance().scheduler().sync().runDelayed(() -> ItemUtils.setItem(inventory, slot - 36, itemStack)); return; } if (emptySlot != -1) { inventory.setHeldItemSlot(emptySlot); - inventory.setItem(emptySlot, itemStack); + ItemUtils.setItem(inventory, emptySlot, itemStack); } else { - BukkitCraftEngine.instance().scheduler().sync().runDelayed(() -> inventory.setItem(slot - 36, itemStack)); + BukkitCraftEngine.instance().scheduler().sync().runDelayed(() -> ItemUtils.setItem(inventory, slot - 36, itemStack)); } } } @@ -395,9 +395,9 @@ public class PacketConsumers { if (picked == null) return; inventory.setHeldItemSlot(targetSlot); ItemStack previous = inventory.getItem(targetSlot); - inventory.setItem(targetSlot, picked.clone()); + ItemUtils.setItem(inventory, targetSlot, picked.clone()); if (previous != null) { - inventory.setItem(matchingSlot, previous); + ItemUtils.setItem(inventory, targetSlot, previous); } else { picked.setAmount(0); } @@ -405,13 +405,13 @@ public class PacketConsumers { } else if (player.getGameMode() == GameMode.CREATIVE) { inventory.setHeldItemSlot(targetSlot); ItemStack previous = inventory.getItem(targetSlot); - inventory.setItem(targetSlot, itemStack); + ItemUtils.setItem(inventory, targetSlot, itemStack); if (previous != null) { for (int j = 1; j <= 3; j++) { for (int i = j * 9; i < j * 9 + 9; i++) { ItemStack itemInSlot = inventory.getItem(i); if (ItemUtils.isEmpty(itemInSlot)) { - inventory.setItem(i, previous); + ItemUtils.setItem(inventory, i, previous); return; } } @@ -448,9 +448,9 @@ public class PacketConsumers { if (picked == null) return; inventory.setHeldItemSlot(targetSlot); ItemStack previous = inventory.getItem(targetSlot); - inventory.setItem(targetSlot, picked.clone()); + ItemUtils.setItem(inventory, targetSlot, picked.clone()); if (previous != null) { - inventory.setItem(matchingSlot, previous); + ItemUtils.setItem(inventory, matchingSlot, previous); } else { picked.setAmount(0); } @@ -458,13 +458,13 @@ public class PacketConsumers { } else if (player.getGameMode() == GameMode.CREATIVE) { inventory.setHeldItemSlot(targetSlot); ItemStack previous = inventory.getItem(targetSlot); - inventory.setItem(targetSlot, itemStack); + ItemUtils.setItem(inventory, targetSlot, itemStack); if (previous != null) { for (int j = 1; j <= 3; j++) { for (int i = j * 9; i < j * 9 + 9; i++) { ItemStack itemInSlot = inventory.getItem(i); if (ItemUtils.isEmpty(itemInSlot)) { - inventory.setItem(i, previous); + ItemUtils.setItem(inventory, i, previous); return; } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ItemUtils.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ItemUtils.java index c88a13ee5..a46fce973 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ItemUtils.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/ItemUtils.java @@ -1,9 +1,14 @@ package net.momirealms.craftengine.bukkit.util; +import net.momirealms.craftengine.core.plugin.CraftEngine; +import net.momirealms.craftengine.core.util.VersionHelper; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; import org.jetbrains.annotations.Contract; +import java.lang.reflect.InvocationTargetException; + public class ItemUtils { @Contract("null -> true") @@ -12,4 +17,23 @@ public class ItemUtils { if (item.getType() == Material.AIR) return true; return item.getAmount() == 0; } + + public static void setItem(PlayerInventory inventory, int slot, ItemStack itemStack) { + try { + Object nmsInventory$getInventory = Reflections.clazz$CraftInventoryPlayer + .getMethod("getInventory").invoke(inventory); + Object nmsInventory$items = Reflections.clazz$Inventory + .getDeclaredField(VersionHelper.isMojmap() ? "items" : "i") + .get(nmsInventory$getInventory); + Object nmsItemStack = Reflections.clazz$CraftItemStack + .getMethod("asNMSCopy", ItemStack.class) + .invoke(null, itemStack); + nmsInventory$items.getClass() + .getMethod("set", int.class, Object.class) + .invoke(nmsInventory$items, slot, nmsItemStack); + } catch (InvocationTargetException | IllegalAccessException | + NoSuchMethodException | NoSuchFieldException e) { + CraftEngine.instance().logger().warn("Failed to set item", e); + } + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java index 09e4c9847..815e606b3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/util/Reflections.java @@ -3881,4 +3881,17 @@ public class Reflections { ReflectionUtils.getDeclaredField( clazz$RecipeManager, clazz$FeatureFlagSet, 0 ); + + public static final Class clazz$CraftInventoryPlayer = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleCBClass("inventory.CraftInventoryPlayer") + ) + ); + + public static final Class clazz$Inventory = requireNonNull( + ReflectionUtils.getClazz( + BukkitReflectionUtils.assembleMCClass("world.entity.player.Inventory"), + BukkitReflectionUtils.assembleMCClass("world.entity.player.PlayerInventory") + ) + ); }