445 lines
19 KiB
Java
445 lines
19 KiB
Java
package com.earth2me.essentials.antibuild;
|
|
|
|
import com.earth2me.essentials.User;
|
|
import com.earth2me.essentials.utils.VersionUtil;
|
|
import net.ess3.api.IEssentials;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.entity.ArmorStand;
|
|
import org.bukkit.entity.EnderCrystal;
|
|
import org.bukkit.entity.Entity;
|
|
import org.bukkit.entity.EntityType;
|
|
import org.bukkit.entity.HumanEntity;
|
|
import org.bukkit.entity.ItemFrame;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.entity.Projectile;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.EventPriority;
|
|
import org.bukkit.event.Listener;
|
|
import org.bukkit.event.block.BlockBreakEvent;
|
|
import org.bukkit.event.block.BlockDispenseEvent;
|
|
import org.bukkit.event.block.BlockPistonExtendEvent;
|
|
import org.bukkit.event.block.BlockPistonRetractEvent;
|
|
import org.bukkit.event.block.BlockPlaceEvent;
|
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
|
import org.bukkit.event.entity.EntityPickupItemEvent;
|
|
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
|
import org.bukkit.event.inventory.CraftItemEvent;
|
|
import org.bukkit.event.player.PlayerDropItemEvent;
|
|
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
|
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
|
import org.bukkit.event.player.PlayerInteractEvent;
|
|
import org.bukkit.event.player.PlayerPickupItemEvent;
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import java.util.logging.Level;
|
|
|
|
import static com.earth2me.essentials.I18n.tl;
|
|
|
|
public class EssentialsAntiBuildListener implements Listener {
|
|
final private transient IAntiBuild prot;
|
|
final private transient IEssentials ess;
|
|
|
|
EssentialsAntiBuildListener(final IAntiBuild parent) {
|
|
this.prot = parent;
|
|
this.ess = prot.getEssentialsConnect().getEssentials();
|
|
|
|
if (isEntityPickupEvent()) {
|
|
ess.getServer().getPluginManager().registerEvents(new EntityPickupItemListener(), prot);
|
|
} else {
|
|
ess.getServer().getPluginManager().registerEvents(new PlayerPickupItemListener(), prot);
|
|
}
|
|
}
|
|
|
|
private static boolean isEntityPickupEvent() {
|
|
try {
|
|
Class.forName("org.bukkit.event.entity.EntityPickupItemEvent");
|
|
return true;
|
|
} catch (final ClassNotFoundException ignored) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private boolean metaPermCheck(final User user, final String action, final Block block) {
|
|
if (block == null) {
|
|
if (ess.getSettings().isDebug()) {
|
|
prot.getLogger().log(Level.INFO, "AntiBuild permission check failed, invalid block.");
|
|
}
|
|
return false;
|
|
}
|
|
if (VersionUtil.PRE_FLATTENING) {
|
|
return metaPermCheck(user, action, block.getType(), block.getData());
|
|
}
|
|
return metaPermCheck(user, action, block.getType());
|
|
}
|
|
|
|
private boolean metaPermCheck(final User user, final String action, final ItemStack item) {
|
|
if (item == null) {
|
|
if (ess.getSettings().isDebug()) {
|
|
prot.getLogger().log(Level.INFO, "AntiBuild permission check failed, invalid item.");
|
|
}
|
|
return false;
|
|
}
|
|
if (VersionUtil.PRE_FLATTENING) {
|
|
return metaPermCheck(user, action, item.getType(), item.getDurability());
|
|
}
|
|
return metaPermCheck(user, action, item.getType());
|
|
}
|
|
|
|
public boolean metaPermCheck(final User user, final String action, final Material material) {
|
|
final String blockPerm = "essentials.build." + action + "." + material;
|
|
return user.isAuthorized(blockPerm);
|
|
}
|
|
|
|
private boolean metaPermCheck(final User user, final String action, final Material material, final short data) {
|
|
final String blockPerm = "essentials.build." + action + "." + material;
|
|
final String dataPerm = blockPerm + ":" + data;
|
|
|
|
if (VersionUtil.PRE_FLATTENING) {
|
|
if (user.getBase().isPermissionSet(dataPerm)) {
|
|
return user.isAuthorized(dataPerm);
|
|
} else {
|
|
if (ess.getSettings().isDebug()) {
|
|
prot.getLogger().log(Level.INFO, "DataValue perm on " + user.getName() + " is not directly set: " + dataPerm);
|
|
}
|
|
}
|
|
}
|
|
|
|
return user.isAuthorized(blockPerm);
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
public void onBlockPlace(final BlockPlaceEvent event) {
|
|
final User user = ess.getUser(event.getPlayer());
|
|
final Block block = event.getBlockPlaced();
|
|
final Material type = block.getType();
|
|
|
|
// Happens with blocks like eyes of ender, we shouldn't treat state changes as a block place.
|
|
if (type.equals(event.getBlockReplacedState().getType())) {
|
|
return;
|
|
}
|
|
|
|
if (prot.getSettingBool(AntiBuildConfig.disable_build) && !user.canBuild() && !metaPermCheck(user, "place", block)) {
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildPlace", EssentialsAntiBuild.getNameForType(type)));
|
|
}
|
|
event.setCancelled(true);
|
|
return;
|
|
}
|
|
|
|
if (prot.checkProtectionItems(AntiBuildConfig.blacklist_placement, type) && !user.isAuthorized("essentials.protect.exemptplacement")) {
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildPlace", EssentialsAntiBuild.getNameForType(type)));
|
|
}
|
|
event.setCancelled(true);
|
|
return;
|
|
}
|
|
|
|
if (prot.checkProtectionItems(AntiBuildConfig.alert_on_placement, type) && !user.isAuthorized("essentials.protect.alerts.notrigger")) {
|
|
prot.getEssentialsConnect().alert(user, EssentialsAntiBuild.getNameForType(type), tl("alertPlaced"));
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
public void onBlockBreak(final BlockBreakEvent event) {
|
|
final User user = ess.getUser(event.getPlayer());
|
|
final Block block = event.getBlock();
|
|
final Material type = block.getType();
|
|
|
|
if (prot.getSettingBool(AntiBuildConfig.disable_build) && !user.canBuild() && !metaPermCheck(user, "break", block)) {
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildBreak", EssentialsAntiBuild.getNameForType(type)));
|
|
}
|
|
event.setCancelled(true);
|
|
return;
|
|
}
|
|
|
|
if (prot.checkProtectionItems(AntiBuildConfig.blacklist_break, type) && !user.isAuthorized("essentials.protect.exemptbreak")) {
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildBreak", EssentialsAntiBuild.getNameForType(type)));
|
|
}
|
|
event.setCancelled(true);
|
|
return;
|
|
}
|
|
|
|
if (prot.checkProtectionItems(AntiBuildConfig.alert_on_break, type) && !user.isAuthorized("essentials.protect.alerts.notrigger")) {
|
|
prot.getEssentialsConnect().alert(user, EssentialsAntiBuild.getNameForType(type), tl("alertBroke"));
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
public void onHangingBreak(final HangingBreakByEntityEvent event) {
|
|
final Entity entity = event.getRemover();
|
|
if (entity instanceof Player) {
|
|
final User user = ess.getUser((Player) entity);
|
|
final EntityType type = event.getEntity().getType();
|
|
final boolean warn = ess.getSettings().warnOnBuildDisallow();
|
|
if (prot.getSettingBool(AntiBuildConfig.disable_build) && !user.canBuild()) {
|
|
if (type == EntityType.PAINTING && !metaPermCheck(user, "break", Material.PAINTING)) {
|
|
if (warn) {
|
|
user.sendMessage(tl("antiBuildBreak", Material.PAINTING.toString()));
|
|
}
|
|
event.setCancelled(true);
|
|
} else if (type == EntityType.ITEM_FRAME && !metaPermCheck(user, "break", Material.ITEM_FRAME)) {
|
|
if (warn) {
|
|
user.sendMessage(tl("antiBuildBreak", Material.ITEM_FRAME.toString()));
|
|
}
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
|
public void onItemFrameInteract(final PlayerInteractEntityEvent event) {
|
|
if (event.getPlayer().hasMetadata("NPC")) {
|
|
return;
|
|
}
|
|
|
|
final User user = ess.getUser(event.getPlayer());
|
|
|
|
if (!(event.getRightClicked() instanceof ItemFrame)) {
|
|
return;
|
|
}
|
|
|
|
if (prot.getSettingBool(AntiBuildConfig.disable_build) && !user.canBuild() && !user.isAuthorized("essentials.build") && !metaPermCheck(user, "place", Material.ITEM_FRAME)) {
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildPlace", Material.ITEM_FRAME.toString()));
|
|
}
|
|
event.setCancelled(true);
|
|
return;
|
|
}
|
|
|
|
if (prot.checkProtectionItems(AntiBuildConfig.blacklist_placement, Material.ITEM_FRAME) && !user.isAuthorized("essentials.protect.exemptplacement")) {
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildPlace", Material.ITEM_FRAME.toString()));
|
|
}
|
|
event.setCancelled(true);
|
|
return;
|
|
}
|
|
|
|
if (prot.checkProtectionItems(AntiBuildConfig.alert_on_placement, Material.ITEM_FRAME) && !user.isAuthorized("essentials.protect.alerts.notrigger")) {
|
|
prot.getEssentialsConnect().alert(user, Material.ITEM_FRAME.toString(), tl("alertPlaced"));
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
|
public void onArmorStandInteract(final PlayerInteractAtEntityEvent event) {
|
|
if (event.getPlayer().hasMetadata("NPC")) {
|
|
return;
|
|
}
|
|
|
|
final User user = ess.getUser(event.getPlayer());
|
|
|
|
if (!(event.getRightClicked() instanceof ArmorStand)) {
|
|
return;
|
|
}
|
|
|
|
if (prot.getSettingBool(AntiBuildConfig.disable_build) && !user.canBuild() && !user.isAuthorized("essentials.build") && !metaPermCheck(user, "place", Material.ARMOR_STAND)) {
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildPlace", Material.ARMOR_STAND.toString()));
|
|
}
|
|
event.setCancelled(true);
|
|
return;
|
|
}
|
|
|
|
if (prot.checkProtectionItems(AntiBuildConfig.blacklist_placement, Material.ARMOR_STAND) && !user.isAuthorized("essentials.protect.exemptplacement")) {
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildPlace", Material.ARMOR_STAND.toString()));
|
|
}
|
|
event.setCancelled(true);
|
|
return;
|
|
}
|
|
|
|
if (prot.checkProtectionItems(AntiBuildConfig.alert_on_placement, Material.ARMOR_STAND) && !user.isAuthorized("essentials.protect.alerts.notrigger")) {
|
|
prot.getEssentialsConnect().alert(user, Material.ARMOR_STAND.toString(), tl("alertPlaced"));
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
public void onBlockEntityDamage(final EntityDamageByEntityEvent event) {
|
|
Player player = null;
|
|
|
|
if (event.getDamager() instanceof Player) {
|
|
player = (Player) event.getDamager();
|
|
} else if (event.getDamager() instanceof Projectile && ((Projectile) event.getDamager()).getShooter() instanceof Player) {
|
|
player = (Player) ((Projectile) event.getDamager()).getShooter();
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
final User user = ess.getUser(player);
|
|
Material type = null;
|
|
|
|
if (event.getEntity() instanceof ItemFrame) {
|
|
type = Material.ITEM_FRAME;
|
|
} else if (event.getEntity() instanceof ArmorStand) {
|
|
type = Material.ARMOR_STAND;
|
|
} else if (event.getEntity() instanceof EnderCrystal) {
|
|
type = Material.END_CRYSTAL;
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
if (prot.getSettingBool(AntiBuildConfig.disable_build) && !user.canBuild() && !user.isAuthorized("essentials.build") && !metaPermCheck(user, "break", type)) {
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildBreak", type.toString()));
|
|
}
|
|
event.setCancelled(true);
|
|
return;
|
|
}
|
|
|
|
if (prot.checkProtectionItems(AntiBuildConfig.blacklist_break, type) && !user.isAuthorized("essentials.protect.exemptbreak")) {
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildBreak", type.toString()));
|
|
}
|
|
event.setCancelled(true);
|
|
return;
|
|
}
|
|
|
|
if (prot.checkProtectionItems(AntiBuildConfig.alert_on_break, type) && !user.isAuthorized("essentials.protect.alerts.notrigger")) {
|
|
prot.getEssentialsConnect().alert(user, type.toString(), tl("alertBroke"));
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
public void onBlockPistonExtend(final BlockPistonExtendEvent event) {
|
|
for (final Block block : event.getBlocks()) {
|
|
if (prot.checkProtectionItems(AntiBuildConfig.blacklist_piston, block.getType())) {
|
|
event.setCancelled(true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
public void onBlockPistonRetract(final BlockPistonRetractEvent event) {
|
|
if (!event.isSticky()) {
|
|
return;
|
|
}
|
|
for (final Block block : event.getBlocks()) {
|
|
if (prot.checkProtectionItems(AntiBuildConfig.blacklist_piston, block.getType())) {
|
|
event.setCancelled(true);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.LOW)
|
|
public void onPlayerInteract(final PlayerInteractEvent event) {
|
|
if (event.getPlayer().hasMetadata("NPC")) {
|
|
return;
|
|
}
|
|
|
|
// Do not return if cancelled, because the interact event has 2 cancelled states.
|
|
final User user = ess.getUser(event.getPlayer());
|
|
final ItemStack item = event.getItem();
|
|
|
|
if (item != null && prot.checkProtectionItems(AntiBuildConfig.blacklist_usage, item.getType()) && !user.isAuthorized("essentials.protect.exemptusage")) {
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildUse", item.getType().toString()));
|
|
}
|
|
event.setCancelled(true);
|
|
return;
|
|
}
|
|
|
|
if (item != null && prot.checkProtectionItems(AntiBuildConfig.alert_on_use, item.getType()) && !user.isAuthorized("essentials.protect.alerts.notrigger")) {
|
|
prot.getEssentialsConnect().alert(user, item.getType().toString(), tl("alertUsed"));
|
|
}
|
|
|
|
if (prot.getSettingBool(AntiBuildConfig.disable_use) && !user.canBuild()) {
|
|
if (event.hasItem() && !metaPermCheck(user, "interact", item)) {
|
|
event.setCancelled(true);
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildUse", item.getType().toString()));
|
|
}
|
|
return;
|
|
}
|
|
if (event.hasBlock() && !metaPermCheck(user, "interact", event.getClickedBlock())) {
|
|
event.setCancelled(true);
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildInteract", event.getClickedBlock().getType().toString()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
public void onCraftItemEvent(final CraftItemEvent event) {
|
|
final HumanEntity entity = event.getWhoClicked();
|
|
|
|
if (entity instanceof Player) {
|
|
final User user = ess.getUser((Player) entity);
|
|
final ItemStack item = event.getRecipe().getResult();
|
|
|
|
if (prot.getSettingBool(AntiBuildConfig.disable_use) && !user.canBuild()) {
|
|
if (!metaPermCheck(user, "craft", item)) {
|
|
event.setCancelled(true);
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildCraft", item.getType().toString()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
public void onPlayerDropItem(final PlayerDropItemEvent event) {
|
|
|
|
final User user = ess.getUser(event.getPlayer());
|
|
final ItemStack item = event.getItemDrop().getItemStack();
|
|
|
|
if (prot.getSettingBool(AntiBuildConfig.disable_use) && !user.canBuild()) {
|
|
if (!metaPermCheck(user, "drop", item)) {
|
|
event.setCancelled(true);
|
|
user.getBase().updateInventory();
|
|
if (ess.getSettings().warnOnBuildDisallow()) {
|
|
user.sendMessage(tl("antiBuildDrop", item.getType().toString()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
public void onBlockDispense(final BlockDispenseEvent event) {
|
|
final ItemStack item = event.getItem();
|
|
if (prot.checkProtectionItems(AntiBuildConfig.blacklist_dispenser, item.getType())) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
|
|
private class EntityPickupItemListener implements Listener {
|
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
public void onPlayerPickupItem(final EntityPickupItemEvent event) {
|
|
if (!(event.getEntity() instanceof Player)) return;
|
|
|
|
final User user = ess.getUser((Player) event.getEntity());
|
|
final ItemStack item = event.getItem().getItemStack();
|
|
|
|
if (prot.getSettingBool(AntiBuildConfig.disable_use) && !user.canBuild()) {
|
|
if (!metaPermCheck(user, "pickup", item)) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private class PlayerPickupItemListener implements Listener {
|
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
|
public void onPlayerPickupItem(final PlayerPickupItemEvent event) {
|
|
if (event.getPlayer().hasMetadata("NPC")) {
|
|
return;
|
|
}
|
|
|
|
final User user = ess.getUser(event.getPlayer());
|
|
final ItemStack item = event.getItem().getItemStack();
|
|
|
|
if (prot.getSettingBool(AntiBuildConfig.disable_use) && !user.canBuild()) {
|
|
if (!metaPermCheck(user, "pickup", item)) {
|
|
event.setCancelled(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|