From aa55472c1a21f0b3213ebbec49d8bc5b0d0f4099 Mon Sep 17 00:00:00 2001 From: Intelli Date: Wed, 21 Jul 2021 18:47:23 -0600 Subject: [PATCH] Utilize item caching on invalid hopper events --- .../net/coreprotect/config/ConfigHandler.java | 2 +- .../listener/player/HopperPullListener.java | 43 +++++++++++++------ .../listener/player/HopperPushListener.java | 32 ++++++++++++-- .../player/InventoryChangeListener.java | 14 +++--- 4 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/main/java/net/coreprotect/config/ConfigHandler.java b/src/main/java/net/coreprotect/config/ConfigHandler.java index b2698fa..97b454a 100644 --- a/src/main/java/net/coreprotect/config/ConfigHandler.java +++ b/src/main/java/net/coreprotect/config/ConfigHandler.java @@ -85,7 +85,7 @@ public class ConfigHandler extends Queue { public static ConcurrentHashMap> oldContainer = new ConcurrentHashMap<>(); public static ConcurrentHashMap> itemsDrop = new ConcurrentHashMap<>(); public static ConcurrentHashMap> itemsPickup = new ConcurrentHashMap<>(); - public static ConcurrentHashMap hopperAbort = new ConcurrentHashMap<>(); + public static ConcurrentHashMap hopperAbort = new ConcurrentHashMap<>(); public static Map> forceContainer = syncMap(); public static Map lookupType = syncMap(); public static Map lookupThrottle = syncMap(); diff --git a/src/main/java/net/coreprotect/listener/player/HopperPullListener.java b/src/main/java/net/coreprotect/listener/player/HopperPullListener.java index 3520c6e..99add06 100644 --- a/src/main/java/net/coreprotect/listener/player/HopperPullListener.java +++ b/src/main/java/net/coreprotect/listener/player/HopperPullListener.java @@ -1,6 +1,9 @@ package net.coreprotect.listener.player; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -15,12 +18,22 @@ import net.coreprotect.utility.Util; public final class HopperPullListener { - static void processHopperPull(Location location, InventoryHolder sourceHolder, InventoryHolder destinationHolder, ItemStack item, ItemStack movedItem) { + static void processHopperPull(Location location, InventoryHolder sourceHolder, InventoryHolder destinationHolder, ItemStack item) { + String loggingChestId = "#hopper-pull." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ(); + Object[] lastAbort = ConfigHandler.hopperAbort.get(loggingChestId); + if (lastAbort != null) { + ItemStack[] destinationContents = destinationHolder.getInventory().getContents(); + if (((Set) lastAbort[0]).contains(item) && Arrays.equals(destinationContents, (ItemStack[]) lastAbort[1])) { + return; + } + } + ItemStack[] containerState = null; if (!ConfigHandler.isPaper) { containerState = Util.getContainerState(sourceHolder.getInventory().getContents()); } ItemStack[] sourceContainer = containerState; + ItemStack movedItem = item.clone(); final long taskStarted = InventoryChangeListener.tasksStarted.incrementAndGet(); Bukkit.getServer().getScheduler().runTaskAsynchronously(CoreProtect.getInstance(), () -> { @@ -32,13 +45,9 @@ public final class HopperPullListener { boolean hopperTransactions = Config.getConfig(location.getWorld()).HOPPER_TRANSACTIONS; int itemHash = Util.getItemStackHashCode(item); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - String loggingChestId = "#hopper." + x + "." + y + "." + z; + boolean abort = false; if (ConfigHandler.isPaper) { - boolean abort = false; for (ItemStack itemStack : sourceHolder.getInventory().getContents()) { if (itemStack != null && Util.getItemStackHashCode(itemStack) == itemHash) { abort = true; @@ -53,22 +62,28 @@ public final class HopperPullListener { break; } } - - if (abort) { - ConfigHandler.hopperAbort.put(loggingChestId, true); - return; - } } } else { ItemStack[] sourceContents = sourceHolder.getInventory().getContents(); boolean addedInventory = Util.addedContainer(sourceContainer, sourceContents); if (addedInventory) { - ConfigHandler.hopperAbort.put(loggingChestId, true); - return; + abort = true; } } + if (abort) { + Set movedItems = new HashSet<>(); + ItemStack[] destinationContents = destinationHolder.getInventory().getContents(); + if (lastAbort != null && Arrays.equals(destinationContents, (ItemStack[]) lastAbort[1])) { + ((Set) lastAbort[0]).forEach(itemStack -> movedItems.add((ItemStack) itemStack)); + } + movedItems.add(movedItem); + + ConfigHandler.hopperAbort.put(loggingChestId, new Object[] { movedItems, Util.getContainerState(destinationContents) }); + return; + } + boolean lastAborted = false; if (ConfigHandler.hopperAbort.get(loggingChestId) != null) { ConfigHandler.hopperAbort.remove(loggingChestId); @@ -78,7 +93,7 @@ public final class HopperPullListener { boolean mergeMoved = true; if (lastAborted) { for (String loggingChestIdViewer : ConfigHandler.oldContainer.keySet()) { - if (loggingChestIdViewer.equals(loggingChestId) || !loggingChestIdViewer.endsWith("." + x + "." + y + "." + z)) { + if (loggingChestIdViewer.equals(loggingChestId) || !loggingChestIdViewer.endsWith("." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ())) { continue; } diff --git a/src/main/java/net/coreprotect/listener/player/HopperPushListener.java b/src/main/java/net/coreprotect/listener/player/HopperPushListener.java index adf2a3c..e386ae3 100644 --- a/src/main/java/net/coreprotect/listener/player/HopperPushListener.java +++ b/src/main/java/net/coreprotect/listener/player/HopperPushListener.java @@ -1,6 +1,9 @@ package net.coreprotect.listener.player; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -15,12 +18,22 @@ import net.coreprotect.utility.Util; public final class HopperPushListener { - static void processHopperPush(Location location, InventoryHolder sourceHolder, InventoryHolder destinationHolder, ItemStack item, ItemStack movedItem) { + static void processHopperPush(Location location, InventoryHolder sourceHolder, InventoryHolder destinationHolder, ItemStack item) { + String loggingChestId = "#hopper-push." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ(); + Object[] lastAbort = ConfigHandler.hopperAbort.get(loggingChestId); + if (lastAbort != null) { + ItemStack[] destinationContents = destinationHolder.getInventory().getContents(); + if (((Set) lastAbort[0]).contains(item) && Arrays.equals(destinationContents, (ItemStack[]) lastAbort[1])) { + return; + } + } + ItemStack[] containerState = null; if (!ConfigHandler.isPaper) { containerState = Util.getContainerState(destinationHolder.getInventory().getContents()); } ItemStack[] destinationContainer = containerState; + ItemStack movedItem = item.clone(); final long taskStarted = InventoryChangeListener.tasksStarted.incrementAndGet(); Bukkit.getServer().getScheduler().runTaskAsynchronously(CoreProtect.getInstance(), () -> { @@ -31,12 +44,13 @@ public final class HopperPushListener { } int itemHash = Util.getItemStackHashCode(item); + boolean abort = false; if (ConfigHandler.isPaper) { for (ItemStack itemStack : sourceHolder.getInventory().getContents()) { if (itemStack != null && Util.getItemStackHashCode(itemStack) == itemHash) { if (itemHash != Util.getItemStackHashCode(movedItem) || destinationHolder.getInventory().firstEmpty() == -1) { - return; + abort = true; } break; @@ -47,10 +61,22 @@ public final class HopperPushListener { ItemStack[] destinationContents = destinationHolder.getInventory().getContents(); boolean addedInventory = Util.addedContainer(destinationContainer, destinationContents); if (!addedInventory) { - return; + abort = true; } } + if (abort) { + Set movedItems = new HashSet<>(); + ItemStack[] destinationContents = destinationHolder.getInventory().getContents(); + if (lastAbort != null && Arrays.equals(destinationContents, (ItemStack[]) lastAbort[1])) { + ((Set) lastAbort[0]).forEach(itemStack -> movedItems.add((ItemStack) itemStack)); + } + movedItems.add(movedItem); + + ConfigHandler.hopperAbort.put(loggingChestId, new Object[] { movedItems, Util.getContainerState(destinationContents) }); + return; + } + List list = ConfigHandler.transactingChest.get(location.getWorld().getUID().toString() + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ()); if (list != null) { list.add(movedItem); diff --git a/src/main/java/net/coreprotect/listener/player/InventoryChangeListener.java b/src/main/java/net/coreprotect/listener/player/InventoryChangeListener.java index 215ba27..2859359 100644 --- a/src/main/java/net/coreprotect/listener/player/InventoryChangeListener.java +++ b/src/main/java/net/coreprotect/listener/player/InventoryChangeListener.java @@ -304,6 +304,10 @@ public final class InventoryChangeListener extends Queue implements Listener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) protected void onInventoryMoveItemEvent(InventoryMoveItemEvent event) { + if (event.isCancelled()) { + return; + } + Location location = event.getSource().getLocation(); if (location == null) { return; @@ -321,14 +325,10 @@ public final class InventoryChangeListener extends Queue implements Listener { if (Config.getConfig(location.getWorld()).HOPPER_TRANSACTIONS) { if (Validate.isHopper(destinationHolder) && (Validate.isContainer(sourceHolder) && !Validate.isHopper(sourceHolder))) { - ItemStack item = event.getItem(); - ItemStack movedItem = item.clone(); - HopperPullListener.processHopperPull(location, sourceHolder, destinationHolder, item, movedItem); + HopperPullListener.processHopperPull(location, sourceHolder, destinationHolder, event.getItem()); } else if (Validate.isHopper(sourceHolder) && (Validate.isContainer(destinationHolder) && !Validate.isHopper(destinationHolder))) { - ItemStack item = event.getItem(); - ItemStack movedItem = item.clone(); - HopperPushListener.processHopperPush(location, sourceHolder, destinationHolder, item, movedItem); + HopperPushListener.processHopperPush(location, sourceHolder, destinationHolder, event.getItem()); } return; @@ -343,6 +343,6 @@ public final class InventoryChangeListener extends Queue implements Listener { return; } - HopperPullListener.processHopperPull(location, sourceHolder, destinationHolder, event.getItem(), event.getItem().clone()); + HopperPullListener.processHopperPull(location, sourceHolder, destinationHolder, event.getItem()); } }