Finished up the place and break block listeners.

There's a lot more that needs to be checked in these listeners! I moved
some common methods into the abstract class because they will be used
again and again by other listeners.

Added an anvil listener.

Added the flags. They were from ASkyBlock so may have name changes.
This commit is contained in:
tastybento 2018-01-31 15:46:38 -08:00
parent 5b087c83e7
commit 4fe94bee3b
7 changed files with 413 additions and 111 deletions

34
pom.xml
View File

@ -64,6 +64,12 @@
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId> <artifactId>mockito-all</artifactId>
@ -71,28 +77,22 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.bukkit</groupId> <groupId>org.powermock</groupId>
<artifactId>bukkit</artifactId> <artifactId>powermock-module-junit4</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version> <version>${powermock.version}</version>
<scope>provided</scope> <scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<repositories> <repositories>
<repository> <repository>
<id>spigot-repo</id> <id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url> <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots</url>
</repository> </repository>
</repositories> </repositories>
</project> </project>

View File

@ -257,4 +257,10 @@ public class User {
return Locale.forLanguageTag(plugin.getSettings().getDefaultLanguage()); return Locale.forLanguageTag(plugin.getSettings().getDefaultLanguage());
} }
@SuppressWarnings("deprecation")
public void updateInventory() {
player.updateInventory();
}
} }

View File

@ -3,20 +3,19 @@
*/ */
package us.tastybento.bskyblock.listeners; package us.tastybento.bskyblock.listeners;
import java.util.Optional;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.player.PlayerEvent;
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 us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.commands.User; 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. * 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 { public abstract class FlagListener implements Listener {
private static final boolean DEBUG = false;
protected BSkyBlock plugin; protected BSkyBlock plugin;
protected User user; private User user = null;
public FlagListener(BSkyBlock plugin) { public FlagListener(BSkyBlock plugin) {
super(); super();
this.plugin = plugin; this.plugin = plugin;
} }
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) /**
public void onEvent(Event e) { * Sets the player associated with this event.
if (DEBUG) { * If the user is a fake player, they are not counted.
plugin.getLogger().info(e.getEventName()); * @param e - the event
} * @return user or empty
*/
protected Optional<User> 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 * 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 * Cancels the event and sends the island protected message to user
* @param e * @param e Event
*/ */
protected void noGo(BlockBreakEvent e) { protected void noGo(Event e) {
e.setCancelled(true); noGo(e, false);
user.sendMessage("protection.protected");
} }
/** /**
* Sends the island protected message to user * Cancels the event and sends the island protected message to user unless silent is true
* @param e * @param e Event
* @param silent - if true, message is not sent
*/ */
protected void noGo(BlockPlaceEvent e) { protected void noGo(Event e, boolean silent) {
e.setCancelled(true); if (e instanceof Cancellable)
user.sendMessage("protection.protected"); ((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 * Check if loc is in the island worlds
* @param loc * @param loc
@ -99,7 +101,7 @@ public abstract class FlagListener implements Listener {
|| loc.getWorld().equals(plugin.getIslandWorldManager().getNetherWorld()) || loc.getWorld().equals(plugin.getIslandWorldManager().getNetherWorld())
|| loc.getWorld().equals(plugin.getIslandWorldManager().getEndWorld())) ? true : false; || loc.getWorld().equals(plugin.getIslandWorldManager().getEndWorld())) ? true : false;
} }
/** /**
* Check if the entity is in the island worlds * Check if the entity is in the island worlds
* @param entity - the entity * @param entity - the entity
@ -108,5 +110,64 @@ public abstract class FlagListener implements Listener {
protected boolean inWorld(Entity entity) { protected boolean inWorld(Entity entity) {
return inWorld(entity.getLocation()); 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> 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;
}
}
} }

View File

@ -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);
}
}
}

View File

@ -1,8 +1,20 @@
package us.tastybento.bskyblock.listeners.flags; 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.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent; 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.BSkyBlock;
import us.tastybento.bskyblock.api.commands.User; import us.tastybento.bskyblock.api.commands.User;
@ -14,7 +26,7 @@ public class BreakBlocksListener extends FlagListener {
public BreakBlocksListener() { public BreakBlocksListener() {
super(BSkyBlock.getInstance()); super(BSkyBlock.getInstance());
} }
/** /**
* Prevents blocks from being broken * Prevents blocks from being broken
* *
@ -22,23 +34,112 @@ public class BreakBlocksListener extends FlagListener {
*/ */
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onBlockBreak(final BlockBreakEvent e) { public void onBlockBreak(final BlockBreakEvent e) {
checkIsland(e, e.getBlock().getLocation(), Flags.BREAK_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.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);
} }
/**
* 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();
}
}
}
}
} }

View File

@ -1,11 +1,16 @@
package us.tastybento.bskyblock.listeners.flags; package us.tastybento.bskyblock.listeners.flags;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockPlaceEvent; 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.BSkyBlock;
import us.tastybento.bskyblock.api.commands.User;
import us.tastybento.bskyblock.listeners.FlagListener; import us.tastybento.bskyblock.listeners.FlagListener;
import us.tastybento.bskyblock.lists.Flags; import us.tastybento.bskyblock.lists.Flags;
@ -14,30 +19,76 @@ public class PlaceBlocksListener extends FlagListener {
public PlaceBlocksListener() { public PlaceBlocksListener() {
super(BSkyBlock.getInstance()); super(BSkyBlock.getInstance());
} }
/** /**
* Prevents blocks from being placed * Check blocks being placed in general
* *
* @param e * @param e
*/ */
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onBlockPlace(final BlockPlaceEvent e) { 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; * Handles placing items into ItemFrames
* @param e
// Handle fake players */
if (plugin.getSettings().getFakePlayers().contains(e.getPlayer().getName())) return; @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerHitEntity(PlayerInteractEntityEvent e) {
// Real players if (e.getRightClicked().getType().equals(EntityType.ITEM_FRAME)) {
// Get the island and if present, check the flag, react if required and return checkIsland(e, e.getRightClicked().getLocation(), Flags.PLACE_BLOCKS);
plugin.getIslands().getIslandAt(e.getBlock().getLocation()).ifPresent(x -> { }
if (!x.isAllowed(User.getInstance(e.getPlayer()), Flags.PLACE_BLOCKS)) noGo(e); }
return;
}); /**
* Handle placing of fireworks, mine carts, end crystals, doors, chests and boats on land
// The player is in the world, but not on an island, so general world settings apply * The doors and chests are related to an exploit.
if (!Flags.PLACE_BLOCKS.isAllowed()) noGo(e); * @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);
}
}
} }

View File

@ -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 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 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();
} }