Implement new 1.19 materials and entities (#1990)

* Update to Spigot and Paper API 1.19 and Java 17

* Set minimal version to 1.18.

* Add breeding protection for Axolotl and Goats (1.18)
Add breeding protection for Frog and Allay (1.19)

* Clean up switch statement in BlockInteractionListener

* Add chest boat support to BreakBlocksListener.

Part of #1987

* Add powdered snow pickup with bucket protection.

* Add glow ink sac protection on signs.
Switch to SheepDyeWoolEvent as it now contains player variable.

* Clean up Hurting Listener

* Mark 1.16.5, 1.17 and 1.17.1 as incompatible.
Mark 1.18, 1.18.1 and 1.18.2 as supported.

Add 1.19 as compatible.
Part of 1987

* Add ChestBoat inventory protection.
Part of #1987

* Clean up LockAndBanListener

* Add MANGROVE_PRESSURE_PLATE protection.
Part of #1987

* Add Glow Item Frame protection to player interact event.

* Clean up MobSpawnListener

* Clean up ChestDamageListener

* Change from custom method to Tag.PRESSURE_PLATES to detect pressure plates.
Part of #1987

* Implement proper chest boat protection.
Part of #1987

* Move to 1.19 R1 world regenerator.
Part of #1987

* Add allay to the animal entity list.
Part of #1987

* Add axolotl and other fish scooping protection.
Part of #1987

* Fixes Bucket and Glass Bottle filling.

Buckets and bottles were not working since cauldron splitting by type. This change fixes that.

It also protects from filling bottles with water from water sources or waterlogged blocks.

* Remove 1.17.1 compatibility check for biome adapter.
Add cheezee 1.19.1 compatibility version.

* Fixes chest boat interactions.

Part of #1987

* Implement Allay protection.
New flag ALLAY is required to interact with allays.

Part of #1987

* Prevent visitors for being targeted by entities if ENTITY_ATTACK is enabled.

* Implement Sculk Sensor and Shrieker activation protection setting.

Part of #1987

* Add music discs to the LangUtilsHook
Part of #1987

* Fixes failing unit-tests.
This commit is contained in:
BONNe 2022-06-14 00:38:53 +03:00 committed by GitHub
parent 6f2a9929c0
commit 85b52f4bfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 955 additions and 527 deletions

10
pom.xml
View File

@ -63,15 +63,15 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>16</java.version> <java.version>17</java.version>
<!-- Non-minecraft related dependencies --> <!-- Non-minecraft related dependencies -->
<powermock.version>2.0.9</powermock.version> <powermock.version>2.0.9</powermock.version>
<mongodb.version>3.12.8</mongodb.version> <mongodb.version>3.12.8</mongodb.version>
<!-- More visible way to change dependency versions --> <!-- More visible way to change dependency versions -->
<spigot.version>1.18.2-R0.1-SNAPSHOT</spigot.version> <spigot.version>1.19-R0.1-SNAPSHOT</spigot.version>
<!-- Might differ from the last Spigot release for short periods <!-- Might differ from the last Spigot release for short periods
of time --> of time -->
<paper.version>1.16.5-R0.1-SNAPSHOT</paper.version> <paper.version>1.19-R0.1-SNAPSHOT</paper.version>
<bstats.version>2.2.1</bstats.version> <bstats.version>2.2.1</bstats.version>
<vault.version>1.7</vault.version> <vault.version>1.7</vault.version>
<placeholderapi.version>2.10.9</placeholderapi.version> <placeholderapi.version>2.10.9</placeholderapi.version>
@ -164,7 +164,7 @@
</repository> </repository>
<repository> <repository>
<id>papermc</id> <id>papermc</id>
<url>https://papermc.io/repo/repository/maven-public/</url> <url>https://repo.papermc.io/repository/maven-public/</url>
</repository> </repository>
<repository> <repository>
<!-- This is a temporary reference as the Maven Shade plugin <!-- This is a temporary reference as the Maven Shade plugin
@ -188,7 +188,7 @@
</dependency> </dependency>
<!-- Paper API --> <!-- Paper API -->
<dependency> <dependency>
<groupId>com.destroystokyo.paper</groupId> <groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId> <artifactId>paper-api</artifactId>
<version>${paper.version}</version> <version>${paper.version}</version>
<scope>provided</scope> <scope>provided</scope>

View File

@ -56,7 +56,7 @@ public class BentoboxTypeAdapterFactory implements TypeAdapterFactory {
if (Location.class.isAssignableFrom(rawType)) { if (Location.class.isAssignableFrom(rawType)) {
// Use our current location adapter for backward compatibility // Use our current location adapter for backward compatibility
return (TypeAdapter<T>) new LocationTypeAdapter(); return (TypeAdapter<T>) new LocationTypeAdapter();
} else if (Biome.class.isAssignableFrom(rawType) && !ServerCompatibility.getInstance().isVersion(ServerCompatibility.ServerVersion.V1_17_1)) { // TODO: Any better way ? } else if (Biome.class.isAssignableFrom(rawType)) {
return (TypeAdapter<T>) new BiomeTypeAdapter(); return (TypeAdapter<T>) new BiomeTypeAdapter();
} else if (Enum.class.isAssignableFrom(rawType)) { } else if (Enum.class.isAssignableFrom(rawType)) {
return new EnumTypeAdapter(rawType); return new EnumTypeAdapter(rawType);

View File

@ -626,6 +626,8 @@ public class LangUtilsHook extends Hook {
case MUSIC_DISC_11 -> "C418 - 11"; case MUSIC_DISC_11 -> "C418 - 11";
case MUSIC_DISC_WAIT -> "C418 - wait"; case MUSIC_DISC_WAIT -> "C418 - wait";
case MUSIC_DISC_PIGSTEP -> "Lena Raine - Pigstep"; case MUSIC_DISC_PIGSTEP -> "Lena Raine - Pigstep";
case MUSIC_DISC_5 -> "Samuel Åberg - 5";
case MUSIC_DISC_OTHERSIDE -> "Lena Raine - otherside";
default -> null; default -> null;
}; };
} }

View File

@ -1,12 +1,15 @@
package world.bentobox.bentobox.listeners.flags.protection; package world.bentobox.bentobox.listeners.flags.protection;
import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import org.bukkit.FluidCollisionMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Tag; import org.bukkit.Tag;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.data.Waterlogged;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Event; import org.bukkit.event.Event;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -26,236 +29,269 @@ import world.bentobox.bentobox.lists.Flags;
* Handle interaction with blocks * Handle interaction with blocks
* @author tastybento * @author tastybento
*/ */
public class BlockInteractionListener extends FlagListener { public class BlockInteractionListener extends FlagListener
{
/** /**
* These cover materials in another server version. * These cover materials in another server version. This avoids run time errors due to unknown enum values, at the
* This avoids run time errors due to unknown enum values, at the expense of a string comparison * expense of a string comparison
*/ */
private final static Map<String, String> stringFlags; private final static Map<String, String> stringFlags;
static {
stringFlags = Map.of("RESPAWN_ANCHOR", "PLACE_BLOCKS"); static
{
stringFlags = Map.of(
"ACACIA_CHEST_BOAT", "CHEST",
"BIRCH_CHEST_BOAT", "CHEST",
"JUNGLE_CHEST_BOAT", "CHEST",
"DARK_OAK_CHEST_BOAT", "CHEST",
"MANGROVE_CHEST_BOAT", "CHEST",
"OAK_CHEST_BOAT", "CHEST",
"SPRUCE_CHEST_BOAT", "CHEST");
} }
/** /**
* Handle interaction with blocks * Handle interaction with blocks
*
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerInteract(final PlayerInteractEvent e) { public void onPlayerInteract(final PlayerInteractEvent e)
{
// We only care about the RIGHT_CLICK_BLOCK action. // We only care about the RIGHT_CLICK_BLOCK action.
if (!e.getAction().equals(Action.RIGHT_CLICK_BLOCK) || e.getClickedBlock() == null) { if (!e.getAction().equals(Action.RIGHT_CLICK_BLOCK) || e.getClickedBlock() == null)
{
return; return;
} }
// Check clicked block // Check clicked block
checkClickedBlock(e, e.getPlayer(), e.getClickedBlock().getLocation(), e.getClickedBlock().getType()); this.checkClickedBlock(e, e.getPlayer(), e.getClickedBlock().getLocation(), e.getClickedBlock().getType());
// Now check for in-hand items // Now check for in-hand items
if (e.getItem() != null && !e.getItem().getType().equals(Material.AIR)) { if (e.getItem() != null && !e.getItem().getType().equals(Material.AIR))
{
// Boats // Boats
if (e.getItem().getType().name().endsWith("_BOAT")) { if (e.getItem().getType().name().endsWith("BOAT"))
checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.BOAT); {
this.checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.BOAT);
} }
// Spawn eggs else if (e.getItem().getType().name().endsWith("_SPAWN_EGG"))
else if (e.getItem().getType().name().endsWith("_SPAWN_EGG")) { {
checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.SPAWN_EGGS); this.checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.SPAWN_EGGS);
} }
// Now check for in-hand items else if (e.getItem().getType() == Material.ENDER_PEARL)
if (e.getItem() != null) { {
if (e.getItem().getType().name().contains("BOAT")) { this.checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.ENDER_PEARL);
checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.PLACE_BLOCKS); }
return; else if (e.getItem().getType() == Material.BONE_MEAL)
} {
switch (e.getItem().getType()) { this.checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.PLACE_BLOCKS);
case ENDER_PEARL: }
checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.ENDER_PEARL); else if (e.getItem().getType() == Material.GLASS_BOTTLE)
break; {
case BONE_MEAL: Block targetedBlock = e.getPlayer().getTargetBlockExact(5, FluidCollisionMode.ALWAYS);
checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.PLACE_BLOCKS);
break; // Check if player is clicking on water or waterlogged block with a bottle.
default: if (targetedBlock != null && (Material.WATER.equals(targetedBlock.getType()) ||
break; targetedBlock.getBlockData() instanceof Waterlogged))
{
this.checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.BREWING);
} }
} }
} }
} }
/** /**
* Check if an action can occur on a clicked block * Check if an action can occur on a clicked block
*
* @param e - event called * @param e - event called
* @param player - player * @param player - player
* @param loc - location of clicked block * @param loc - location of clicked block
* @param type - material type of clicked block * @param type - material type of clicked block
*/ */
private void checkClickedBlock(Event e, Player player, Location loc, Material type) { private void checkClickedBlock(Event e, Player player, Location loc, Material type)
{
// Handle pots // Handle pots
if (type.name().startsWith("POTTED")) { if (type.name().startsWith("POTTED"))
checkIsland(e, player, loc, Flags.FLOWER_POT); {
return; this.checkIsland(e, player, loc, Flags.FLOWER_POT);
}
if (Tag.ANVIL.isTagged(type)) {
checkIsland(e, player, loc, Flags.ANVIL);
return;
}
if (Tag.BUTTONS.isTagged(type)) {
checkIsland(e, player, loc, Flags.BUTTON);
return;
}
if (Tag.BEDS.isTagged(type)) {
checkIsland(e, player, loc, Flags.BED);
return;
}
if (Tag.DOORS.isTagged(type)) {
checkIsland(e, player, loc, Flags.DOOR);
return;
}
if (Tag.SHULKER_BOXES.isTagged(type)) {
checkIsland(e, player, loc, Flags.SHULKER_BOX);
return;
}
if (Tag.TRAPDOORS.isTagged(type)) {
checkIsland(e, player, loc, Flags.TRAPDOOR);
return; return;
} }
switch (type) { if (Tag.ANVIL.isTagged(type))
case BEACON: {
checkIsland(e, player, loc, Flags.BEACON); this.checkIsland(e, player, loc, Flags.ANVIL);
break; return;
case BREWING_STAND: }
case CAULDRON:
checkIsland(e, player, loc, Flags.BREWING); if (Tag.BUTTONS.isTagged(type))
break; {
case BEEHIVE: this.checkIsland(e, player, loc, Flags.BUTTON);
case BEE_NEST: return;
checkIsland(e, player, loc, Flags.HIVE); }
break;
case BARREL: if (Tag.BEDS.isTagged(type))
checkIsland(e, player, loc, Flags.BARREL); {
break; this.checkIsland(e, player, loc, Flags.BED);
case CHEST: return;
case CHEST_MINECART: }
checkIsland(e, player, loc, Flags.CHEST);
break; if (Tag.DOORS.isTagged(type))
case TRAPPED_CHEST: {
checkIsland(e, player, loc, Flags.TRAPPED_CHEST); this.checkIsland(e, player, loc, Flags.DOOR);
break; return;
case FLOWER_POT: }
checkIsland(e, player, loc, Flags.FLOWER_POT);
break; if (Tag.SHULKER_BOXES.isTagged(type))
case COMPOSTER: {
checkIsland(e, player, loc, Flags.COMPOSTER); this.checkIsland(e, player, loc, Flags.SHULKER_BOX);
break; return;
case DISPENSER: }
checkIsland(e, player, loc, Flags.DISPENSER);
break; if (Tag.TRAPDOORS.isTagged(type))
case DROPPER: {
checkIsland(e, player, loc, Flags.DROPPER); this.checkIsland(e, player, loc, Flags.TRAPDOOR);
break; return;
case HOPPER: }
case HOPPER_MINECART:
checkIsland(e, player, loc, Flags.HOPPER); if (Tag.FENCE_GATES.isTagged(type))
break; {
case BLAST_FURNACE: this.checkIsland(e, player, loc, Flags.GATE);
case CAMPFIRE: }
case FURNACE_MINECART: // TODO: 1.18 compatibility
case FURNACE: // if (Tag.ITEMS_CHEST_BOATS.isTagged(type)) {
case SMOKER: // this.checkIsland(e, player, loc, Flags.CHEST);
checkIsland(e, player, loc, Flags.FURNACE); // }
break;
case ENCHANTING_TABLE: switch (type)
checkIsland(e, player, loc, Flags.ENCHANTING); {
break; case BEACON -> this.checkIsland(e, player, loc, Flags.BEACON);
case ENDER_CHEST: case BREWING_STAND -> this.checkIsland(e, player, loc, Flags.BREWING);
checkIsland(e, player, loc, Flags.ENDER_CHEST); case BEEHIVE, BEE_NEST -> this.checkIsland(e, player, loc, Flags.HIVE);
break; case BARREL -> this.checkIsland(e, player, loc, Flags.BARREL);
case JUKEBOX: case CHEST, CHEST_MINECART -> this.checkIsland(e, player, loc, Flags.CHEST);
checkIsland(e, player, loc, Flags.JUKEBOX); case TRAPPED_CHEST -> this.checkIsland(e, player, loc, Flags.TRAPPED_CHEST);
break; case FLOWER_POT -> this.checkIsland(e, player, loc, Flags.FLOWER_POT);
case NOTE_BLOCK: case COMPOSTER -> this.checkIsland(e, player, loc, Flags.COMPOSTER);
checkIsland(e, player, loc, Flags.NOTE_BLOCK); case DISPENSER -> this.checkIsland(e, player, loc, Flags.DISPENSER);
break; case DROPPER -> this.checkIsland(e, player, loc, Flags.DROPPER);
case CRAFTING_TABLE: case HOPPER, HOPPER_MINECART -> this.checkIsland(e, player, loc, Flags.HOPPER);
case CARTOGRAPHY_TABLE: case BLAST_FURNACE, CAMPFIRE, FURNACE_MINECART, FURNACE, SMOKER ->
case GRINDSTONE: this.checkIsland(e, player, loc, Flags.FURNACE);
case STONECUTTER: case ENCHANTING_TABLE -> this.checkIsland(e, player, loc, Flags.ENCHANTING);
case LOOM: case ENDER_CHEST -> this.checkIsland(e, player, loc, Flags.ENDER_CHEST);
checkIsland(e, player, loc, Flags.CRAFTING); case JUKEBOX -> this.checkIsland(e, player, loc, Flags.JUKEBOX);
break; case NOTE_BLOCK -> this.checkIsland(e, player, loc, Flags.NOTE_BLOCK);
case LEVER: case CRAFTING_TABLE, CARTOGRAPHY_TABLE, GRINDSTONE, STONECUTTER, LOOM ->
checkIsland(e, player, loc, Flags.LEVER); this.checkIsland(e, player, loc, Flags.CRAFTING);
break; case LEVER -> this.checkIsland(e, player, loc, Flags.LEVER);
case REDSTONE_WIRE: case REDSTONE_WIRE, REPEATER, COMPARATOR, DAYLIGHT_DETECTOR -> this.checkIsland(e, player, loc, Flags.REDSTONE);
case REPEATER: case DRAGON_EGG -> this.checkIsland(e, player, loc, Flags.DRAGON_EGG);
case COMPARATOR: case END_PORTAL_FRAME, RESPAWN_ANCHOR -> this.checkIsland(e, player, loc, Flags.PLACE_BLOCKS);
case DAYLIGHT_DETECTOR: case GLOW_ITEM_FRAME, ITEM_FRAME -> this.checkIsland(e, player, loc, Flags.ITEM_FRAME);
checkIsland(e, player, loc, Flags.REDSTONE); case SWEET_BERRY_BUSH -> this.checkIsland(e, player, loc, Flags.BREAK_BLOCKS);
break; case CAKE -> this.checkIsland(e, player, loc, Flags.CAKE);
case DRAGON_EGG: case LAVA_CAULDRON ->
checkIsland(e, player, loc, Flags.DRAGON_EGG); {
break; if (BlockInteractionListener.holds(player, Material.BUCKET))
case END_PORTAL_FRAME: {
checkIsland(e, player, loc, Flags.PLACE_BLOCKS); this.checkIsland(e, player, loc, Flags.COLLECT_LAVA);
break; }
case GLOW_ITEM_FRAME: }
case ITEM_FRAME: case WATER_CAULDRON ->
checkIsland(e, player, loc, Flags.ITEM_FRAME); {
break; if (BlockInteractionListener.holds(player, Material.BUCKET))
case SWEET_BERRY_BUSH: {
checkIsland(e, player, loc, Flags.BREAK_BLOCKS); this.checkIsland(e, player, loc, Flags.COLLECT_WATER);
break; }
case CAKE: else if (BlockInteractionListener.holds(player, Material.GLASS_BOTTLE) ||
checkIsland(e, player, loc, Flags.CAKE); BlockInteractionListener.holds(player, Material.POTION))
break; {
case OAK_FENCE_GATE: this.checkIsland(e, player, loc, Flags.BREWING);
case SPRUCE_FENCE_GATE: }
case BIRCH_FENCE_GATE: }
case JUNGLE_FENCE_GATE: case POWDER_SNOW_CAULDRON ->
case DARK_OAK_FENCE_GATE: {
case ACACIA_FENCE_GATE: if (BlockInteractionListener.holds(player, Material.BUCKET))
case CRIMSON_FENCE_GATE: {
case WARPED_FENCE_GATE: this.checkIsland(e, player, loc, Flags.COLLECT_POWDERED_SNOW);
checkIsland(e, player, loc, Flags.GATE); }
break; }
default: case CAULDRON ->
if (stringFlags.containsKey(type.name())) { {
Optional<Flag> f = BentoBox.getInstance().getFlagsManager().getFlag(stringFlags.get(type.name())); if (BlockInteractionListener.holds(player, Material.WATER_BUCKET) ||
f.ifPresent(flag -> checkIsland(e, player, loc, flag)); BlockInteractionListener.holds(player, Material.LAVA_BUCKET) ||
BlockInteractionListener.holds(player, Material.POWDER_SNOW_BUCKET))
{
this.checkIsland(e, player, loc, Flags.BUCKET);
}
else if (BlockInteractionListener.holds(player, Material.POTION))
{
this.checkIsland(e, player, loc, Flags.BREWING);
}
}
default ->
{
if (stringFlags.containsKey(type.name()))
{
Optional<Flag> f = BentoBox.getInstance().getFlagsManager().getFlag(stringFlags.get(type.name()));
f.ifPresent(flag -> this.checkIsland(e, player, loc, flag));
}
} }
} }
} }
/** /**
* When breaking blocks is allowed, this protects * When breaking blocks is allowed, this protects specific blocks from being broken, which would bypass the
* specific blocks from being broken, which would bypass the protection. * protection. For example, player enables break blocks, but chests are still protected Fires after the BreakBlocks
* For example, player enables break blocks, but chests are still protected * check.
* Fires after the BreakBlocks check.
* *
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onBlockBreak(final BlockBreakEvent e) { public void onBlockBreak(final BlockBreakEvent e)
checkClickedBlock(e, e.getPlayer(), e.getBlock().getLocation(), e.getBlock().getType()); {
this.checkClickedBlock(e, e.getPlayer(), e.getBlock().getLocation(), e.getBlock().getType());
} }
/** /**
* Prevents dragon eggs from flying out of an island's protected space * Prevents dragon eggs from flying out of an island's protected space
*
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
public void onDragonEggTeleport(BlockFromToEvent e) { public void onDragonEggTeleport(BlockFromToEvent e)
{
Block block = e.getBlock(); Block block = e.getBlock();
if (!block.getType().equals(Material.DRAGON_EGG) || !getIWM().inWorld(block.getLocation())) {
if (!block.getType().equals(Material.DRAGON_EGG) || !this.getIWM().inWorld(block.getLocation()))
{
return; return;
} }
// If egg starts in a protected island... // If egg starts in a protected island...
// Cancel if toIsland is not fromIsland or if there is no protected island there // Cancel if toIsland is not fromIsland or if there is no protected island there
// This protects against eggs dropping into adjacent islands, e.g. island distance and protection range are equal // This protects against eggs dropping into adjacent islands, e.g. island distance and protection range are equal
Optional<Island> fromIsland = getIslands().getProtectedIslandAt(block.getLocation()); Optional<Island> fromIsland = this.getIslands().getProtectedIslandAt(block.getLocation());
Optional<Island> toIsland = getIslands().getProtectedIslandAt(e.getToBlock().getLocation()); Optional<Island> toIsland = this.getIslands().getProtectedIslandAt(e.getToBlock().getLocation());
fromIsland.ifPresent(from -> e.setCancelled(toIsland.map(to -> to != from).orElse(true))); fromIsland.ifPresent(from -> e.setCancelled(toIsland.map(to -> to != from).orElse(true)));
} }
/**
* This method returns if player is holding given material in main or offhand.
* @param player Player that must be checked.
* @param material item that mus t be checjed.
* @return {@code true} if player is holding item in main hand or offhand.
*/
private static boolean holds(Player player, Material material)
{
return player.getInventory().getItemInMainHand().getType().equals(material) ||
player.getInventory().getItemInOffHand().getType().equals(material);
}
} }

View File

@ -58,19 +58,23 @@ public class BreakBlocksListener extends FlagListener {
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerInteract(final PlayerInteractEvent e) { public void onPlayerInteract(final PlayerInteractEvent e)
{
// Only handle hitting things // Only handle hitting things
if (!e.getAction().equals(Action.LEFT_CLICK_BLOCK)) { if (!e.getAction().equals(Action.LEFT_CLICK_BLOCK) || e.getClickedBlock() == null)
{
return; return;
} }
Player p = e.getPlayer(); Player p = e.getPlayer();
Location l = e.getClickedBlock().getLocation(); Location l = e.getClickedBlock().getLocation();
switch (e.getClickedBlock().getType()) {
case CAKE -> checkIsland(e, p, l, Flags.BREAK_BLOCKS); switch (e.getClickedBlock().getType())
case SPAWNER -> checkIsland(e, p, l, Flags.BREAK_SPAWNERS); {
case DRAGON_EGG -> checkIsland(e, p, l, Flags.DRAGON_EGG); case CAKE -> this.checkIsland(e, p, l, Flags.BREAK_BLOCKS);
case HOPPER -> checkIsland(e, p, l, Flags.BREAK_HOPPERS); case SPAWNER -> this.checkIsland(e, p, l, Flags.BREAK_SPAWNERS);
default -> {} case DRAGON_EGG -> this.checkIsland(e, p, l, Flags.DRAGON_EGG);
case HOPPER -> this.checkIsland(e, p, l, Flags.BREAK_HOPPERS);
} }
} }
@ -79,16 +83,26 @@ public class BreakBlocksListener extends FlagListener {
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOW, ignoreCancelled=true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled=true)
public void onVehicleDamageEvent(VehicleDamageEvent e) { public void onVehicleDamageEvent(VehicleDamageEvent e)
{
Location l = e.getVehicle().getLocation(); Location l = e.getVehicle().getLocation();
if (getIWM().inWorld(l) && e.getAttacker() instanceof Player p) {
String vehicleType = e.getVehicle().getType().toString(); if (getIWM().inWorld(l) && e.getAttacker() instanceof Player p)
if (e.getVehicle().getType().equals(EntityType.BOAT)) { {
checkIsland(e, p, l, Flags.BOAT); String vehicleType = e.getVehicle().getType().name();
} else if (vehicleType.contains("MINECART")) {
checkIsland(e, p, l, Flags.MINECART); // 1.19 introduced Chest Boat.
} else { if (vehicleType.contains("BOAT"))
checkIsland(e, p, l, Flags.BREAK_BLOCKS); {
this.checkIsland(e, p, l, Flags.BOAT);
}
else if (vehicleType.contains("MINECART"))
{
this.checkIsland(e, p, l, Flags.MINECART);
}
else
{
this.checkIsland(e, p, l, Flags.BREAK_BLOCKS);
} }
} }
} }

View File

@ -56,16 +56,27 @@ public class BreedingListener extends FlagListener {
bi.put(EntityType.TURTLE, Collections.singletonList(Material.SEAGRASS)); bi.put(EntityType.TURTLE, Collections.singletonList(Material.SEAGRASS));
bi.put(EntityType.PANDA, Collections.singletonList(Material.BAMBOO)); bi.put(EntityType.PANDA, Collections.singletonList(Material.BAMBOO));
bi.put(EntityType.FOX, Collections.singletonList(Material.SWEET_BERRIES)); bi.put(EntityType.FOX, Collections.singletonList(Material.SWEET_BERRIES));
if (Enums.getIfPresent(EntityType.class, "BEES").isPresent()) { // 1.15.2 // 1.15+
bi.put(EntityType.BEE, Arrays.asList(Material.SUNFLOWER, Material.ORANGE_TULIP, Material.PINK_TULIP, bi.put(EntityType.BEE, Arrays.asList(Material.SUNFLOWER, Material.ORANGE_TULIP, Material.PINK_TULIP,
Material.RED_TULIP, Material.WHITE_TULIP, Material.ALLIUM, Material.RED_TULIP, Material.WHITE_TULIP, Material.ALLIUM,
Material.AZURE_BLUET, Material.BLUE_ORCHID, Material.CORNFLOWER, Material.AZURE_BLUET, Material.BLUE_ORCHID, Material.CORNFLOWER,
Material.DANDELION, Material.OXEYE_DAISY, Material.PEONY, Material.POPPY)); Material.DANDELION, Material.OXEYE_DAISY, Material.PEONY, Material.POPPY));
} // 1.16+
if (Enums.getIfPresent(EntityType.class, "HOGLIN").isPresent()) { bi.put(EntityType.HOGLIN, Collections.singletonList(Material.CRIMSON_FUNGUS));
bi.put(EntityType.HOGLIN, Collections.singletonList(Material.CRIMSON_FUNGUS)); // 1.16.1 bi.put(EntityType.STRIDER, Collections.singletonList(Material.WARPED_FUNGUS));
bi.put(EntityType.STRIDER, Collections.singletonList(Material.WARPED_FUNGUS)); // 1.16.1 // 1.18+
bi.put(EntityType.AXOLOTL, Collections.singletonList(Material.TROPICAL_FISH_BUCKET));
bi.put(EntityType.GOAT, Collections.singletonList(Material.WHEAT));
// 1.19+
// TODO: remove one 1.18 is dropped.
if (Enums.getIfPresent(EntityType.class, "FROG").isPresent()) {
bi.put(EntityType.FROG, Collections.singletonList(Material.SLIME_BALL));
bi.put(EntityType.ALLAY, Collections.singletonList(Material.AMETHYST_SHARD));
} }
// Helper
// if (Enums.getIfPresent(EntityType.class, "<name>").isPresent()) {
// bi.put(EntityType.<type>, Collections.singletonList(Material.<material>));
// }
BREEDING_ITEMS = Collections.unmodifiableMap(bi); BREEDING_ITEMS = Collections.unmodifiableMap(bi);
} }

View File

@ -3,9 +3,10 @@ package world.bentobox.bentobox.listeners.flags.protection;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Axolotl;
import org.bukkit.entity.Fish;
import org.bukkit.entity.MushroomCow; import org.bukkit.entity.MushroomCow;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.TropicalFish;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerBucketEmptyEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent;
@ -31,7 +32,7 @@ public class BucketListener extends FlagListener {
public void onBucketEmpty(final PlayerBucketEmptyEvent e) { public void onBucketEmpty(final PlayerBucketEmptyEvent e) {
// This is where the water or lava actually will be dumped // This is where the water or lava actually will be dumped
Block dumpBlock = e.getBlockClicked().getRelative(e.getBlockFace()); Block dumpBlock = e.getBlockClicked().getRelative(e.getBlockFace());
checkIsland(e, e.getPlayer(), dumpBlock.getLocation(), Flags.BUCKET); this.checkIsland(e, e.getPlayer(), dumpBlock.getLocation(), Flags.BUCKET);
} }
/** /**
@ -42,19 +43,35 @@ public class BucketListener extends FlagListener {
public void onBucketFill(final PlayerBucketFillEvent e) { public void onBucketFill(final PlayerBucketFillEvent e) {
Player p = e.getPlayer(); Player p = e.getPlayer();
Location l = e.getBlockClicked().getLocation(); Location l = e.getBlockClicked().getLocation();
if (e.getItemStack() == null)
{
// Null-pointer check.
return;
}
// Check filling of various liquids // Check filling of various liquids
switch (e.getItemStack().getType()) { switch (e.getItemStack().getType())
case LAVA_BUCKET -> checkIsland(e, p, l, Flags.COLLECT_LAVA); {
case WATER_BUCKET -> checkIsland(e, p, l, Flags.COLLECT_WATER); case LAVA_BUCKET -> this.checkIsland(e, p, l, Flags.COLLECT_LAVA);
case MILK_BUCKET -> checkIsland(e, p, l, Flags.MILKING); case WATER_BUCKET -> this.checkIsland(e, p, l, Flags.COLLECT_WATER);
default -> checkIsland(e, p, l, Flags.BUCKET); case POWDER_SNOW_BUCKET -> this.checkIsland(e, p, l, Flags.COLLECT_POWDERED_SNOW);
case MILK_BUCKET -> this.checkIsland(e, p, l, Flags.MILKING);
default -> this.checkIsland(e, p, l, Flags.BUCKET);
} }
} }
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onTropicalFishScooping(final PlayerInteractEntityEvent e) { public void onTropicalFishScooping(final PlayerInteractEntityEvent e) {
if (e.getRightClicked() instanceof TropicalFish && e.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.WATER_BUCKET)) { if (e.getRightClicked() instanceof Fish &&
checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.FISH_SCOOPING); e.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.WATER_BUCKET))
{
this.checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.FISH_SCOOPING);
}
else if (e.getRightClicked() instanceof Axolotl &&
e.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.WATER_BUCKET))
{
this.checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.AXOLOTL_SCOOPING);
} }
} }

View File

@ -1,10 +1,10 @@
package world.bentobox.bentobox.listeners.flags.protection; package world.bentobox.bentobox.listeners.flags.protection;
import org.bukkit.entity.EntityType; import org.bukkit.Material;
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.Action;
import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.entity.SheepDyeWoolEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import world.bentobox.bentobox.api.flags.FlagListener; import world.bentobox.bentobox.api.flags.FlagListener;
@ -22,24 +22,35 @@ public class DyeListener extends FlagListener {
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerInteract(final PlayerInteractEvent e) { public void onPlayerInteract(final PlayerInteractEvent e)
if (e.getClickedBlock() == null || e.getItem() == null) { {
if (e.getClickedBlock() == null || e.getItem() == null)
{
return; return;
} }
if (e.getAction().equals(Action.RIGHT_CLICK_BLOCK) && e.getClickedBlock().getType().name().contains("SIGN") if (e.getAction().equals(Action.RIGHT_CLICK_BLOCK) &&
&& e.getItem().getType().name().contains("DYE")) { e.getClickedBlock().getType().name().contains("SIGN") &&
checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.DYE); (e.getItem().getType().name().contains("DYE") || e.getItem().getType().equals(Material.GLOW_INK_SAC)))
{
this.checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.DYE);
} }
} }
/**
* Prevents from interacting with sheep.
* @param e - event
*/
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerInteract(final PlayerInteractEntityEvent e) { public void onPlayerInteract(final SheepDyeWoolEvent e)
// We cannot use SheepDyeWoolEvent since it doesn't provide who dyed the sheep {
if (e.getRightClicked().getType().equals(EntityType.SHEEP) if (e.getPlayer() == null)
&& (e.getPlayer().getInventory().getItemInMainHand().getType().name().contains("DYE") {
|| e.getPlayer().getInventory().getItemInOffHand().getType().name().contains("DYE"))) { // Sheep is not dyed by the player.
checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.DYE); return;
} }
this.checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.DYE);
} }
} }

