9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-25 01:49:30 +00:00

Merge pull request #4 from jhqwqmc/main

refactor(bukkit): 优化鼠标中键获取物品操作
This commit is contained in:
XiaoMoMi
2025-02-12 16:20:16 +08:00
committed by GitHub
4 changed files with 77 additions and 9 deletions

View File

@@ -16,6 +16,7 @@ import net.momirealms.craftengine.core.entity.player.InteractionHand;
import net.momirealms.craftengine.core.item.Item;
import net.momirealms.craftengine.core.loot.parameter.LootParameters;
import net.momirealms.craftengine.core.plugin.config.ConfigManager;
import net.momirealms.craftengine.core.util.Key;
import net.momirealms.craftengine.core.util.context.ContextHolder;
import net.momirealms.craftengine.core.world.BlockPos;
import net.momirealms.craftengine.core.world.CEWorld;
@@ -120,8 +121,14 @@ public class BlockEventListener implements Listener {
BukkitServerPlayer serverPlayer = plugin.adapt(player);
Item<ItemStack> itemInHand = serverPlayer.getItemInHand(InteractionHand.MAIN_HAND);
Key itemId;
if (itemInHand == null) {
itemId = Key.of("minecraft:air");
} else {
itemId = itemInHand.id();
}
// do not drop if it's not the correct tool
if (!state.settings().isCorrectTool(itemInHand.id())) {
if (!state.settings().isCorrectTool(itemId)) {
return;
}
// drop items

View File

@@ -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, matchingSlot, 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,13 @@
package net.momirealms.craftengine.bukkit.util;
import net.momirealms.craftengine.core.plugin.CraftEngine;
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 +16,19 @@ 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 = Reflections.method$CraftInventoryPlayer$getInventory
.invoke(inventory);
Object nmsInventory$items = Reflections.field$Inventory$items
.get(nmsInventory);
Object nmsItemStack = Reflections.method$CraftItemStack$asNMSMirror
.invoke(null, itemStack);
Reflections.method$NonNullList$set
.invoke(nmsInventory$items, slot, nmsItemStack);
} catch (InvocationTargetException | IllegalAccessException e) {
CraftEngine.instance().logger().warn("Failed to set item", e);
}
}
}

View File

@@ -41,6 +41,7 @@ public class Reflections {
}
public static final Unsafe UNSAFE;
public static final String INVENTORY$ITEMS = VersionHelper.isMojmap() ? "items" : "i";
static {
try {
@@ -3881,4 +3882,45 @@ 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")
)
);
public static final Method method$CraftInventoryPlayer$getInventory = requireNonNull(
ReflectionUtils.getMethod(
clazz$CraftInventoryPlayer,
new String[]{ "getInventory" }
)
);
public static final Field field$Inventory$items = requireNonNull(
ReflectionUtils.getDeclaredField(
clazz$Inventory,
INVENTORY$ITEMS
)
);
public static final Class<?> clazz$NonNullList = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("core.NonNullList")
)
);
public static final Method method$NonNullList$set = requireNonNull(
ReflectionUtils.getMethod(
clazz$NonNullList,
Object.class,
int.class,
Object.class
)
);
}