Grabbing a bundle from creative mode does work

This commit is contained in:
Camotoy 2024-11-12 19:54:48 -05:00
parent cde0cae776
commit 3236712e31
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
3 changed files with 17 additions and 10 deletions

View file

@ -41,7 +41,6 @@ import org.geysermc.geyser.inventory.click.Click;
import org.geysermc.geyser.inventory.click.ClickPlan; import org.geysermc.geyser.inventory.click.ClickPlan;
import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.session.cache.BundleCache; 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.InventoryUtils;
import org.geysermc.geyser.util.thirdparty.Fraction; import org.geysermc.geyser.util.thirdparty.Fraction;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType; 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; return slotData.getContainerName().getContainer() == ContainerSlotType.DYNAMIC_CONTAINER;
} }
static boolean isBundle(GeyserSession session, ClickPlan plan, int slot) { static boolean isBundle(ClickPlan plan, int slot) {
return isBundle(session, plan.getItem(slot)); return isBundle(plan.getItem(slot));
} }
static boolean isBundle(GeyserSession session, GeyserItemStack stack) { static boolean isBundle(GeyserItemStack stack) {
// Client as of 1.21.3 does use this return stack.getBundleData() != null;
return session.getTagCache().is(ItemTag.BUNDLES, stack);
} }
private BundleInventoryTranslator() { private BundleInventoryTranslator() {

View file

@ -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) if (InventoryUtils.canStack(cursor, plan.getItem(destSlot))) { //TODO: cannot simply swap if cursor stacks with slot (temp slot)
return rejectRequest(request); 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 } else if (isDestCursor) { //swap cursor
if (InventoryUtils.canStack(cursor, plan.getItem(sourceSlot))) { //TODO if (InventoryUtils.canStack(cursor, plan.getItem(sourceSlot))) { //TODO
return rejectRequest(request); 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 { } else {
if (!cursor.isEmpty()) { //TODO: (temp slot) if (!cursor.isEmpty()) { //TODO: (temp slot)
return rejectRequest(request); return rejectRequest(request);
@ -466,7 +466,7 @@ public abstract class InventoryTranslator {
return rejectRequest(request); return rejectRequest(request);
} }
plan.add(Click.LEFT, sourceSlot); //pickup source into cursor 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 plan.add(Click.LEFT, sourceSlot); //release cursor onto source
} }
break; break;

View file

@ -423,6 +423,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
@Override @Override
protected ItemStackResponse translateCreativeRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) { protected ItemStackResponse translateCreativeRequest(GeyserSession session, Inventory inventory, ItemStackRequest request) {
ItemStack javaCreativeItem = null; ItemStack javaCreativeItem = null;
boolean bundle = false;
IntSet affectedSlots = new IntOpenHashSet(); IntSet affectedSlots = new IntOpenHashSet();
CraftState craftState = CraftState.START; CraftState craftState = CraftState.START;
for (ItemStackRequestAction action : request.getActions()) { for (ItemStackRequestAction action : request.getActions()) {
@ -477,8 +478,10 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
if (isCursor(transferAction.getDestination())) { if (isCursor(transferAction.getDestination())) {
if (session.getPlayerInventory().getCursor().isEmpty()) { if (session.getPlayerInventory().getCursor().isEmpty()) {
GeyserItemStack newItemStack = GeyserItemStack.from(javaCreativeItem); GeyserItemStack newItemStack = GeyserItemStack.from(javaCreativeItem);
session.getBundleCache().initialize(newItemStack);
newItemStack.setAmount(transferAction.getCount()); newItemStack.setAmount(transferAction.getCount());
session.getPlayerInventory().setCursor(newItemStack, session); session.getPlayerInventory().setCursor(newItemStack, session);
bundle = newItemStack.getBundleData() != null;
} else { } else {
session.getPlayerInventory().getCursor().add(transferAction.getCount()); session.getPlayerInventory().getCursor().add(transferAction.getCount());
} }
@ -487,8 +490,10 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
int destSlot = bedrockSlotToJava(transferAction.getDestination()); int destSlot = bedrockSlotToJava(transferAction.getDestination());
if (inventory.getItem(destSlot).isEmpty()) { if (inventory.getItem(destSlot).isEmpty()) {
GeyserItemStack newItemStack = GeyserItemStack.from(javaCreativeItem); GeyserItemStack newItemStack = GeyserItemStack.from(javaCreativeItem);
session.getBundleCache().initialize(newItemStack);
newItemStack.setAmount(transferAction.getCount()); newItemStack.setAmount(transferAction.getCount());
inventory.setItem(destSlot, newItemStack, session); inventory.setItem(destSlot, newItemStack, session);
bundle = newItemStack.getBundleData() != null;
} else { } else {
inventory.getItem(destSlot).add(transferAction.getCount()); inventory.getItem(destSlot).add(transferAction.getCount());
} }
@ -528,7 +533,11 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
int slot = it.nextInt(); int slot = it.nextInt();
sendCreativeAction(session, inventory, slot); 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) { private static void sendCreativeAction(GeyserSession session, Inventory inventory, int slot) {