View File

@ -2,13 +2,7 @@ package world.bentobox.bentobox.listeners.flags.protection;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Animals; import org.bukkit.entity.*;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.entity.Villager;
import org.bukkit.entity.WanderingTrader;
import org.bukkit.entity.minecart.RideableMinecart; import org.bukkit.entity.minecart.RideableMinecart;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -17,6 +11,8 @@ import org.bukkit.event.player.PlayerInteractEntityEvent;
import world.bentobox.bentobox.api.flags.FlagListener; import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.versions.ServerCompatibility;
/** /**
* Handles interaction with entities like armor stands * Handles interaction with entities like armor stands
@ -34,34 +30,68 @@ public class EntityInteractListener extends FlagListener {
} }
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerInteractEntity(PlayerInteractEntityEvent e) { public void onPlayerInteractEntity(PlayerInteractEntityEvent e)
{
Player p = e.getPlayer(); Player p = e.getPlayer();
Location l = e.getRightClicked().getLocation(); Location l = e.getRightClicked().getLocation();
if (e.getRightClicked() instanceof Vehicle) {
// Animal riding if (e.getRightClicked() instanceof Vehicle)
if (e.getRightClicked() instanceof Animals) { {
checkIsland(e, p, l, Flags.RIDING); if (e.getRightClicked() instanceof Animals)
{
// Animal riding
this.checkIsland(e, p, l, Flags.RIDING);
} }
// Minecart riding else if (e.getRightClicked() instanceof RideableMinecart)
else if (e.getRightClicked() instanceof RideableMinecart) { {
checkIsland(e, p, l, Flags.MINECART); // Minecart riding
this.checkIsland(e, p, l, Flags.MINECART);
} }
// Boat riding else if (!ServerCompatibility.getInstance().isVersion(
else if (e.getRightClicked() instanceof Boat) { ServerCompatibility.ServerVersion.V1_18,
checkIsland(e, p, l, Flags.BOAT); ServerCompatibility.ServerVersion.V1_18_1,
ServerCompatibility.ServerVersion.V1_18_2) &&
e.getPlayer().isSneaking() && e.getRightClicked() instanceof ChestBoat)
{
// Access to chest boat since 1.19
this.checkIsland(e, p, l, Flags.CHEST);
}
else if (e.getRightClicked() instanceof Boat)
{
// Boat riding
this.checkIsland(e, p, l, Flags.BOAT);
} }
} }
// Villager trading else if (e.getRightClicked() instanceof Villager || e.getRightClicked() instanceof WanderingTrader)
else if (e.getRightClicked() instanceof Villager || e.getRightClicked() instanceof WanderingTrader) { {
// Villager trading
// Check naming and check trading // Check naming and check trading
checkIsland(e, p, l, Flags.TRADING); this.checkIsland(e, p, l, Flags.TRADING);
if (e.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.NAME_TAG)) {
checkIsland(e, p, l, Flags.NAME_TAG); if (e.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.NAME_TAG))
{
this.checkIsland(e, p, l, Flags.NAME_TAG);
} }
} }
// Name tags else if (!ServerCompatibility.getInstance().isVersion(
else if (e.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.NAME_TAG)) { ServerCompatibility.ServerVersion.V1_18,
checkIsland(e, p, l, Flags.NAME_TAG); ServerCompatibility.ServerVersion.V1_18_1,
ServerCompatibility.ServerVersion.V1_18_2) &&
e.getRightClicked() instanceof Allay)
{
// Allay item giving/taking
this.checkIsland(e, p, l, Flags.ALLAY);
// Check naming
if (e.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.NAME_TAG))
{
this.checkIsland(e, p, l, Flags.NAME_TAG);
}
}
else if (e.getPlayer().getInventory().getItemInMainHand().getType().equals(Material.NAME_TAG))
{
// Name tags
this.checkIsland(e, p, l, Flags.NAME_TAG);
} }
} }
} }

View File

@ -14,7 +14,6 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Parrot; import org.bukkit.entity.Parrot;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile; import org.bukkit.entity.Projectile;
import org.bukkit.entity.Villager;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
@ -31,7 +30,6 @@ import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.flags.FlagListener; import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
import world.bentobox.bentobox.versions.ServerCompatibility;
/** /**
@ -50,17 +48,24 @@ public class HurtingListener extends FlagListener {
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onEntityDamage(final EntityDamageByEntityEvent e) { public void onEntityDamage(final EntityDamageByEntityEvent e)
{
// Mobs being hurt // Mobs being hurt
if (Util.isPassiveEntity(e.getEntity())) { if (Util.isPassiveEntity(e.getEntity()))
respond(e, e.getDamager(), Flags.HURT_ANIMALS); {
} else if (e.getEntity() instanceof Villager || e.getEntityType().name().equals("WANDERING_TRADER")) { // TODO: Simplify when 1.13.2 support is dropped this.respond(e, e.getDamager(), Flags.HURT_ANIMALS);
respond(e, e.getDamager(), Flags.HURT_VILLAGERS); }
} else if (Util.isHostileEntity(e.getEntity())) { else if (e.getEntity() instanceof AbstractVillager)
respond(e, e.getDamager(), Flags.HURT_MONSTERS); {
this.respond(e, e.getDamager(), Flags.HURT_VILLAGERS);
}
else if (Util.isHostileEntity(e.getEntity()))
{
this.respond(e, e.getDamager(), Flags.HURT_MONSTERS);
} }
} }
/** /**
* Finds the true attacker, even if the attack was via a projectile * Finds the true attacker, even if the attack was via a projectile
* @param e - event * @param e - event
@ -159,12 +164,6 @@ public class HurtingListener extends FlagListener {
*/ */
@EventHandler(priority = EventPriority.LOW, ignoreCancelled=true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled=true)
public void onLingeringPotionSplash(final LingeringPotionSplashEvent e) { public void onLingeringPotionSplash(final LingeringPotionSplashEvent e) {
// TODO Switch this to 1.13 when we move to 1.14 officially
if (!ServerCompatibility.getInstance().isVersion(ServerCompatibility.ServerVersion.V1_14, ServerCompatibility.ServerVersion.V1_14_1)) {
// We're disabling this check for non-1.14 servers.
return;
}
// Try to get the shooter // Try to get the shooter
Projectile projectile = e.getEntity(); Projectile projectile = e.getEntity();
if (projectile.getShooter() instanceof Player) { if (projectile.getShooter() instanceof Player) {

View File

@ -13,6 +13,7 @@ import org.bukkit.block.Furnace;
import org.bukkit.block.Hopper; import org.bukkit.block.Hopper;
import org.bukkit.block.ShulkerBox; import org.bukkit.block.ShulkerBox;
import org.bukkit.entity.Animals; import org.bukkit.entity.Animals;
import org.bukkit.entity.ChestBoat;
import org.bukkit.entity.NPC; import org.bukkit.entity.NPC;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.minecart.HopperMinecart; import org.bukkit.entity.minecart.HopperMinecart;
@ -20,83 +21,146 @@ import org.bukkit.entity.minecart.StorageMinecart;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.InventoryHolder;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.flags.FlagListener; import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.versions.ServerCompatibility;
/** /**
* Handles inventory protection * Handles inventory protection
* @author tastybento * @author tastybento
*/ */
public class InventoryListener extends FlagListener { public class InventoryListener extends FlagListener
{
/**
* Prevents players opening inventories
* @param event - event
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled=true)
public void onInventoryOpen(InventoryOpenEvent event)
{
InventoryHolder inventoryHolder = event.getInventory().getHolder();
if (inventoryHolder == null || !(event.getPlayer() instanceof Player player))
{
return;
}
if (inventoryHolder instanceof Animals)
{
// Prevent opening animal inventories.
this.checkIsland(event, player, event.getInventory().getLocation(), Flags.MOUNT_INVENTORY);
}
else if (!ServerCompatibility.getInstance().isVersion(ServerCompatibility.ServerVersion.V1_18,
ServerCompatibility.ServerVersion.V1_18_1,
ServerCompatibility.ServerVersion.V1_18_2) &&
inventoryHolder instanceof ChestBoat)
{
// Prevent opening chest inventories
this.checkIsland(event, player, event.getInventory().getLocation(), Flags.CHEST);
}
}
/** /**
* Prevents players picking items from inventories * Prevents players picking items from inventories
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOW, ignoreCancelled=true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled=true)
public void onInventoryClick(InventoryClickEvent e) { public void onInventoryClick(InventoryClickEvent e)
Player player = (Player)e.getWhoClicked(); {
Player player = (Player) e.getWhoClicked();
InventoryHolder inventoryHolder = e.getInventory().getHolder(); InventoryHolder inventoryHolder = e.getInventory().getHolder();
if (inventoryHolder == null || !(e.getWhoClicked() instanceof Player)) {
if (inventoryHolder == null || !(e.getWhoClicked() instanceof Player))
{
return; return;
} }
if (inventoryHolder instanceof Animals) {
checkIsland(e, player, e.getInventory().getLocation(), Flags.MOUNT_INVENTORY); if (inventoryHolder instanceof Animals)
{
this.checkIsland(e, player, e.getInventory().getLocation(), Flags.MOUNT_INVENTORY);
} }
else if (inventoryHolder instanceof Dispenser) { else if (inventoryHolder instanceof Dispenser)
checkIsland(e, player, e.getInventory().getLocation(), Flags.DISPENSER); {
this.checkIsland(e, player, e.getInventory().getLocation(), Flags.DISPENSER);
} }
else if (inventoryHolder instanceof Dropper) { else if (inventoryHolder instanceof Dropper)
checkIsland(e, player, e.getInventory().getLocation(), Flags.DROPPER); {
this.checkIsland(e, player, e.getInventory().getLocation(), Flags.DROPPER);
} }
else if (inventoryHolder instanceof Hopper else if (inventoryHolder instanceof Hopper || inventoryHolder instanceof HopperMinecart)
|| inventoryHolder instanceof HopperMinecart) { {
checkIsland(e, player, e.getInventory().getLocation(), Flags.HOPPER); this.checkIsland(e, player, e.getInventory().getLocation(), Flags.HOPPER);
} }
else if (inventoryHolder instanceof Furnace) { else if (inventoryHolder instanceof Furnace)
checkIsland(e, player, e.getInventory().getLocation(), Flags.FURNACE); {
this.checkIsland(e, player, e.getInventory().getLocation(), Flags.FURNACE);
} }
else if (inventoryHolder instanceof BrewingStand) { else if (inventoryHolder instanceof BrewingStand)
checkIsland(e, player, e.getInventory().getLocation(), Flags.BREWING); {
this.checkIsland(e, player, e.getInventory().getLocation(), Flags.BREWING);
} }
else if (inventoryHolder instanceof Beacon) { else if (inventoryHolder instanceof Beacon)
checkIsland(e, player, e.getInventory().getLocation(), Flags.BEACON); {
this.checkIsland(e, player, e.getInventory().getLocation(), Flags.BEACON);
} }
else if (inventoryHolder instanceof NPC) { else if (inventoryHolder instanceof NPC)
checkIsland(e, player, e.getInventory().getLocation(), Flags.TRADING); {
this.checkIsland(e, player, e.getInventory().getLocation(), Flags.TRADING);
} }
else if (inventoryHolder instanceof Barrel) { else if (inventoryHolder instanceof Barrel)
checkIsland(e, player, e.getInventory().getLocation(), Flags.BARREL); {
this.checkIsland(e, player, e.getInventory().getLocation(), Flags.BARREL);
} }
else if (inventoryHolder instanceof ShulkerBox) { else if (inventoryHolder instanceof ShulkerBox)
checkIsland(e, player, e.getInventory().getLocation(), Flags.SHULKER_BOX); {
this.checkIsland(e, player, e.getInventory().getLocation(), Flags.SHULKER_BOX);
} }
else if (inventoryHolder instanceof Chest c) { else if (inventoryHolder instanceof Chest c)
checkInvHolder(c.getLocation(), e, player); {
this.checkInvHolder(c.getLocation(), e, player);
} }
else if (inventoryHolder instanceof DoubleChest dc) { else if (inventoryHolder instanceof DoubleChest dc)
checkInvHolder(dc.getLocation(), e, player); {
this.checkInvHolder(dc.getLocation(), e, player);
} }
else if (inventoryHolder instanceof StorageMinecart) { else if (inventoryHolder instanceof StorageMinecart)
checkIsland(e, player, e.getInventory().getLocation(), Flags.CHEST); {
this.checkIsland(e, player, e.getInventory().getLocation(), Flags.CHEST);
} }
else if (!(inventoryHolder instanceof Player)) { else if (!ServerCompatibility.getInstance().isVersion(ServerCompatibility.ServerVersion.V1_18, ServerCompatibility.ServerVersion.V1_18_1, ServerCompatibility.ServerVersion.V1_18_2) &&
inventoryHolder instanceof ChestBoat)
{
// TODO: 1.19 added chest boat. Remove compatibility check when 1.18 is dropped.
this.checkIsland(e, player, e.getInventory().getLocation(), Flags.CHEST);
}
else if (!(inventoryHolder instanceof Player))
{
// All other containers // All other containers
checkIsland(e, player, e.getInventory().getLocation(), Flags.CONTAINER); this.checkIsland(e, player, e.getInventory().getLocation(), Flags.CONTAINER);
} }
} }
private void checkInvHolder(Location l, InventoryClickEvent e, Player player) {
if (l.getBlock().getType().equals(Material.TRAPPED_CHEST)) { /**
checkIsland(e, player, l, Flags.TRAPPED_CHEST); * This method runs check based on clicked chest type.
} else { * @param l location of chest.
checkIsland(e, player, l, Flags.CHEST); * @param e click event.
* @param player player who clicked.
*/
private void checkInvHolder(Location l, InventoryClickEvent e, Player player)
{
if (l.getBlock().getType().equals(Material.TRAPPED_CHEST))
{
this.checkIsland(e, player, l, Flags.TRAPPED_CHEST);
}
else
{
this.checkIsland(e, player, l, Flags.CHEST);
} }
} }
} }

View File

@ -104,22 +104,31 @@ public class LockAndBanListener extends FlagListener {
* @param loc - location to check * @param loc - location to check
* @return CheckResult LOCKED, BANNED or OPEN. If an island is locked, that will take priority over banned * @return CheckResult LOCKED, BANNED or OPEN. If an island is locked, that will take priority over banned
*/ */
private CheckResult check(@NonNull Player player, Location loc) { private CheckResult check(@NonNull Player player, Location loc)
{
// Ops or NPC's are allowed everywhere // Ops or NPC's are allowed everywhere
if (player.isOp() || player.hasMetadata("NPC")) { if (player.isOp() || player.hasMetadata("NPC"))
{
return CheckResult.OPEN; return CheckResult.OPEN;
} }
// See if the island is locked to non-members or player is banned // See if the island is locked to non-members or player is banned
return getIslands().getProtectedIslandAt(loc) return this.getIslands().getProtectedIslandAt(loc).
.map(is -> { map(is ->
if (is.isBanned(player.getUniqueId())) { {
return player.hasPermission(getIWM().getPermissionPrefix(loc.getWorld()) + "mod.bypassban") ? CheckResult.OPEN : CheckResult.BANNED; if (is.isBanned(player.getUniqueId()))
} {
if (!is.isAllowed(User.getInstance(player), Flags.LOCK)) { return player.hasPermission(getIWM().getPermissionPrefix(loc.getWorld()) + "mod.bypassban") ?
return player.hasPermission(getIWM().getPermissionPrefix(loc.getWorld()) + "mod.bypasslock") ? CheckResult.OPEN : CheckResult.LOCKED; CheckResult.OPEN : CheckResult.BANNED;
} }
return CheckResult.OPEN; if (!is.isAllowed(User.getInstance(player), Flags.LOCK))
}).orElse(CheckResult.OPEN); {
return player.hasPermission(getIWM().getPermissionPrefix(loc.getWorld()) + "mod.bypasslock") ?
CheckResult.OPEN : CheckResult.LOCKED;
}
return CheckResult.OPEN;
}).
orElse(CheckResult.OPEN);
} }
/** /**
@ -128,19 +137,17 @@ public class LockAndBanListener extends FlagListener {
* @param loc - location to check * @param loc - location to check
* @return true if banned * @return true if banned
*/ */
private CheckResult checkAndNotify(@NonNull Player player, Location loc) { private CheckResult checkAndNotify(@NonNull Player player, Location loc)
CheckResult r = check(player,loc); {
switch (r) { CheckResult result = this.check(player, loc);
case BANNED:
User.getInstance(player).notify("commands.island.ban.you-are-banned"); switch (result)
break; {
case LOCKED: case BANNED -> User.getInstance(player).notify("commands.island.ban.you-are-banned");
User.getInstance(player).notify("protection.locked"); case LOCKED -> User.getInstance(player).notify("protection.locked");
break;
default:
break;
} }
return r;
return result;
} }
/** /**

View File

@ -13,67 +13,66 @@ import org.bukkit.event.player.PlayerInteractEvent;
import world.bentobox.bentobox.api.flags.FlagListener; import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.lists.Flags;
/** /**
* @author tastybento * @author tastybento
* *
*/ */
public class PhysicalInteractionListener extends FlagListener { public class PhysicalInteractionListener extends FlagListener
{
/** /**
* Handle physical interaction with blocks * Handle physical interaction with blocks
* Crop trample, pressure plates, triggering redstone, tripwires * Crop trample, pressure plates, triggering redstone, tripwires
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerInteract(PlayerInteractEvent e) { public void onPlayerInteract(PlayerInteractEvent e)
if (!e.getAction().equals(Action.PHYSICAL)) { {
if (!e.getAction().equals(Action.PHYSICAL) || e.getClickedBlock() == null)
{
return; return;
} }
if (isPressurePlate(e.getClickedBlock().getType())) {
if (Tag.PRESSURE_PLATES.isTagged(e.getClickedBlock().getType()))
{
// Pressure plates // Pressure plates
checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.PRESSURE_PLATE); this.checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.PRESSURE_PLATE);
return; return;
} }
switch (e.getClickedBlock().getType()) {
case FARMLAND: switch (e.getClickedBlock().getType())
// Crop trample {
checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.CROP_TRAMPLE); case FARMLAND -> this.checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.CROP_TRAMPLE);
break; case TURTLE_EGG -> this.checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.TURTLE_EGGS);
case TURTLE_EGG:
checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.TURTLE_EGGS);
break;
default:
break;
} }
} }
/** /**
* Protects buttons and plates from being activated by projectiles * Protects buttons and plates from being activated by projectiles
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onProjectileHit(EntityInteractEvent e) { public void onProjectileHit(EntityInteractEvent e)
if (!(e.getEntity() instanceof Projectile p)) { {
if (!(e.getEntity() instanceof Projectile p))
{
return; return;
} }
if (p.getShooter() instanceof Player) {
if (Tag.WOODEN_BUTTONS.isTagged(e.getBlock().getType())) { if (p.getShooter() instanceof Player)
checkIsland(e, (Player)p.getShooter(), e.getBlock().getLocation(), Flags.BUTTON); {
if (Tag.WOODEN_BUTTONS.isTagged(e.getBlock().getType()))
{
this.checkIsland(e, (Player) p.getShooter(), e.getBlock().getLocation(), Flags.BUTTON);
return; return;
} }
if (isPressurePlate(e.getBlock().getType())) { if (Tag.PRESSURE_PLATES.isTagged(e.getBlock().getType()))
{
// Pressure plates // Pressure plates
checkIsland(e, (Player)p.getShooter(), e.getBlock().getLocation(), Flags.PRESSURE_PLATE); this.checkIsland(e, (Player) p.getShooter(), e.getBlock().getLocation(), Flags.PRESSURE_PLATE);
} }
} }
} }
private boolean isPressurePlate(Material material) {
return switch (material) {
case STONE_PRESSURE_PLATE, POLISHED_BLACKSTONE_PRESSURE_PLATE, ACACIA_PRESSURE_PLATE, BIRCH_PRESSURE_PLATE, CRIMSON_PRESSURE_PLATE, DARK_OAK_PRESSURE_PLATE, HEAVY_WEIGHTED_PRESSURE_PLATE, JUNGLE_PRESSURE_PLATE, LIGHT_WEIGHTED_PRESSURE_PLATE, OAK_PRESSURE_PLATE, SPRUCE_PRESSURE_PLATE, WARPED_PRESSURE_PLATE -> true;
default -> false;
};
}
} }

View File

@ -18,95 +18,126 @@ import world.bentobox.bentobox.lists.Flags;
/** /**
* @author tastybento * @author tastybento
*/ */
public class PlaceBlocksListener extends FlagListener { public class PlaceBlocksListener extends FlagListener
{
/** /**
* Check blocks being placed in general * Check blocks being placed in general
* *
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onBlockPlace(final BlockPlaceEvent e) { public void onBlockPlace(final BlockPlaceEvent e)
if (e.getBlock().getType().equals(Material.FIRE) {
|| e.getItemInHand() == null // Note that this should never happen officially, but it's possible for other plugins to cause it to happen if (e.getBlock().getType().equals(Material.FIRE) ||
|| e.getItemInHand().getType().equals(Material.WRITABLE_BOOK) e.getItemInHand() == null || // Note that this should never happen officially, but it's possible for other plugins to cause it to happen
|| e.getItemInHand().getType().equals(Material.WRITTEN_BOOK)) { e.getItemInHand().getType().equals(Material.WRITABLE_BOOK) ||
e.getItemInHand().getType().equals(Material.WRITTEN_BOOK))
{
// Books can only be placed on lecterns and as such are protected by the LECTERN flag. // Books can only be placed on lecterns and as such are protected by the LECTERN flag.
return; return;
} }
checkIsland(e, e.getPlayer(), e.getBlock().getLocation(), Flags.PLACE_BLOCKS);
this.checkIsland(e, e.getPlayer(), e.getBlock().getLocation(), Flags.PLACE_BLOCKS);
} }
/** /**
* Check for paintings and other hanging placements * Check for paintings and other hanging placements
*
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onHangingPlace(final HangingPlaceEvent e) { public void onHangingPlace(final HangingPlaceEvent e)
checkIsland(e, e.getPlayer(), e.getBlock().getLocation(), Flags.PLACE_BLOCKS); {
this.checkIsland(e, e.getPlayer(), e.getBlock().getLocation(), Flags.PLACE_BLOCKS);
} }
/** /**
* Handles placing items into ItemFrames * Handles placing items into ItemFrames
*
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerHitItemFrame(PlayerInteractEntityEvent e) { public void onPlayerHitItemFrame(PlayerInteractEntityEvent e)
if (e.getRightClicked().getType().equals(EntityType.ITEM_FRAME) || e.getRightClicked().getType().equals(EntityType.GLOW_ITEM_FRAME)) { {
if (!checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.PLACE_BLOCKS)) return; if (e.getRightClicked().getType().equals(EntityType.ITEM_FRAME) ||
checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.ITEM_FRAME); e.getRightClicked().getType().equals(EntityType.GLOW_ITEM_FRAME))
{
if (!this.checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.PLACE_BLOCKS))
{
return;
}
this.checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.ITEM_FRAME);
} }
} }
/** /**
* Handle placing of fireworks, item frames, mine carts, end crystals, chests and boats on land * Handle placing of fireworks, item frames, mine carts, end crystals, chests and boats on land The doors and chests
* The doors and chests are related to an exploit. * are related to an exploit.
*
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerInteract(final PlayerInteractEvent e) { public void onPlayerInteract(final PlayerInteractEvent e)
if (!e.getAction().equals(Action.RIGHT_CLICK_BLOCK) || e.getClickedBlock() == null) { {
if (!e.getAction().equals(Action.RIGHT_CLICK_BLOCK) || e.getClickedBlock() == null)
{
return; return;
} }
switch (e.getClickedBlock().getType()) { switch (e.getClickedBlock().getType())
case FIREWORK_ROCKET: {
checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.PLACE_BLOCKS); case FIREWORK_ROCKET ->
return; {
case RAIL: this.checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.PLACE_BLOCKS);
case POWERED_RAIL:
case DETECTOR_RAIL:
case ACTIVATOR_RAIL:
if ((e.getMaterial() == Material.MINECART || e.getMaterial() == Material.CHEST_MINECART || e.getMaterial() == Material.HOPPER_MINECART
|| e.getMaterial() == Material.TNT_MINECART || e.getMaterial() == Material.FURNACE_MINECART)) {
checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.MINECART);
} }
return; case RAIL, POWERED_RAIL, DETECTOR_RAIL, ACTIVATOR_RAIL ->
default: {
// Check in-hand items if (e.getMaterial() == Material.MINECART ||
if (e.getMaterial().equals(Material.FIREWORK_ROCKET) e.getMaterial() == Material.CHEST_MINECART ||
|| e.getMaterial().equals(Material.ARMOR_STAND) e.getMaterial() == Material.HOPPER_MINECART ||
|| e.getMaterial().equals(Material.END_CRYSTAL) e.getMaterial() == Material.TNT_MINECART ||
|| e.getMaterial().equals(Material.ITEM_FRAME) e.getMaterial() == Material.FURNACE_MINECART)
//|| Tag.DOORS.isTagged(e.getMaterial()) {
|| e.getMaterial().equals(Material.CHEST) this.checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.MINECART);
|| e.getMaterial().equals(Material.TRAPPED_CHEST)) { }
checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.PLACE_BLOCKS);
} }
else if (e.getMaterial().name().contains("BOAT")) { default ->
checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.BOAT); {
// Check in-hand items
if (e.getMaterial() == Material.FIREWORK_ROCKET ||
e.getMaterial() == Material.ARMOR_STAND ||
e.getMaterial() == Material.END_CRYSTAL ||
e.getMaterial() == Material.ITEM_FRAME ||
e.getMaterial() == Material.GLOW_ITEM_FRAME ||
e.getMaterial() == Material.CHEST ||
e.getMaterial() == Material.TRAPPED_CHEST)
{
this.checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.PLACE_BLOCKS);
}
else if (e.getMaterial().name().contains("BOAT"))
{
this.checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.BOAT);
}
} }
} }
} }
/** /**
* Handles Frost Walking on visitor's islands. This creates ice blocks, which is like placing blocks * Handles Frost Walking on visitor's islands. This creates ice blocks, which is like placing blocks
*
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOW, ignoreCancelled=true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onBlockForm(EntityBlockFormEvent e) { public void onBlockForm(EntityBlockFormEvent e)
if (e.getNewState().getType().equals(Material.FROSTED_ICE) && e.getEntity() instanceof Player) { {
checkIsland(e, (Player)e.getEntity(), e.getBlock().getLocation(), Flags.FROST_WALKER); if (e.getNewState().getType().equals(Material.FROSTED_ICE) && e.getEntity() instanceof Player)
{
this.checkIsland(e, (Player) e.getEntity(), e.getBlock().getLocation(), Flags.FROST_WALKER);
} }
} }
} }

View File

@ -0,0 +1,53 @@
//
// Created by BONNe
// Copyright - 2022
//
package world.bentobox.bentobox.listeners.flags.protection;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockReceiveGameEvent;
import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.versions.ServerCompatibility;
/**
* This method prevents sculk sensor from activation based on protection settings.
*/
public class SculkSensorListener extends FlagListener
{
/**
* This listener detects if a visitor activates sculk sensor, and block it, if required.
* @param event Sculk activation event.
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onSculkSensor(BlockReceiveGameEvent event)
{
if (!this.getIWM().inWorld(event.getBlock().getWorld()))
{
return;
}
if (ServerCompatibility.getInstance().isVersion(ServerCompatibility.ServerVersion.V1_18,
ServerCompatibility.ServerVersion.V1_18_1,
ServerCompatibility.ServerVersion.V1_18_2))
{
// TODO: 1.18 compatibility exit
return;
}
if (event.getBlock().getType() == Material.SCULK_SENSOR &&
event.getEntity() != null &&
event.getEntity() instanceof Player player)
{
this.checkIsland(event, player, event.getBlock().getLocation(), Flags.SCULK_SENSOR, true);
}
}
}

View File

@ -0,0 +1,53 @@
//
// Created by BONNe
// Copyright - 2022
//
package world.bentobox.bentobox.listeners.flags.protection;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockReceiveGameEvent;
import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.versions.ServerCompatibility;
/**
* This method prevents sculk shrieker from activation based on protection settings.
*/
public class SculkShriekerListener extends FlagListener
{
/**
* This listener detects if a visitor activates sculk sensor, and block it, if required.
* @param event Sculk activation event.
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onSculkShrieker(BlockReceiveGameEvent event)
{
if (!this.getIWM().inWorld(event.getBlock().getWorld()))
{
return;
}
if (ServerCompatibility.getInstance().isVersion(ServerCompatibility.ServerVersion.V1_18,
ServerCompatibility.ServerVersion.V1_18_1,
ServerCompatibility.ServerVersion.V1_18_2))
{
// TODO: 1.18 compatibility exit
return;
}
if (event.getBlock().getType() == Material.SCULK_SHRIEKER &&
event.getEntity() != null &&
event.getEntity() instanceof Player player)
{
this.checkIsland(event, player, event.getBlock().getLocation(), Flags.SCULK_SHRIEKER, true);
}
}
}

View File

@ -19,68 +19,82 @@ import world.bentobox.bentobox.util.Util;
* Handles natural mob spawning. * Handles natural mob spawning.
* @author tastybento * @author tastybento
*/ */
public class MobSpawnListener extends FlagListener { public class MobSpawnListener extends FlagListener
{
/**
* Prevents mobs spawning naturally
*
* @param e - event
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onMobSpawnEvent(CreatureSpawnEvent e)
{
this.onMobSpawn(e);
}
/** /**
* Prevents mobs spawning naturally * Prevents mobs spawning naturally
*
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) void onMobSpawn(CreatureSpawnEvent e)
public void onMobSpawnEvent(CreatureSpawnEvent e) { {
onMobSpawn(e);
}
/**
* Prevents mobs spawning naturally
*
* @param e - event
* @return true if cancelled
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
void onMobSpawn(CreatureSpawnEvent e) {
// If not in the right world, or spawning is not natural return // If not in the right world, or spawning is not natural return
if (!getIWM().inWorld(e.getEntity().getLocation())) { if (!this.getIWM().inWorld(e.getEntity().getLocation()))
{
return; return;
} }
switch (e.getSpawnReason()) {
// Natural switch (e.getSpawnReason())
case DEFAULT: {
case DROWNED: // Natural
case JOCKEY: case DEFAULT, DROWNED, JOCKEY, LIGHTNING, MOUNT, NATURAL, NETHER_PORTAL, OCELOT_BABY, PATROL,
case LIGHTNING: RAID, REINFORCEMENTS, SILVERFISH_BLOCK, TRAP, VILLAGE_DEFENSE, VILLAGE_INVASION ->
case MOUNT: {
case NATURAL: boolean cancelNatural = this.shouldCancel(e.getEntity(),
case NETHER_PORTAL: e.getLocation(),
case OCELOT_BABY: Flags.ANIMAL_NATURAL_SPAWN,
case PATROL: Flags.MONSTER_NATURAL_SPAWN);
case RAID: e.setCancelled(cancelNatural);
case REINFORCEMENTS: }
case SILVERFISH_BLOCK:
//case SLIME_SPLIT: messes with slimes from spawners, slime must have previously existed to create another
case TRAP:
case VILLAGE_DEFENSE:
case VILLAGE_INVASION:
boolean cancelNatural = shouldCancel(e.getEntity(), e.getLocation(), Flags.ANIMAL_NATURAL_SPAWN, Flags.MONSTER_NATURAL_SPAWN);
e.setCancelled(cancelNatural);
return;
// Spawners // Spawners
case SPAWNER: case SPAWNER ->
boolean cancelSpawners = shouldCancel(e.getEntity(), e.getLocation(), Flags.ANIMAL_SPAWNERS_SPAWN, Flags.MONSTER_SPAWNERS_SPAWN); {
e.setCancelled(cancelSpawners); boolean cancelSpawners = this.shouldCancel(e.getEntity(),
return; e.getLocation(),
default: Flags.ANIMAL_SPAWNERS_SPAWN,
return; Flags.MONSTER_SPAWNERS_SPAWN);
e.setCancelled(cancelSpawners);
}
} }
} }
private boolean shouldCancel(Entity entity, Location loc, Flag animalSpawnFlag, Flag monsterSpawnFlag) {
/**
* This method checks if entity should be cancelled from spawning in given location base on flag values.
* @param entity Entity that is checked.
* @param loc location where entity is spawned.
* @param animalSpawnFlag Animal Spawn Flag.
* @param monsterSpawnFlag Monster Spawn Flag.
* @return {@code true} if flag prevents entity to spawn, {@code false} otherwise.
*/
private boolean shouldCancel(Entity entity, Location loc, Flag animalSpawnFlag, Flag monsterSpawnFlag)
{
Optional<Island> island = getIslands().getIslandAt(loc); Optional<Island> island = getIslands().getIslandAt(loc);
if (Util.isHostileEntity(entity) && !(entity instanceof PufferFish)) {
return island.map(i -> !i.isAllowed(monsterSpawnFlag)).orElseGet(() -> !monsterSpawnFlag.isSetForWorld(entity.getWorld()));
} else if (Util.isPassiveEntity(entity) || entity instanceof PufferFish) {
return island.map(i -> !i.isAllowed(animalSpawnFlag)).orElseGet(() -> !animalSpawnFlag.isSetForWorld(entity.getWorld()));
}
return false;
}
if (Util.isHostileEntity(entity) && !(entity instanceof PufferFish))
{
return island.map(i -> !i.isAllowed(monsterSpawnFlag)).
orElseGet(() -> !monsterSpawnFlag.isSetForWorld(entity.getWorld()));
}
else if (Util.isPassiveEntity(entity) || entity instanceof PufferFish)
{
return island.map(i -> !i.isAllowed(animalSpawnFlag)).
orElseGet(() -> !animalSpawnFlag.isSetForWorld(entity.getWorld()));
}
else
{
return false;
}
}
} }

View File

@ -1,6 +1,7 @@
package world.bentobox.bentobox.listeners.flags.worldsettings; package world.bentobox.bentobox.listeners.flags.worldsettings;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityExplodeEvent;
@ -18,12 +19,13 @@ public class ChestDamageListener extends FlagListener {
* @param e - event * @param e - event
*/ */
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onExplosion(final EntityExplodeEvent e) { public void onExplosion(final EntityExplodeEvent e)
if (getIWM().inWorld(e.getLocation()) && !Flags.CHEST_DAMAGE.isSetForWorld(e.getLocation().getWorld())) { {
e.blockList().removeIf(b -> b.getType().equals(Material.CHEST) if (getIWM().inWorld(e.getLocation()) && !Flags.CHEST_DAMAGE.isSetForWorld(e.getLocation().getWorld()))
|| b.getType().equals(Material.TRAPPED_CHEST) {
|| b.getType().name().contains("SHULKER_BOX") e.blockList().removeIf(b -> b.getType().equals(Material.CHEST) ||
); b.getType().equals(Material.TRAPPED_CHEST) ||
Tag.SHULKER_BOXES.isTagged(b.getType()));
} }
} }
} }

View File

@ -12,6 +12,8 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.BentoBox;
@ -157,5 +159,28 @@ public class InvincibleVisitorsListener extends FlagListener implements ClickHan
} }
/**
* This listener cancels entity targeting a player if he is a visitor, and visitors are immune to entity damage.
* @param e EntityTargetLivingEntityEvent
*/
@EventHandler(priority = EventPriority.HIGHEST)
public void onVisitorTargeting(EntityTargetLivingEntityEvent e)
{
World world = e.getEntity().getWorld();
if (!(e.getTarget() instanceof Player p) ||
!this.getIWM().inWorld(world) ||
e.getTarget().hasMetadata("NPC") ||
this.getIslands().userIsOnIsland(world, User.getInstance(e.getEntity())) ||
this.PVPAllowed(p.getLocation()) ||
e.getReason() == EntityTargetEvent.TargetReason.TARGET_DIED ||
!this.getIWM().getIvSettings(world).contains(DamageCause.ENTITY_ATTACK.name()))
{
return;
}
// Cancel targeting event.
e.setCancelled(true);
}
} }

View File

@ -1,5 +1,6 @@
package world.bentobox.bentobox.lists; package world.bentobox.bentobox.lists;
import com.google.common.base.Enums;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -13,30 +14,7 @@ import world.bentobox.bentobox.api.flags.clicklisteners.CycleClick;
import world.bentobox.bentobox.listeners.flags.clicklisteners.CommandRankClickListener; import world.bentobox.bentobox.listeners.flags.clicklisteners.CommandRankClickListener;
import world.bentobox.bentobox.listeners.flags.clicklisteners.GeoLimitClickListener; import world.bentobox.bentobox.listeners.flags.clicklisteners.GeoLimitClickListener;
import world.bentobox.bentobox.listeners.flags.clicklisteners.MobLimitClickListener; import world.bentobox.bentobox.listeners.flags.clicklisteners.MobLimitClickListener;
import world.bentobox.bentobox.listeners.flags.protection.BlockInteractionListener; import world.bentobox.bentobox.listeners.flags.protection.*;
import world.bentobox.bentobox.listeners.flags.protection.BreakBlocksListener;
import world.bentobox.bentobox.listeners.flags.protection.BreedingListener;
import world.bentobox.bentobox.listeners.flags.protection.BucketListener;
import world.bentobox.bentobox.listeners.flags.protection.DyeListener;
import world.bentobox.bentobox.listeners.flags.protection.EggListener;
import world.bentobox.bentobox.listeners.flags.protection.ElytraListener;
import world.bentobox.bentobox.listeners.flags.protection.EntityInteractListener;
import world.bentobox.bentobox.listeners.flags.protection.ExperiencePickupListener;
import world.bentobox.bentobox.listeners.flags.protection.FireListener;
import world.bentobox.bentobox.listeners.flags.protection.HurtingListener;
import world.bentobox.bentobox.listeners.flags.protection.InventoryListener;
import world.bentobox.bentobox.listeners.flags.protection.ItemDropPickUpListener;
import world.bentobox.bentobox.listeners.flags.protection.LeashListener;
import world.bentobox.bentobox.listeners.flags.protection.LecternListener;
import world.bentobox.bentobox.listeners.flags.protection.LockAndBanListener;
import world.bentobox.bentobox.listeners.flags.protection.PaperExperiencePickupListener;
import world.bentobox.bentobox.listeners.flags.protection.PhysicalInteractionListener;
import world.bentobox.bentobox.listeners.flags.protection.PlaceBlocksListener;
import world.bentobox.bentobox.listeners.flags.protection.PortalListener;
import world.bentobox.bentobox.listeners.flags.protection.ShearingListener;
import world.bentobox.bentobox.listeners.flags.protection.TNTListener;
import world.bentobox.bentobox.listeners.flags.protection.TeleportationListener;
import world.bentobox.bentobox.listeners.flags.protection.ThrowingListener;
import world.bentobox.bentobox.listeners.flags.settings.DecayListener; import world.bentobox.bentobox.listeners.flags.settings.DecayListener;
import world.bentobox.bentobox.listeners.flags.settings.MobSpawnListener; import world.bentobox.bentobox.listeners.flags.settings.MobSpawnListener;
import world.bentobox.bentobox.listeners.flags.settings.PVPListener; import world.bentobox.bentobox.listeners.flags.settings.PVPListener;
@ -174,7 +152,10 @@ public final class Flags {
public static final Flag BOAT = new Flag.Builder("BOAT", Material.OAK_BOAT).mode(Flag.Mode.BASIC).build(); public static final Flag BOAT = new Flag.Builder("BOAT", Material.OAK_BOAT).mode(Flag.Mode.BASIC).build();
public static final Flag TRADING = new Flag.Builder("TRADING", Material.EMERALD).defaultSetting(true).mode(Flag.Mode.BASIC).build(); public static final Flag TRADING = new Flag.Builder("TRADING", Material.EMERALD).defaultSetting(true).mode(Flag.Mode.BASIC).build();
public static final Flag NAME_TAG = new Flag.Builder("NAME_TAG", Material.NAME_TAG).mode(Flag.Mode.ADVANCED).build(); public static final Flag NAME_TAG = new Flag.Builder("NAME_TAG", Material.NAME_TAG).mode(Flag.Mode.ADVANCED).build();
/**
* @since 1.21
*/
public static final Flag ALLAY = new Flag.Builder("ALLAY", Material.AMETHYST_SHARD).mode(Flag.Mode.ADVANCED).build();
// Breeding // Breeding
public static final Flag BREEDING = new Flag.Builder("BREEDING", Material.CARROT).listener(new BreedingListener()).mode(Flag.Mode.ADVANCED).build(); public static final Flag BREEDING = new Flag.Builder("BREEDING", Material.CARROT).listener(new BreedingListener()).mode(Flag.Mode.ADVANCED).build();
@ -182,8 +163,16 @@ public final class Flags {
public static final Flag BUCKET = new Flag.Builder("BUCKET", Material.BUCKET).listener(new BucketListener()).mode(Flag.Mode.BASIC).build(); public static final Flag BUCKET = new Flag.Builder("BUCKET", Material.BUCKET).listener(new BucketListener()).mode(Flag.Mode.BASIC).build();
public static final Flag COLLECT_LAVA = new Flag.Builder("COLLECT_LAVA", Material.LAVA_BUCKET).build(); public static final Flag COLLECT_LAVA = new Flag.Builder("COLLECT_LAVA", Material.LAVA_BUCKET).build();
public static final Flag COLLECT_WATER = new Flag.Builder("COLLECT_WATER", Material.WATER_BUCKET).mode(Flag.Mode.ADVANCED).build(); public static final Flag COLLECT_WATER = new Flag.Builder("COLLECT_WATER", Material.WATER_BUCKET).mode(Flag.Mode.ADVANCED).build();
/**
* @since 1.21
*/
public static final Flag COLLECT_POWDERED_SNOW = new Flag.Builder("COLLECT_POWDERED_SNOW", Material.POWDER_SNOW_BUCKET).mode(Flag.Mode.ADVANCED).build();
public static final Flag MILKING = new Flag.Builder("MILKING", Material.MILK_BUCKET).mode(Flag.Mode.ADVANCED).build(); public static final Flag MILKING = new Flag.Builder("MILKING", Material.MILK_BUCKET).mode(Flag.Mode.ADVANCED).build();
public static final Flag FISH_SCOOPING = new Flag.Builder("FISH_SCOOPING", Material.TROPICAL_FISH_BUCKET).build(); public static final Flag FISH_SCOOPING = new Flag.Builder("FISH_SCOOPING", Material.TROPICAL_FISH_BUCKET).build();
/**
* @since 1.21
*/
public static final Flag AXOLOTL_SCOOPING = new Flag.Builder("AXOLOTL_SCOOPING", Material.AXOLOTL_BUCKET).build();
// Chorus Fruit and Enderpearls // Chorus Fruit and Enderpearls
public static final Flag CHORUS_FRUIT = new Flag.Builder("CHORUS_FRUIT", Material.CHORUS_FRUIT).listener(new TeleportationListener()).build(); public static final Flag CHORUS_FRUIT = new Flag.Builder("CHORUS_FRUIT", Material.CHORUS_FRUIT).listener(new TeleportationListener()).build();
@ -314,6 +303,32 @@ public final class Flags {
.clickHandler(new CycleClick("CHANGE_SETTINGS", RanksManager.MEMBER_RANK, RanksManager.OWNER_RANK)) .clickHandler(new CycleClick("CHANGE_SETTINGS", RanksManager.MEMBER_RANK, RanksManager.OWNER_RANK))
.mode(Flag.Mode.TOP_ROW).build(); .mode(Flag.Mode.TOP_ROW).build();
/**
* This flag allows choosing which island member group can activate sculk sensors.
* TODO: Enums#getIfPresent is used to support 1.18
* @since 1.21.0
*/
public static final Flag SCULK_SENSOR = new Flag.Builder("SCULK_SENSOR", Enums.getIfPresent(Material.class, "SCULK_SENSOR").or(Material.BARRIER)).
listener(new SculkSensorListener()).
type(Type.PROTECTION).
defaultSetting(true).
defaultRank(RanksManager.MEMBER_RANK).
clickHandler(new CycleClick("SCULK_SENSOR", RanksManager.VISITOR_RANK, RanksManager.MEMBER_RANK)).
build();
/**
* This flag allows choosing which island member group can activate sculk shrieker.
* TODO: Enums#getIfPresent is used to support 1.18
* @since 1.21.0
*/
public static final Flag SCULK_SHRIEKER = new Flag.Builder("SCULK_SHRIEKER", Enums.getIfPresent(Material.class, "SCULK_SHRIEKER").or(Material.BARRIER)).
listener(new SculkShriekerListener()).
type(Type.PROTECTION).
defaultSetting(true).
defaultRank(RanksManager.MEMBER_RANK).
clickHandler(new CycleClick("SCULK_SHRIEKER", RanksManager.VISITOR_RANK, RanksManager.MEMBER_RANK)).
build();
/* /*
* Settings flags (not protection flags) * Settings flags (not protection flags)
*/ */

View File

@ -1,10 +1,10 @@
package world.bentobox.bentobox.nms.v1_18_R2; package world.bentobox.bentobox.nms.v1_19_R1;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData; import org.bukkit.craftbukkit.v1_19_R1.block.data.CraftBlockData;
import net.minecraft.core.BlockPosition; import net.minecraft.core.BlockPosition;
import net.minecraft.world.level.World; import net.minecraft.world.level.World;

View File

@ -25,19 +25,7 @@ import org.bukkit.World.Environment;
import org.bukkit.attribute.Attribute; import org.bukkit.attribute.Attribute;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.entity.Animals; import org.bukkit.entity.*;
import org.bukkit.entity.Bat;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Flying;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Player;
import org.bukkit.entity.PufferFish;
import org.bukkit.entity.Shulker;
import org.bukkit.entity.Slime;
import org.bukkit.entity.Snowman;
import org.bukkit.entity.WaterMob;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNull;
@ -49,6 +37,7 @@ import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.nms.PasteHandler; import world.bentobox.bentobox.nms.PasteHandler;
import world.bentobox.bentobox.nms.WorldRegenerator; import world.bentobox.bentobox.nms.WorldRegenerator;
import world.bentobox.bentobox.versions.ServerCompatibility;
/** /**
@ -356,8 +345,19 @@ public class Util {
// Bat extends Mob // Bat extends Mob
// Most of passive mobs extends Animals // Most of passive mobs extends Animals
return entity instanceof Animals || entity instanceof IronGolem || entity instanceof Snowman || if (ServerCompatibility.getInstance().isVersion(ServerCompatibility.ServerVersion.V1_18,
ServerCompatibility.ServerVersion.V1_18_1,
ServerCompatibility.ServerVersion.V1_18_2))
{
return entity instanceof Animals || entity instanceof IronGolem || entity instanceof Snowman ||
entity instanceof WaterMob && !(entity instanceof PufferFish) || entity instanceof Bat; entity instanceof WaterMob && !(entity instanceof PufferFish) || entity instanceof Bat;
}
else
{
return entity instanceof Animals || entity instanceof IronGolem || entity instanceof Snowman ||
entity instanceof WaterMob && !(entity instanceof PufferFish) || entity instanceof Bat ||
entity instanceof Allay;
}
} }
/* /*

View File

@ -176,28 +176,36 @@ public class ServerCompatibility {
/** /**
* @since 1.16.0 * @since 1.16.0
*/ */
V1_16_5(Compatibility.NOT_SUPPORTED), V1_16_5(Compatibility.INCOMPATIBLE),
/** /**
* @since 1.17.0 * @since 1.17.0
*/ */
V1_17(Compatibility.NOT_SUPPORTED), V1_17(Compatibility.INCOMPATIBLE),
/** /**
* @since 1.17.1 * @since 1.17.1
*/ */
V1_17_1(Compatibility.SUPPORTED), V1_17_1(Compatibility.INCOMPATIBLE),
/** /**
* @since 1.19.0 * @since 1.19.0
*/ */
V1_18(Compatibility.COMPATIBLE), V1_18(Compatibility.SUPPORTED),
/** /**
* @since 1.19.0 * @since 1.19.0
*/ */
V1_18_1(Compatibility.COMPATIBLE), V1_18_1(Compatibility.SUPPORTED),
/** /**
* @since 1.20.1 * @since 1.20.1
*/ */
V1_18_2(Compatibility.COMPATIBLE), V1_18_2(Compatibility.SUPPORTED),
/**
* @since 1.21.0
*/
V1_19(Compatibility.COMPATIBLE),
/**
* @since 1.21.0
*/
V1_19_1(Compatibility.COMPATIBLE),
; ;
private final Compatibility compatibility; private final Compatibility compatibility;

View File

@ -731,6 +731,10 @@ ranks:
protection: protection:
command-is-banned: "Command is banned for visitors" command-is-banned: "Command is banned for visitors"
flags: flags:
ALLAY:
name: "Allay interaction"
description: "Allow giving and taking items to/from Allay"
hint: "Allay interaction disabled"
ANIMAL_NATURAL_SPAWN: ANIMAL_NATURAL_SPAWN:
description: "Toggle natural animal spawning" description: "Toggle natural animal spawning"
name: "Animal natural spawn" name: "Animal natural spawn"
@ -745,6 +749,10 @@ protection:
description: "Toggle interaction" description: "Toggle interaction"
name: "Armor stands" name: "Armor stands"
hint: "Armor stand use disabled" hint: "Armor stand use disabled"
AXOLOTL_SCOOPING:
name: "Axolotl Scooping"
description: "Allow scooping of axolotl using a bucket"
hint: "Axolotl scooping disabled"
BEACON: BEACON:
description: "Toggle interaction" description: "Toggle interaction"
name: "Beacons" name: "Beacons"
@ -889,6 +897,12 @@ protection:
&a (override Buckets) &a (override Buckets)
name: "Collect water" name: "Collect water"
hint: "Water buckets disabled" hint: "Water buckets disabled"
COLLECT_POWDERED_SNOW:
description: |-
&a Toggle collecting powdered snow
&a (override Buckets)
name: "Collect powdered snow"
hint: "Powdered snow buckets disabled"
COMMAND_RANKS: COMMAND_RANKS:
name: "&e Command Ranks" name: "&e Command Ranks"
description: "&a Configure command ranks" description: "&a Configure command ranks"
@ -1271,6 +1285,18 @@ protection:
&a using spawn eggs. &a using spawn eggs.
name: "Spawn eggs on spawners" name: "Spawn eggs on spawners"
hint: "changing a spawner's entity type using spawn eggs is not allowed" hint: "changing a spawner's entity type using spawn eggs is not allowed"
SCULK_SENSOR:
description: |-
&a Allows to change if sculk sensor
&a can be activated by visitor.
name: "Sculk Sensor"
hint: "sculk sensor activation is disabled"
SCULK_SHRIEKER:
description: |-
&a Allows to change if sculk shrieker
&a can be activated by visitor.
name: "Sculk Shrieker"
hint: "sculk shrieker activation is disabled"
TNT_DAMAGE: TNT_DAMAGE:
description: |- description: |-
&a Allow TNT and TNT minecarts &a Allow TNT and TNT minecarts

View File

@ -1,7 +1,7 @@
name: BentoBox name: BentoBox
main: world.bentobox.bentobox.BentoBox main: world.bentobox.bentobox.BentoBox
version: ${project.version}${build.number} version: ${project.version}${build.number}
api-version: "1.17" api-version: "1.18"
authors: [tastybento, Poslovitch] authors: [tastybento, Poslovitch]
contributors: ["The BentoBoxWorld Community"] contributors: ["The BentoBoxWorld Community"]

View File

@ -110,13 +110,13 @@ public class GeoMobLimitTabTest {
assertEquals("AXOLOTL", list.get(0)); assertEquals("AXOLOTL", list.get(0));
// Click on AXOLOTL // Click on AXOLOTL
tab.onClick(panel, user, ClickType.LEFT, 9); tab.onClick(panel, user, ClickType.LEFT, 10);
list.forEach(System.out::println); list.forEach(System.out::println);
assertEquals(2, list.size()); assertEquals(2, list.size());
assertEquals("COW", list.get(1)); assertEquals("COW", list.get(1));
assertEquals("BAT", list.get(0)); assertEquals("BAT", list.get(0));
// Click on AXOLOTL again to have it added // Click on AXOLOTL again to have it added
tab.onClick(panel, user, ClickType.LEFT, 9); tab.onClick(panel, user, ClickType.LEFT, 10);
assertEquals(3, list.size()); assertEquals(3, list.size());
assertEquals("BAT", list.get(0)); assertEquals("BAT", list.get(0));
assertEquals("COW", list.get(1)); assertEquals("COW", list.get(1));

View File

@ -69,7 +69,7 @@ public class BlockInteractionListenerTest extends AbstractCommonSetup {
clickedBlocks.put(Material.WHITE_BED, Flags.BED); clickedBlocks.put(Material.WHITE_BED, Flags.BED);
when(Tag.BEDS.isTagged(Material.WHITE_BED)).thenReturn(true); when(Tag.BEDS.isTagged(Material.WHITE_BED)).thenReturn(true);
clickedBlocks.put(Material.BREWING_STAND, Flags.BREWING); clickedBlocks.put(Material.BREWING_STAND, Flags.BREWING);
clickedBlocks.put(Material.CAULDRON, Flags.BREWING); clickedBlocks.put(Material.WATER_CAULDRON, Flags.COLLECT_WATER);
clickedBlocks.put(Material.BARREL, Flags.BARREL); clickedBlocks.put(Material.BARREL, Flags.BARREL);
clickedBlocks.put(Material.CHEST, Flags.CHEST); clickedBlocks.put(Material.CHEST, Flags.CHEST);
clickedBlocks.put(Material.CHEST_MINECART, Flags.CHEST); clickedBlocks.put(Material.CHEST_MINECART, Flags.CHEST);
@ -87,6 +87,7 @@ public class BlockInteractionListenerTest extends AbstractCommonSetup {
clickedBlocks.put(Material.IRON_TRAPDOOR, Flags.TRAPDOOR); clickedBlocks.put(Material.IRON_TRAPDOOR, Flags.TRAPDOOR);
when(Tag.TRAPDOORS.isTagged(Material.IRON_TRAPDOOR)).thenReturn(true); when(Tag.TRAPDOORS.isTagged(Material.IRON_TRAPDOOR)).thenReturn(true);
clickedBlocks.put(Material.SPRUCE_FENCE_GATE, Flags.GATE); clickedBlocks.put(Material.SPRUCE_FENCE_GATE, Flags.GATE);
when(Tag.FENCE_GATES.isTagged(Material.SPRUCE_FENCE_GATE)).thenReturn(true);
clickedBlocks.put(Material.BLAST_FURNACE, Flags.FURNACE); clickedBlocks.put(Material.BLAST_FURNACE, Flags.FURNACE);
clickedBlocks.put(Material.CAMPFIRE, Flags.FURNACE); clickedBlocks.put(Material.CAMPFIRE, Flags.FURNACE);
clickedBlocks.put(Material.FURNACE_MINECART, Flags.FURNACE); clickedBlocks.put(Material.FURNACE_MINECART, Flags.FURNACE);
@ -135,6 +136,8 @@ public class BlockInteractionListenerTest extends AbstractCommonSetup {
// Nothing in hand right now // Nothing in hand right now
when(item.getType()).thenReturn(Material.AIR); when(item.getType()).thenReturn(Material.AIR);
when(player.getInventory()).thenReturn(inv); when(player.getInventory()).thenReturn(inv);
when(inv.getItemInMainHand()).thenReturn(item);
when(inv.getItemInOffHand()).thenReturn(new ItemStack(Material.BUCKET));
// FlagsManager // FlagsManager
setFlags(); setFlags();

View File

@ -45,6 +45,8 @@ import world.bentobox.bentobox.managers.FlagsManager;
import world.bentobox.bentobox.managers.IslandWorldManager; import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
import world.bentobox.bentobox.versions.ServerCompatibility;
@RunWith(PowerMockRunner.class) @RunWith(PowerMockRunner.class)
@PrepareForTest( {BentoBox.class, Bukkit.class, Flags.class, Util.class }) @PrepareForTest( {BentoBox.class, Bukkit.class, Flags.class, Util.class })
@ -78,6 +80,10 @@ public class MobSpawnListenerTest {
when(server.getWorld("world")).thenReturn(world); when(server.getWorld("world")).thenReturn(world);
when(server.getVersion()).thenReturn("BSB_Mocking"); when(server.getVersion()).thenReturn("BSB_Mocking");
ServerCompatibility serverCompatibility = mock(ServerCompatibility.class);
Whitebox.setInternalState(ServerCompatibility.class, "instance", serverCompatibility);
when(serverCompatibility.getServerVersion()).thenReturn(ServerCompatibility.ServerVersion.V1_19);
PluginManager pim = mock(PluginManager.class); PluginManager pim = mock(PluginManager.class);
ItemFactory itemFactory = mock(ItemFactory.class); ItemFactory itemFactory = mock(ItemFactory.class);

View File

@ -19,11 +19,7 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.bukkit.Bukkit; import org.bukkit.*;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Cow; import org.bukkit.entity.Cow;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
@ -50,6 +46,7 @@ import world.bentobox.bentobox.Settings;
import world.bentobox.bentobox.api.configuration.WorldSettings; import world.bentobox.bentobox.api.configuration.WorldSettings;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.listeners.flags.AbstractCommonSetup;
import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.managers.FlagsManager; import world.bentobox.bentobox.managers.FlagsManager;
import world.bentobox.bentobox.managers.IslandWorldManager; import world.bentobox.bentobox.managers.IslandWorldManager;
@ -64,18 +61,25 @@ import world.bentobox.bentobox.util.Util;
*/ */
@RunWith(PowerMockRunner.class) @RunWith(PowerMockRunner.class)
@PrepareForTest( {Bukkit.class, BentoBox.class, Flags.class, Util.class} ) @PrepareForTest( {Bukkit.class, BentoBox.class, Flags.class, Util.class} )
public class ChestDamageListenerTest { public class ChestDamageListenerTest extends AbstractCommonSetup
{
private Location location; private Location location;
private BentoBox plugin; private BentoBox plugin;
private World world; private World world;
@Override
@Before @Before
public void setUp() { public void setUp() throws Exception {
super.setUp();
// Set up plugin // Set up plugin
plugin = mock(BentoBox.class); plugin = mock(BentoBox.class);
Whitebox.setInternalState(BentoBox.class, "instance", plugin); Whitebox.setInternalState(BentoBox.class, "instance", plugin);
// Tags
when(Tag.SHULKER_BOXES.isTagged(any(Material.class))).thenReturn(false);
Server server = mock(Server.class); Server server = mock(Server.class);
world = mock(World.class); world = mock(World.class);
when(server.getLogger()).thenReturn(Logger.getAnonymousLogger()); when(server.getLogger()).thenReturn(Logger.getAnonymousLogger());
@ -161,8 +165,6 @@ public class ChestDamageListenerTest {
// Util // Util
PowerMockito.mockStatic(Util.class); PowerMockito.mockStatic(Util.class);
when(Util.getWorld(Mockito.any())).thenReturn(mock(World.class)); when(Util.getWorld(Mockito.any())).thenReturn(mock(World.class));
} }
@After @After

View File

@ -46,7 +46,7 @@ public class FlagsManagerTest {
/** /**
* Update this value if the number of registered listeners changes * Update this value if the number of registered listeners changes
*/ */
private static final int NUMBER_OF_LISTENERS = 50; private static final int NUMBER_OF_LISTENERS = 52;
@Mock @Mock
private BentoBox plugin; private BentoBox plugin;
@Mock @Mock