9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-25 09:59:20 +00:00

refactor(bukkit): 优化鼠标中键获取物品操作

- 新增 ItemUtils.setItem 方法,使用反射设置玩家背包中的物品
- 在 PacketConsumers 类中使用新的 setItem 方法替换原有的直接设置物品方式
- 添加 Reflections 类中的相关字段,用于物品设置的反射操作
This commit is contained in:
jhqwqmc
2025-02-12 04:38:59 +08:00
parent be601742c3
commit 1e956f1e57
3 changed files with 51 additions and 14 deletions

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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")
)
);
}