Add BlockDispenseEvent listener to ensure armor stands placed through dispensers respect the armor stand chunk limit

This commit is contained in:
akastijn 2026-01-21 07:10:46 +01:00
parent f7313f8f25
commit 4b1c2078eb

View File

@ -11,13 +11,16 @@ import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
import org.bukkit.block.Dispenser;
import org.bukkit.block.TrialSpawner;
import org.bukkit.block.data.Directional;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockDispenseEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.persistence.PersistentDataContainer;
@ -87,8 +90,10 @@ import java.util.Optional;
if (!willBreak) {
return;
}
Optional<ChunkContainerAndNamespacedKey> optionalResult = getGetChunkContainerAndNamespacedKey(armorStand.getLocation().getChunk(), player);
Optional<ChunkContainerAndNamespacedKey> optionalResult = getGetChunkContainerAndNamespacedKey(armorStand.getLocation().getChunk());
if (optionalResult.isEmpty()) {
player.sendRichMessage("<red>Something went wrong while checking the armor stand count. " +
"You will not be able to place this until this is fixed. Please contact a staff member</red>");
event.setCancelled(true);
return;
}
@ -100,6 +105,40 @@ import java.util.Optional;
private record ChunkContainerAndNamespacedKey(NamespacedKey namespacedKey, PersistentDataContainer persistentDataContainer, int armorStandCount) {
}
@EventHandler
public void onBlockDispense(BlockDispenseEvent event) {
if (!event.getItem().getType().equals(Material.ARMOR_STAND)) {
return;
}
Block block = event.getBlock();
if (!(block.getState() instanceof Dispenser)) {
return;
}
if (!(block.getBlockData() instanceof Directional directional)) {
return;
}
Chunk targetChunk = block.getRelative(directional.getFacing()).getChunk();
Optional<ChunkContainerAndNamespacedKey> optional = getGetChunkContainerAndNamespacedKey(targetChunk);
if (optional.isEmpty()) {
event.setCancelled(true);
return;
}
ChunkContainerAndNamespacedKey result = optional.get();
Optional<Integer> optionalLimit = Config.ARMOR_STAND_LIMIT.LIMIT.values().stream().min(Integer::compareTo);
if (optionalLimit.isEmpty()) {
log.error("Unable to find a valid limit for armor stands");
event.setCancelled(true);
return;
}
if (result.armorStandCount() >= optionalLimit.get()) {
event.setCancelled(true);
return;
}
result.persistentDataContainer().set(result.namespacedKey(), PersistentDataType.INTEGER, result.armorStandCount() + 1);
}
private void handleArmorStandPlacing(PlayerInteractEvent event, ArmorStandCountConsumer consumer) {
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
return;
@ -112,8 +151,10 @@ import java.util.Optional;
}
Player player = event.getPlayer();
Chunk chunk = event.getClickedBlock().getChunk();
Optional<ChunkContainerAndNamespacedKey> getChunkContainerAndNamespacedKey = getGetChunkContainerAndNamespacedKey(chunk, player);
Optional<ChunkContainerAndNamespacedKey> getChunkContainerAndNamespacedKey = getGetChunkContainerAndNamespacedKey(chunk);
if (getChunkContainerAndNamespacedKey.isEmpty()) {
player.sendRichMessage("<red>Something went wrong while checking the armor stand count. " +
"You will not be able to place this until this is fixed. Please contact a staff member</red>");
event.setCancelled(true);
return;
}
@ -121,12 +162,10 @@ import java.util.Optional;
consumer.apply(result.armorStandCount(), event.getPlayer(), result.namespacedKey(), result.persistentDataContainer());
}
private Optional<LimitArmorStands.ChunkContainerAndNamespacedKey> getGetChunkContainerAndNamespacedKey(Chunk chunk, Player player) {
private Optional<LimitArmorStands.ChunkContainerAndNamespacedKey> getGetChunkContainerAndNamespacedKey(Chunk chunk) {
NamespacedKey namespacedKey = NamespacedKey.fromString("armor_stand_count", playerUtils);
if (namespacedKey == null) {
log.warn("Unable to retrieve name spaced key for armor stand count.");
player.sendRichMessage("<red>Something went wrong while checking the armor stand count. " +
"You will not be able to place this until this is fixed. Please contact a staff member</red>");
return Optional.empty();
}
PersistentDataContainer persistentDataContainer = chunk.getPersistentDataContainer();