From 2672ee5d1bd0f57f94cfc723332facd72a71baf5 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 10 Jun 2023 21:31:39 -0700 Subject: [PATCH] Handle Boats and other Materials for 1.20. Uses Tags a lot. May break compatibility with older server versions. --- .../blueprints/BlueprintClipboard.java | 7 +- .../dataobjects/BlueprintBlock.java | 67 ++++++++++++++ .../protection/BlockInteractionListener.java | 40 ++------- .../flags/protection/PlaceBlocksListener.java | 5 +- .../bentobox/managers/IslandsManager.java | 87 ++++++++----------- .../bentobox/nms/CopyWorldRegenerator.java | 85 ++++++++++-------- .../bentobox/util/DefaultPasteUtil.java | 23 +++-- .../listeners/flags/AbstractCommonSetup.java | 28 +++++- .../protection/PlaceBlocksListenerTest.java | 9 +- .../IslandRespawnListenerTest.java | 9 +- .../worldsettings/RemoveMobsListenerTest.java | 7 +- .../BlueprintClipboardManagerTest.java | 1 - .../managers/BlueprintsManagerTest.java | 1 - .../managers/IslandWorldManagerTest.java | 2 + .../bentobox/managers/IslandsManagerTest.java | 33 ++++--- 15 files changed, 238 insertions(+), 166 deletions(-) diff --git a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java index c0dff17bc..dd035adc3 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/BlueprintClipboard.java @@ -18,6 +18,7 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.CreatureSpawner; import org.bukkit.block.Sign; +import org.bukkit.block.sign.Side; import org.bukkit.entity.AbstractHorse; import org.bukkit.entity.Ageable; import org.bukkit.entity.ChestedHorse; @@ -221,8 +222,10 @@ public class BlueprintClipboard { // Signs if (blockState instanceof Sign sign) { - b.setSignLines(Arrays.asList(sign.getLines())); - b.setGlowingText(sign.isGlowingText()); + for (Side side : Side.values()) { + b.setSignLines(side, Arrays.asList(sign.getSide(side).getLines())); + b.setGlowingText(side, sign.getSide(side).isGlowingText()); + } } // Set block data if (blockState.getData() instanceof Attachable) { diff --git a/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintBlock.java b/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintBlock.java index 7b2584087..f7b9e5a4e 100644 --- a/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintBlock.java +++ b/src/main/java/world/bentobox/bentobox/blueprints/dataobjects/BlueprintBlock.java @@ -6,6 +6,7 @@ import java.util.Map; import org.bukkit.block.Biome; import org.bukkit.block.banner.Pattern; +import org.bukkit.block.sign.Side; import org.bukkit.inventory.ItemStack; import com.google.gson.annotations.Expose; @@ -21,6 +22,8 @@ public class BlueprintBlock { @Expose private List signLines; @Expose + private List signLines2; + @Expose private Map inventory; @Expose private BlueprintCreatureSpawner creatureSpawner; @@ -36,6 +39,8 @@ public class BlueprintBlock { private List bannerPatterns; @Expose private boolean glowingText; + @Expose + private boolean glowingText2; public BlueprintBlock(String blockData) { this.blockData = blockData; @@ -57,14 +62,20 @@ public class BlueprintBlock { /** * @return the signLines + * @deprecated signs now have two sides + * @since 1.24.0 */ + @Deprecated public List getSignLines() { return signLines; } /** * @param signLines the signLines to set + * @deprecated signs now have two sides + * @since 1.24.0 */ + @Deprecated public void setSignLines(List signLines) { this.signLines = signLines; } @@ -129,17 +140,73 @@ public class BlueprintBlock { /** * @return the glowingText + * @deprecated signs now have two sides + * @since 1.24.0 */ + @Deprecated public boolean isGlowingText() { return glowingText; } /** * @param glowingText the glowingText to set + * @deprecated signs now have two sides + * @since 1.24.0 */ + @Deprecated public void setGlowingText(boolean glowingText) { this.glowingText = glowingText; } + /** + * @param side side of sign + * @param glowingText the glowingText to set + * @since 1.24.0 + */ + public void setGlowingText(Side side, boolean glowingText) { + switch (side) { + case FRONT -> this.glowingText = glowingText; + default -> this.glowingText2 = glowingText; + }; + + } + + /** + * @param side side of sign + * @return the glowingText + * @since 1.24.0 + */ + public boolean isGlowingText(Side side) { + return switch (side) { + case FRONT -> glowingText; + default -> glowingText2; + }; + } + + /** + * @param side side of sign + * @return the signLines + * @since 1.24.0 + */ + public List getSignLines(Side side) { + return switch (side) { + case FRONT -> signLines; + default -> signLines2; + }; + } + + /** + * @param side side of sign + * @param signLines the signLines to set + * @since 1.24.0 + */ + public void setSignLines(Side side, List signLines) { + switch (side) { + case FRONT -> this.signLines = signLines; + default -> this.signLines2 = signLines; + }; + } + + } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java index 801968894..400bd8eb3 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java @@ -1,6 +1,5 @@ package world.bentobox.bentobox.listeners.flags.protection; -import java.util.Map; import java.util.Optional; import org.bukkit.FluidCollisionMode; @@ -18,8 +17,6 @@ import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockFromToEvent; import org.bukkit.event.player.PlayerInteractEvent; -import world.bentobox.bentobox.BentoBox; -import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.api.flags.FlagListener; import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.lists.Flags; @@ -31,25 +28,6 @@ import world.bentobox.bentobox.lists.Flags; public class BlockInteractionListener extends FlagListener { - /** - * These cover materials in another server version. This avoids run time errors due to unknown enum values, at the - * expense of a string comparison - */ - private static final Map stringFlags; - private static final String CHEST = "CHEST"; - - 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 * @@ -71,7 +49,7 @@ public class BlockInteractionListener extends FlagListener if (e.getItem() != null && !e.getItem().getType().equals(Material.AIR)) { // Boats - if (e.getItem().getType().name().endsWith("BOAT")) + if (Tag.ITEMS_BOATS.isTagged(e.getItem().getType())) { this.checkIsland(e, e.getPlayer(), e.getClickedBlock().getLocation(), Flags.BOAT); } @@ -164,10 +142,11 @@ public class BlockInteractionListener extends FlagListener { this.checkIsland(e, player, loc, Flags.GATE); } - // TODO: 1.18 compatibility - // if (Tag.ITEMS_CHEST_BOATS.isTagged(type)) { - // this.checkIsland(e, player, loc, Flags.CHEST); - // } + + if (Tag.ITEMS_CHEST_BOATS.isTagged(type)) + { + this.checkIsland(e, player, loc, Flags.CHEST); + } switch (type) { @@ -237,12 +216,7 @@ public class BlockInteractionListener extends FlagListener } } default -> - { - if (stringFlags.containsKey(type.name())) - { - Optional f = BentoBox.getInstance().getFlagsManager().getFlag(stringFlags.get(type.name())); - f.ifPresent(flag -> this.checkIsland(e, player, loc, flag)); - } + { // nothing to do } } } diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/PlaceBlocksListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/PlaceBlocksListener.java index 924e38fb7..b68487729 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/PlaceBlocksListener.java +++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/PlaceBlocksListener.java @@ -3,6 +3,7 @@ package world.bentobox.bentobox.listeners.flags.protection; import java.util.Set; import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -44,7 +45,7 @@ public class PlaceBlocksListener extends FlagListener // Crops if (against.equals(Material.FARMLAND) && SEEDS.contains(e.getItemInHand().getType())) { this.checkIsland(e, e.getPlayer(), e.getBlock().getLocation(), Flags.CROP_PLANTING); - } else { + } else { this.checkIsland(e, e.getPlayer(), e.getBlock().getLocation(), Flags.PLACE_BLOCKS); } } @@ -124,7 +125,7 @@ public class PlaceBlocksListener extends FlagListener { this.checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.PLACE_BLOCKS); } - else if (e.getMaterial().name().contains("BOAT")) + else if (Tag.ITEMS_BOATS.isTagged(e.getMaterial())) { this.checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.BOAT); } diff --git a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java index ce585a6cb..bcdb75b90 100644 --- a/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java +++ b/src/main/java/world/bentobox/bentobox/managers/IslandsManager.java @@ -22,11 +22,11 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Boat; -import org.bukkit.entity.Boat.Type; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; @@ -38,8 +38,6 @@ import org.bukkit.util.Vector; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; -import com.google.common.collect.ImmutableMap; - import io.papermc.lib.PaperLib; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.events.IslandBaseEvent; @@ -67,15 +65,6 @@ public class IslandsManager { private final BentoBox plugin; - // Tree species to boat material map - private static final Map TREE_TO_BOAT = ImmutableMap.builder(). - put(Type.ACACIA, Material.ACACIA_BOAT). - put(Type.BIRCH, Material.BIRCH_BOAT). - put(Type.DARK_OAK, Material.DARK_OAK_BOAT). - put(Type.JUNGLE, Material.JUNGLE_BOAT). - put(Type.OAK, Material.OAK_BOAT). - put(Type.SPRUCE, Material.SPRUCE_BOAT).build(); - /** * One island can be spawn, this is the one - otherwise, this value is null */ @@ -250,8 +239,8 @@ public class IslandsManager { public boolean checkIfSafe(@Nullable World world, @NonNull Material ground, @NonNull Material space1, @NonNull Material space2) { // Ground must be solid, space 1 and 2 must not be solid if (world == null || !ground.isSolid() - || (space1.isSolid() && !space1.name().contains("SIGN")) - || (space2.isSolid() && !space2.name().contains("SIGN"))) { + || (space1.isSolid() && !Tag.SIGNS.isTagged(space1)) + || (space2.isSolid() && !Tag.SIGNS.isTagged(space2))) { return false; } // Cannot be submerged or water cannot be dangerous @@ -262,14 +251,19 @@ public class IslandsManager { if (ground.equals(Material.LAVA) || space1.equals(Material.LAVA) || space2.equals(Material.LAVA) - || ground.name().contains("FENCE") - || ground.name().contains("DOOR") - || ground.name().contains("GATE") - || ground.name().contains("PLATE") - || ground.name().contains("SIGN") - || ground.name().contains("BANNER") - || ground.name().contains("BUTTON") - || ground.name().contains("BOAT") + || Tag.SIGNS.isTagged(ground) + || Tag.TRAPDOORS.isTagged(ground) + || Tag.BANNERS.isTagged(ground) + || Tag.PRESSURE_PLATES.isTagged(ground) + || Tag.FENCE_GATES.isTagged(ground) + || Tag.DOORS.isTagged(ground) + || Tag.FENCES.isTagged(ground) + || Tag.BUTTONS.isTagged(ground) + || Tag.ITEMS_BOATS.isTagged(ground) + || Tag.ITEMS_CHEST_BOATS.isTagged(ground) + || Tag.CAMPFIRES.isTagged(ground) + || Tag.FIRE.isTagged(ground) + || Tag.FIRE.isTagged(space1) || space1.equals(Material.END_PORTAL) || space2.equals(Material.END_PORTAL) || space1.equals(Material.END_GATEWAY) @@ -1072,19 +1066,7 @@ public class IslandsManager { User user = User.getInstance(player); user.sendMessage("commands.island.go.teleport"); goingHome.add(user.getUniqueId()); - // Stop any gliding - player.setGliding(false); - // Check if the player is a passenger in a boat - if (player.isInsideVehicle()) { - Entity boat = player.getVehicle(); - if (boat instanceof Boat boaty) { - player.leaveVehicle(); - // Remove the boat so they don't lie around everywhere - boat.remove(); - player.getInventory().addItem(new ItemStack(TREE_TO_BOAT.getOrDefault(boaty.getBoatType(), Material.OAK_BOAT))); - player.updateInventory(); - } - } + readyPlayer(player); this.getAsyncSafeHomeLocation(world, user, name).thenAccept(home -> { Island island = getIsland(world, user); if (home == null) { @@ -1196,23 +1178,7 @@ public class IslandsManager { user.sendMessage("commands.island.spawn.no-spawn"); } else { // Teleport the player to the spawn - // Stop any gliding - player.setGliding(false); - // Check if the player is a passenger in a boat - if (player.isInsideVehicle()) { - Entity boat = player.getVehicle(); - if (boat instanceof Boat boaty) { - player.leaveVehicle(); - // Remove the boat so they don't lie around everywhere - boat.remove(); - Material boatMat = Material.getMaterial(boaty.getType() + "_BOAT"); - if (boatMat == null) { - boatMat = Material.OAK_BOAT; - } - player.getInventory().addItem(new ItemStack(boatMat, 1)); - player.updateInventory(); - } - } + readyPlayer(player); user.sendMessage("commands.island.spawn.teleporting"); // Safe teleport @@ -1220,6 +1186,23 @@ public class IslandsManager { } } + private void readyPlayer(@NonNull Player player) { + // Stop any gliding + player.setGliding(false); + // Check if the player is a passenger in a boat + if (player.isInsideVehicle()) { + Entity boat = player.getVehicle(); + if (boat instanceof Boat boaty) { + player.leaveVehicle(); + // Remove the boat so they don't lie around everywhere + boat.remove(); + player.getInventory().addItem(new ItemStack(boaty.getBoatType().getMaterial())); + player.updateInventory(); + } + } + + } + /** * Indicates whether a player is at an island spawn or not * diff --git a/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java b/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java index 141aa0852..e8c60c53d 100644 --- a/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java +++ b/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java @@ -17,6 +17,8 @@ import org.bukkit.block.BlockState; import org.bukkit.block.CreatureSpawner; import org.bukkit.block.Sign; import org.bukkit.block.data.BlockData; +import org.bukkit.block.sign.Side; +import org.bukkit.block.sign.SignSide; import org.bukkit.entity.AbstractHorse; import org.bukkit.entity.Ageable; import org.bukkit.entity.ChestedHorse; @@ -45,6 +47,7 @@ import world.bentobox.bentobox.util.MyBiomeGrid; * */ public abstract class CopyWorldRegenerator implements WorldRegenerator { + private final BentoBox plugin; protected CopyWorldRegenerator() { @@ -68,7 +71,7 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator { public CompletableFuture regenerate(GameModeAddon gm, IslandDeletion di, World world) { return gm.isUsesNewChunkGeneration() ? regenerateCopy(gm, di, world) : regenerateSimple(gm, di, world); } - + public CompletableFuture regenerateCopy(GameModeAddon gm, IslandDeletion di, World world) { CompletableFuture bigFuture = new CompletableFuture<>(); new BukkitRunnable() { @@ -110,7 +113,7 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator { @Override public CompletableFuture regenerateChunk(Chunk chunk) { - return regenerateChunk(null, chunk.getWorld(), chunk.getX(), chunk.getZ()); + return regenerateChunk(null, chunk.getWorld(), chunk.getX(), chunk.getZ()); } private CompletableFuture regenerateChunk(@Nullable IslandDeletion di, World world, int chunkX, int chunkZ) { @@ -132,7 +135,7 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator { copyChunkDataToChunk(chunkTo, chunkFrom, di != null ? di.getBox() : null); } catch (InterruptedException | ExecutionException e) { - Thread.currentThread().interrupt(); + Thread.currentThread().interrupt(); } }); return CompletableFuture.allOf(cleanFuture, copyFuture); @@ -159,7 +162,7 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator { ); // Similarly, when the chunk is loaded, remove all the entities in the chunk apart from players - CompletableFuture entitiesFuture = chunkFuture.thenAccept(chunk -> + CompletableFuture entitiesFuture = chunkFuture.thenAccept(chunk -> // Remove all entities in chunk, including any dropped items as a result of clearing the blocks above Arrays.stream(chunk.getEntities()) .filter(e -> !(e instanceof Player) && di.inBounds(e.getLocation().getBlockX(), e.getLocation().getBlockZ())) @@ -200,35 +203,35 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator { } private void processEntity(Entity entity, Location location) { - Entity bpe = location.getWorld().spawnEntity(location, entity.getType()); - bpe.setCustomName(entity.getCustomName()); - if (entity instanceof Villager villager && bpe instanceof Villager villager2) { - setVillager(villager, villager2); - } - if (entity instanceof Colorable c && bpe instanceof Colorable cc) { - if (c.getColor() != null) { - cc.setColor(c.getColor()); - } - } - if (entity instanceof Tameable t && bpe instanceof Tameable tt) { - tt.setTamed(t.isTamed()); - } - if (entity instanceof ChestedHorse ch && bpe instanceof ChestedHorse ch2) { - ch2.setCarryingChest(ch.isCarryingChest()); - } - // Only set if child. Most animals are adults - if (entity instanceof Ageable a && bpe instanceof Ageable aa) { - if (a.isAdult()) aa.setAdult(); - } - if (entity instanceof AbstractHorse horse && bpe instanceof AbstractHorse horse2) { - horse2.setDomestication(horse.getDomestication()); - horse2.getInventory().setContents(horse.getInventory().getContents()); - } - - if (entity instanceof Horse horse && bpe instanceof Horse horse2) { - horse2.setStyle(horse.getStyle()); + Entity bpe = location.getWorld().spawnEntity(location, entity.getType()); + bpe.setCustomName(entity.getCustomName()); + if (entity instanceof Villager villager && bpe instanceof Villager villager2) { + setVillager(villager, villager2); + } + if (entity instanceof Colorable c && bpe instanceof Colorable cc) { + if (c.getColor() != null) { + cc.setColor(c.getColor()); } } + if (entity instanceof Tameable t && bpe instanceof Tameable tt) { + tt.setTamed(t.isTamed()); + } + if (entity instanceof ChestedHorse ch && bpe instanceof ChestedHorse ch2) { + ch2.setCarryingChest(ch.isCarryingChest()); + } + // Only set if child. Most animals are adults + if (entity instanceof Ageable a && bpe instanceof Ageable aa) { + if (a.isAdult()) aa.setAdult(); + } + if (entity instanceof AbstractHorse horse && bpe instanceof AbstractHorse horse2) { + horse2.setDomestication(horse.getDomestication()); + horse2.getInventory().setContents(horse.getInventory().getContents()); + } + + if (entity instanceof Horse horse && bpe instanceof Horse horse2) { + horse2.setStyle(horse.getStyle()); + } + } /** * Set the villager stats @@ -241,7 +244,7 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator { villager2.setProfession(v.getProfession()); villager2.setVillagerType(v.getVillagerType()); } - + private void processTileEntity(Block fromBlock, Block toBlock) { // Block state BlockState blockState = fromBlock.getState(); @@ -249,11 +252,9 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator { // Signs if (blockState instanceof Sign fromSign && b instanceof Sign toSign) { - int i = 0; - for (String line : fromSign.getLines()) { - toSign.setLine(i++, line); + for (Side side : Side.values()) { + writeSign(fromSign, toSign, side); } - toSign.setGlowingText(fromSign.isGlowingText()); } // Chests else if (blockState instanceof InventoryHolder ih && b instanceof InventoryHolder toChest) { @@ -270,7 +271,17 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator { toBanner.setPatterns(banner.getPatterns()); } } - + + + private void writeSign(Sign fromSign, Sign toSign, Side side) { + SignSide fromSide = fromSign.getSide(side); + SignSide toSide = toSign.getSide(side); + int i = 0; + for (String line : fromSide.getLines()) { + toSide.setLine(i++, line); + } + toSide.setGlowingText(fromSide.isGlowingText()); + } public CompletableFuture regenerateSimple(GameModeAddon gm, IslandDeletion di, World world) { CompletableFuture bigFuture = new CompletableFuture<>(); diff --git a/src/main/java/world/bentobox/bentobox/util/DefaultPasteUtil.java b/src/main/java/world/bentobox/bentobox/util/DefaultPasteUtil.java index 7cd43cef5..8231ffd8b 100644 --- a/src/main/java/world/bentobox/bentobox/util/DefaultPasteUtil.java +++ b/src/main/java/world/bentobox/bentobox/util/DefaultPasteUtil.java @@ -19,6 +19,8 @@ import org.bukkit.block.CreatureSpawner; import org.bukkit.block.Sign; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.type.WallSign; +import org.bukkit.block.sign.Side; +import org.bukkit.block.sign.SignSide; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; @@ -120,7 +122,9 @@ public class DefaultPasteUtil { BlockState bs = block.getState(); // Signs if (bs instanceof Sign) { - writeSign(island, block, bpBlock.getSignLines(), bpBlock.isGlowingText()); + for (Side side : Side.values()) { + writeSign(island, block, bpBlock, side); + } } // Chests, in general else if (bs instanceof InventoryHolder holder) { @@ -200,8 +204,12 @@ public class DefaultPasteUtil { * @param block - block * @param lines - lines * @param glow - is sign glowing? + * @param side - the side being writted */ - public static void writeSign(Island island, final Block block, final List lines, boolean glow) { + public static void writeSign(Island island, final Block block, BlueprintBlock bpSign, Side side) { + List lines = bpSign.getSignLines(side); + boolean glow = bpSign.isGlowingText(side); + BlockFace bf; if (block.getType().name().contains("WALL_SIGN")) { WallSign wallSign = (WallSign) block.getBlockData(); @@ -211,7 +219,7 @@ public class DefaultPasteUtil { bf = sign.getRotation(); } // Handle spawn sign - if (island != null && !lines.isEmpty() && lines.get(0).equalsIgnoreCase(TextVariables.SPAWN_HERE)) { + if (side == Side.FRONT && island != null && !lines.isEmpty() && lines.get(0).equalsIgnoreCase(TextVariables.SPAWN_HERE)) { block.setType(Material.AIR); // Orient to face same direction as sign Location spawnPoint = new Location(block.getWorld(), block.getX() + 0.5D, block.getY(), @@ -225,7 +233,8 @@ public class DefaultPasteUtil { name = plugin.getPlayers().getName(island.getOwner()); } // Handle locale text for starting sign - org.bukkit.block.Sign s = (org.bukkit.block.Sign) block.getState(); + Sign s = (org.bukkit.block.Sign) block.getState(); + SignSide signSide = s.getSide(side); // Sign text must be stored under the addon's name.sign.line0,1,2,3 in the yaml file if (island != null && !lines.isEmpty() && lines.get(0).equalsIgnoreCase(TextVariables.START_TEXT)) { // Get the addon that is operating in this world @@ -233,17 +242,17 @@ public class DefaultPasteUtil { Optional user = Optional.ofNullable(island.getOwner()).map(User::getInstance); if (user.isPresent()) { for (int i = 0; i < 4; i++) { - s.setLine(i, Util.translateColorCodes(plugin.getLocalesManager().getOrDefault(user.get(), + signSide.setLine(i, Util.translateColorCodes(plugin.getLocalesManager().getOrDefault(user.get(), addonName + ".sign.line" + i, "").replace(TextVariables.NAME, name))); } } } else { // Just paste for (int i = 0; i < 4; i++) { - s.setLine(i, lines.get(i)); + signSide.setLine(i, lines.get(i)); } } - s.setGlowingText(glow); + signSide.setGlowingText(glow); // Update the sign s.update(); } diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/AbstractCommonSetup.java b/src/test/java/world/bentobox/bentobox/listeners/flags/AbstractCommonSetup.java index 6d5406a37..84613ccf3 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/AbstractCommonSetup.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/AbstractCommonSetup.java @@ -12,6 +12,8 @@ import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Tag; import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemFactory; @@ -169,12 +171,36 @@ public abstract class AbstractCommonSetup { // Util translate color codes (used in user translate methods) when(Util.translateColorCodes(anyString())).thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); + // Tags + for (Material m : Material.values()) { + if (m.name().contains("_SIGN")) { + when(Tag.ALL_SIGNS.isTagged(m)).thenReturn(true); + when(Tag.SIGNS.isTagged(m)).thenReturn(true); + } + if (m.name().contains("_WALL_SIGN")) { + when(Tag.WALL_SIGNS.isTagged(m)).thenReturn(true); + } + if (m.name().contains("_TRAPDOOR")) { + when(Tag.TRAPDOORS.isTagged(m)).thenReturn(true); + } + if (m.name().contains("FENCE")) { + when(Tag.FENCES.isTagged(m)).thenReturn(true); + } + if (m.name().contains("_DOOR")) { + when(Tag.DOORS.isTagged(m)).thenReturn(true); + } + if (m.name().contains("_BOAT") || m.name().contains("_RAFT")) { + when(Tag.ITEMS_BOATS.isTagged(m)).thenReturn(true); + } + + } } /** + * @throws Exception */ @After - public void tearDown() { + public void tearDown() throws Exception { User.clearUsers(); Mockito.framework().clearInlineMocks(); } diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/protection/PlaceBlocksListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/protection/PlaceBlocksListenerTest.java index e04f72b41..8c39590aa 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/protection/PlaceBlocksListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/protection/PlaceBlocksListenerTest.java @@ -13,7 +13,6 @@ import static org.mockito.Mockito.when; import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; @@ -45,7 +44,7 @@ import world.bentobox.bentobox.util.Util; * */ @RunWith(PowerMockRunner.class) -@PrepareForTest( {BentoBox.class, Flags.class, Util.class, Bukkit.class, Tag.class} ) +@PrepareForTest( {BentoBox.class, Flags.class, Util.class, Bukkit.class} ) public class PlaceBlocksListenerTest extends AbstractCommonSetup { private PlaceBlocksListener pbl; @@ -163,7 +162,7 @@ public class PlaceBlocksListenerTest extends AbstractCommonSetup { assertTrue(e.isCancelled()); verify(notifier).notify(any(), eq("protection.protected")); } - + /** * Test method for {@link PlaceBlocksListener#onBlockPlace(org.bukkit.event.block.BlockPlaceEvent)}. */ @@ -184,7 +183,7 @@ public class PlaceBlocksListenerTest extends AbstractCommonSetup { pbl.onBlockPlace(e); assertFalse(e.isCancelled()); } - + /** * Test method for {@link PlaceBlocksListener#onBlockPlace(org.bukkit.event.block.BlockPlaceEvent)}. */ @@ -206,7 +205,7 @@ public class PlaceBlocksListenerTest extends AbstractCommonSetup { assertTrue(e.isCancelled()); verify(notifier).notify(any(), eq("protection.protected")); } - + /** * Test method for {@link PlaceBlocksListener#onBlockPlace(org.bukkit.event.block.BlockPlaceEvent)}. */ diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListenerTest.java index 54c805df4..3bd91e968 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/IslandRespawnListenerTest.java @@ -23,6 +23,7 @@ import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.event.player.PlayerRespawnEvent.RespawnReason; import org.bukkit.inventory.ItemStack; import org.junit.After; import org.junit.Before; @@ -213,7 +214,7 @@ public class IslandRespawnListenerTest { // Has island when(im.hasIsland(any(), any(UUID.class))).thenReturn(true); // Respawn - PlayerRespawnEvent ev = new PlayerRespawnEvent(player, location, false, false); + PlayerRespawnEvent ev = new PlayerRespawnEvent(player, location, false, false, RespawnReason.DEATH); l.onPlayerRespawn(ev); assertEquals(safeLocation, ev.getRespawnLocation()); // Verify commands @@ -232,7 +233,7 @@ public class IslandRespawnListenerTest { // Has island when(im.hasIsland(any(), any(UUID.class))).thenReturn(true); // Respawn - PlayerRespawnEvent ev = new PlayerRespawnEvent(player, location, false, false); + PlayerRespawnEvent ev = new PlayerRespawnEvent(player, location, false, false, RespawnReason.DEATH); l.onPlayerRespawn(ev); assertEquals(location, ev.getRespawnLocation()); } @@ -255,7 +256,7 @@ public class IslandRespawnListenerTest { // Has island when(im.hasIsland(any(), any(UUID.class))).thenReturn(true); // Respawn - PlayerRespawnEvent ev = new PlayerRespawnEvent(player, location, false, false); + PlayerRespawnEvent ev = new PlayerRespawnEvent(player, location, false, false, RespawnReason.DEATH); l.onPlayerRespawn(ev); assertEquals(location, ev.getRespawnLocation()); } @@ -276,7 +277,7 @@ public class IslandRespawnListenerTest { // Has island when(im.hasIsland(any(), any(UUID.class))).thenReturn(true); // Respawn - PlayerRespawnEvent ev = new PlayerRespawnEvent(player, location, false, false); + PlayerRespawnEvent ev = new PlayerRespawnEvent(player, location, false, false, RespawnReason.DEATH); l.onPlayerRespawn(ev); assertEquals(location, ev.getRespawnLocation()); } diff --git a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/RemoveMobsListenerTest.java b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/RemoveMobsListenerTest.java index 8cfb2cf8c..a74929e35 100644 --- a/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/RemoveMobsListenerTest.java +++ b/src/test/java/world/bentobox/bentobox/listeners/flags/worldsettings/RemoveMobsListenerTest.java @@ -17,6 +17,7 @@ import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.player.PlayerRespawnEvent.RespawnReason; import org.bukkit.scheduler.BukkitScheduler; import org.junit.After; import org.junit.Before; @@ -200,7 +201,7 @@ public class RemoveMobsListenerTest { */ @Test public void testOnUserRespawn() { - PlayerRespawnEvent e = new PlayerRespawnEvent(player, inside, false, false); + PlayerRespawnEvent e = new PlayerRespawnEvent(player, inside, false, false, RespawnReason.DEATH); new RemoveMobsListener().onUserRespawn(e); verify(scheduler).runTask(any(), any(Runnable.class)); } @@ -211,7 +212,7 @@ public class RemoveMobsListenerTest { @Test public void testOnUserRespawnDoNotRemove() { Flags.REMOVE_MOBS.setSetting(world, false); - PlayerRespawnEvent e = new PlayerRespawnEvent(player, inside, false, false); + PlayerRespawnEvent e = new PlayerRespawnEvent(player, inside, false, false, RespawnReason.DEATH); new RemoveMobsListener().onUserRespawn(e); verify(scheduler, never()).runTask(any(), any(Runnable.class)); } @@ -223,7 +224,7 @@ public class RemoveMobsListenerTest { public void testOnUserRespawnNotIsland() { // Not on island when(im.locationIsOnIsland(any(), any())).thenReturn(false); - PlayerRespawnEvent e = new PlayerRespawnEvent(player, inside, false, false); + PlayerRespawnEvent e = new PlayerRespawnEvent(player, inside, false, false, RespawnReason.DEATH); new RemoveMobsListener().onUserRespawn(e); verify(scheduler, never()).runTask(any(), any(Runnable.class)); } diff --git a/src/test/java/world/bentobox/bentobox/managers/BlueprintClipboardManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/BlueprintClipboardManagerTest.java index 66f90c51a..30e24cb16 100644 --- a/src/test/java/world/bentobox/bentobox/managers/BlueprintClipboardManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/BlueprintClipboardManagerTest.java @@ -12,7 +12,6 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; diff --git a/src/test/java/world/bentobox/bentobox/managers/BlueprintsManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/BlueprintsManagerTest.java index 055efe1b3..b3b24ab42 100644 --- a/src/test/java/world/bentobox/bentobox/managers/BlueprintsManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/BlueprintsManagerTest.java @@ -40,7 +40,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; diff --git a/src/test/java/world/bentobox/bentobox/managers/IslandWorldManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/IslandWorldManagerTest.java index 8b4af6d1e..c846a168d 100644 --- a/src/test/java/world/bentobox/bentobox/managers/IslandWorldManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/IslandWorldManagerTest.java @@ -614,6 +614,7 @@ public class IslandWorldManagerTest { /** * Test method for {@link world.bentobox.bentobox.managers.IslandWorldManager#getDefaultIslandFlags(org.bukkit.World)}. */ + @SuppressWarnings("removal") @Test public void testGetDefaultIslandFlags() { Map flags = new HashMap<>(); @@ -634,6 +635,7 @@ public class IslandWorldManagerTest { /** * Test method for {@link world.bentobox.bentobox.managers.IslandWorldManager#getDefaultIslandSettings(org.bukkit.World)}. */ + @SuppressWarnings("removal") @Test public void testGetDefaultIslandSettings() { Map flags = new HashMap<>(); diff --git a/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java b/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java index 169551906..f9bc0105c 100644 --- a/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java +++ b/src/test/java/world/bentobox/bentobox/managers/IslandsManagerTest.java @@ -78,13 +78,14 @@ import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.database.Database; import world.bentobox.bentobox.database.DatabaseSetup.DatabaseType; import world.bentobox.bentobox.database.objects.Island; +import world.bentobox.bentobox.listeners.flags.AbstractCommonSetup; import world.bentobox.bentobox.lists.Flags; import world.bentobox.bentobox.managers.island.IslandCache; import world.bentobox.bentobox.util.Util; @RunWith(PowerMockRunner.class) @PrepareForTest( { Bukkit.class, BentoBox.class, Util.class, Location.class }) -public class IslandsManagerTest { +public class IslandsManagerTest extends AbstractCommonSetup { @Mock private BentoBox plugin; @@ -141,11 +142,12 @@ public class IslandsManagerTest { // Class under test IslandsManager im; - /** - */ + @Override @SuppressWarnings("unchecked") @Before public void setUp() throws Exception { + super.setUp(); + // Clear any lingering database tearDown(); // Set up plugin @@ -315,14 +317,8 @@ public class IslandsManagerTest { db = mock(Database.class); // Signs - sign = Material.getMaterial("SIGN"); - if (sign == null) { - sign = Material.getMaterial("OAK_SIGN"); - } - wallSign = Material.getMaterial("WALL_SIGN"); - if (wallSign == null) { - wallSign = Material.getMaterial("OAK_WALL_SIGN"); - } + sign = Material.BIRCH_SIGN; + wallSign = Material.ACACIA_WALL_SIGN; // PaperLib env = new CraftBukkitEnvironment(); @@ -337,10 +333,10 @@ public class IslandsManagerTest { //im.setIslandCache(islandCache); } - /** - */ + @Override @After public void tearDown() throws Exception { + super.tearDown(); Mockito.framework().clearInlineMocks(); deleteAll(new File("database")); deleteAll(new File("database_backup")); @@ -393,12 +389,13 @@ public class IslandsManagerTest { assertFalse(im.isSafeLocation(location)); } + @SuppressWarnings("deprecation") @Test public void testCheckIfSafeTrapdoor() { for (Material d : Material.values()) { if (d.name().contains("DOOR")) { for (Material s : Material.values()) { - if (s.name().contains("_SIGN")) { + if (s.name().contains("_SIGN") && !s.isLegacy()) { assertFalse("Fail " + d.name() + " " + s.name(), im.checkIfSafe(world, d, s, Material.AIR)); } } @@ -486,13 +483,13 @@ public class IslandsManagerTest { @Test public void testBadBlocks() { // Fences - Arrays.stream(Material.values()).filter(m -> m.toString().contains("FENCE")).forEach(m -> { - when(ground.getType()).thenReturn(m); - assertFalse("Fence :" + m.toString(), im.isSafeLocation(location)); - }); + when(ground.getType()).thenReturn(Material.SPRUCE_FENCE); + assertFalse("Fence :" + Material.SPRUCE_FENCE.toString(), im.isSafeLocation(location)); // Signs + sign = Material.BIRCH_SIGN; when(ground.getType()).thenReturn(sign); assertFalse("Sign", im.isSafeLocation(location)); + wallSign = Material.ACACIA_WALL_SIGN; when(ground.getType()).thenReturn(wallSign); assertFalse("Sign", im.isSafeLocation(location)); // Bad Blocks