From fb79071ee79d01b84d879e9add6bc240a73f341e Mon Sep 17 00:00:00 2001 From: Intelli Date: Thu, 17 Feb 2022 20:56:20 -0700 Subject: [PATCH] Added container transaction support for item frames (...) Fixed ClassCastException when targeting an armor stand with #container --- .../net/coreprotect/bukkit/BukkitAdapter.java | 6 + .../coreprotect/bukkit/BukkitInterface.java | 3 + .../net/coreprotect/bukkit/Bukkit_v1_17.java | 13 + .../java/net/coreprotect/consumer/Queue.java | 14 - .../process/HangingRemoveProcess.java | 15 - .../consumer/process/HangingSpawnProcess.java | 16 - .../coreprotect/consumer/process/Process.java | 8 - .../database/ContainerRollback.java | 9 +- .../java/net/coreprotect/database/Lookup.java | 2 +- .../net/coreprotect/database/Rollback.java | 36 ++- .../database/logger/ContainerLogger.java | 7 +- .../entity/EntityDamageByBlockListener.java | 22 +- .../entity/EntityDamageByEntityListener.java | 28 +- .../entity/HangingBreakByEntityListener.java | 10 +- .../listener/entity/HangingBreakListener.java | 14 +- .../player/ArmorStandManipulateListener.java | 124 ++++---- .../player/InventoryChangeListener.java | 2 +- .../listener/player/PlayerDeathListener.java | 4 +- .../player/PlayerDropItemListener.java | 17 +- .../player/PlayerInteractEntityListener.java | 97 +++++- .../net/coreprotect/model/BlockGroup.java | 2 +- .../java/net/coreprotect/utility/Util.java | 37 ++- .../utility/entity/HangingUtil.java | 296 +++++++++--------- 23 files changed, 423 insertions(+), 359 deletions(-) delete mode 100644 src/main/java/net/coreprotect/consumer/process/HangingRemoveProcess.java delete mode 100644 src/main/java/net/coreprotect/consumer/process/HangingSpawnProcess.java diff --git a/src/main/java/net/coreprotect/bukkit/BukkitAdapter.java b/src/main/java/net/coreprotect/bukkit/BukkitAdapter.java index b5fd322..988bb3d 100644 --- a/src/main/java/net/coreprotect/bukkit/BukkitAdapter.java +++ b/src/main/java/net/coreprotect/bukkit/BukkitAdapter.java @@ -10,6 +10,7 @@ import org.bukkit.block.Sign; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Directional; import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; import org.bukkit.entity.ItemFrame; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; @@ -118,6 +119,11 @@ public class BukkitAdapter implements BukkitInterface { return Material.ITEM_FRAME; } + @Override + public Material getFrameType(EntityType type) { + return type == EntityType.ITEM_FRAME ? Material.ITEM_FRAME : null; + } + @Override public Class getFrameClass(Material material) { return ItemFrame.class; diff --git a/src/main/java/net/coreprotect/bukkit/BukkitInterface.java b/src/main/java/net/coreprotect/bukkit/BukkitInterface.java index 75d3425..0861ff9 100644 --- a/src/main/java/net/coreprotect/bukkit/BukkitInterface.java +++ b/src/main/java/net/coreprotect/bukkit/BukkitInterface.java @@ -9,6 +9,7 @@ import org.bukkit.block.Block; import org.bukkit.block.Sign; import org.bukkit.block.data.BlockData; import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -20,6 +21,8 @@ public interface BukkitInterface { public Material getFrameType(Entity entity); + public Material getFrameType(EntityType type); + public Class getFrameClass(Material material); public String parseLegacyName(String name); diff --git a/src/main/java/net/coreprotect/bukkit/Bukkit_v1_17.java b/src/main/java/net/coreprotect/bukkit/Bukkit_v1_17.java index 424a7af..259bf26 100644 --- a/src/main/java/net/coreprotect/bukkit/Bukkit_v1_17.java +++ b/src/main/java/net/coreprotect/bukkit/Bukkit_v1_17.java @@ -15,6 +15,7 @@ import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.PointedDripstone; import org.bukkit.entity.Axolotl; import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; import org.bukkit.entity.GlowItemFrame; import org.bukkit.entity.Goat; import org.bukkit.entity.ItemFrame; @@ -199,6 +200,18 @@ public class Bukkit_v1_17 extends Bukkit_v1_16 implements BukkitInterface { return (entity instanceof GlowItemFrame) ? Material.GLOW_ITEM_FRAME : Material.ITEM_FRAME; } + @Override + public Material getFrameType(EntityType type) { + switch (type) { + case ITEM_FRAME: + return Material.ITEM_FRAME; + case GLOW_ITEM_FRAME: + return Material.GLOW_ITEM_FRAME; + default: + return null; + } + } + @Override public Class getFrameClass(Material material) { return (material == Material.GLOW_ITEM_FRAME) ? GlowItemFrame.class : ItemFrame.class; diff --git a/src/main/java/net/coreprotect/consumer/Queue.java b/src/main/java/net/coreprotect/consumer/Queue.java index 640787a..b1bf21f 100755 --- a/src/main/java/net/coreprotect/consumer/Queue.java +++ b/src/main/java/net/coreprotect/consumer/Queue.java @@ -253,20 +253,6 @@ public class Queue { queueStandardData(consumerId, currentConsumer, new String[] { user, null }, new Object[] { block, type }); } - protected static void queueHangingRemove(String user, BlockState block, String blockData, int delay) { - int currentConsumer = Consumer.currentConsumer; - int consumerId = Consumer.newConsumerId(currentConsumer); - addConsumer(currentConsumer, new Object[] { consumerId, Process.HANGING_REMOVE, null, 0, null, 0, delay, blockData }); - queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block); - } - - protected static void queueHangingSpawn(String user, BlockState block, Material type, String blockData, int data, int delay) { - int currentConsumer = Consumer.currentConsumer; - int consumerId = Consumer.newConsumerId(currentConsumer); - addConsumer(currentConsumer, new Object[] { consumerId, Process.HANGING_SPAWN, type, data, null, 0, delay, blockData }); - queueStandardData(consumerId, currentConsumer, new String[] { user, null }, block); - } - protected static void queueMaterialInsert(int id, String name) { int currentConsumer = Consumer.currentConsumer; int consumerId = Consumer.newConsumerId(currentConsumer); diff --git a/src/main/java/net/coreprotect/consumer/process/HangingRemoveProcess.java b/src/main/java/net/coreprotect/consumer/process/HangingRemoveProcess.java deleted file mode 100644 index 9edd1ad..0000000 --- a/src/main/java/net/coreprotect/consumer/process/HangingRemoveProcess.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.coreprotect.consumer.process; - -import org.bukkit.block.BlockState; - -import net.coreprotect.utility.entity.HangingUtil; - -class HangingRemoveProcess { - - static void process(Object object, String hangingData, int delay) { - if (object instanceof BlockState) { - BlockState block = (BlockState) object; - HangingUtil.removeHanging(block, hangingData, delay); - } - } -} diff --git a/src/main/java/net/coreprotect/consumer/process/HangingSpawnProcess.java b/src/main/java/net/coreprotect/consumer/process/HangingSpawnProcess.java deleted file mode 100644 index 31f43cc..0000000 --- a/src/main/java/net/coreprotect/consumer/process/HangingSpawnProcess.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.coreprotect.consumer.process; - -import org.bukkit.Material; -import org.bukkit.block.BlockState; - -import net.coreprotect.utility.entity.HangingUtil; - -class HangingSpawnProcess { - - static void process(Object object, Material type, int data, String hangingData, int delay) { - if (object instanceof BlockState) { - BlockState block = (BlockState) object; - HangingUtil.spawnHanging(block, type, hangingData, data, delay); - } - } -} diff --git a/src/main/java/net/coreprotect/consumer/process/Process.java b/src/main/java/net/coreprotect/consumer/process/Process.java index f68d8e8..23cd110 100755 --- a/src/main/java/net/coreprotect/consumer/process/Process.java +++ b/src/main/java/net/coreprotect/consumer/process/Process.java @@ -35,8 +35,6 @@ public class Process { public static final int PLAYER_LOGOUT = 15; public static final int ENTITY_KILL = 16; public static final int ENTITY_SPAWN = 17; - public static final int HANGING_REMOVE = 18; - public static final int HANGING_SPAWN = 19; public static final int NATURAL_BLOCK_BREAK = 20; public static final int MATERIAL_INSERT = 21; public static final int ART_INSERT = 22; @@ -195,12 +193,6 @@ public class Process { case Process.ENTITY_SPAWN: EntitySpawnProcess.process(statement, object, forceData); break; - case Process.HANGING_REMOVE: - HangingRemoveProcess.process(object, (String) data[7], forceData); - break; - case Process.HANGING_SPAWN: - HangingSpawnProcess.process(object, blockType, blockData, (String) data[7], forceData); - break; case Process.NATURAL_BLOCK_BREAK: NaturalBlockBreakProcess.process(statement, preparedStmtBlocks, i, processId, id, user, object, blockType, blockData, (String) data[7]); break; diff --git a/src/main/java/net/coreprotect/database/ContainerRollback.java b/src/main/java/net/coreprotect/database/ContainerRollback.java index 42c1963..5415b09 100644 --- a/src/main/java/net/coreprotect/database/ContainerRollback.java +++ b/src/main/java/net/coreprotect/database/ContainerRollback.java @@ -11,6 +11,7 @@ import org.bukkit.block.Block; import org.bukkit.command.CommandSender; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Entity; +import org.bukkit.entity.ItemFrame; import org.bukkit.entity.LivingEntity; import org.bukkit.inventory.ItemStack; @@ -65,11 +66,15 @@ public class ContainerRollback extends Queue { } else { for (Entity entity : block.getChunk().getEntities()) { - if (entity instanceof ArmorStand) { - if (entity.getLocation().getBlockX() == location.getBlockX() && entity.getLocation().getBlockY() == location.getBlockY() && entity.getLocation().getBlockZ() == location.getBlockZ()) { + if (entity.getLocation().getBlockX() == location.getBlockX() && entity.getLocation().getBlockY() == location.getBlockY() && entity.getLocation().getBlockZ() == location.getBlockZ()) { + if (entity instanceof ArmorStand) { type = Material.ARMOR_STAND; container = Util.getEntityEquipment((LivingEntity) entity); } + else if (entity instanceof ItemFrame) { + type = Material.ITEM_FRAME; + container = entity; + } } } } diff --git a/src/main/java/net/coreprotect/database/Lookup.java b/src/main/java/net/coreprotect/database/Lookup.java index 3a41998..06d85d6 100755 --- a/src/main/java/net/coreprotect/database/Lookup.java +++ b/src/main/java/net/coreprotect/database/Lookup.java @@ -688,7 +688,7 @@ public class Lookup extends Queue { if (!count) { rows = "rowid as id,time,user,wid,x,y,z,type,data as metadata,0 as data,amount,action,rolled_back"; - queryOrder = " ORDER BY time DESC, id DESC"; + queryOrder = " ORDER BY time DESC, tbl DESC, id DESC"; } query = query + unionSelect + "SELECT " + "'2' as tbl," + rows + " FROM " + ConfigHandler.prefix + "item WHERE" + queryBlock + unionLimit + ")"; } diff --git a/src/main/java/net/coreprotect/database/Rollback.java b/src/main/java/net/coreprotect/database/Rollback.java index 3371b92..ad62773 100644 --- a/src/main/java/net/coreprotect/database/Rollback.java +++ b/src/main/java/net/coreprotect/database/Rollback.java @@ -55,6 +55,7 @@ import org.bukkit.entity.ArmorStand; import org.bukkit.entity.EnderCrystal; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; +import org.bukkit.entity.ItemFrame; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.EntityEquipment; @@ -88,6 +89,7 @@ import net.coreprotect.utility.ChestTool; import net.coreprotect.utility.Color; import net.coreprotect.utility.Teleport; import net.coreprotect.utility.Util; +import net.coreprotect.utility.entity.HangingUtil; public class Rollback extends Queue { @@ -300,7 +302,6 @@ public class Rollback extends Queue { ArrayList data = finalBlockList.get(chunkKey); ArrayList itemData = finalItemList.get(chunkKey); Map chunkChanges = new LinkedHashMap<>(); - Map hangingDelay = new HashMap<>(); int finalChunkX = (int) chunkKey; int finalChunkZ = (int) (chunkKey >> 32); @@ -563,12 +564,10 @@ public class Rollback extends Queue { } if ((rowType == Material.AIR) && ((BukkitAdapter.ADAPTER.isItemFrame(oldTypeMaterial)) || (oldTypeMaterial == Material.PAINTING))) { - int delay = Util.getHangingDelay(hangingDelay, rowWorldId, rowX, rowY, rowZ); - Queue.queueHangingRemove(rowUser, block.getState(), blockDataString, delay); + HangingUtil.removeHanging(block.getState(), blockDataString); } else if ((BukkitAdapter.ADAPTER.isItemFrame(rowType)) || (rowType == Material.PAINTING)) { - int delay = Util.getHangingDelay(hangingDelay, rowWorldId, rowX, rowY, rowZ); - Queue.queueHangingSpawn(rowUser, block.getState(), rowType, blockDataString, rowData, delay); + HangingUtil.spawnHanging(block.getState(), rowType, blockDataString, rowData); } else if ((rowType == Material.ARMOR_STAND)) { Location location1 = block.getLocation(); @@ -989,7 +988,6 @@ public class Rollback extends Queue { // count++; ConfigHandler.rollbackHash.put(finalUserString, new int[] { itemCount1, blockCount1, entityCount1, 0 }); } - hangingDelay.clear(); data.clear(); // Apply cached changes @@ -1096,13 +1094,17 @@ public class Rollback extends Queue { container = Util.getContainerInventory(block.getState(), false); containerType = block.getType(); } - else if (BlockGroup.CONTAINERS.contains(Material.ARMOR_STAND)) { + else if (BlockGroup.CONTAINERS.contains(Material.ARMOR_STAND) || BlockGroup.CONTAINERS.contains(Material.ITEM_FRAME)) { for (Entity entity : block.getChunk().getEntities()) { - if (entity instanceof ArmorStand) { - if (entity.getLocation().getBlockX() == rowX && entity.getLocation().getBlockY() == rowY && entity.getLocation().getBlockZ() == rowZ) { + if (entity.getLocation().getBlockX() == rowX && entity.getLocation().getBlockY() == rowY && entity.getLocation().getBlockZ() == rowZ) { + if (entity instanceof ArmorStand) { container = Util.getEntityEquipment((LivingEntity) entity); containerType = Material.ARMOR_STAND; } + else if (entity instanceof ItemFrame) { + container = entity; + containerType = Material.ITEM_FRAME; + } } } } @@ -1543,6 +1545,20 @@ public class Rollback extends Queue { } } } + else if (type != null && type.equals(Material.ITEM_FRAME)) { + ItemFrame frame = (ItemFrame) container; + if (frame != null) { + if (action == 1) { + itemstack.setAmount(1); + } + else { + itemstack.setType(Material.AIR); + itemstack.setAmount(0); + } + + frame.setItem(itemstack); + } + } else { Inventory inventory = (Inventory) container; if (inventory != null) { @@ -1785,7 +1801,7 @@ public class Rollback extends Queue { return new Object[] { slot, itemstack }; } - private static Object[] populateItemStack(ItemStack itemstack, byte[] metadata) { + public static Object[] populateItemStack(ItemStack itemstack, byte[] metadata) { if (metadata != null) { try { ByteArrayInputStream metaByteStream = new ByteArrayInputStream(metadata); diff --git a/src/main/java/net/coreprotect/database/logger/ContainerLogger.java b/src/main/java/net/coreprotect/database/logger/ContainerLogger.java index 8f21b7f..0b6312b 100644 --- a/src/main/java/net/coreprotect/database/logger/ContainerLogger.java +++ b/src/main/java/net/coreprotect/database/logger/ContainerLogger.java @@ -9,6 +9,7 @@ import java.util.Map; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.entity.ItemFrame; import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -31,12 +32,16 @@ public class ContainerLogger extends Queue { public static void log(PreparedStatement preparedStmtContainer, PreparedStatement preparedStmtItems, int batchCount, String player, Material type, Object container, Location location) { try { ItemStack[] contents = null; - if (type.equals(Material.ARMOR_STAND)) { + if (type == Material.ARMOR_STAND) { EntityEquipment equipment = (EntityEquipment) container; if (equipment != null) { contents = Util.getArmorStandContents(equipment); } } + else if (type == Material.ITEM_FRAME) { + ItemFrame itemFrame = (ItemFrame) container; + contents = Util.getItemFrameItem(itemFrame); + } else { Inventory inventory = (Inventory) container; if (inventory != null) { diff --git a/src/main/java/net/coreprotect/listener/entity/EntityDamageByBlockListener.java b/src/main/java/net/coreprotect/listener/entity/EntityDamageByBlockListener.java index 19e975c..ad1fe05 100644 --- a/src/main/java/net/coreprotect/listener/entity/EntityDamageByBlockListener.java +++ b/src/main/java/net/coreprotect/listener/entity/EntityDamageByBlockListener.java @@ -13,11 +13,10 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageByBlockEvent; -import net.coreprotect.bukkit.BukkitAdapter; import net.coreprotect.config.Config; import net.coreprotect.consumer.Queue; import net.coreprotect.database.Database; -import net.coreprotect.utility.Util; +import net.coreprotect.listener.player.PlayerInteractEntityListener; public final class EntityDamageByBlockListener extends Queue implements Listener { @@ -33,7 +32,7 @@ public final class EntityDamageByBlockListener extends Queue implements Listener return; } - if (event.isCancelled() || !Config.getConfig(entity.getWorld()).BLOCK_BREAK) { + if (event.isCancelled()) { return; } @@ -43,22 +42,17 @@ public final class EntityDamageByBlockListener extends Queue implements Listener user = "#tnt"; } - if (entity instanceof ItemFrame) { - Material frameType = BukkitAdapter.ADAPTER.getFrameType(entity); - ItemFrame frame = (ItemFrame) event.getEntity(); - int data = 0; - if (frame.getItem() != null) { - data = Util.getBlockId(frame.getItem().getType()); + if (entity instanceof ItemFrame && Config.getConfig(entity.getWorld()).ITEM_TRANSACTIONS) { + ItemFrame frame = (ItemFrame) entity; + if (frame.getItem().getType() != Material.AIR) { + PlayerInteractEntityListener.queueFrameTransaction(user, frame, false); } - - Queue.queueBlockBreak(user, block.getState(), frameType, null, data); - Queue.queueBlockPlace(user, block.getState(), frameType, null, frameType, -1, 0, null); } - else if (entity instanceof ArmorStand) { + else if (entity instanceof ArmorStand && Config.getConfig(entity.getWorld()).BLOCK_BREAK) { Database.containerBreakCheck(user, Material.ARMOR_STAND, entity, null, block.getLocation()); Queue.queueBlockBreak(user, block.getState(), Material.ARMOR_STAND, null, (int) entity.getLocation().getYaw()); } - else if (entity instanceof EnderCrystal) { + else if (entity instanceof EnderCrystal && Config.getConfig(entity.getWorld()).BLOCK_BREAK) { EnderCrystal crystal = (EnderCrystal) event.getEntity(); Queue.queueBlockBreak(user, block.getState(), Material.END_CRYSTAL, null, crystal.isShowingBottom() ? 1 : 0); } diff --git a/src/main/java/net/coreprotect/listener/entity/EntityDamageByEntityListener.java b/src/main/java/net/coreprotect/listener/entity/EntityDamageByEntityListener.java index 90c1f93..d792949 100644 --- a/src/main/java/net/coreprotect/listener/entity/EntityDamageByEntityListener.java +++ b/src/main/java/net/coreprotect/listener/entity/EntityDamageByEntityListener.java @@ -3,6 +3,7 @@ package net.coreprotect.listener.entity; import java.util.Locale; import org.bukkit.Bukkit; +import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; @@ -29,16 +30,17 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.projectiles.ProjectileSource; import net.coreprotect.CoreProtect; -import net.coreprotect.bukkit.BukkitAdapter; import net.coreprotect.config.Config; import net.coreprotect.config.ConfigHandler; import net.coreprotect.consumer.Queue; import net.coreprotect.database.Database; +import net.coreprotect.listener.player.PlayerInteractEntityListener; import net.coreprotect.utility.Util; public final class EntityDamageByEntityListener extends Queue implements Listener { - @EventHandler(priority = EventPriority.MONITOR) + // EntityPickupItemEvent resulting from this event can trigger BEFORE this event if both are set to MONITOR + @EventHandler(priority = EventPriority.HIGHEST) protected void onEntityDamageByEntity(EntityDamageByEntityEvent event) { Entity damager = event.getDamager(); @@ -50,10 +52,12 @@ public final class EntityDamageByEntityListener extends Queue implements Listene final Entity entity = event.getEntity(); Location entityLocation = entity.getLocation(); Block block = entityLocation.getBlock(); + boolean logDrops = true; if (damager instanceof Player) { Player player = (Player) damager; user = player.getName(); + logDrops = player.getGameMode() != GameMode.CREATIVE; if (ConfigHandler.inspecting.get(player.getName()) != null) { if (ConfigHandler.inspecting.get(player.getName())) { @@ -105,24 +109,18 @@ public final class EntityDamageByEntityListener extends Queue implements Listene user = "#" + damager.getType().name().toLowerCase(Locale.ROOT); } - if (!event.isCancelled() && Config.getConfig(entity.getWorld()).BLOCK_BREAK && !inspecting) { - if (entity instanceof ItemFrame) { - ItemFrame frame = (ItemFrame) event.getEntity(); - int data = 0; - - if (frame.getItem() != null) { - data = Util.getBlockId(frame.getItem().getType()); + if (!event.isCancelled() && !inspecting) { + if (entity instanceof ItemFrame && Config.getConfig(entityLocation.getWorld()).ITEM_TRANSACTIONS) { + ItemFrame frame = (ItemFrame) entity; + if (frame.getItem().getType() != Material.AIR) { + PlayerInteractEntityListener.queueFrameTransaction(user, frame, logDrops); } - - Material frameType = BukkitAdapter.ADAPTER.getFrameType(entity); - Queue.queueBlockBreak(user, block.getState(), frameType, null, data); - Queue.queueBlockPlace(user, block.getState(), frameType, null, frameType, data, 1, null); } - else if (entity instanceof EnderCrystal) { + else if (entity instanceof EnderCrystal && Config.getConfig(entity.getWorld()).BLOCK_BREAK) { EnderCrystal crystal = (EnderCrystal) event.getEntity(); Queue.queueBlockBreak(user, block.getState(), Material.END_CRYSTAL, null, crystal.isShowingBottom() ? 1 : 0); } - else if (entity instanceof ArmorStand) { + else if (entity instanceof ArmorStand && Config.getConfig(entity.getWorld()).BLOCK_BREAK) { // Do this here, as we're unable to read armor stand contents on EntityDeathEvent (in survival mode) if (Config.getConfig(entityLocation.getWorld()).ITEM_TRANSACTIONS) { String killer = user; diff --git a/src/main/java/net/coreprotect/listener/entity/HangingBreakByEntityListener.java b/src/main/java/net/coreprotect/listener/entity/HangingBreakByEntityListener.java index 3092942..63f052c 100755 --- a/src/main/java/net/coreprotect/listener/entity/HangingBreakByEntityListener.java +++ b/src/main/java/net/coreprotect/listener/entity/HangingBreakByEntityListener.java @@ -4,6 +4,7 @@ import java.sql.Connection; import java.sql.Statement; import java.util.Locale; +import org.bukkit.GameMode; import org.bukkit.Material; import org.bukkit.block.BlockState; import org.bukkit.entity.Entity; @@ -22,6 +23,7 @@ import net.coreprotect.consumer.Queue; import net.coreprotect.database.Database; import net.coreprotect.database.lookup.BlockLookup; import net.coreprotect.language.Phrase; +import net.coreprotect.listener.player.PlayerInteractEntityListener; import net.coreprotect.utility.Chat; import net.coreprotect.utility.Color; import net.coreprotect.utility.Util; @@ -92,6 +94,7 @@ public final class HangingBreakByEntityListener extends Queue implements Listene Entity entity = event.getEntity(); Entity remover = event.getRemover(); BlockState blockEvent = event.getEntity().getLocation().getBlock().getState(); + boolean logDrops = true; boolean inspecting = false; if (event.getRemover() instanceof Player) { @@ -113,6 +116,7 @@ public final class HangingBreakByEntityListener extends Queue implements Listene if (remover instanceof Player) { Player player = (Player) remover; culprit = player.getName(); + logDrops = player.getGameMode() != GameMode.CREATIVE; } else if (remover.getType() != null) { culprit = "#" + remover.getType().name().toLowerCase(Locale.ROOT); @@ -127,8 +131,10 @@ public final class HangingBreakByEntityListener extends Queue implements Listene ItemFrame itemframe = (ItemFrame) entity; blockData = "FACING=" + itemframe.getFacing().name(); - if (itemframe.getItem() != null) { - itemData = Util.getBlockId(itemframe.getItem().getType()); + if (!event.isCancelled() && Config.getConfig(entity.getWorld()).ITEM_TRANSACTIONS && !inspecting) { + if (itemframe.getItem().getType() != Material.AIR) { + PlayerInteractEntityListener.queueFrameTransaction(culprit, itemframe, logDrops); + } } } else { diff --git a/src/main/java/net/coreprotect/listener/entity/HangingBreakListener.java b/src/main/java/net/coreprotect/listener/entity/HangingBreakListener.java index 60f5c0e..1705ea2 100644 --- a/src/main/java/net/coreprotect/listener/entity/HangingBreakListener.java +++ b/src/main/java/net/coreprotect/listener/entity/HangingBreakListener.java @@ -15,6 +15,8 @@ import org.bukkit.event.hanging.HangingBreakEvent; import net.coreprotect.bukkit.BukkitAdapter; import net.coreprotect.config.Config; import net.coreprotect.consumer.Queue; +import net.coreprotect.database.Lookup; +import net.coreprotect.listener.player.PlayerInteractEntityListener; import net.coreprotect.utility.Util; public final class HangingBreakListener extends Queue implements Listener { @@ -29,6 +31,7 @@ public final class HangingBreakListener extends Queue implements Listener { if (cause.equals(HangingBreakEvent.RemoveCause.EXPLOSION) || cause.equals(HangingBreakEvent.RemoveCause.PHYSICS) || cause.equals(HangingBreakEvent.RemoveCause.OBSTRUCTION)) { String causeName = "#explosion"; Block attachedBlock = null; + boolean logDrops = false; if (cause.equals(HangingBreakEvent.RemoveCause.PHYSICS)) { causeName = "#physics"; @@ -41,6 +44,11 @@ public final class HangingBreakListener extends Queue implements Listener { Hanging hangingEntity = (Hanging) entity; BlockFace attached = hangingEntity.getAttachedFace(); attachedBlock = hangingEntity.getLocation().getBlock().getRelative(attached); + String removed = Lookup.whoRemovedCache(attachedBlock.getState()); + if (removed.length() > 0) { + causeName = removed; + logDrops = true; + } } String blockData = null; @@ -51,8 +59,10 @@ public final class HangingBreakListener extends Queue implements Listener { ItemFrame itemframe = (ItemFrame) entity; blockData = "FACING=" + itemframe.getFacing().name(); - if (itemframe.getItem() != null) { - itemData = Util.getBlockId(itemframe.getItem().getType()); + if (!event.isCancelled() && Config.getConfig(entity.getWorld()).ITEM_TRANSACTIONS) { + if (itemframe.getItem().getType() != Material.AIR) { + PlayerInteractEntityListener.queueFrameTransaction(causeName, itemframe, logDrops); + } } } else { diff --git a/src/main/java/net/coreprotect/listener/player/ArmorStandManipulateListener.java b/src/main/java/net/coreprotect/listener/player/ArmorStandManipulateListener.java index a83e097..4f355af 100644 --- a/src/main/java/net/coreprotect/listener/player/ArmorStandManipulateListener.java +++ b/src/main/java/net/coreprotect/listener/player/ArmorStandManipulateListener.java @@ -31,6 +31,63 @@ import net.coreprotect.utility.Util; public final class ArmorStandManipulateListener extends Queue implements Listener { + public static void inspectHangingTransactions(final Location location, final Player finalPlayer) { + class BasicThread implements Runnable { + @Override + public void run() { + if (!finalPlayer.hasPermission("coreprotect.inspect")) { + Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION)); + ConfigHandler.inspecting.put(finalPlayer.getName(), false); + return; + } + if (ConfigHandler.converterRunning) { + Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS)); + return; + } + if (ConfigHandler.purgeRunning) { + Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS)); + return; + } + if (ConfigHandler.lookupThrottle.get(finalPlayer.getName()) != null) { + Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(finalPlayer.getName()); + if ((boolean) lookupThrottle[0] || ((System.currentTimeMillis() - (long) lookupThrottle[1])) < 100) { + Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY)); + return; + } + } + ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { true, System.currentTimeMillis() }); + + try (Connection connection = Database.getConnection(true)) { + if (connection != null) { + Statement statement = connection.createStatement(); + String blockData = ChestTransactionLookup.performLookup(null, statement, location, finalPlayer, 1, 7, true); + + if (blockData.contains("\n")) { + for (String b : blockData.split("\n")) { + Chat.sendComponent(finalPlayer, b); + } + } + else { + Chat.sendComponent(finalPlayer, blockData); + } + statement.close(); + } + else { + Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY)); + } + } + catch (Exception e) { + e.printStackTrace(); + } + + ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { false, System.currentTimeMillis() }); + } + } + Runnable runnable = new BasicThread(); + Thread thread = new Thread(runnable); + thread.start(); + } + @EventHandler(priority = EventPriority.MONITOR) protected void onPlayerArmorStandManipulateEvent(PlayerArmorStandManipulateEvent event) { Player player = event.getPlayer(); @@ -40,72 +97,11 @@ public final class ArmorStandManipulateListener extends Queue implements Listene ItemStack item = event.getArmorStandItem(); ItemStack playerItem = event.getPlayerItem(); - if (!Config.getConfig(player.getWorld()).ITEM_TRANSACTIONS) { - return; - } - if (ConfigHandler.inspecting.get(player.getName()) != null) { if (ConfigHandler.inspecting.get(player.getName())) { - final Player finalPlayer = player; - if (BlockGroup.CONTAINERS.contains(Material.ARMOR_STAND)) { // logged armor stand items - class BasicThread implements Runnable { - @Override - public void run() { - if (!finalPlayer.hasPermission("coreprotect.inspect")) { - Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.NO_PERMISSION)); - ConfigHandler.inspecting.put(finalPlayer.getName(), false); - return; - } - if (ConfigHandler.converterRunning) { - Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.UPGRADE_IN_PROGRESS)); - return; - } - if (ConfigHandler.purgeRunning) { - Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.PURGE_IN_PROGRESS)); - return; - } - if (ConfigHandler.lookupThrottle.get(finalPlayer.getName()) != null) { - Object[] lookupThrottle = ConfigHandler.lookupThrottle.get(finalPlayer.getName()); - if ((boolean) lookupThrottle[0] || ((System.currentTimeMillis() - (long) lookupThrottle[1])) < 100) { - Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY)); - return; - } - } - ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { true, System.currentTimeMillis() }); - - try (Connection connection = Database.getConnection(true)) { - if (connection != null) { - Statement statement = connection.createStatement(); - Location standLocation = armorStand.getLocation(); - String blockData = ChestTransactionLookup.performLookup(null, statement, standLocation, finalPlayer, 1, 7, true); - - if (blockData.contains("\n")) { - for (String b : blockData.split("\n")) { - Chat.sendComponent(finalPlayer, b); - } - } - else { - Chat.sendComponent(finalPlayer, blockData); - } - statement.close(); - } - else { - Chat.sendMessage(finalPlayer, Color.DARK_AQUA + "CoreProtect " + Color.WHITE + "- " + Phrase.build(Phrase.DATABASE_BUSY)); - } - } - catch (Exception e) { - e.printStackTrace(); - } - - ConfigHandler.lookupThrottle.put(finalPlayer.getName(), new Object[] { false, System.currentTimeMillis() }); - } - } - - Runnable runnable = new BasicThread(); - Thread thread = new Thread(runnable); - thread.start(); + inspectHangingTransactions(armorStand.getLocation(), player); } event.setCancelled(true); @@ -116,6 +112,10 @@ public final class ArmorStandManipulateListener extends Queue implements Listene return; } + if (!Config.getConfig(player.getWorld()).ITEM_TRANSACTIONS) { + return; + } + if (item == null && playerItem == null) { return; } diff --git a/src/main/java/net/coreprotect/listener/player/InventoryChangeListener.java b/src/main/java/net/coreprotect/listener/player/InventoryChangeListener.java index c8f2e41..9bbe64e 100644 --- a/src/main/java/net/coreprotect/listener/player/InventoryChangeListener.java +++ b/src/main/java/net/coreprotect/listener/player/InventoryChangeListener.java @@ -59,7 +59,7 @@ public final class InventoryChangeListener extends Queue implements Listener { BlockState blockState = location.getBlock().getState(); Material type = blockState.getType(); - if (BlockGroup.CONTAINERS.contains(type)) { + if (BlockGroup.CONTAINERS.contains(type) && blockState instanceof InventoryHolder) { InventoryHolder inventoryHolder = (InventoryHolder) blockState; return onInventoryInteract(user, inventoryHolder.getInventory(), inventoryData, null, location, false); } diff --git a/src/main/java/net/coreprotect/listener/player/PlayerDeathListener.java b/src/main/java/net/coreprotect/listener/player/PlayerDeathListener.java index 1b723bf..cf14696 100644 --- a/src/main/java/net/coreprotect/listener/player/PlayerDeathListener.java +++ b/src/main/java/net/coreprotect/listener/player/PlayerDeathListener.java @@ -32,14 +32,14 @@ public final class PlayerDeathListener extends Queue implements Listener { return; } - Player player = (Player) entity; + String user = ((Player) entity).getName(); List items = event.getDrops(); if (items == null || items.size() == 0) { return; } for (ItemStack itemStack : items) { - PlayerDropItemListener.playerDropItem(location, player, itemStack); + PlayerDropItemListener.playerDropItem(location, user, itemStack); } } diff --git a/src/main/java/net/coreprotect/listener/player/PlayerDropItemListener.java b/src/main/java/net/coreprotect/listener/player/PlayerDropItemListener.java index 9618caa..68b0516 100644 --- a/src/main/java/net/coreprotect/listener/player/PlayerDropItemListener.java +++ b/src/main/java/net/coreprotect/listener/player/PlayerDropItemListener.java @@ -6,7 +6,6 @@ import java.util.Locale; import org.bukkit.Location; import org.bukkit.entity.Item; -import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -19,12 +18,12 @@ import net.coreprotect.consumer.Queue; public final class PlayerDropItemListener extends Queue implements Listener { - protected static void playerDropItem(Location location, Player player, ItemStack itemStack) { - if (itemStack == null) { + public static void playerDropItem(Location location, String user, ItemStack itemStack) { + if (!Config.getConfig(location.getWorld()).ITEM_DROPS || itemStack == null) { return; } - String loggingItemId = player.getName().toLowerCase(Locale.ROOT) + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ(); + String loggingItemId = user.toLowerCase(Locale.ROOT) + "." + location.getBlockX() + "." + location.getBlockY() + "." + location.getBlockZ(); int itemId = getItemId(loggingItemId); List list = ConfigHandler.itemsDrop.getOrDefault(loggingItemId, new ArrayList<>()); @@ -32,20 +31,14 @@ public final class PlayerDropItemListener extends Queue implements Listener { ConfigHandler.itemsDrop.put(loggingItemId, list); int time = (int) (System.currentTimeMillis() / 1000L) + 1; - Queue.queueItemTransaction(player.getName(), location.clone(), time, itemId); + Queue.queueItemTransaction(user, location.clone(), time, itemId); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) protected void onPlayerDropItem(PlayerDropItemEvent event) { Item item = event.getItemDrop(); - Location location = item.getLocation(); - if (!Config.getConfig(location.getWorld()).ITEM_DROPS) { - return; - } - - Player player = event.getPlayer(); ItemStack itemStack = item.getItemStack(); - playerDropItem(location, player, itemStack); + playerDropItem(item.getLocation(), event.getPlayer().getName(), itemStack); } } diff --git a/src/main/java/net/coreprotect/listener/player/PlayerInteractEntityListener.java b/src/main/java/net/coreprotect/listener/player/PlayerInteractEntityListener.java index d2e953d..5eb4188 100644 --- a/src/main/java/net/coreprotect/listener/player/PlayerInteractEntityListener.java +++ b/src/main/java/net/coreprotect/listener/player/PlayerInteractEntityListener.java @@ -1,8 +1,12 @@ package net.coreprotect.listener.player; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Player; @@ -11,10 +15,13 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerArmorStandManipulateEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; -import net.coreprotect.bukkit.BukkitAdapter; import net.coreprotect.config.Config; +import net.coreprotect.config.ConfigHandler; import net.coreprotect.consumer.Queue; +import net.coreprotect.model.BlockGroup; import net.coreprotect.utility.Util; public final class PlayerInteractEntityListener extends Queue implements Listener { @@ -27,24 +34,82 @@ public final class PlayerInteractEntityListener extends Queue implements Listene Player player = event.getPlayer(); final Entity entity = event.getRightClicked(); // change item in ItemFrame, etc - World world = entity.getWorld(); - - if (entity instanceof ItemFrame && !event.isCancelled() && Config.getConfig(world).BLOCK_PLACE) { + if (entity instanceof ItemFrame) { ItemFrame frame = (ItemFrame) entity; - if (frame.getItem().getType().equals(Material.AIR) && !player.getInventory().getItemInMainHand().getType().equals(Material.AIR)) { - Material material = BukkitAdapter.ADAPTER.getFrameType(entity); - int hand = Util.getBlockId(player.getInventory().getItemInMainHand().getType()); - int data = 0; + Material handType = Material.AIR; + ItemStack mainHand = player.getInventory().getItemInMainHand(); + ItemStack offHand = player.getInventory().getItemInOffHand(); + if (event.getHand().equals(EquipmentSlot.HAND) && mainHand.getType() != Material.AIR) { + handType = mainHand.getType(); + } + else if (event.getHand().equals(EquipmentSlot.OFF_HAND) && offHand.getType() != Material.AIR) { + handType = offHand.getType(); + } + else if (event.getHand().equals(EquipmentSlot.OFF_HAND)) { + return; + } - if (frame.getItem() != null) { - data = Util.getBlockId(frame.getItem().getType()); + if (ConfigHandler.inspecting.get(player.getName()) != null && ConfigHandler.inspecting.get(player.getName())) { + if (BlockGroup.CONTAINERS.contains(Material.ARMOR_STAND)) { + // logged armor stand items + ArmorStandManipulateListener.inspectHangingTransactions(frame.getLocation(), player); } - String playerName = player.getName(); - Block block = frame.getLocation().getBlock(); - Queue.queueBlockBreak(playerName, block.getState(), material, null, data); - Queue.queueBlockPlace(playerName, block.getState(), block.getType(), null, material, hand, 1, null); + event.setCancelled(true); + } + + if (event.isCancelled()) { + return; + } + + if (!Config.getConfig(player.getWorld()).ITEM_TRANSACTIONS) { + return; + } + + if (frame.getItem().getType().equals(Material.AIR) && !handType.equals(Material.AIR)) { + queueFrameTransaction(player.getName(), frame, false); } } } + + public static void queueFrameTransaction(String user, ItemFrame frame, boolean logDrop) { + ItemStack[] contents = Util.getItemFrameItem(frame); + Material type = Material.ITEM_FRAME; + Location frameLocation = frame.getLocation(); + int x = frameLocation.getBlockX(); + int y = frameLocation.getBlockY(); + int z = frameLocation.getBlockZ(); + + String transactingChestId = frameLocation.getWorld().getUID().toString() + "." + x + "." + y + "." + z; + String loggingChestId = user.toLowerCase(Locale.ROOT) + "." + x + "." + y + "." + z; + int chestId = Queue.getChestId(loggingChestId); + if (chestId > 0) { + if (ConfigHandler.forceContainer.get(loggingChestId) != null) { + int forceSize = ConfigHandler.forceContainer.get(loggingChestId).size(); + List list = ConfigHandler.oldContainer.get(loggingChestId); + + if (list.size() <= forceSize) { + list.add(Util.getContainerState(contents)); + ConfigHandler.oldContainer.put(loggingChestId, list); + } + } + } + else { + List list = new ArrayList<>(); + list.add(Util.getContainerState(contents)); + ConfigHandler.oldContainer.put(loggingChestId, list); + } + + ConfigHandler.transactingChest.computeIfAbsent(transactingChestId, k -> Collections.synchronizedList(new ArrayList<>())); + Queue.queueContainerTransaction(user, frameLocation, type, frame, chestId); + + if (logDrop) { + ItemStack dropItem = frame.getItem(); + if (dropItem.getType() == Material.AIR) { + return; + } + + PlayerDropItemListener.playerDropItem(frame.getLocation(), user, dropItem); + } + } } diff --git a/src/main/java/net/coreprotect/model/BlockGroup.java b/src/main/java/net/coreprotect/model/BlockGroup.java index c7039d9..409c2fd 100644 --- a/src/main/java/net/coreprotect/model/BlockGroup.java +++ b/src/main/java/net/coreprotect/model/BlockGroup.java @@ -17,7 +17,7 @@ public final class BlockGroup { public static Set TRACK_BOTTOM = new HashSet<>(Arrays.asList()); public static Set TRACK_SIDE = new HashSet<>(Arrays.asList(Material.WALL_TORCH, Material.REDSTONE_WALL_TORCH, Material.RAIL, Material.POWERED_RAIL, Material.DETECTOR_RAIL, Material.ACTIVATOR_RAIL, Material.WHITE_BED, Material.ORANGE_BED, Material.MAGENTA_BED, Material.LIGHT_BLUE_BED, Material.YELLOW_BED, Material.LIME_BED, Material.PINK_BED, Material.GRAY_BED, Material.LIGHT_GRAY_BED, Material.CYAN_BED, Material.PURPLE_BED, Material.BLUE_BED, Material.BROWN_BED, Material.GREEN_BED, Material.RED_BED, Material.BLACK_BED, Material.LADDER, Material.ACACIA_WALL_SIGN, Material.BIRCH_WALL_SIGN, Material.DARK_OAK_WALL_SIGN, Material.JUNGLE_WALL_SIGN, Material.OAK_WALL_SIGN, Material.SPRUCE_WALL_SIGN, Material.VINE, Material.COCOA, Material.TRIPWIRE_HOOK, Material.WHITE_WALL_BANNER, Material.ORANGE_WALL_BANNER, Material.MAGENTA_WALL_BANNER, Material.LIGHT_BLUE_WALL_BANNER, Material.YELLOW_WALL_BANNER, Material.LIME_WALL_BANNER, Material.PINK_WALL_BANNER, Material.GRAY_WALL_BANNER, Material.LIGHT_GRAY_WALL_BANNER, Material.CYAN_WALL_BANNER, Material.PURPLE_WALL_BANNER, Material.BLUE_WALL_BANNER, Material.BROWN_WALL_BANNER, Material.GREEN_WALL_BANNER, Material.RED_WALL_BANNER, Material.BLACK_WALL_BANNER)); public static Set SHULKER_BOXES = new HashSet<>(Arrays.asList(Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX)); - public static Set CONTAINERS = new HashSet<>(Arrays.asList(Material.DISPENSER, Material.CHEST, Material.FURNACE, Material.BREWING_STAND, Material.TRAPPED_CHEST, Material.HOPPER, Material.DROPPER, Material.ARMOR_STAND, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.SMOKER, Material.LECTERN)); + public static Set CONTAINERS = new HashSet<>(Arrays.asList(Material.DISPENSER, Material.CHEST, Material.FURNACE, Material.BREWING_STAND, Material.TRAPPED_CHEST, Material.HOPPER, Material.DROPPER, Material.ARMOR_STAND, Material.ITEM_FRAME, Material.SHULKER_BOX, Material.BLACK_SHULKER_BOX, Material.BLUE_SHULKER_BOX, Material.BROWN_SHULKER_BOX, Material.CYAN_SHULKER_BOX, Material.GRAY_SHULKER_BOX, Material.GREEN_SHULKER_BOX, Material.LIGHT_BLUE_SHULKER_BOX, Material.LIME_SHULKER_BOX, Material.MAGENTA_SHULKER_BOX, Material.ORANGE_SHULKER_BOX, Material.PINK_SHULKER_BOX, Material.PURPLE_SHULKER_BOX, Material.RED_SHULKER_BOX, Material.LIGHT_GRAY_SHULKER_BOX, Material.WHITE_SHULKER_BOX, Material.YELLOW_SHULKER_BOX, Material.BARREL, Material.BLAST_FURNACE, Material.SMOKER, Material.LECTERN)); public static Set DOORS = new HashSet<>(Arrays.asList(Material.OAK_DOOR, Material.SPRUCE_DOOR, Material.BIRCH_DOOR, Material.JUNGLE_DOOR, Material.ACACIA_DOOR, Material.DARK_OAK_DOOR)); public static Set BUTTONS = new HashSet<>(Arrays.asList(Material.STONE_BUTTON, Material.OAK_BUTTON, Material.ACACIA_BUTTON, Material.BIRCH_BUTTON, Material.DARK_OAK_BUTTON, Material.JUNGLE_BUTTON, Material.SPRUCE_BUTTON)); public static Set PRESSURE_PLATES = new HashSet<>(Arrays.asList(Material.STONE_PRESSURE_PLATE, Material.ACACIA_PRESSURE_PLATE, Material.BIRCH_PRESSURE_PLATE, Material.DARK_OAK_PRESSURE_PLATE, Material.HEAVY_WEIGHTED_PRESSURE_PLATE, Material.JUNGLE_PRESSURE_PLATE, Material.LIGHT_WEIGHTED_PRESSURE_PLATE, Material.OAK_PRESSURE_PLATE, Material.SPRUCE_PRESSURE_PLATE)); diff --git a/src/main/java/net/coreprotect/utility/Util.java b/src/main/java/net/coreprotect/utility/Util.java index 3e0f88d..486e39f 100755 --- a/src/main/java/net/coreprotect/utility/Util.java +++ b/src/main/java/net/coreprotect/utility/Util.java @@ -38,6 +38,7 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.configuration.serialization.DelegateDeserialization; import org.bukkit.entity.EntityType; +import org.bukkit.entity.ItemFrame; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.BlockInventoryHolder; @@ -400,7 +401,7 @@ public class Util extends Queue { } public static void mergeItems(Material material, ItemStack[] items) { - if (material != null && material.equals(Material.ARMOR_STAND)) { + if (material != null && (material.equals(Material.ARMOR_STAND) || BukkitAdapter.ADAPTER.isItemFrame(material))) { return; } try { @@ -681,13 +682,17 @@ public class Util extends Queue { container = location.getBlock(); } - if (type.equals(Material.ARMOR_STAND)) { + if (type == Material.ARMOR_STAND) { LivingEntity entity = (LivingEntity) container; EntityEquipment equipment = Util.getEntityEquipment(entity); if (equipment != null) { contents = getArmorStandContents(equipment); } } + else if (type == Material.ITEM_FRAME) { + ItemFrame entity = (ItemFrame) container; + contents = Util.getItemFrameItem(entity); + } else { Block block = (Block) container; Inventory inventory = Util.getContainerInventory(block.getState(), true); @@ -695,7 +700,8 @@ public class Util extends Queue { contents = inventory.getContents(); } } - if (type.equals(Material.ARMOR_STAND)) { + + if (type == Material.ARMOR_STAND || type == Material.ITEM_FRAME) { boolean hasItem = false; for (ItemStack item : contents) { if (item != null && !item.getType().equals(Material.AIR)) { @@ -753,6 +759,17 @@ public class Util extends Queue { return equipment; } + public static ItemStack[] getItemFrameItem(ItemFrame entity) { + ItemStack[] contents = null; + try { + contents = new ItemStack[] { entity.getItem() }; + } + catch (Exception e) { + e.printStackTrace(); + } + return contents; + } + public static int getEntityId(EntityType type) { return getEntityId(type.name(), true); } @@ -780,10 +797,12 @@ public class Util extends Queue { switch (type) { case ARMOR_STAND: return Material.ARMOR_STAND; + case ITEM_FRAME: + return Material.ITEM_FRAME; case ENDER_CRYSTAL: return Material.END_CRYSTAL; default: - return null; + return BukkitAdapter.ADAPTER.getFrameType(type); } } @@ -824,16 +843,6 @@ public class Util extends Queue { return type; } - public static int getHangingDelay(Map hangingDelay, int wid, int x, int y, int z) { - String token = wid + "." + x + "." + y + "." + z; - int delay = 0; - if (hangingDelay.get(token) != null) { - delay = hangingDelay.get(token) + 1; - } - hangingDelay.put(token, delay); - return delay; - } - public static int getItemStackHashCode(ItemStack item) { try { return item.hashCode(); diff --git a/src/main/java/net/coreprotect/utility/entity/HangingUtil.java b/src/main/java/net/coreprotect/utility/entity/HangingUtil.java index 4606a96..f0eb42d 100644 --- a/src/main/java/net/coreprotect/utility/entity/HangingUtil.java +++ b/src/main/java/net/coreprotect/utility/entity/HangingUtil.java @@ -3,7 +3,6 @@ package net.coreprotect.utility.entity; import java.util.Locale; import org.bukkit.Art; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; @@ -15,7 +14,6 @@ import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Painting; import org.bukkit.inventory.ItemStack; -import net.coreprotect.CoreProtect; import net.coreprotect.bukkit.BukkitAdapter; import net.coreprotect.model.BlockGroup; import net.coreprotect.utility.Util; @@ -27,178 +25,174 @@ public class HangingUtil { } @SuppressWarnings({ "unchecked", "rawtypes" }) - public static void spawnHanging(final BlockState blockstate, final Material rowType, final String hangingData, final int rowData, int delay) { - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> { - try { - Block block = blockstate.getBlock(); - int x = block.getX(); - int y = block.getY(); - int z = block.getZ(); + public static void spawnHanging(final BlockState blockstate, final Material rowType, final String hangingData, final int rowData) { + try { + Block block = blockstate.getBlock(); + int x = block.getX(); + int y = block.getY(); + int z = block.getZ(); - BlockFace hangingFace = null; - if (hangingData != null && !hangingData.contains(":") && hangingData.contains("=")) { + BlockFace hangingFace = null; + if (hangingData != null && !hangingData.contains(":") && hangingData.contains("=")) { + try { + hangingFace = BlockFace.valueOf(hangingData.split("=")[1].toUpperCase(Locale.ROOT)); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + for (Entity e : block.getChunk().getEntities()) { + if ((BukkitAdapter.ADAPTER.isItemFrame(rowType) && e instanceof ItemFrame) || (rowType.equals(Material.PAINTING) && e instanceof Painting)) { + Location el = e.getLocation(); + if (el.getBlockX() == x && el.getBlockY() == y && el.getBlockZ() == z) { + if (hangingFace == null || ((Hanging) e).getFacing() == hangingFace) { + e.remove(); + break; + } + } + } + } + + BlockFace faceSet = null; + BlockFace face = null; + if (hangingFace == null) { + Block c1 = block.getWorld().getBlockAt((x + 1), y, z); + Block c2 = block.getWorld().getBlockAt((x - 1), y, z); + Block c3 = block.getWorld().getBlockAt(x, y, (z + 1)); + Block c4 = block.getWorld().getBlockAt(x, y, (z - 1)); + + if (!BlockGroup.NON_ATTACHABLE.contains(c1.getType())) { + faceSet = BlockFace.WEST; + block = c1; + } + else if (!BlockGroup.NON_ATTACHABLE.contains(c2.getType())) { + faceSet = BlockFace.EAST; + block = c2; + } + else if (!BlockGroup.NON_ATTACHABLE.contains(c3.getType())) { + faceSet = BlockFace.NORTH; + block = c3; + } + else if (!BlockGroup.NON_ATTACHABLE.contains(c4.getType())) { + faceSet = BlockFace.SOUTH; + block = c4; + } + + if (!Util.solidBlock(Util.getType(block.getRelative(BlockFace.EAST)))) { + face = BlockFace.EAST; + } + else if (!Util.solidBlock(Util.getType(block.getRelative(BlockFace.NORTH)))) { + face = BlockFace.NORTH; + } + else if (!Util.solidBlock(Util.getType(block.getRelative(BlockFace.WEST)))) { + face = BlockFace.WEST; + } + else if (!Util.solidBlock(Util.getType(block.getRelative(BlockFace.SOUTH)))) { + face = BlockFace.SOUTH; + } + } + else { + faceSet = hangingFace; + face = hangingFace; + } + + if (faceSet != null && face != null) { + if (rowType.equals(Material.PAINTING)) { + String name = Util.getArtName(rowData); + Art painting = Art.getByName(name.toUpperCase(Locale.ROOT)); + int height = painting.getBlockHeight(); + int width = painting.getBlockWidth(); + int paintingX = x; + int paintingY = y; + int paintingZ = z; + if (height != 1 || width != 1) { + if (height > 1) { + if (height != 3) { + paintingY = paintingY - 1; + } + } + if (width > 1) { + if (faceSet.equals(BlockFace.WEST)) { + paintingZ--; + } + else if (faceSet.equals(BlockFace.SOUTH)) { + paintingX--; + } + } + } + Block spawnBlock = hangingFace != null ? block : block.getRelative(face); + if (hangingFace == null) { + Util.setTypeAndData(spawnBlock, Material.AIR, null, true); + } + Painting hanging = null; try { - hangingFace = BlockFace.valueOf(hangingData.split("=")[1].toUpperCase(Locale.ROOT)); + hanging = block.getWorld().spawn(spawnBlock.getLocation(), Painting.class); } catch (Exception e) { - e.printStackTrace(); + } + if (hanging != null) { + hanging.teleport(block.getWorld().getBlockAt(paintingX, paintingY, paintingZ).getLocation()); + hanging.setFacingDirection(faceSet, true); + hanging.setArt(painting, true); } } - - for (Entity e : block.getChunk().getEntities()) { - if ((BukkitAdapter.ADAPTER.isItemFrame(rowType) && e instanceof ItemFrame) || (rowType.equals(Material.PAINTING) && e instanceof Painting)) { - Location el = e.getLocation(); - if (el.getBlockX() == x && el.getBlockY() == y && el.getBlockZ() == z) { - if (hangingFace == null || ((Hanging) e).getFacing() == hangingFace) { - e.remove(); - break; - } - } - } - } - - BlockFace faceSet = null; - BlockFace face = null; - if (hangingFace == null) { - Block c1 = block.getWorld().getBlockAt((x + 1), y, z); - Block c2 = block.getWorld().getBlockAt((x - 1), y, z); - Block c3 = block.getWorld().getBlockAt(x, y, (z + 1)); - Block c4 = block.getWorld().getBlockAt(x, y, (z - 1)); - - if (!BlockGroup.NON_ATTACHABLE.contains(c1.getType())) { - faceSet = BlockFace.WEST; - block = c1; - } - else if (!BlockGroup.NON_ATTACHABLE.contains(c2.getType())) { - faceSet = BlockFace.EAST; - block = c2; - } - else if (!BlockGroup.NON_ATTACHABLE.contains(c3.getType())) { - faceSet = BlockFace.NORTH; - block = c3; - } - else if (!BlockGroup.NON_ATTACHABLE.contains(c4.getType())) { - faceSet = BlockFace.SOUTH; - block = c4; - } - - if (!Util.solidBlock(Util.getType(block.getRelative(BlockFace.EAST)))) { - face = BlockFace.EAST; - } - else if (!Util.solidBlock(Util.getType(block.getRelative(BlockFace.NORTH)))) { - face = BlockFace.NORTH; - } - else if (!Util.solidBlock(Util.getType(block.getRelative(BlockFace.WEST)))) { - face = BlockFace.WEST; - } - else if (!Util.solidBlock(Util.getType(block.getRelative(BlockFace.SOUTH)))) { - face = BlockFace.SOUTH; - } - } - else { - faceSet = hangingFace; - face = hangingFace; - } - - if (faceSet != null && face != null) { - if (rowType.equals(Material.PAINTING)) { - String name = Util.getArtName(rowData); - Art painting = Art.getByName(name.toUpperCase(Locale.ROOT)); - int height = painting.getBlockHeight(); - int width = painting.getBlockWidth(); - int paintingX = x; - int paintingY = y; - int paintingZ = z; - if (height != 1 || width != 1) { - if (height > 1) { - if (height != 3) { - paintingY = paintingY - 1; - } - } - if (width > 1) { - if (faceSet.equals(BlockFace.WEST)) { - paintingZ--; - } - else if (faceSet.equals(BlockFace.SOUTH)) { - paintingX--; - } - } - } + else if (BukkitAdapter.ADAPTER.isItemFrame(rowType)) { + try { Block spawnBlock = hangingFace != null ? block : block.getRelative(face); if (hangingFace == null) { Util.setTypeAndData(spawnBlock, Material.AIR, null, true); } - Painting hanging = null; - try { - hanging = block.getWorld().spawn(spawnBlock.getLocation(), Painting.class); - } - catch (Exception e) { - } - if (hanging != null) { - hanging.teleport(block.getWorld().getBlockAt(paintingX, paintingY, paintingZ).getLocation()); + Class itemFrame = BukkitAdapter.ADAPTER.getFrameClass(rowType); + Entity entity = block.getWorld().spawn(spawnBlock.getLocation(), itemFrame); + if (entity instanceof ItemFrame) { + ItemFrame hanging = (ItemFrame) entity; + hanging.teleport(block.getWorld().getBlockAt(x, y, z).getLocation()); hanging.setFacingDirection(faceSet, true); - hanging.setArt(painting, true); - } - } - else if (BukkitAdapter.ADAPTER.isItemFrame(rowType)) { - try { - Block spawnBlock = hangingFace != null ? block : block.getRelative(face); - if (hangingFace == null) { - Util.setTypeAndData(spawnBlock, Material.AIR, null, true); - } - Class itemFrame = BukkitAdapter.ADAPTER.getFrameClass(rowType); - Entity entity = block.getWorld().spawn(spawnBlock.getLocation(), itemFrame); - if (entity instanceof ItemFrame) { - ItemFrame hanging = (ItemFrame) entity; - hanging.teleport(block.getWorld().getBlockAt(x, y, z).getLocation()); - hanging.setFacingDirection(faceSet, true); - Material type = Util.getType(rowData); - if (type != null) { - ItemStack istack = new ItemStack(type, 1); - hanging.setItem(istack); - } + Material type = Util.getType(rowData); + if (type != null) { + ItemStack istack = new ItemStack(type, 1); + hanging.setItem(istack); } } - catch (Exception e) { - } - } - } - } - catch (Exception e) { - e.printStackTrace(); - } - }, delay); - } - - public static void removeHanging(final BlockState block, final String hangingData, int delay) { - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CoreProtect.getInstance(), () -> { - try { - BlockFace hangingFace = null; - if (hangingData != null && !hangingData.contains(":") && hangingData.contains("=")) { - try { - hangingFace = BlockFace.valueOf(hangingData.split("=")[1].toUpperCase(Locale.ROOT)); } catch (Exception e) { - e.printStackTrace(); } } + } + } + catch (Exception e) { + e.printStackTrace(); + } + } - for (Entity e : block.getChunk().getEntities()) { - if (e instanceof ItemFrame || e instanceof Painting) { - Location el = e.getLocation(); - if (el.getBlockX() == block.getX() && el.getBlockY() == block.getY() && el.getBlockZ() == block.getZ()) { - if (hangingFace == null || ((Hanging) e).getFacing() == hangingFace) { - e.remove(); - } + public static void removeHanging(final BlockState block, final String hangingData) { + try { + BlockFace hangingFace = null; + if (hangingData != null && !hangingData.contains(":") && hangingData.contains("=")) { + try { + hangingFace = BlockFace.valueOf(hangingData.split("=")[1].toUpperCase(Locale.ROOT)); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + for (Entity e : block.getChunk().getEntities()) { + if (e instanceof ItemFrame || e instanceof Painting) { + Location el = e.getLocation(); + if (el.getBlockX() == block.getX() && el.getBlockY() == block.getY() && el.getBlockZ() == block.getZ()) { + if (hangingFace == null || ((Hanging) e).getFacing() == hangingFace) { + e.remove(); } } } } - catch (Exception e) { - e.printStackTrace(); - } - }, delay); + } + catch (Exception e) { + e.printStackTrace(); + } } }