3939import net .minecraft .entity .player .EntityPlayerMP ;
4040import net .minecraft .entity .player .InventoryPlayer ;
4141import net .minecraft .inventory .Container ;
42+ import net .minecraft .inventory .ContainerPlayer ;
4243import net .minecraft .inventory .IInventory ;
4344import net .minecraft .inventory .Slot ;
4445import net .minecraft .item .ItemStack ;
103104import org .spongepowered .common .interfaces .world .IMixinWorldServer ;
104105import org .spongepowered .common .item .inventory .SpongeItemStackSnapshot ;
105106import org .spongepowered .common .item .inventory .adapter .impl .slots .SlotAdapter ;
106- import org .spongepowered .common .item .inventory .util .ItemStackUtil ;
107107import org .spongepowered .common .item .inventory .util .ContainerUtil ;
108+ import org .spongepowered .common .item .inventory .util .ItemStackUtil ;
108109import org .spongepowered .common .registry .provider .DirectionFacingProvider ;
109110import org .spongepowered .common .text .SpongeTexts ;
110111import 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
0 commit comments