Skip to content

Commit a0e0fb0

Browse files
committed
Fix Player#closeInventory implementation and ignore InteractInventoryEvent.Close cancelled result if it was caused by client input
Fixes #1404 Signed-off-by: Walker Crouse <walkercrouse@hotmail.com>
1 parent a6c16aa commit a0e0fb0

File tree

3 files changed

+31
-20
lines changed

3 files changed

+31
-20
lines changed

src/main/java/org/spongepowered/common/event/SpongeCommonEventFactory.java

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import net.minecraft.entity.player.EntityPlayerMP;
4040
import net.minecraft.entity.player.InventoryPlayer;
4141
import net.minecraft.inventory.Container;
42+
import net.minecraft.inventory.ContainerPlayer;
4243
import net.minecraft.inventory.IInventory;
4344
import net.minecraft.inventory.Slot;
4445
import net.minecraft.item.ItemStack;
@@ -103,8 +104,8 @@
103104
import org.spongepowered.common.interfaces.world.IMixinWorldServer;
104105
import org.spongepowered.common.item.inventory.SpongeItemStackSnapshot;
105106
import org.spongepowered.common.item.inventory.adapter.impl.slots.SlotAdapter;
106-
import org.spongepowered.common.item.inventory.util.ItemStackUtil;
107107
import org.spongepowered.common.item.inventory.util.ContainerUtil;
108+
import org.spongepowered.common.item.inventory.util.ItemStackUtil;
108109
import org.spongepowered.common.registry.provider.DirectionFacingProvider;
109110
import org.spongepowered.common.text.SpongeTexts;
110111
import org.spongepowered.common.util.VecHelper;
@@ -544,28 +545,34 @@ public static boolean callInteractInventoryOpenEvent(Cause cause, EntityPlayerMP
544545
}
545546
}
546547

547-
public static InteractInventoryEvent.Close callInteractInventoryCloseEvent(Cause cause, Container container, EntityPlayerMP player, ItemStackSnapshot lastCursor, ItemStackSnapshot newCursor) {
548+
public static InteractInventoryEvent.Close callInteractInventoryCloseEvent(Cause cause, Container container, EntityPlayerMP player, ItemStackSnapshot lastCursor, ItemStackSnapshot newCursor, boolean clientSource) {
548549
Transaction<ItemStackSnapshot> cursorTransaction = new Transaction<>(lastCursor, newCursor);
549-
final InteractInventoryEvent.Close
550-
event =
551-
SpongeEventFactory.createInteractInventoryEventClose(cause, cursorTransaction, ContainerUtil.fromNative(container));
550+
final InteractInventoryEvent.Close event
551+
= SpongeEventFactory.createInteractInventoryEventClose(cause, cursorTransaction, ContainerUtil.fromNative(container));
552552
SpongeImpl.postEvent(event);
553553
if (event.isCancelled()) {
554-
if (container.getSlot(0) != null) {
555-
player.openContainer = container;
556-
final Slot slot = container.getSlot(0);
557-
final String guiId;
558-
final IInventory slotInventory = slot.inventory;
559-
if (slotInventory instanceof IInteractionObject) {
560-
guiId = ((IInteractionObject) slotInventory).getGuiID();
554+
if (clientSource && container.getSlot(0) != null) {
555+
if (!(container instanceof ContainerPlayer)) {
556+
// Inventory closed by client, reopen window and send container
557+
player.openContainer = container;
558+
final String guiId;
559+
final Slot slot = container.getSlot(0);
560+
final IInventory slotInventory = slot.inventory;
561+
if (slotInventory instanceof IInteractionObject) {
562+
guiId = ((IInteractionObject) slotInventory).getGuiID();
563+
} else {
564+
guiId = "minecraft:container"; // expected fallback for unknown types
565+
}
566+
slotInventory.openInventory(player);
567+
player.connection.sendPacket(new SPacketOpenWindow(container.windowId, guiId, slotInventory
568+
.getDisplayName(), slotInventory.getSizeInventory()));
569+
// resync data to client
570+
player.sendContainerToPlayer(container);
561571
} else {
562-
guiId = "unknown";
572+
// TODO: Maybe print a warning or throw an exception here? The player gui cannot be opened from the
573+
// server so allowing this event to be cancellable when the GUI has been closed already would result
574+
// in opening the wrong GUI window.
563575
}
564-
slotInventory.openInventory(player);
565-
player.connection.sendPacket(new SPacketOpenWindow(container.windowId, guiId, slotInventory
566-
.getDisplayName(), slotInventory.getSizeInventory()));
567-
// resync data to client
568-
player.sendContainerToPlayer(container);
569576
}
570577
} else {
571578
IMixinContainer mixinContainer = (IMixinContainer) player.openContainer;
@@ -575,7 +582,11 @@ public static InteractInventoryEvent.Close callInteractInventoryCloseEvent(Cause
575582
if (event.getCursorTransaction().getCustom().isPresent()) {
576583
handleCustomCursor(player, event.getCursorTransaction().getFinal());
577584
}
585+
if (!clientSource) {
586+
player.closeScreen();
587+
}
578588
}
589+
579590
return event;
580591
}
581592

src/main/java/org/spongepowered/common/event/tracking/phase/packet/PacketFunction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ static void processEntities(EntityPlayerMP player, CauseTracker causeTracker, Co
842842
.orElseThrow(TrackingUtil.throwWithContext("Expected a cursor item stack, but had nothing!", context));
843843
ItemStackSnapshot newCursor = ItemStackUtil.snapshotOf(player.inventory.getItemStack());
844844
final Cause cause = Cause.source(player).build();
845-
InteractInventoryEvent.Close event = SpongeCommonEventFactory.callInteractInventoryCloseEvent(cause, container, player, lastCursor, newCursor);
845+
InteractInventoryEvent.Close event = SpongeCommonEventFactory.callInteractInventoryCloseEvent(cause, container, player, lastCursor, newCursor, true);
846846
if (!event.isCancelled()) {
847847
// Non-merged items
848848
context.getCapturedItemsSupplier().ifPresentAndNotEmpty(items -> {

src/main/java/org/spongepowered/common/mixin/core/entity/player/MixinEntityPlayerMP.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ public Optional<Container> openInventory(Inventory inventory, Cause cause) throw
501501
@Override
502502
public boolean closeInventory(Cause cause) throws IllegalArgumentException {
503503
ItemStackSnapshot cursor = ItemStackUtil.snapshotOf(this.inventory.getItemStack());
504-
return !SpongeCommonEventFactory.callInteractInventoryCloseEvent(cause, this.openContainer, this$, cursor, cursor).isCancelled();
504+
return !SpongeCommonEventFactory.callInteractInventoryCloseEvent(cause, this.openContainer, this.this$, cursor, cursor, false).isCancelled();
505505
}
506506

507507
@Override

0 commit comments

Comments
 (0)