diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/BundleInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/BundleInventoryTranslator.java index b281945aa..44477945f 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/BundleInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/BundleInventoryTranslator.java @@ -41,7 +41,6 @@ import org.geysermc.geyser.inventory.click.Click; import org.geysermc.geyser.inventory.click.ClickPlan; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.cache.BundleCache; -import org.geysermc.geyser.session.cache.tags.ItemTag; import org.geysermc.geyser.util.InventoryUtils; import org.geysermc.geyser.util.thirdparty.Fraction; import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; @@ -318,13 +317,12 @@ public final class BundleInventoryTranslator { return slotData.getContainerName().getContainer() == ContainerSlotType.DYNAMIC_CONTAINER; } - static boolean isBundle(GeyserSession session, ClickPlan plan, int slot) { - return isBundle(session, plan.getItem(slot)); + static boolean isBundle(ClickPlan plan, int slot) { + return isBundle(plan.getItem(slot)); } - static boolean isBundle(GeyserSession session, GeyserItemStack stack) { - // Client as of 1.21.3 does use this - return session.getTagCache().is(ItemTag.BUNDLES, stack); + static boolean isBundle(GeyserItemStack stack) { + return stack.getBundleData() != null; } private BundleInventoryTranslator() { diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java index 6cbc81957..16be81e12 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java @@ -449,12 +449,12 @@ public abstract class InventoryTranslator { if (InventoryUtils.canStack(cursor, plan.getItem(destSlot))) { //TODO: cannot simply swap if cursor stacks with slot (temp slot) return rejectRequest(request); } - plan.add(isBundle(session, plan, destSlot) || isBundle(session, cursor) ? Click.RIGHT : Click.LEFT, destSlot); + plan.add(isBundle(plan, destSlot) || isBundle(cursor) ? Click.RIGHT : Click.LEFT, destSlot); } else if (isDestCursor) { //swap cursor if (InventoryUtils.canStack(cursor, plan.getItem(sourceSlot))) { //TODO return rejectRequest(request); } - plan.add(isBundle(session, plan, sourceSlot) || isBundle(session, cursor) ? Click.RIGHT : Click.LEFT, sourceSlot); + plan.add(isBundle(plan, sourceSlot) || isBundle(cursor) ? Click.RIGHT : Click.LEFT, sourceSlot); } else { if (!cursor.isEmpty()) { //TODO: (temp slot) return rejectRequest(request); @@ -466,7 +466,7 @@ public abstract class InventoryTranslator { return rejectRequest(request); } plan.add(Click.LEFT, sourceSlot); //pickup source into cursor - plan.add(isBundle(session, plan, sourceSlot) || isBundle(session, plan, destSlot) ? Click.RIGHT : Click.LEFT, destSlot); //swap cursor with dest slot + plan.add(isBundle(plan, sourceSlot) || isBundle(plan, destSlot) ? Click.RIGHT : Click.LEFT, destSlot); //swap cursor with dest slot plan.add(Click.LEFT, sourceSlot); //release cursor onto source } break; diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java index 7eefffa3e..e8548745e 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java @@ -423,6 +423,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator { @Override protected ItemStackResponse translateCreativeRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { ItemStack javaCreativeItem = null; + boolean bundle = false; IntSet affectedSlots = new IntOpenHashSet(); CraftState craftState = CraftState.START; for (ItemStackRequestAction action : request.getActions()) { @@ -477,8 +478,10 @@ public class PlayerInventoryTranslator extends InventoryTranslator { if (isCursor(transferAction.getDestination())) { if (session.getPlayerInventory().getCursor().isEmpty()) { GeyserItemStack newItemStack = GeyserItemStack.from(javaCreativeItem); + session.getBundleCache().initialize(newItemStack); newItemStack.setAmount(transferAction.getCount()); session.getPlayerInventory().setCursor(newItemStack, session); + bundle = newItemStack.getBundleData() != null; } else { session.getPlayerInventory().getCursor().add(transferAction.getCount()); } @@ -487,8 +490,10 @@ public class PlayerInventoryTranslator extends InventoryTranslator { int destSlot = bedrockSlotToJava(transferAction.getDestination()); if (inventory.getItem(destSlot).isEmpty()) { GeyserItemStack newItemStack = GeyserItemStack.from(javaCreativeItem); + session.getBundleCache().initialize(newItemStack); newItemStack.setAmount(transferAction.getCount()); inventory.setItem(destSlot, newItemStack, session); + bundle = newItemStack.getBundleData() != null; } else { inventory.getItem(destSlot).add(transferAction.getCount()); } @@ -528,7 +533,11 @@ public class PlayerInventoryTranslator extends InventoryTranslator { int slot = it.nextInt(); sendCreativeAction(session, inventory, slot); } - return acceptRequest(request, makeContainerEntries(session, inventory, affectedSlots)); + // On the bundle check: + // We can also accept the request, but sending a bad request indicates to Geyser to refresh the inventory + // and we need to refresh the inventory to send the bundle ID/inventory to the client. + // It's not great, but I don't want to create a container class for request responses + return bundle ? rejectRequest(request, false) : acceptRequest(request, makeContainerEntries(session, inventory, affectedSlots)); } private static void sendCreativeAction(GeyserSession session, Inventory inventory, int slot) {