diff --git a/pom.xml b/pom.xml
index 799b8bfc2..d9b064db8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,6 +64,12 @@
+
+ org.bukkit
+ bukkit
+ 1.12.2-R0.1-SNAPSHOT
+ provided
+
org.mockito
mockito-all
@@ -71,28 +77,22 @@
test
- org.bukkit
- bukkit
- 1.12.2-R0.1-SNAPSHOT
- provided
+ org.powermock
+ powermock-module-junit4
+ ${powermock.version}
+ test
+
+
+ org.powermock
+ powermock-api-mockito
+ ${powermock.version}
+ test
-
- org.powermock
- powermock-module-junit4
- ${powermock.version}
- test
-
-
- org.powermock
- powermock-api-mockito
- ${powermock.version}
- test
-
spigot-repo
- https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+ https://hub.spigotmc.org/nexus/content/repositories/snapshots
diff --git a/src/main/java/us/tastybento/bskyblock/api/commands/User.java b/src/main/java/us/tastybento/bskyblock/api/commands/User.java
index 1826e3848..ce59e3556 100644
--- a/src/main/java/us/tastybento/bskyblock/api/commands/User.java
+++ b/src/main/java/us/tastybento/bskyblock/api/commands/User.java
@@ -257,4 +257,10 @@ public class User {
return Locale.forLanguageTag(plugin.getSettings().getDefaultLanguage());
}
+
+ @SuppressWarnings("deprecation")
+ public void updateInventory() {
+ player.updateInventory();
+
+ }
}
diff --git a/src/main/java/us/tastybento/bskyblock/listeners/FlagListener.java b/src/main/java/us/tastybento/bskyblock/listeners/FlagListener.java
index 1ee308626..dedf42541 100644
--- a/src/main/java/us/tastybento/bskyblock/listeners/FlagListener.java
+++ b/src/main/java/us/tastybento/bskyblock/listeners/FlagListener.java
@@ -3,20 +3,19 @@
*/
package us.tastybento.bskyblock.listeners;
+import java.util.Optional;
+
import org.bukkit.Location;
import org.bukkit.entity.Entity;
+import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
-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.BlockPlaceEvent;
-import org.bukkit.event.entity.PlayerLeashEntityEvent;
-import org.bukkit.event.inventory.InventoryMoveItemEvent;
-import org.bukkit.event.inventory.InventoryPickupItemEvent;
+import org.bukkit.event.player.PlayerEvent;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.commands.User;
+import us.tastybento.bskyblock.api.flags.Flag;
+import us.tastybento.bskyblock.database.objects.Island;
/**
* Abstract class for flag listeners to inherit. Provides some common code.
@@ -24,71 +23,74 @@ import us.tastybento.bskyblock.api.commands.User;
*
*/
public abstract class FlagListener implements Listener {
-
- private static final boolean DEBUG = false;
+
protected BSkyBlock plugin;
- protected User user;
-
+ private User user = null;
+
public FlagListener(BSkyBlock plugin) {
super();
this.plugin = plugin;
}
-
- @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
- public void onEvent(Event e) {
- if (DEBUG) {
- plugin.getLogger().info(e.getEventName());
- }
+
+ /**
+ * Sets the player associated with this event.
+ * If the user is a fake player, they are not counted.
+ * @param e - the event
+ * @return user or empty
+ */
+ protected Optional getEventUser(Event e) {
+ // Set the user
+ if (e instanceof PlayerEvent) {
+ user = User.getInstance(((PlayerEvent)e).getPlayer());
+ // Handle fake players
+ if (plugin.getSettings().getFakePlayers().contains(user.getName())) user = null;
+ }
+ return Optional.ofNullable(user);
+ }
+
+ /**
+ * Explicitly set the user
+ * @param user
+ */
+ protected void setUser(User user) {
+ this.user = user;
+ }
+
+ /**
+ * Get the user associated with this event
+ * @return User or null
+ */
+ protected User getUser() {
+ return user;
}
/*
* The following methods cover the cancellable events and enable a simple noGo(e) to be used to cancel and send the error message
*/
+
/**
- * Sends the island protected message to user
- * @param e
+ * Cancels the event and sends the island protected message to user
+ * @param e Event
*/
- protected void noGo(BlockBreakEvent e) {
- e.setCancelled(true);
- user.sendMessage("protection.protected");
+ protected void noGo(Event e) {
+ noGo(e, false);
}
-
+
/**
- * Sends the island protected message to user
- * @param e
+ * Cancels the event and sends the island protected message to user unless silent is true
+ * @param e Event
+ * @param silent - if true, message is not sent
*/
- protected void noGo(BlockPlaceEvent e) {
- e.setCancelled(true);
- user.sendMessage("protection.protected");
+ protected void noGo(Event e, boolean silent) {
+ if (e instanceof Cancellable)
+ ((Cancellable)e).setCancelled(true);
+ if (user != null) {
+ if (!silent)
+ user.sendMessage("protection.protected");
+ user.updateInventory();
+ }
}
-
- /**
- * Sends the island protected message to user
- * @param e
- */
- protected void noGo(InventoryPickupItemEvent e) {
- e.setCancelled(true);
- user.sendMessage("protection.protected");
- }
-
- /**
- * Sends the island protected message to user
- * @param e
- */
- protected void noGo(PlayerLeashEntityEvent e) {
- e.setCancelled(true);
- user.sendMessage("protection.protected");
- }
-
- /**
- * Sends the island protected message to user
- * @param e
- */
- protected void noGo(InventoryMoveItemEvent e) {
- e.setCancelled(true);
- user.sendMessage("protection.protected");
- }
-
+
/**
* Check if loc is in the island worlds
* @param loc
@@ -99,7 +101,7 @@ public abstract class FlagListener implements Listener {
|| loc.getWorld().equals(plugin.getIslandWorldManager().getNetherWorld())
|| loc.getWorld().equals(plugin.getIslandWorldManager().getEndWorld())) ? true : false;
}
-
+
/**
* Check if the entity is in the island worlds
* @param entity - the entity
@@ -108,5 +110,64 @@ public abstract class FlagListener implements Listener {
protected boolean inWorld(Entity entity) {
return inWorld(entity.getLocation());
}
-
+
+ /**
+ * Check if user is in the island worlds
+ * @param user - a user
+ * @return true if in world
+ */
+ protected boolean inWorld(User user) {
+ return inWorld(user.getLocation());
+ }
+
+ /**
+ * Generic place blocks checker
+ * @param e
+ * @param loc
+ * @return true if the check is okay, false if it was disallowed
+ */
+ protected boolean checkIsland(Event e, Location loc, Flag flag) {
+ return checkIsland(e, loc, flag, false);
+ }
+
+
+
+ /**
+ * Generic place blocks checker
+ * @param e
+ * @param loc
+ * @param silent - if true, no attempt is made to tell the user
+ * @return true if the check is okay, false if it was disallowed
+ */
+ protected boolean checkIsland(Event e, Location loc, Flag flag, boolean silent) {
+ // If the user is not set, try to get it from the event
+ if (getUser() == null) {
+ // Set the user associated with this event
+ if (!getEventUser(e).isPresent()) return true;
+ }
+ // If this is not an Island World, skip
+ if (!inWorld(getUser())) return true;
+
+ // Get the island and if present, check the flag, react if required and return
+ Optional island = plugin.getIslands().getIslandAt(loc);
+
+ if (island.isPresent()) {
+ if (!island.get().isAllowed(getUser(), flag)) {
+ noGo(e, silent);
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ // The player is in the world, but not on an island, so general world settings apply
+ if (!flag.isAllowed()) {
+ noGo(e, silent);
+ return false;
+ } else {
+ return true;
+ }
+
+ }
+
}
diff --git a/src/main/java/us/tastybento/bskyblock/listeners/flags/AnvilListener.java b/src/main/java/us/tastybento/bskyblock/listeners/flags/AnvilListener.java
new file mode 100644
index 000000000..0a662e69e
--- /dev/null
+++ b/src/main/java/us/tastybento/bskyblock/listeners/flags/AnvilListener.java
@@ -0,0 +1,39 @@
+/**
+ *
+ */
+package us.tastybento.bskyblock.listeners.flags;
+
+import org.bukkit.Material;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.block.Action;
+import org.bukkit.event.player.PlayerInteractEvent;
+
+import us.tastybento.bskyblock.BSkyBlock;
+import us.tastybento.bskyblock.listeners.FlagListener;
+import us.tastybento.bskyblock.lists.Flags;
+
+/**
+ * @author ben
+ *
+ */
+public class AnvilListener extends FlagListener {
+
+ public AnvilListener() {
+ super(BSkyBlock.getInstance());
+ }
+
+ /**
+ * Handle placing of Anvils
+ * @param e
+ */
+ @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
+ public void onPlayerInteract(final PlayerInteractEvent e) {
+ if (!e.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
+ return;
+ }
+ if (e.getClickedBlock().getType().equals(Material.ANVIL)) {
+ checkIsland(e, getUser().getLocation(), Flags.ANVIL);
+ }
+ }
+}
diff --git a/src/main/java/us/tastybento/bskyblock/listeners/flags/BreakBlocksListener.java b/src/main/java/us/tastybento/bskyblock/listeners/flags/BreakBlocksListener.java
index b29da55e2..d86e41742 100644
--- a/src/main/java/us/tastybento/bskyblock/listeners/flags/BreakBlocksListener.java
+++ b/src/main/java/us/tastybento/bskyblock/listeners/flags/BreakBlocksListener.java
@@ -1,8 +1,20 @@
package us.tastybento.bskyblock.listeners.flags;
+import org.bukkit.Material;
+import org.bukkit.World.Environment;
+import org.bukkit.block.Block;
+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.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
+import org.bukkit.event.entity.EntityDamageByEntityEvent;
+import org.bukkit.event.hanging.HangingBreakByEntityEvent;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.event.vehicle.VehicleDamageEvent;
+import org.bukkit.util.BlockIterator;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.commands.User;
@@ -14,7 +26,7 @@ public class BreakBlocksListener extends FlagListener {
public BreakBlocksListener() {
super(BSkyBlock.getInstance());
}
-
+
/**
* Prevents blocks from being broken
*
@@ -22,23 +34,112 @@ public class BreakBlocksListener extends FlagListener {
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onBlockBreak(final BlockBreakEvent e) {
-
- // If this is not an Island World, skip
- if (!inWorld(e.getPlayer())) return;
-
- // Handle fake players
- if (plugin.getSettings().getFakePlayers().contains(e.getPlayer().getName())) return;
-
- // Real players
- // Get the island and if present, check the flag, react if required and return
- plugin.getIslands().getIslandAt(e.getBlock().getLocation()).ifPresent(x -> {
- if (!x.isAllowed(User.getInstance(e.getPlayer()), Flags.BREAK_BLOCKS)) noGo(e);
- return;
- });
-
- // The player is in the world, but not on an island, so general world settings apply
- if (!Flags.BREAK_BLOCKS.isAllowed()) noGo(e);
+ checkIsland(e, e.getBlock().getLocation(), Flags.BREAK_BLOCKS);
}
-
+ /**
+ * Prevents the breakage of hanging items
+ *
+ * @param e
+ */
+ @EventHandler(priority = EventPriority.LOW)
+ public void onBreakHanging(final HangingBreakByEntityEvent e) {
+ if (e.getRemover() instanceof Player) {
+ setUser(User.getInstance(e.getRemover()));
+ checkIsland(e, e.getEntity().getLocation(), Flags.BREAK_BLOCKS);
+ }
+ }
+
+ /**
+ * Handles breaking objects
+ *
+ * @param e
+ */
+ @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
+ public void onPlayerInteract(final PlayerInteractEvent e) {
+ // Only handle hitting things
+ if (!e.getAction().equals(Action.LEFT_CLICK_BLOCK)) return;
+
+ // Look along player's sight line to see if any blocks are skulls
+ try {
+ BlockIterator iter = new BlockIterator(e.getPlayer(), 10);
+ Block lastBlock = iter.next();
+ while (iter.hasNext()) {
+ lastBlock = iter.next();
+ if (lastBlock.getType().equals(Material.SKULL)) {
+ checkIsland(e, lastBlock.getLocation(), Flags.BREAK_BLOCKS);
+ return;
+ }
+ }
+ } catch (Exception ex) {}
+
+ switch (e.getClickedBlock().getType()) {
+ case CAKE_BLOCK:
+ case DRAGON_EGG:
+ case MOB_SPAWNER:
+ checkIsland(e, e.getClickedBlock().getLocation(), Flags.BREAK_BLOCKS);
+ return;
+ case BED_BLOCK:
+ if (e.getPlayer().getWorld().getEnvironment().equals(Environment.NETHER)) {
+ // Prevent explosions checkIsland(e, e.getClickedBlock().getLocation(), Flags.BREAK_BLOCKS);
+ return;
+ }
+ default:
+ break;
+ }
+ }
+
+
+ /**
+ * Handles vehicle breaking
+ * @param e
+ */
+ @EventHandler(priority = EventPriority.LOW, ignoreCancelled=true)
+ public void onVehicleDamageEvent(VehicleDamageEvent e) {
+ if (inWorld(e.getVehicle()) && e.getAttacker() instanceof Player) {
+ User user = User.getInstance((Player) e.getAttacker());
+ // Get the island and if present, check the flag, react if required and return
+ plugin.getIslands().getIslandAt(e.getVehicle().getLocation()).ifPresent(x -> {
+ if (!x.isAllowed(getUser(), Flags.BREAK_BLOCKS)) {
+ e.setCancelled(true);
+ user.sendMessage("protection.protected");
+ }
+ return;
+ });
+
+ // The player is in the world, but not on an island, so general world settings apply
+ if (!Flags.BREAK_BLOCKS.isAllowed()) {
+ e.setCancelled(true);
+ user.sendMessage("protection.protected");
+ }
+ }
+ }
+
+ /**
+ * Protect item frames, armor stands, etc. Entities that are actually blocks...
+ * @param e
+ */
+ @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
+ public void onEntityDamage(EntityDamageByEntityEvent e) {
+ // Only handle item frames
+ if (!(e.getEntity() instanceof ItemFrame) && !e.getEntityType().toString().endsWith("STAND")) return;
+
+ // Get the attacker
+ if (e.getDamager() instanceof Player) {
+ setUser(User.getInstance(e.getDamager()));
+ checkIsland(e, e.getEntity().getLocation(), Flags.BREAK_BLOCKS);
+ } else if (e.getDamager() instanceof Projectile) {
+ // Find out who fired the arrow
+ Projectile p = (Projectile) e.getDamager();
+ if (p.getShooter() instanceof Player) {
+ setUser(User.getInstance((Player)p.getShooter()));
+ if (!checkIsland(e, e.getEntity().getLocation(), Flags.BREAK_BLOCKS)) {
+ e.getEntity().setFireTicks(0);
+ e.getDamager().remove();
+ }
+ }
+ }
+ }
+
+
}
diff --git a/src/main/java/us/tastybento/bskyblock/listeners/flags/PlaceBlocksListener.java b/src/main/java/us/tastybento/bskyblock/listeners/flags/PlaceBlocksListener.java
index d4922b637..a1b212721 100644
--- a/src/main/java/us/tastybento/bskyblock/listeners/flags/PlaceBlocksListener.java
+++ b/src/main/java/us/tastybento/bskyblock/listeners/flags/PlaceBlocksListener.java
@@ -1,11 +1,16 @@
package us.tastybento.bskyblock.listeners.flags;
+import org.bukkit.Material;
+import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
+import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockPlaceEvent;
+import org.bukkit.event.block.EntityBlockFormEvent;
+import org.bukkit.event.player.PlayerInteractEntityEvent;
+import org.bukkit.event.player.PlayerInteractEvent;
import us.tastybento.bskyblock.BSkyBlock;
-import us.tastybento.bskyblock.api.commands.User;
import us.tastybento.bskyblock.listeners.FlagListener;
import us.tastybento.bskyblock.lists.Flags;
@@ -14,30 +19,76 @@ public class PlaceBlocksListener extends FlagListener {
public PlaceBlocksListener() {
super(BSkyBlock.getInstance());
}
-
+
+
/**
- * Prevents blocks from being placed
+ * Check blocks being placed in general
*
* @param e
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onBlockPlace(final BlockPlaceEvent e) {
+ checkIsland(e, e.getBlock().getLocation(), Flags.PLACE_BLOCKS);
+ }
- // If this is not an Island World, skip
- if (!inWorld(e.getPlayer())) return;
-
- // Handle fake players
- if (plugin.getSettings().getFakePlayers().contains(e.getPlayer().getName())) return;
-
- // Real players
- // Get the island and if present, check the flag, react if required and return
- plugin.getIslands().getIslandAt(e.getBlock().getLocation()).ifPresent(x -> {
- if (!x.isAllowed(User.getInstance(e.getPlayer()), Flags.PLACE_BLOCKS)) noGo(e);
- return;
- });
-
- // The player is in the world, but not on an island, so general world settings apply
- if (!Flags.PLACE_BLOCKS.isAllowed()) noGo(e);
+ /**
+ * Handles placing items into ItemFrames
+ * @param e
+ */
+ @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
+ public void onPlayerHitEntity(PlayerInteractEntityEvent e) {
+ if (e.getRightClicked().getType().equals(EntityType.ITEM_FRAME)) {
+ checkIsland(e, e.getRightClicked().getLocation(), Flags.PLACE_BLOCKS);
+ }
+ }
+
+ /**
+ * Handle placing of fireworks, mine carts, end crystals, doors, chests and boats on land
+ * The doors and chests are related to an exploit.
+ * @param e
+ */
+ @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
+ public void onPlayerInteract(final PlayerInteractEvent e) {
+ if (!e.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
+ return;
+ }
+ switch (e.getClickedBlock().getType()) {
+ case FIREWORK:
+ checkIsland(e, e.getClickedBlock().getLocation(), Flags.PLACE_BLOCKS);
+ return;
+ case RAILS:
+ case POWERED_RAIL:
+ case DETECTOR_RAIL:
+ case ACTIVATOR_RAIL:
+ if (e.getMaterial() != null && (e.getMaterial() == Material.MINECART || e.getMaterial() == Material.STORAGE_MINECART || e.getMaterial() == Material.HOPPER_MINECART
+ || e.getMaterial() == Material.EXPLOSIVE_MINECART || e.getMaterial() == Material.POWERED_MINECART)) {
+ checkIsland(e, e.getClickedBlock().getLocation(), Flags.PLACE_BLOCKS);
+ }
+ return;
+ default:
+ // Check in-hand items
+ if (e.getMaterial() != null) {
+ // This check protects against an exploit in 1.7.9 against cactus
+ // and sugar cane and placing boats on non-liquids
+ if (e.getMaterial().equals(Material.END_CRYSTAL) || e.getMaterial() == Material.WOOD_DOOR || e.getMaterial() == Material.CHEST
+ || e.getMaterial() == Material.TRAPPED_CHEST || e.getMaterial() == Material.IRON_DOOR
+ || (e.getMaterial().name().contains("BOAT") && !e.getClickedBlock().isLiquid())) {
+ checkIsland(e, getUser().getLocation(), Flags.PLACE_BLOCKS);
+ }
+ }
+ }
}
+ /**
+ * Handles Frost Walking on visitor's islands. This creates ice blocks, which is like placing blocks
+ * @param e
+ */
+ @EventHandler(priority = EventPriority.LOW, ignoreCancelled=true)
+ public void onBlockForm(EntityBlockFormEvent e) {
+ if (e.getNewState().getType().equals(Material.FROSTED_ICE)) {
+ // Silently check
+ checkIsland(e, getUser().getLocation(), Flags.PLACE_BLOCKS, true);
+ }
+ }
+
}
diff --git a/src/main/java/us/tastybento/bskyblock/lists/Flags.java b/src/main/java/us/tastybento/bskyblock/lists/Flags.java
index 58b551020..66edc3c7c 100644
--- a/src/main/java/us/tastybento/bskyblock/lists/Flags.java
+++ b/src/main/java/us/tastybento/bskyblock/lists/Flags.java
@@ -9,4 +9,48 @@ public class Flags {
public static final Flag BREAK_BLOCKS = new FlagBuilder().id("BREAK_BLOCKS").icon(Material.STONE).listener(new BreakBlocksListener()).build();
public static final Flag PLACE_BLOCKS = new FlagBuilder().id("PLACE_BLOCKS").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag ANVIL = new FlagBuilder().id("ANVIL").icon(Material.DIRT).listener(new AnvilListener()).build();
+ public static final Flag ARMOR_STAND = new FlagBuilder().id("ARMOR_STAND").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag BEACON = new FlagBuilder().id("BEACON").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag BED = new FlagBuilder().id("BED").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag BREEDING = new FlagBuilder().id("BREEDING").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag BREWING = new FlagBuilder().id("BREWING").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag BUCKET = new FlagBuilder().id("BUCKET").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag COLLECT_LAVA = new FlagBuilder().id("COLLECT_LAVA").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag COLLECT_WATER = new FlagBuilder().id("COLLECT_WATER").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag CHEST = new FlagBuilder().id("CHEST").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag CHORUS_FRUIT = new FlagBuilder().id("CHORUS_FRUIT").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag CRAFTING = new FlagBuilder().id("CRAFTING").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag CROP_TRAMPLE = new FlagBuilder().id("CROP_TRAMPLE").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag DOOR = new FlagBuilder().id("DOOR").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag EGGS = new FlagBuilder().id("EGGS").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag ENCHANTING = new FlagBuilder().id("ENCHANTING").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag ENDER_PEARL = new FlagBuilder().id("ENDER_PEARL").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag ENTER_EXIT_MESSAGES = new FlagBuilder().id("ENTER_EXIT_MESSAGES").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag FIRE = new FlagBuilder().id("FIRE").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag FIRE_EXTINGUISH = new FlagBuilder().id("FIRE_EXTINGUISH").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag FIRE_SPREAD = new FlagBuilder().id("FIRE_SPREAD").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag FURNACE = new FlagBuilder().id("FURNACE").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag GATE = new FlagBuilder().id("GATE").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag MOUNT_INVENTORY = new FlagBuilder().id("MOUNT_INVENTORY").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag RIDING = new FlagBuilder().id("RIDING").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag HURT_MOBS = new FlagBuilder().id("HURT_MOBS").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag LEASH = new FlagBuilder().id("LEASH").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag LEVER_BUTTON = new FlagBuilder().id("LEVER_BUTTON").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag MOB_SPAWN = new FlagBuilder().id("MOB_SPAWN").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag MUSIC = new FlagBuilder().id("MUSIC").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag PORTAL = new FlagBuilder().id("PORTAL").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag PRESSURE_PLATE = new FlagBuilder().id("PRESSURE_PLATE").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag PVP = new FlagBuilder().id("PVP").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag MILKING = new FlagBuilder().id("MILKING").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag NETHER_PVP = new FlagBuilder().id("NETHER_PVP").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag END_PVP = new FlagBuilder().id("END_PVP").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag REDSTONE = new FlagBuilder().id("REDSTONE").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag SPAWN_EGGS = new FlagBuilder().id("SPAWN_EGGS").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag SHEARING = new FlagBuilder().id("SHEARING").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag TRADING = new FlagBuilder().id("TRADING").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag VISITOR_ITEM_DROP = new FlagBuilder().id("VISITOR_ITEM_DROP").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+ public static final Flag VISITOR_ITEM_PICKUP = new FlagBuilder().id("VISITOR_ITEM_PICKUP").icon(Material.DIRT).listener(new PlaceBlocksListener()).build();
+
+
}