Utilize item caching on invalid hopper events

This commit is contained in:
Intelli 2021-07-21 18:47:23 -06:00
parent bd98bdfe05
commit aa55472c1a
4 changed files with 66 additions and 25 deletions

View File

@ -85,7 +85,7 @@ public class ConfigHandler extends Queue {
public static ConcurrentHashMap<String, List<ItemStack[]>> oldContainer = new ConcurrentHashMap<>(); public static ConcurrentHashMap<String, List<ItemStack[]>> oldContainer = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, List<ItemStack>> itemsDrop = new ConcurrentHashMap<>(); public static ConcurrentHashMap<String, List<ItemStack>> itemsDrop = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, List<ItemStack>> itemsPickup = new ConcurrentHashMap<>(); public static ConcurrentHashMap<String, List<ItemStack>> itemsPickup = new ConcurrentHashMap<>();
public static ConcurrentHashMap<String, Boolean> hopperAbort = new ConcurrentHashMap<>(); public static ConcurrentHashMap<String, Object[]> hopperAbort = new ConcurrentHashMap<>();
public static Map<String, List<ItemStack[]>> forceContainer = syncMap(); public static Map<String, List<ItemStack[]>> forceContainer = syncMap();
public static Map<String, Integer> lookupType = syncMap(); public static Map<String, Integer> lookupType = syncMap();
public static Map<String, Object[]> lookupThrottle = syncMap(); public static Map<String, Object[]> lookupThrottle = syncMap();

View File

@ -1,6 +1,9 @@
package net.coreprotect.listener.player; package net.coreprotect.listener.player;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -15,12 +18,22 @@ import net.coreprotect.utility.Util;
public final class HopperPullListener { 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; ItemStack[] containerState = null;
if (!ConfigHandler.isPaper) { if (!ConfigHandler.isPaper) {
containerState = Util.getContainerState(sourceHolder.getInventory().getContents()); containerState = Util.getContainerState(sourceHolder.getInventory().getContents());
} }
ItemStack[] sourceContainer = containerState; ItemStack[] sourceContainer = containerState;
ItemStack movedItem = item.clone();
final long taskStarted = InventoryChangeListener.tasksStarted.incrementAndGet(); final long taskStarted = InventoryChangeListener.tasksStarted.incrementAndGet();
Bukkit.getServer().getScheduler().runTaskAsynchronously(CoreProtect.getInstance(), () -> { Bukkit.getServer().getScheduler().runTaskAsynchronously(CoreProtect.getInstance(), () -> {
@ -32,13 +45,9 @@ public final class HopperPullListener {
boolean hopperTransactions = Config.getConfig(location.getWorld()).HOPPER_TRANSACTIONS; boolean hopperTransactions = Config.getConfig(location.getWorld()).HOPPER_TRANSACTIONS;
int itemHash = Util.getItemStackHashCode(item); int itemHash = Util.getItemStackHashCode(item);
int x = location.getBlockX(); boolean abort = false;
int y = location.getBlockY();
int z = location.getBlockZ();
String loggingChestId = "#hopper." + x + "." + y + "." + z;
if (ConfigHandler.isPaper) { if (ConfigHandler.isPaper) {
boolean abort = false;
for (ItemStack itemStack : sourceHolder.getInventory().getContents()) { for (ItemStack itemStack : sourceHolder.getInventory().getContents()) {
if (itemStack != null && Util.getItemStackHashCode(itemStack) == itemHash) { if (itemStack != null && Util.getItemStackHashCode(itemStack) == itemHash) {
abort = true; abort = true;
@ -53,22 +62,28 @@ public final class HopperPullListener {
break; break;
} }
} }
if (abort) {
ConfigHandler.hopperAbort.put(loggingChestId, true);
return;
}
} }
} }
else { else {
ItemStack[] sourceContents = sourceHolder.getInventory().getContents(); ItemStack[] sourceContents = sourceHolder.getInventory().getContents();
boolean addedInventory = Util.addedContainer(sourceContainer, sourceContents); boolean addedInventory = Util.addedContainer(sourceContainer, sourceContents);
if (addedInventory) { if (addedInventory) {
ConfigHandler.hopperAbort.put(loggingChestId, true); abort = true;
return;
} }
} }
if (abort) {
Set<ItemStack> 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; boolean lastAborted = false;
if (ConfigHandler.hopperAbort.get(loggingChestId) != null) { if (ConfigHandler.hopperAbort.get(loggingChestId) != null) {
ConfigHandler.hopperAbort.remove(loggingChestId); ConfigHandler.hopperAbort.remove(loggingChestId);
@ -78,7 +93,7 @@ public final class HopperPullListener {
boolean mergeMoved = true; boolean mergeMoved = true;
if (lastAborted) { if (lastAborted) {
for (String loggingChestIdViewer : ConfigHandler.oldContainer.keySet()) { 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; continue;
} }

View File

@ -1,6 +1,9 @@
package net.coreprotect.listener.player; package net.coreprotect.listener.player;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -15,12 +18,22 @@ import net.coreprotect.utility.Util;
public final class HopperPushListener { 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; ItemStack[] containerState = null;
if (!ConfigHandler.isPaper) { if (!ConfigHandler.isPaper) {
containerState = Util.getContainerState(destinationHolder.getInventory().getContents()); containerState = Util.getContainerState(destinationHolder.getInventory().getContents());
} }
ItemStack[] destinationContainer = containerState; ItemStack[] destinationContainer = containerState;
ItemStack movedItem = item.clone();
final long taskStarted = InventoryChangeListener.tasksStarted.incrementAndGet(); final long taskStarted = InventoryChangeListener.tasksStarted.incrementAndGet();
Bukkit.getServer().getScheduler().runTaskAsynchronously(CoreProtect.getInstance(), () -> { Bukkit.getServer().getScheduler().runTaskAsynchronously(CoreProtect.getInstance(), () -> {
@ -31,12 +44,13 @@ public final class HopperPushListener {
} }
int itemHash = Util.getItemStackHashCode(item); int itemHash = Util.getItemStackHashCode(item);
boolean abort = false;
if (ConfigHandler.isPaper) { if (ConfigHandler.isPaper) {
for (ItemStack itemStack : sourceHolder.getInventory().getContents()) { for (ItemStack itemStack : sourceHolder.getInventory().getContents()) {
if (itemStack != null && Util.getItemStackHashCode(itemStack) == itemHash) { if (itemStack != null && Util.getItemStackHashCode(itemStack) == itemHash) {
if (itemHash != Util.getItemStackHashCode(movedItem) || destinationHolder.getInventory().firstEmpty() == -1) { if (itemHash != Util.getItemStackHashCode(movedItem) || destinationHolder.getInventory().firstEmpty() == -1) {
return; abort = true;
} }
break; break;
@ -47,10 +61,22 @@ public final class HopperPushListener {
ItemStack[] destinationContents = destinationHolder.getInventory().getContents(); ItemStack[] destinationContents = destinationHolder.getInventory().getContents();
boolean addedInventory = Util.addedContainer(destinationContainer, destinationContents); boolean addedInventory = Util.addedContainer(destinationContainer, destinationContents);
if (!addedInventory) { if (!addedInventory) {
return; abort = true;
} }
} }
if (abort) {
Set<ItemStack> 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<Object> list = ConfigHandler.transactingChest.get(location.getWorld().getUID().toString() + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ()); List<Object> list = ConfigHandler.transactingChest.get(location.getWorld().getUID().toString() + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ());
if (list != null) { if (list != null) {
list.add(movedItem); list.add(movedItem);

View File

@ -304,6 +304,10 @@ public final class InventoryChangeListener extends Queue implements Listener {
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
protected void onInventoryMoveItemEvent(InventoryMoveItemEvent event) { protected void onInventoryMoveItemEvent(InventoryMoveItemEvent event) {
if (event.isCancelled()) {
return;
}
Location location = event.getSource().getLocation(); Location location = event.getSource().getLocation();
if (location == null) { if (location == null) {
return; return;
@ -321,14 +325,10 @@ public final class InventoryChangeListener extends Queue implements Listener {
if (Config.getConfig(location.getWorld()).HOPPER_TRANSACTIONS) { if (Config.getConfig(location.getWorld()).HOPPER_TRANSACTIONS) {
if (Validate.isHopper(destinationHolder) && (Validate.isContainer(sourceHolder) && !Validate.isHopper(sourceHolder))) { if (Validate.isHopper(destinationHolder) && (Validate.isContainer(sourceHolder) && !Validate.isHopper(sourceHolder))) {
ItemStack item = event.getItem(); HopperPullListener.processHopperPull(location, sourceHolder, destinationHolder, event.getItem());
ItemStack movedItem = item.clone();
HopperPullListener.processHopperPull(location, sourceHolder, destinationHolder, item, movedItem);
} }
else if (Validate.isHopper(sourceHolder) && (Validate.isContainer(destinationHolder) && !Validate.isHopper(destinationHolder))) { else if (Validate.isHopper(sourceHolder) && (Validate.isContainer(destinationHolder) && !Validate.isHopper(destinationHolder))) {
ItemStack item = event.getItem(); HopperPushListener.processHopperPush(location, sourceHolder, destinationHolder, event.getItem());
ItemStack movedItem = item.clone();
HopperPushListener.processHopperPush(location, sourceHolder, destinationHolder, item, movedItem);
} }
return; return;
@ -343,6 +343,6 @@ public final class InventoryChangeListener extends Queue implements Listener {
return; return;
} }
HopperPullListener.processHopperPull(location, sourceHolder, destinationHolder, event.getItem(), event.getItem().clone()); HopperPullListener.processHopperPull(location, sourceHolder, destinationHolder, event.getItem());
} }
} }