Skip to content

Commit

Permalink
fixed a timing-based item-duplication-glitch for both survival- and c…
Browse files Browse the repository at this point in the history
…reative-mode
  • Loading branch information
BlvckBytes committed Nov 8, 2024
1 parent 74a9049 commit c87979f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,22 @@ public class ResultDisplay implements ShopDistanceProvider {
private int numberOfPages;
public final SelectionState selectionState;

// If players move to their own inventory and close the UI quickly enough, the server will send back a packet
// undoing that slot which assumed the top-inventory to still be open, and thus the undo won't work. For survival,
// it's merely cosmetic, but for creative, the client will actually call this item into existence. While not
// necessarily critical, it just makes the plugin look bad. On closing the inventory, if the last move happened
// within a certain threshold of time, let's just update the player's inventory, as to make that ghost-item vanish.
public long lastMoveToOwnInventoryStamp;

private IEvaluationEnvironment pageEnvironment;
private IEvaluationEnvironment sortingEnvironment;
private IEvaluationEnvironment filteringEnvironment;

private Inventory inventory;
private int currentPage = 1;

// TODO: Do not render whole UI only because selection-state is changed

public ResultDisplay(
PlatformScheduler scheduler,
ConfigKeeper<MainSection> config,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.*;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.util.Vector;
Expand All @@ -34,6 +31,7 @@

public class ResultDisplayHandler implements Listener {

private static final long MOVE_GHOST_ITEM_THRESHOLD_MS = 500;
private static final double PLAYER_EYE_HEIGHT = 1.5;

private static final BlockFace[] SHOP_SIGN_FACES = new BlockFace[] {
Expand Down Expand Up @@ -87,6 +85,13 @@ public void onInventoryClose(InventoryCloseEvent event) {
if (display != null && display.isInventory(event.getInventory())) {
display.cleanup(false);
displayByPlayer.remove(playerId);

if (
display.lastMoveToOwnInventoryStamp != 0 &&
System.currentTimeMillis() - display.lastMoveToOwnInventoryStamp < MOVE_GHOST_ITEM_THRESHOLD_MS
) {
scheduler.runNextTick(task -> player.updateInventory());
}
}
}

Expand All @@ -105,11 +110,21 @@ public void onInventoryClick(InventoryClickEvent event) {

var display = displayByPlayer.get(player.getUniqueId());

if (display == null || !display.isInventory(player.getOpenInventory().getTopInventory()))
if (display == null)
return;

event.setCancelled(true);

if (
event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY &&
event.getClickedInventory() != player.getInventory()
) {
display.lastMoveToOwnInventoryStamp = System.currentTimeMillis();
}

if (!display.isInventory(player.getOpenInventory().getTopInventory()))
return;

var slot = event.getRawSlot();

if (slot < 0 || slot >= config.rootSection.resultDisplay.getRows() * 9)
Expand Down Expand Up @@ -361,12 +376,8 @@ public void onInventoryDrag(InventoryDragEvent event) {
if (!(event.getWhoClicked() instanceof Player player))
return;

var display = displayByPlayer.get(player.getUniqueId());

if (display == null || display.isInventory(event.getInventory()))
return;

event.setCancelled(true);
if (displayByPlayer.containsKey(player.getUniqueId()))
event.setCancelled(true);
}

public void onShutdown() {
Expand Down

0 comments on commit c87979f

Please sign in to comment.