diff --git a/pom.xml b/pom.xml
index 8ad0cbe..e888e33 100755
--- a/pom.xml
+++ b/pom.xml
@@ -216,7 +216,7 @@
io.papermc.paper
paper-api
- 1.21.1-R0.1-SNAPSHOT
+ 1.21.10-R0.1-SNAPSHOT
provided
diff --git a/src/main/java/net/coreprotect/listener/ListenerHandler.java b/src/main/java/net/coreprotect/listener/ListenerHandler.java
index 338b532..64beee4 100644
--- a/src/main/java/net/coreprotect/listener/ListenerHandler.java
+++ b/src/main/java/net/coreprotect/listener/ListenerHandler.java
@@ -55,6 +55,7 @@ import net.coreprotect.listener.world.LeavesDecayListener;
import net.coreprotect.listener.world.PortalCreateListener;
import net.coreprotect.listener.world.StructureGrowListener;
import net.coreprotect.paper.listener.BlockPreDispenseListener;
+import net.coreprotect.paper.listener.CopperGolemChestListener;
import net.coreprotect.paper.listener.PaperChatListener;
public final class ListenerHandler {
@@ -72,6 +73,14 @@ public final class ListenerHandler {
BlockPreDispenseListener.useBlockPreDispenseEvent = false;
}
+ try {
+ Class.forName("io.papermc.paper.event.entity.ItemTransportingEntityValidateTargetEvent"); // Paper 1.21.10+
+ pluginManager.registerEvents(new CopperGolemChestListener(plugin), plugin);
+ }
+ catch (Exception e) {
+ // Ignore registration failures to remain compatible with older servers.
+ }
+
// Block Listeners
pluginManager.registerEvents(new BlockBreakListener(), plugin);
pluginManager.registerEvents(new BlockBurnListener(), plugin);
diff --git a/src/main/java/net/coreprotect/paper/listener/CopperGolemChestListener.java b/src/main/java/net/coreprotect/paper/listener/CopperGolemChestListener.java
new file mode 100644
index 0000000..b6874ee
--- /dev/null
+++ b/src/main/java/net/coreprotect/paper/listener/CopperGolemChestListener.java
@@ -0,0 +1,108 @@
+package net.coreprotect.paper.listener;
+
+import java.util.Map;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.bukkit.Location;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockState;
+import org.bukkit.entity.Entity;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.Listener;
+import org.bukkit.inventory.InventoryHolder;
+import org.bukkit.scheduler.BukkitTask;
+
+import io.papermc.paper.event.entity.ItemTransportingEntityValidateTargetEvent;
+import net.coreprotect.CoreProtect;
+import net.coreprotect.config.Config;
+import net.coreprotect.listener.player.InventoryChangeListener;
+
+public final class CopperGolemChestListener implements Listener {
+
+ private static final String COPPER_GOLEM_NAME = "COPPER_GOLEM";
+ private static final String USERNAME = "#copper_golem";
+ private static final long DELAY_TICKS = 50L;
+
+ private final CoreProtect plugin;
+ private final Map pendingTransactions = new ConcurrentHashMap<>();
+
+ public CopperGolemChestListener(CoreProtect plugin) {
+ this.plugin = plugin;
+ }
+
+ @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
+ public void onValidate(ItemTransportingEntityValidateTargetEvent event) {
+ if (!event.isAllowed()) {
+ return;
+ }
+
+ Entity entity = event.getEntity();
+ if (entity == null || entity.getType() == null || !COPPER_GOLEM_NAME.equals(entity.getType().name())) {
+ return;
+ }
+
+ Block block = event.getBlock();
+ if (block == null) {
+ return;
+ }
+
+ BlockState blockState = block.getState();
+ if (!(blockState instanceof InventoryHolder)) {
+ return;
+ }
+
+ Location location = blockState.getLocation();
+ if (location == null || location.getWorld() == null) {
+ return;
+ }
+
+ if (!Config.getConfig(location.getWorld()).ITEM_TRANSACTIONS) {
+ return;
+ }
+
+ scheduleTransaction(entity, location);
+ }
+
+ private void scheduleTransaction(Entity entity, Location location) {
+ UUID entityId = entity.getUniqueId();
+ PendingTransaction pendingTransaction = pendingTransactions.remove(entityId);
+ if (pendingTransaction != null) {
+ pendingTransaction.cancel();
+ }
+
+ Location targetLocation = location.clone();
+ PendingTransaction scheduled = new PendingTransaction();
+ BukkitTask task = plugin.getServer().getScheduler().runTaskLater(plugin, () -> {
+ if (!pendingTransactions.remove(entityId, scheduled)) {
+ return;
+ }
+
+ Entity trackedEntity = plugin.getServer().getEntity(entityId);
+ if (trackedEntity == null || !trackedEntity.isValid()) {
+ return;
+ }
+
+ InventoryChangeListener.inventoryTransaction(USERNAME, targetLocation, null);
+ }, DELAY_TICKS);
+
+ scheduled.setTask(task);
+ pendingTransactions.put(entityId, scheduled);
+ }
+
+ private static final class PendingTransaction {
+
+ private BukkitTask task;
+
+ private void cancel() {
+ if (task != null) {
+ task.cancel();
+ }
+ }
+
+ private void setTask(BukkitTask task) {
+ this.task = task;
+ }
+ }
+}
diff --git a/src/main/java/net/coreprotect/worldedit/WorldEditBlockState.java b/src/main/java/net/coreprotect/worldedit/WorldEditBlockState.java
index 89007f1..23a9a81 100644
--- a/src/main/java/net/coreprotect/worldedit/WorldEditBlockState.java
+++ b/src/main/java/net/coreprotect/worldedit/WorldEditBlockState.java
@@ -196,4 +196,9 @@ public final class WorldEditBlockState implements BlockState {
return null;
}
+ @Override
+ public boolean isSuffocating() {
+ return false;
+ }
+
}