From b60aaee01fc18f75782b74d09471549d93fc362d Mon Sep 17 00:00:00 2001 From: tastybento Date: Mon, 8 Apr 2024 18:40:46 -0700 Subject: [PATCH 1/4] No-cache version for Multipaper --- .../world/bentobox/aoneblock/AOneBlock.java | 7 - .../world/bentobox/aoneblock/Settings.java | 1 - .../aoneblock/listeners/BlockListener.java | 628 +++++++++--------- .../aoneblock/listeners/CheckPhase.java | 2 +- .../listeners/JoinLeaveListener.java | 40 -- .../listeners/JoinLeaveListenerTest.java | 131 ---- 6 files changed, 307 insertions(+), 502 deletions(-) delete mode 100644 src/main/java/world/bentobox/aoneblock/listeners/JoinLeaveListener.java delete mode 100644 src/test/java/world/bentobox/aoneblock/listeners/JoinLeaveListenerTest.java diff --git a/src/main/java/world/bentobox/aoneblock/AOneBlock.java b/src/main/java/world/bentobox/aoneblock/AOneBlock.java index 5a9c27ea..bb4ce9fc 100644 --- a/src/main/java/world/bentobox/aoneblock/AOneBlock.java +++ b/src/main/java/world/bentobox/aoneblock/AOneBlock.java @@ -23,7 +23,6 @@ import world.bentobox.aoneblock.listeners.HoloListener; import world.bentobox.aoneblock.listeners.InfoListener; import world.bentobox.aoneblock.listeners.ItemsAdderListener; -import world.bentobox.aoneblock.listeners.JoinLeaveListener; import world.bentobox.aoneblock.listeners.NoBlockHandler; import world.bentobox.aoneblock.listeners.StartSafetyListener; import world.bentobox.aoneblock.oneblocks.OneBlockCustomBlockCreator; @@ -118,7 +117,6 @@ public void onEnable() { registerListener(blockListener); registerListener(new NoBlockHandler(this)); registerListener(new BlockProtect(this)); - registerListener(new JoinLeaveListener(this)); registerListener(new InfoListener(this)); // Register placeholders phManager = new AOneBlockPlaceholders(this, getPlugin().getPlaceholdersManager()); @@ -148,17 +146,12 @@ public boolean loadData() { @Override public void onDisable() { - // save cache - blockListener.saveCache(); - // Clear holograms holoListener.clear(); } @Override public void onReload() { - // save cache - blockListener.saveCache(); if (loadSettings()) { log("Reloaded AOneBlock settings"); loadData(); diff --git a/src/main/java/world/bentobox/aoneblock/Settings.java b/src/main/java/world/bentobox/aoneblock/Settings.java index 4ec144e3..c1b5faaf 100644 --- a/src/main/java/world/bentobox/aoneblock/Settings.java +++ b/src/main/java/world/bentobox/aoneblock/Settings.java @@ -2188,7 +2188,6 @@ public void setClickType(String clickType) { /** * @return the disallowTeamMemberIslands */ - @Override public boolean isDisallowTeamMemberIslands() { return disallowTeamMemberIslands; } diff --git a/src/main/java/world/bentobox/aoneblock/listeners/BlockListener.java b/src/main/java/world/bentobox/aoneblock/listeners/BlockListener.java index e0135a28..da3a0fd6 100644 --- a/src/main/java/world/bentobox/aoneblock/listeners/BlockListener.java +++ b/src/main/java/world/bentobox/aoneblock/listeners/BlockListener.java @@ -1,8 +1,6 @@ package world.bentobox.aoneblock.listeners; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Random; @@ -79,7 +77,7 @@ public class BlockListener implements Listener { /** * Oneblock cache. */ - private final Map cache; + //private final Map cache; /** * Phase checker class @@ -99,7 +97,7 @@ public class BlockListener implements Listener { /** * How often data is saved. */ - public static final int SAVE_EVERY = 50; + public static final int SAVE_EVERY = 1; private final Random random = new Random(); @@ -107,19 +105,11 @@ public class BlockListener implements Listener { * @param addon - OneBlock */ public BlockListener(@NonNull AOneBlock addon) { - this.addon = addon; - handler = new Database<>(addon, OneBlockIslands.class); - cache = new HashMap<>(); - oneBlocksManager = addon.getOneBlockManager(); - check = new CheckPhase(addon, this); - warningSounder = new WarningSounder(addon); - } - - /** - * Save the island cache - */ - public void saveCache() { - cache.values().forEach(handler::saveObjectAsync); + this.addon = addon; + handler = new Database<>(addon, OneBlockIslands.class); + oneBlocksManager = addon.getOneBlockManager(); + check = new CheckPhase(addon, this); + warningSounder = new WarningSounder(addon); } // --------------------------------------------------------------------- @@ -128,24 +118,24 @@ public void saveCache() { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onNewIsland(IslandCreatedEvent e) { - if (addon.inWorld(e.getIsland().getWorld())) { - setUp(e.getIsland()); - } + if (addon.inWorld(e.getIsland().getWorld())) { + setUp(e.getIsland()); + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onNewIsland(IslandResettedEvent e) { - if (addon.inWorld(e.getIsland().getWorld())) { - setUp(e.getIsland()); - } + if (addon.inWorld(e.getIsland().getWorld())) { + setUp(e.getIsland()); + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onDeletedIsland(IslandDeleteEvent e) { - if (addon.inWorld(e.getIsland().getWorld())) { - cache.remove(e.getIsland().getUniqueId()); - handler.deleteID(e.getIsland().getUniqueId()); - } + if (addon.inWorld(e.getIsland().getWorld())) { + //cache.remove(e.getIsland().getUniqueId()); + handler.deleteID(e.getIsland().getUniqueId()); + } } /** @@ -155,22 +145,22 @@ public void onDeletedIsland(IslandDeleteEvent e) { */ @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlockFromTo(final BlockFromToEvent e) { - if (!addon.inWorld(e.getBlock().getWorld())) { - return; - } - Location l = e.getToBlock().getLocation(); - // Cannot flow to center block - e.setCancelled(addon.getIslands().getIslandAt(l).filter(i -> l.equals(i.getCenter())).isPresent()); + if (!addon.inWorld(e.getBlock().getWorld())) { + return; + } + Location l = e.getToBlock().getLocation(); + // Cannot flow to center block + e.setCancelled(addon.getIslands().getIslandAt(l).filter(i -> l.equals(i.getCenter())).isPresent()); } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onBlockBreak(final BlockBreakEvent e) { - if (!addon.inWorld(e.getBlock().getWorld())) { - return; - } - Location l = e.getBlock().getLocation(); - addon.getIslands().getIslandAt(l).filter(i -> l.equals(i.getCenter())) - .ifPresent(i -> process(e, i, e.getPlayer(), e.getPlayer().getWorld())); + if (!addon.inWorld(e.getBlock().getWorld())) { + return; + } + Location l = e.getBlock().getLocation(); + addon.getIslands().getIslandAt(l).filter(i -> l.equals(i.getCenter())) + .ifPresent(i -> process(e, i, e.getPlayer(), e.getPlayer().getWorld())); } /** @@ -181,12 +171,12 @@ public void onBlockBreak(final BlockBreakEvent e) { */ @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlockBreakByMinion(final EntityInteractEvent e) { - if (!addon.inWorld(e.getBlock().getWorld()) || !e.getEntityType().equals(EntityType.ARMOR_STAND)) { - return; - } - Location l = e.getBlock().getLocation(); - addon.getIslands().getIslandAt(l).filter(i -> l.equals(i.getCenter())) - .ifPresent(i -> process(e, i, null, e.getBlock().getWorld())); + if (!addon.inWorld(e.getBlock().getWorld()) || !e.getEntityType().equals(EntityType.ARMOR_STAND)) { + return; + } + Location l = e.getBlock().getLocation(); + addon.getIslands().getIslandAt(l).filter(i -> l.equals(i.getCenter())) + .ifPresent(i -> process(e, i, null, e.getBlock().getWorld())); } /** @@ -196,11 +186,11 @@ public void onBlockBreakByMinion(final EntityInteractEvent e) { */ @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlockBreak(final PlayerBucketFillEvent e) { - if (addon.inWorld(e.getBlock().getWorld())) { - Location l = e.getBlock().getLocation(); - addon.getIslands().getIslandAt(l).filter(i -> l.equals(i.getCenter())) - .ifPresent(i -> process(e, i, e.getPlayer(), e.getPlayer().getWorld())); - } + if (addon.inWorld(e.getBlock().getWorld())) { + Location l = e.getBlock().getLocation(); + addon.getIslands().getIslandAt(l).filter(i -> l.equals(i.getCenter())) + .ifPresent(i -> process(e, i, e.getPlayer(), e.getPlayer().getWorld())); + } } /** @@ -210,32 +200,32 @@ public void onBlockBreak(final PlayerBucketFillEvent e) { */ @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onItemStackSpawn(EntitySpawnEvent event) { - if (!this.addon.getSettings().isDropOnTop()) { - // Do nothing as item spawning is not interested in this case. - return; - } - - if (!EntityType.DROPPED_ITEM.equals(event.getEntityType())) { - // We are interested only in dropped item entities. - return; - } - - if (!this.addon.inWorld(event.getLocation().getWorld())) { - // Not correct world - return; - } - - Entity entity = event.getEntity(); - Location location = event.getLocation(); - - Optional optionalIsland = this.addon.getIslands().getIslandAt(location) - .filter(island -> location.getBlock().getLocation().equals(island.getCenter())); - - if (optionalIsland.isPresent()) { - // Teleport entity to the top of magic block. - entity.teleport(optionalIsland.get().getCenter().add(0.5, 1, 0.5)); - entity.setVelocity(new Vector(0, 0, 0)); - } + if (!this.addon.getSettings().isDropOnTop()) { + // Do nothing as item spawning is not interested in this case. + return; + } + + if (!EntityType.DROPPED_ITEM.equals(event.getEntityType())) { + // We are interested only in dropped item entities. + return; + } + + if (!this.addon.inWorld(event.getLocation().getWorld())) { + // Not correct world + return; + } + + Entity entity = event.getEntity(); + Location location = event.getLocation(); + + Optional optionalIsland = this.addon.getIslands().getIslandAt(location) + .filter(island -> location.getBlock().getLocation().equals(island.getCenter())); + + if (optionalIsland.isPresent()) { + // Teleport entity to the top of magic block. + entity.teleport(optionalIsland.get().getCenter().add(0.5, 1, 0.5)); + entity.setVelocity(new Vector(0, 0, 0)); + } } // --------------------------------------------------------------------- @@ -243,14 +233,14 @@ public void onItemStackSpawn(EntitySpawnEvent event) { // --------------------------------------------------------------------- private void setUp(@NonNull Island island) { - // Set the bedrock to the initial block - Util.getChunkAtAsync(Objects.requireNonNull(island.getCenter())) - .thenRun(() -> island.getCenter().getBlock().setType(Material.GRASS_BLOCK)); - // Create a database entry - OneBlockIslands is = new OneBlockIslands(island.getUniqueId()); - cache.put(island.getUniqueId(), is); - handler.saveObjectAsync(is); - addon.getHoloListener().setUp(island, is, true); + // Set the bedrock to the initial block + Util.getChunkAtAsync(Objects.requireNonNull(island.getCenter())) + .thenRun(() -> island.getCenter().getBlock().setType(Material.GRASS_BLOCK)); + // Create a database entry + OneBlockIslands is = new OneBlockIslands(island.getUniqueId()); + //cache.put(island.getUniqueId(), is); + handler.saveObjectAsync(is); + addon.getHoloListener().setUp(island, is, true); } /** @@ -262,148 +252,150 @@ private void setUp(@NonNull Island island) { * @param world - world where the block is being broken */ private void process(@NonNull Cancellable e, @NonNull Island i, @Nullable Player player, @NonNull World world) { - // Get the block that is being broken - Block block = Objects.requireNonNull(i.getCenter()).toVector().toLocation(world).getBlock(); - - // Get oneblock island - OneBlockIslands is = getIsland(i); - - // Get the phase for current block number - OneBlockPhase phase = oneBlocksManager.getPhase(is.getBlockNumber()); - - // Save previous processing phase name - String prevPhaseName = is.getPhaseName(); - - // Check if phase contains `gotoBlock` - if(Objects.requireNonNull(phase).getGotoBlock() != null){ - phase = handleGoto(is, phase.getGotoBlock()); - } - - // Get current phase name - String currPhaseName = phase.getPhaseName() == null ? "" : phase.getPhaseName(); - - // Get the phase for next block number - OneBlockPhase nextPhase = oneBlocksManager.getPhase(is.getBlockNumber() + 1); - - // Check if nextPhase contains `gotoBlock` and override `nextPhase` - if (Objects.requireNonNull(nextPhase).getGotoBlock() != null) { - nextPhase = oneBlocksManager.getPhase(nextPhase.getGotoBlock()); - } - - // Get next phase name - String nextPhaseName = nextPhase == null || nextPhase.getPhaseName() == null ? "" : nextPhase.getPhaseName(); - - // If next phase is new, log break time of the last block of this phase - if (!currPhaseName.equalsIgnoreCase(nextPhaseName)) { - is.setLastPhaseChangeTime(System.currentTimeMillis()); - } - - boolean isCurrPhaseNew = !is.getPhaseName().equalsIgnoreCase(currPhaseName); - - if (isCurrPhaseNew) { - - // Check if requirements for new phase are met - if (check.phaseRequirementsFail(player, i, is, phase, world)) { - e.setCancelled(true); - return; - } - - check.setNewPhase(player, i, is, phase); - is.clearQueue(); - - // Set the biome for the block and one block above it - setBiome(block, phase.getPhaseBiome()); - - // Fire new phase event - Bukkit.getPluginManager() - .callEvent(new MagicBlockPhaseEvent(i, player == null ? null : player.getUniqueId(), block, - phase.getPhaseName(), prevPhaseName, is.getBlockNumber())); - } - - if (!isCurrPhaseNew && is.getBlockNumber() % SAVE_EVERY == 0) { - // Save island data every MAX_LOOK_AHEAD blocks. - saveIsland(i); - } - - // Get the block number in this phase - int materialBlocksInQueue = (int) is.getQueue().stream().filter(obo -> obo.isMaterial() || obo.isCustomBlock()) - .count(); - int blockNumber = is.getBlockNumber() - (phase.getBlockNumberValue() - 1) + materialBlocksInQueue; - - // Fill a 5 block queue - if (is.getQueue().isEmpty() || isCurrPhaseNew) { - // Add initial 5 blocks - for (int j = 0; j < MAX_LOOK_AHEAD; j++) { - is.add(phase.getNextBlock(addon, blockNumber++)); - } - } - - // Manage Holograms - addon.getHoloListener().process(i, is, phase); - - // Play warning sound for upcoming mobs - if (addon.getSettings().getMobWarning() > 0) { - warningSounder.play(is, block); - } - - // Get the next block - OneBlockObject nextBlock = (isCurrPhaseNew && phase.getFirstBlock() != null) ? phase.getFirstBlock() - : is.pollAndAdd(phase.getNextBlock(addon, blockNumber)); - - // Entity - if (nextBlock.isEntity()) { - if (!(e instanceof EntitySpawnEvent)) { - e.setCancelled(true); - } - // Entity spawns do not increment the block number or break the block - spawnEntity(nextBlock, block); - // Fire event - Bukkit.getPluginManager().callEvent(new MagicBlockEntityEvent(i, - player == null ? null : player.getUniqueId(), block, nextBlock.getEntityType())); - return; - } - - // Break the block - if (e instanceof BlockBreakEvent) { - this.breakBlock(player, block, nextBlock, i); - } else if (e instanceof PlayerBucketFillEvent) { - Bukkit.getScheduler().runTask(addon.getPlugin(), () -> spawnBlock(nextBlock, block)); - // Fire event - ItemStack tool = Objects.requireNonNull(player).getInventory().getItemInMainHand(); - Bukkit.getPluginManager() - .callEvent(new MagicBlockEvent(i, player.getUniqueId(), tool, block, nextBlock.getMaterial())); - } else if (e instanceof EntitySpawnEvent) { - Bukkit.getScheduler().runTask(addon.getPlugin(), () -> spawnBlock(nextBlock, block)); - } else if (e instanceof EntityInteractEvent) { - // Minion breaking block - Bukkit.getScheduler().runTask(addon.getPlugin(), () -> spawnBlock(nextBlock, block)); - // Fire event - Bukkit.getPluginManager().callEvent(new MagicBlockEvent(i, null, null, block, nextBlock.getMaterial())); - } - - // Increment the block number - is.incrementBlockNumber(); + // Get the block that is being broken + Block block = Objects.requireNonNull(i.getCenter()).toVector().toLocation(world).getBlock(); + + // Get oneblock island + OneBlockIslands is = getIsland(i); + + // Get the phase for current block number + OneBlockPhase phase = oneBlocksManager.getPhase(is.getBlockNumber()); + + // Save previous processing phase name + String prevPhaseName = is.getPhaseName(); + + // Check if phase contains `gotoBlock` + if (Objects.requireNonNull(phase).getGotoBlock() != null) { + phase = handleGoto(is, phase.getGotoBlock()); + } + + // Get current phase name + String currPhaseName = phase.getPhaseName() == null ? "" : phase.getPhaseName(); + + // Get the phase for next block number + OneBlockPhase nextPhase = oneBlocksManager.getPhase(is.getBlockNumber() + 1); + + // Check if nextPhase contains `gotoBlock` and override `nextPhase` + if (Objects.requireNonNull(nextPhase).getGotoBlock() != null) { + nextPhase = oneBlocksManager.getPhase(nextPhase.getGotoBlock()); + } + + // Get next phase name + String nextPhaseName = nextPhase == null || nextPhase.getPhaseName() == null ? "" : nextPhase.getPhaseName(); + + // If next phase is new, log break time of the last block of this phase + if (!currPhaseName.equalsIgnoreCase(nextPhaseName)) { + is.setLastPhaseChangeTime(System.currentTimeMillis()); + } + + boolean isCurrPhaseNew = !is.getPhaseName().equalsIgnoreCase(currPhaseName); + + if (isCurrPhaseNew) { + + // Check if requirements for new phase are met + if (check.phaseRequirementsFail(player, i, is, phase, world)) { + e.setCancelled(true); + return; + } + + check.setNewPhase(player, i, is, phase); + is.clearQueue(); + + // Set the biome for the block and one block above it + setBiome(block, phase.getPhaseBiome()); + + // Fire new phase event + Bukkit.getPluginManager() + .callEvent(new MagicBlockPhaseEvent(i, player == null ? null : player.getUniqueId(), block, + phase.getPhaseName(), prevPhaseName, is.getBlockNumber())); + } + + /* + if (!isCurrPhaseNew && is.getBlockNumber() % SAVE_EVERY == 0) { + // Save island data every MAX_LOOK_AHEAD blocks. + saveIsland(is); + }*/ + + // Get the block number in this phase + int materialBlocksInQueue = (int) is.getQueue().stream().filter(obo -> obo.isMaterial() || obo.isCustomBlock()) + .count(); + int blockNumber = is.getBlockNumber() - (phase.getBlockNumberValue() - 1) + materialBlocksInQueue; + + // Fill a 5 block queue + if (is.getQueue().isEmpty() || isCurrPhaseNew) { + // Add initial 5 blocks + for (int j = 0; j < MAX_LOOK_AHEAD; j++) { + is.add(phase.getNextBlock(addon, blockNumber++)); + } + } + + // Manage Holograms + addon.getHoloListener().process(i, is, phase); + + // Play warning sound for upcoming mobs + if (addon.getSettings().getMobWarning() > 0) { + warningSounder.play(is, block); + } + + // Get the next block + OneBlockObject nextBlock = (isCurrPhaseNew && phase.getFirstBlock() != null) ? phase.getFirstBlock() + : is.pollAndAdd(phase.getNextBlock(addon, blockNumber)); + + // Entity + if (nextBlock.isEntity()) { + if (!(e instanceof EntitySpawnEvent)) { + e.setCancelled(true); + } + // Entity spawns do not increment the block number or break the block + spawnEntity(nextBlock, block); + // Fire event + Bukkit.getPluginManager().callEvent(new MagicBlockEntityEvent(i, + player == null ? null : player.getUniqueId(), block, nextBlock.getEntityType())); + return; + } + + // Break the block + if (e instanceof BlockBreakEvent) { + this.breakBlock(player, block, nextBlock, i); + } else if (e instanceof PlayerBucketFillEvent) { + Bukkit.getScheduler().runTask(addon.getPlugin(), () -> spawnBlock(nextBlock, block)); + // Fire event + ItemStack tool = Objects.requireNonNull(player).getInventory().getItemInMainHand(); + Bukkit.getPluginManager() + .callEvent(new MagicBlockEvent(i, player.getUniqueId(), tool, block, nextBlock.getMaterial())); + } else if (e instanceof EntitySpawnEvent) { + Bukkit.getScheduler().runTask(addon.getPlugin(), () -> spawnBlock(nextBlock, block)); + } else if (e instanceof EntityInteractEvent) { + // Minion breaking block + Bukkit.getScheduler().runTask(addon.getPlugin(), () -> spawnBlock(nextBlock, block)); + // Fire event + Bukkit.getPluginManager().callEvent(new MagicBlockEvent(i, null, null, block, nextBlock.getMaterial())); + } + + // Increment the block number + is.incrementBlockNumber(); + saveIsland(is); } private OneBlockPhase handleGoto(OneBlockIslands is, int gotoBlock) { - // Store lifetime - is.setLifetime(is.getLifetime() + gotoBlock); - // Set current block - is.setBlockNumber(gotoBlock); - return oneBlocksManager.getPhase(gotoBlock); + // Store lifetime + is.setLifetime(is.getLifetime() + gotoBlock); + // Set current block + is.setBlockNumber(gotoBlock); + return oneBlocksManager.getPhase(gotoBlock); } private void setBiome(@NonNull Block block, @Nullable Biome biome) { - if (biome == null) { - return; - } - for (int x = -4; x <= 4; x++) { - for (int z = -4; z <= 4; z++) { - for (int y = -4; y <= 4; y++) { - block.getWorld().setBiome(block.getX() + x, block.getY() + y, block.getZ() + z, biome); - } - } - } + if (biome == null) { + return; + } + for (int x = -4; x <= 4; x++) { + for (int z = -4; z <= 4; z++) { + for (int y = -4; y <= 4; y++) { + block.getWorld().setBiome(block.getX() + x, block.getY() + y, block.getZ() + z, biome); + } + } + } } /** @@ -416,96 +408,96 @@ private void setBiome(@NonNull Block block, @Nullable Biome biome) { * @param island Island where player is located. */ private void breakBlock(@Nullable Player player, Block block, @NonNull OneBlockObject nextBlock, - @NonNull Island island) { - ItemStack tool = Objects.requireNonNull(player).getInventory().getItemInMainHand(); - - // Break normally and lift the player up so they don't fall - Bukkit.getScheduler().runTask(addon.getPlugin(), () -> this.spawnBlock(nextBlock, block)); - - if (player.getLocation().getBlock().equals(block)) { - double delta = 1 - (player.getLocation().getY() - block.getY()); - player.teleport(player.getLocation().add(new Vector(0, delta, 0))); - player.setVelocity(new Vector(0, 0, 0)); - } else if (player.getLocation().getBlock().equals(block.getRelative(BlockFace.UP))) { - player.teleport(player.getLocation()); - player.setVelocity(new Vector(0, 0, 0)); - } - - // Fire event - Bukkit.getPluginManager() - .callEvent(new MagicBlockEvent(island, player.getUniqueId(), tool, block, nextBlock.getMaterial())); + @NonNull Island island) { + ItemStack tool = Objects.requireNonNull(player).getInventory().getItemInMainHand(); + + // Break normally and lift the player up so they don't fall + Bukkit.getScheduler().runTask(addon.getPlugin(), () -> this.spawnBlock(nextBlock, block)); + + if (player.getLocation().getBlock().equals(block)) { + double delta = 1 - (player.getLocation().getY() - block.getY()); + player.teleport(player.getLocation().add(new Vector(0, delta, 0))); + player.setVelocity(new Vector(0, 0, 0)); + } else if (player.getLocation().getBlock().equals(block.getRelative(BlockFace.UP))) { + player.teleport(player.getLocation()); + player.setVelocity(new Vector(0, 0, 0)); + } + + // Fire event + Bukkit.getPluginManager() + .callEvent(new MagicBlockEvent(island, player.getUniqueId(), tool, block, nextBlock.getMaterial())); } private void spawnBlock(@NonNull OneBlockObject nextBlock, @NonNull Block block) { - if (nextBlock.isCustomBlock()) { - nextBlock.getCustomBlock().execute(addon, block); - } else { - @NonNull - Material type = nextBlock.getMaterial(); - // Place new block with no physics - block.setType(type, false); - // Fill the chest - if (type.equals(Material.CHEST) && nextBlock.getChest() != null) { - fillChest(nextBlock, block); - return; - } else if (Tag.LEAVES.isTagged(type)) { - Leaves leaves = (Leaves) block.getState().getBlockData(); - leaves.setPersistent(true); - block.setBlockData(leaves); - } else if (block.getState() instanceof BrushableBlock bb) { - LootTable lt = switch (bb.getBlock().getBiome()) { - default -> { - if (random.nextDouble() < 0.8) { - yield LootTables.TRAIL_RUINS_ARCHAEOLOGY_COMMON.getLootTable(); - } else { - // 20% rare - yield LootTables.TRAIL_RUINS_ARCHAEOLOGY_RARE.getLootTable(); - } - } - case DESERT -> LootTables.DESERT_PYRAMID_ARCHAEOLOGY.getLootTable(); - case FROZEN_OCEAN -> LootTables.OCEAN_RUIN_COLD_ARCHAEOLOGY.getLootTable(); - case OCEAN -> LootTables.OCEAN_RUIN_COLD_ARCHAEOLOGY.getLootTable(); - case WARM_OCEAN -> LootTables.OCEAN_RUIN_WARM_ARCHAEOLOGY.getLootTable(); - }; - bb.setLootTable(lt); - bb.update(); - } - } + if (nextBlock.isCustomBlock()) { + nextBlock.getCustomBlock().execute(addon, block); + } else { + @NonNull + Material type = nextBlock.getMaterial(); + // Place new block with no physics + block.setType(type, false); + // Fill the chest + if (type.equals(Material.CHEST) && nextBlock.getChest() != null) { + fillChest(nextBlock, block); + return; + } else if (Tag.LEAVES.isTagged(type)) { + Leaves leaves = (Leaves) block.getState().getBlockData(); + leaves.setPersistent(true); + block.setBlockData(leaves); + } else if (block.getState() instanceof BrushableBlock bb) { + LootTable lt = switch (bb.getBlock().getBiome()) { + default -> { + if (random.nextDouble() < 0.8) { + yield LootTables.TRAIL_RUINS_ARCHAEOLOGY_COMMON.getLootTable(); + } else { + // 20% rare + yield LootTables.TRAIL_RUINS_ARCHAEOLOGY_RARE.getLootTable(); + } + } + case DESERT -> LootTables.DESERT_PYRAMID_ARCHAEOLOGY.getLootTable(); + case FROZEN_OCEAN -> LootTables.OCEAN_RUIN_COLD_ARCHAEOLOGY.getLootTable(); + case OCEAN -> LootTables.OCEAN_RUIN_COLD_ARCHAEOLOGY.getLootTable(); + case WARM_OCEAN -> LootTables.OCEAN_RUIN_WARM_ARCHAEOLOGY.getLootTable(); + }; + bb.setLootTable(lt); + bb.update(); + } + } } private void spawnEntity(@NonNull OneBlockObject nextBlock, @NonNull Block block) { - if (block.isEmpty()) - block.setType(Material.STONE); - Location spawnLoc = block.getLocation().add(new Vector(0.5D, 1D, 0.5D)); - Entity entity = block.getWorld().spawnEntity(spawnLoc, nextBlock.getEntityType()); - // Make space for entity - this will blot out blocks - if (addon.getSettings().isClearBlocks()) { - new MakeSpace(addon).makeSpace(entity, spawnLoc); - } - block.getWorld().playSound(block.getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1F, 2F); + if (block.isEmpty()) + block.setType(Material.STONE); + Location spawnLoc = block.getLocation().add(new Vector(0.5D, 1D, 0.5D)); + Entity entity = block.getWorld().spawnEntity(spawnLoc, nextBlock.getEntityType()); + // Make space for entity - this will blot out blocks + if (addon.getSettings().isClearBlocks()) { + new MakeSpace(addon).makeSpace(entity, spawnLoc); + } + block.getWorld().playSound(block.getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1F, 2F); } private void fillChest(@NonNull OneBlockObject nextBlock, @NonNull Block block) { - Chest chest = (Chest) block.getState(); - nextBlock.getChest().forEach(chest.getBlockInventory()::setItem); - Color color = Color.fromBGR(0, 255, 255); // yellow - switch (nextBlock.getRarity()) { - case EPIC: - color = Color.fromBGR(255, 0, 255); // magenta - break; - case RARE: - color = Color.fromBGR(255, 255, 255); // cyan - break; - case UNCOMMON: - // Yellow - break; - default: - // No sparkles for regular chests - return; - } - block.getWorld().spawnParticle(Particle.REDSTONE, block.getLocation().add(new Vector(0.5, 1.0, 0.5)), 50, 0.5, - 0, 0.5, 1, new Particle.DustOptions(color, 1)); + Chest chest = (Chest) block.getState(); + nextBlock.getChest().forEach(chest.getBlockInventory()::setItem); + Color color = Color.fromBGR(0, 255, 255); // yellow + switch (nextBlock.getRarity()) { + case EPIC: + color = Color.fromBGR(255, 0, 255); // magenta + break; + case RARE: + color = Color.fromBGR(255, 255, 255); // cyan + break; + case UNCOMMON: + // Yellow + break; + default: + // No sparkles for regular chests + return; + } + block.getWorld().spawnParticle(Particle.REDSTONE, block.getLocation().add(new Vector(0.5, 1.0, 0.5)), 50, 0.5, + 0, 0.5, 1, new Particle.DustOptions(color, 1)); } /** @@ -516,7 +508,15 @@ private void fillChest(@NonNull OneBlockObject nextBlock, @NonNull Block block) */ @NonNull public OneBlockIslands getIsland(@NonNull Island i) { - return cache.containsKey(i.getUniqueId()) ? cache.get(i.getUniqueId()) : loadIsland(i.getUniqueId()); + if (handler.objectExists(i.getUniqueId())) { + OneBlockIslands island = handler.loadObject(i.getUniqueId()); + if (island != null) { + return island; + } + } + OneBlockIslands n = new OneBlockIslands(i.getUniqueId()); + handler.saveObject(n); + return n; } /** @@ -525,40 +525,24 @@ public OneBlockIslands getIsland(@NonNull Island i) { * @return list of oneblock islands */ public List getAllIslands() { - return handler.loadObjects(); - } - - @NonNull - private OneBlockIslands loadIsland(@NonNull String uniqueId) { - if (handler.objectExists(uniqueId)) { - OneBlockIslands island = handler.loadObject(uniqueId); - if (island != null) { - // Add to cache - cache.put(island.getUniqueId(), island); - return island; - } - } - return cache.computeIfAbsent(uniqueId, OneBlockIslands::new); + return handler.loadObjects(); } /** * @return the oneBlocksManager */ public OneBlocksManager getOneBlocksManager() { - return oneBlocksManager; + return oneBlocksManager; } /** * Saves the island progress to the database async * - * @param island - island + * @param is - island * @return CompletableFuture - true if saved or not in cache, false if save * failed */ - public CompletableFuture saveIsland(@NonNull Island island) { - if (cache.containsKey(island.getUniqueId())) { - return handler.saveObjectAsync(cache.get(island.getUniqueId())); - } - return CompletableFuture.completedFuture(true); + public CompletableFuture saveIsland(OneBlockIslands is) { + return handler.saveObjectAsync(is); } } diff --git a/src/main/java/world/bentobox/aoneblock/listeners/CheckPhase.java b/src/main/java/world/bentobox/aoneblock/listeners/CheckPhase.java index 6423a345..3e15361e 100644 --- a/src/main/java/world/bentobox/aoneblock/listeners/CheckPhase.java +++ b/src/main/java/world/bentobox/aoneblock/listeners/CheckPhase.java @@ -89,7 +89,7 @@ void setNewPhase(@Nullable Player player, @NonNull Island i, @NonNull OneBlockIs replacePlaceholders(player, newPhaseName, phase.getBlockNumber(), i, phase.getStartCommands()), "Commands run for start of " + newPhaseName); - blockListener.saveIsland(i); + blockListener.saveIsland(is); } /** diff --git a/src/main/java/world/bentobox/aoneblock/listeners/JoinLeaveListener.java b/src/main/java/world/bentobox/aoneblock/listeners/JoinLeaveListener.java deleted file mode 100644 index e0b2978b..00000000 --- a/src/main/java/world/bentobox/aoneblock/listeners/JoinLeaveListener.java +++ /dev/null @@ -1,40 +0,0 @@ -package world.bentobox.aoneblock.listeners; - -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerQuitEvent; - -import world.bentobox.aoneblock.AOneBlock; -import world.bentobox.bentobox.database.objects.Island; -import world.bentobox.bentobox.util.Util; - -public class JoinLeaveListener implements Listener { - - final AOneBlock addon; - - /** - * Save island on player quitting - * @param addon - AOneBlock - */ - public JoinLeaveListener(AOneBlock addon) { - this.addon = addon; - } - - /** - * Save island on player quitting - * @param e - event - */ - @EventHandler(priority = EventPriority.NORMAL) - public void onPlayerQuit(PlayerQuitEvent e) { - Island island = addon.getIslands().getIsland(addon.getOverWorld(), e.getPlayer().getUniqueId()); - if (island != null) { - addon.getBlockListener().saveIsland(island).thenAccept(r -> { - if (Boolean.FALSE.equals(r)) { - addon.logError("Could not save AOneBlock island at " + Util.xyz(island.getCenter().toVector()) + " to database " + island.getUniqueId()); - } - }); - } - } - -} diff --git a/src/test/java/world/bentobox/aoneblock/listeners/JoinLeaveListenerTest.java b/src/test/java/world/bentobox/aoneblock/listeners/JoinLeaveListenerTest.java deleted file mode 100644 index e88d1269..00000000 --- a/src/test/java/world/bentobox/aoneblock/listeners/JoinLeaveListenerTest.java +++ /dev/null @@ -1,131 +0,0 @@ -package world.bentobox.aoneblock.listeners; - -import static org.junit.Assert.assertNotNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.UUID; -import java.util.concurrent.CompletableFuture; - -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.util.Vector; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.modules.junit4.PowerMockRunner; - -import world.bentobox.aoneblock.AOneBlock; -import world.bentobox.bentobox.database.objects.Island; -import world.bentobox.bentobox.managers.IslandsManager; - -/** - * @author tastybento - */ -@RunWith(PowerMockRunner.class) -public class JoinLeaveListenerTest { - - @Mock - private AOneBlock aob; - @Mock - private Player p; - - private JoinLeaveListener jll; - @Mock - private BlockListener bl; - @Mock - private Location location; - @Mock - private IslandsManager im; - @Mock - private Island island; - @Mock - private World world; - - private static final UUID ID = UUID.randomUUID(); - private static final Vector VECTOR = new Vector(123,120,456); - /** - * @throws java.lang.Exception - */ - @Before - public void setUp() throws Exception { - - when(aob.getOverWorld()).thenReturn(world); - // Player - when(p.getUniqueId()).thenReturn(ID); - - // Island - when(island.getCenter()).thenReturn(location); - when(location.toVector()).thenReturn(VECTOR); - - // Island Manager - when(aob.getIslands()).thenReturn(im); - when(island.getCenter()).thenReturn(location); - when(im.getIsland(world, ID)).thenReturn(island); - - // Save is successful - when(bl.saveIsland(any())).thenReturn(CompletableFuture.completedFuture(Boolean.TRUE)); - when(aob.getBlockListener()).thenReturn(bl); - jll = new JoinLeaveListener(aob); - - } - - /** - * @throws java.lang.Exception - */ - @After - public void tearDown() throws Exception { - } - - /** - * Test method for {@link world.bentobox.aoneblock.listeners.JoinLeaveListener#JoinLeaveListener(world.bentobox.aoneblock.AOneBlock)}. - */ - @Test - public void testJoinLeaveListener() { - assertNotNull(jll); - } - - /** - * Test method for {@link world.bentobox.aoneblock.listeners.JoinLeaveListener#onPlayerQuit(org.bukkit.event.player.PlayerQuitEvent)}. - */ - @Test - public void testOnPlayerQuit() { - PlayerQuitEvent event = new PlayerQuitEvent(p, "nothing"); - jll.onPlayerQuit(event); - verify(aob,never()).logError(anyString()); - verify(bl).saveIsland(island); - } - - /** - * Test method for {@link world.bentobox.aoneblock.listeners.JoinLeaveListener#onPlayerQuit(org.bukkit.event.player.PlayerQuitEvent)}. - */ - @Test - public void testOnPlayerQuitNoIsland() { - when(im.getIsland(world, ID)).thenReturn(null); - PlayerQuitEvent event = new PlayerQuitEvent(p, "nothing"); - jll.onPlayerQuit(event); - verify(aob,never()).logError(anyString()); - verify(bl, never()).saveIsland(island); - } - - /** - * Test method for {@link world.bentobox.aoneblock.listeners.JoinLeaveListener#onPlayerQuit(org.bukkit.event.player.PlayerQuitEvent)}. - */ - @Test - public void testOnPlayerQuitSaveError() { - when(bl.saveIsland(any())).thenReturn(CompletableFuture.completedFuture(Boolean.FALSE)); - PlayerQuitEvent event = new PlayerQuitEvent(p, "nothing"); - jll.onPlayerQuit(event); - verify(aob).logError(anyString()); - verify(bl).saveIsland(island); - verify(aob).logError("Could not save AOneBlock island at 123,120,456 to database null"); - } - -} From 2fa2bf2b4d05baa1c35b04523757dd5c8731e121 Mon Sep 17 00:00:00 2001 From: tastybento Date: Tue, 16 Apr 2024 18:00:42 -0700 Subject: [PATCH 2/4] WIP - config.yml checker --- .../world/bentobox/aoneblock/AOneBlock.java | 520 +++++++++--------- 1 file changed, 267 insertions(+), 253 deletions(-) diff --git a/src/main/java/world/bentobox/aoneblock/AOneBlock.java b/src/main/java/world/bentobox/aoneblock/AOneBlock.java index bb4ce9fc..1df19781 100644 --- a/src/main/java/world/bentobox/aoneblock/AOneBlock.java +++ b/src/main/java/world/bentobox/aoneblock/AOneBlock.java @@ -1,5 +1,6 @@ package world.bentobox.aoneblock; +import java.io.File; import java.io.IOException; import java.util.Objects; @@ -45,275 +46,288 @@ */ public class AOneBlock extends GameModeAddon { - private static final String NETHER = "_nether"; - private static final String THE_END = "_the_end"; - private boolean hasItemsAdder = false; + private static final String NETHER = "_nether"; + private static final String THE_END = "_the_end"; + private boolean hasItemsAdder = false; - // Settings - private Settings settings; - private ChunkGeneratorWorld chunkGenerator; - private final Config configObject = new Config<>(this, Settings.class); - private BlockListener blockListener; - private OneBlocksManager oneBlockManager; + // Settings + private Settings settings; + private ChunkGeneratorWorld chunkGenerator; + private final Config configObject = new Config<>(this, Settings.class); + private BlockListener blockListener; + private OneBlocksManager oneBlockManager; private AOneBlockPlaceholders phManager; - private HoloListener holoListener; - - // Flag + private HoloListener holoListener; + + // Flag public final Flag START_SAFETY = new Flag.Builder("START_SAFETY", Material.BAMBOO_BLOCK) .mode(Mode.BASIC) .type(Type.WORLD_SETTING) .listener(new StartSafetyListener(this)) .defaultSetting(false) .build(); - - @Override - public void onLoad() { - // Check if ItemsAdder exists, if yes register listener - if (Bukkit.getPluginManager().getPlugin("ItemsAdder") != null) { - registerListener(new ItemsAdderListener(this)); - OneBlockCustomBlockCreator.register(ItemsAdderCustomBlock::fromId); - OneBlockCustomBlockCreator.register("itemsadder", ItemsAdderCustomBlock::fromMap); - hasItemsAdder = true; - } - // Save the default config from config.yml - saveDefaultConfig(); - // Load settings from config.yml. This will check if there are any issues with - // it too. - if (loadSettings()) { - // Chunk generator - chunkGenerator = settings.isUseOwnGenerator() ? null : new ChunkGeneratorWorld(this); - // Register commands - playerCommand = new PlayerCommand(this); - adminCommand = new AdminCommand(this); + private long configLastModified; + + @Override + public void onLoad() { + // Check if ItemsAdder exists, if yes register listener + if (Bukkit.getPluginManager().getPlugin("ItemsAdder") != null) { + registerListener(new ItemsAdderListener(this)); + OneBlockCustomBlockCreator.register(ItemsAdderCustomBlock::fromId); + OneBlockCustomBlockCreator.register("itemsadder", ItemsAdderCustomBlock::fromMap); + hasItemsAdder = true; + } + // Save the default config from config.yml + saveDefaultConfig(); + // Load settings from config.yml. This will check if there are any issues with + // it too. + if (loadSettings()) { + // Chunk generator + chunkGenerator = settings.isUseOwnGenerator() ? null : new ChunkGeneratorWorld(this); + // Register commands + playerCommand = new PlayerCommand(this); + adminCommand = new AdminCommand(this); // Register flag with BentoBox // Register protection flag with BentoBox getPlugin().getFlagsManager().registerFlag(this, START_SAFETY); - } - } + } + } private boolean loadSettings() { - // Load settings again to get worlds - settings = configObject.loadConfigObject(); - if (settings == null) { - // Disable - logError("AOneBlock settings could not load! Addon disabled."); - setState(State.DISABLED); - return false; - } else { - // Save the settings - configObject.saveConfigObject(settings); - } - return true; - } - - @Override - public void onEnable() { - oneBlockManager = new OneBlocksManager(this); - if (loadData()) { - // Failed to load - don't register anything - return; - } - blockListener = new BlockListener(this); - registerListener(blockListener); - registerListener(new NoBlockHandler(this)); - registerListener(new BlockProtect(this)); - registerListener(new InfoListener(this)); - // Register placeholders + // Load settings again to get worlds + settings = configObject.loadConfigObject(); + if (settings == null) { + // Disable + logError("AOneBlock settings could not load! Addon disabled."); + setState(State.DISABLED); + return false; + } else { + // Save the settings + configObject.saveConfigObject(settings); + } + if (configLastModified == 0) { + // Start config.yml monitor + // TODO check if this works or not + final File configFile = new File(getDataFolder(), "config.yml"); + configLastModified = configFile.lastModified(); + Bukkit.getScheduler().runTaskTimer(getPlugin(), () -> { + if (configFile.lastModified() != configLastModified) { + configLastModified = configFile.lastModified(); + loadSettings(); + } + }, 20L, 20L); + } + return true; + } + + @Override + public void onEnable() { + oneBlockManager = new OneBlocksManager(this); + if (loadData()) { + // Failed to load - don't register anything + return; + } + blockListener = new BlockListener(this); + registerListener(blockListener); + registerListener(new NoBlockHandler(this)); + registerListener(new BlockProtect(this)); + registerListener(new InfoListener(this)); + // Register placeholders phManager = new AOneBlockPlaceholders(this, getPlugin().getPlaceholdersManager()); - // Register request handlers - registerRequestHandler(new IslandStatsHandler(this)); - registerRequestHandler(new LocationStatsHandler(this)); - - // Register Holograms - holoListener = new HoloListener(this); - registerListener(holoListener); - } - - // Load phase data - public boolean loadData() { - try { - oneBlockManager.loadPhases(); - } catch (IOException e) { - // Disable - logError("AOneBlock settings could not load (oneblock.yml error)! Addon disabled."); - logError(e.getMessage()); - setState(State.DISABLED); - return true; - } - return false; - } - - @Override - public void onDisable() { - // Clear holograms - holoListener.clear(); - } - - @Override - public void onReload() { - if (loadSettings()) { - log("Reloaded AOneBlock settings"); - loadData(); - } - } - - /** - * @return the settings - */ - public Settings getSettings() { - return settings; - } - - @Override - public void createWorlds() { - String worldName = settings.getWorldName().toLowerCase(); - if (getServer().getWorld(worldName) == null) { - log("Creating AOneBlock world ..."); - } - - // Create the world if it does not exist - islandWorld = getWorld(worldName, World.Environment.NORMAL, chunkGenerator); - // Make the nether if it does not exist - if (settings.isNetherGenerate()) { - if (getServer().getWorld(worldName + NETHER) == null) { - log("Creating AOneBlock's Nether..."); - } - netherWorld = settings.isNetherIslands() ? getWorld(worldName, World.Environment.NETHER, chunkGenerator) - : getWorld(worldName, World.Environment.NETHER, null); - } - // Make the end if it does not exist - if (settings.isEndGenerate()) { - if (getServer().getWorld(worldName + THE_END) == null) { - log("Creating AOneBlock's End World..."); - } - endWorld = settings.isEndIslands() ? getWorld(worldName, World.Environment.THE_END, chunkGenerator) - : getWorld(worldName, World.Environment.THE_END, null); - } - } - - /** - * Gets a world or generates a new world if it does not exist - * - * @param worldName2 - the overworld name - * @param env - the environment - * @param chunkGenerator2 - the chunk generator. If null then the - * generator will not be specified - * @return world loaded or generated - */ - private World getWorld(String worldName2, Environment env, ChunkGeneratorWorld chunkGenerator2) { - // Set world name - worldName2 = env.equals(World.Environment.NETHER) ? worldName2 + NETHER : worldName2; - worldName2 = env.equals(World.Environment.THE_END) ? worldName2 + THE_END : worldName2; - WorldCreator wc = WorldCreator.name(worldName2).type(WorldType.FLAT).environment(env); - World w = settings.isUseOwnGenerator() ? wc.createWorld() : wc.generator(chunkGenerator2).createWorld(); - // Set spawn rates - if (w != null) { - setSpawnRates(w); - } - return w; - - } - - private void setSpawnRates(World w) { - if (getSettings().getSpawnLimitMonsters() > 0) { - w.setSpawnLimit(SpawnCategory.MONSTER, getSettings().getSpawnLimitMonsters()); - } - if (getSettings().getSpawnLimitAmbient() > 0) { - w.setSpawnLimit(SpawnCategory.AMBIENT, getSettings().getSpawnLimitAmbient()); - } - if (getSettings().getSpawnLimitAnimals() > 0) { - w.setSpawnLimit(SpawnCategory.ANIMAL, getSettings().getSpawnLimitAnimals()); - } - if (getSettings().getSpawnLimitWaterAnimals() > 0) { - w.setSpawnLimit(SpawnCategory.WATER_ANIMAL, getSettings().getSpawnLimitWaterAnimals()); - } - if (getSettings().getTicksPerAnimalSpawns() > 0) { - w.setTicksPerSpawns(SpawnCategory.ANIMAL, getSettings().getTicksPerAnimalSpawns()); - } - if (getSettings().getTicksPerMonsterSpawns() > 0) { - w.setTicksPerSpawns(SpawnCategory.MONSTER, getSettings().getTicksPerMonsterSpawns()); - } - - } - - @Override - public WorldSettings getWorldSettings() { - return getSettings(); - } - - @Override - public @Nullable ChunkGenerator getDefaultWorldGenerator(String worldName, String id) { - return chunkGenerator; - } - - @Override - public void saveWorldSettings() { - if (settings != null) { - configObject.saveConfigObject(settings); - } - } - - @Override - public void saveDefaultConfig() { - super.saveDefaultConfig(); - // Save default phases panel - this.saveResource("panels/phases_panel.yml", false); - } - - /* - * (non-Javadoc) - * - * @see world.bentobox.bentobox.api.addons.Addon#allLoaded() - */ - @Override - public void allLoaded() { - // save settings. This will occur after all addons have loaded - this.saveWorldSettings(); - } - - /** - * @param i - island - * @return one block island data - */ - @NonNull - public OneBlockIslands getOneBlocksIsland(@NonNull Island i) { - return blockListener.getIsland(Objects.requireNonNull(i)); - } - - public OneBlocksManager getOneBlockManager() { - return oneBlockManager; - } - - /** - * @return the blockListener - */ - public BlockListener getBlockListener() { - return blockListener; - } - - /** - * Get the placeholder manager - * - * @return the phManager - */ + // Register request handlers + registerRequestHandler(new IslandStatsHandler(this)); + registerRequestHandler(new LocationStatsHandler(this)); + + // Register Holograms + holoListener = new HoloListener(this); + registerListener(holoListener); + } + + // Load phase data + public boolean loadData() { + try { + oneBlockManager.loadPhases(); + } catch (IOException e) { + // Disable + logError("AOneBlock settings could not load (oneblock.yml error)! Addon disabled."); + logError(e.getMessage()); + setState(State.DISABLED); + return true; + } + return false; + } + + @Override + public void onDisable() { + // Clear holograms + holoListener.clear(); + } + + @Override + public void onReload() { + if (loadSettings()) { + log("Reloaded AOneBlock settings"); + loadData(); + } + } + + /** + * @return the settings + */ + public Settings getSettings() { + return settings; + } + + @Override + public void createWorlds() { + String worldName = settings.getWorldName().toLowerCase(); + if (getServer().getWorld(worldName) == null) { + log("Creating AOneBlock world ..."); + } + + // Create the world if it does not exist + islandWorld = getWorld(worldName, World.Environment.NORMAL, chunkGenerator); + // Make the nether if it does not exist + if (settings.isNetherGenerate()) { + if (getServer().getWorld(worldName + NETHER) == null) { + log("Creating AOneBlock's Nether..."); + } + netherWorld = settings.isNetherIslands() ? getWorld(worldName, World.Environment.NETHER, chunkGenerator) + : getWorld(worldName, World.Environment.NETHER, null); + } + // Make the end if it does not exist + if (settings.isEndGenerate()) { + if (getServer().getWorld(worldName + THE_END) == null) { + log("Creating AOneBlock's End World..."); + } + endWorld = settings.isEndIslands() ? getWorld(worldName, World.Environment.THE_END, chunkGenerator) + : getWorld(worldName, World.Environment.THE_END, null); + } + } + + /** + * Gets a world or generates a new world if it does not exist + * + * @param worldName2 - the overworld name + * @param env - the environment + * @param chunkGenerator2 - the chunk generator. If null then the + * generator will not be specified + * @return world loaded or generated + */ + private World getWorld(String worldName2, Environment env, ChunkGeneratorWorld chunkGenerator2) { + // Set world name + worldName2 = env.equals(World.Environment.NETHER) ? worldName2 + NETHER : worldName2; + worldName2 = env.equals(World.Environment.THE_END) ? worldName2 + THE_END : worldName2; + WorldCreator wc = WorldCreator.name(worldName2).type(WorldType.FLAT).environment(env); + World w = settings.isUseOwnGenerator() ? wc.createWorld() : wc.generator(chunkGenerator2).createWorld(); + // Set spawn rates + if (w != null) { + setSpawnRates(w); + } + return w; + + } + + private void setSpawnRates(World w) { + if (getSettings().getSpawnLimitMonsters() > 0) { + w.setSpawnLimit(SpawnCategory.MONSTER, getSettings().getSpawnLimitMonsters()); + } + if (getSettings().getSpawnLimitAmbient() > 0) { + w.setSpawnLimit(SpawnCategory.AMBIENT, getSettings().getSpawnLimitAmbient()); + } + if (getSettings().getSpawnLimitAnimals() > 0) { + w.setSpawnLimit(SpawnCategory.ANIMAL, getSettings().getSpawnLimitAnimals()); + } + if (getSettings().getSpawnLimitWaterAnimals() > 0) { + w.setSpawnLimit(SpawnCategory.WATER_ANIMAL, getSettings().getSpawnLimitWaterAnimals()); + } + if (getSettings().getTicksPerAnimalSpawns() > 0) { + w.setTicksPerSpawns(SpawnCategory.ANIMAL, getSettings().getTicksPerAnimalSpawns()); + } + if (getSettings().getTicksPerMonsterSpawns() > 0) { + w.setTicksPerSpawns(SpawnCategory.MONSTER, getSettings().getTicksPerMonsterSpawns()); + } + + } + + @Override + public WorldSettings getWorldSettings() { + return getSettings(); + } + + @Override + public @Nullable ChunkGenerator getDefaultWorldGenerator(String worldName, String id) { + return chunkGenerator; + } + + @Override + public void saveWorldSettings() { + if (settings != null) { + configObject.saveConfigObject(settings); + } + } + + @Override + public void saveDefaultConfig() { + super.saveDefaultConfig(); + // Save default phases panel + this.saveResource("panels/phases_panel.yml", false); + } + + /* + * (non-Javadoc) + * + * @see world.bentobox.bentobox.api.addons.Addon#allLoaded() + */ + @Override + public void allLoaded() { + // save settings. This will occur after all addons have loaded + this.saveWorldSettings(); + } + + /** + * @param i - island + * @return one block island data + */ + @NonNull + public OneBlockIslands getOneBlocksIsland(@NonNull Island i) { + return blockListener.getIsland(Objects.requireNonNull(i)); + } + + public OneBlocksManager getOneBlockManager() { + return oneBlockManager; + } + + /** + * @return the blockListener + */ + public BlockListener getBlockListener() { + return blockListener; + } + + /** + * Get the placeholder manager + * + * @return the phManager + */ public AOneBlockPlaceholders getPlaceholdersManager() { - return phManager; - } - - /** - * @return the holoListener - */ - public HoloListener getHoloListener() { - return holoListener; - } - - /** - * @return true if ItemsAdder is on the server - */ - public boolean hasItemsAdder() { - return hasItemsAdder; - } + return phManager; + } + + /** + * @return the holoListener + */ + public HoloListener getHoloListener() { + return holoListener; + } + + /** + * @return true if ItemsAdder is on the server + */ + public boolean hasItemsAdder() { + return hasItemsAdder; + } /** * Set the addon's world. Used only for testing. From 5d74dda17c1e84e943ea8faca5034450f7ec6cd1 Mon Sep 17 00:00:00 2001 From: tastybento Date: Thu, 2 May 2024 15:23:25 -0700 Subject: [PATCH 3/4] WIP --- pom.xml | 2 +- .../world/bentobox/aoneblock/AOneBlock.java | 19 +++---------------- .../aoneblock/listeners/BlockListener.java | 12 ------------ src/main/resources/addon.yml | 2 +- 4 files changed, 5 insertions(+), 30 deletions(-) diff --git a/pom.xml b/pom.xml index bedd75f9..188598e4 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 2.0.9 1.20.4-R0.1-SNAPSHOT - 2.3.0-SNAPSHOT + 2.4.0-SNAPSHOT 2.6.2 1.3.0 diff --git a/src/main/java/world/bentobox/aoneblock/AOneBlock.java b/src/main/java/world/bentobox/aoneblock/AOneBlock.java index 1df19781..4ec7c158 100644 --- a/src/main/java/world/bentobox/aoneblock/AOneBlock.java +++ b/src/main/java/world/bentobox/aoneblock/AOneBlock.java @@ -1,6 +1,5 @@ package world.bentobox.aoneblock; -import java.io.File; import java.io.IOException; import java.util.Objects; @@ -66,7 +65,6 @@ public class AOneBlock extends GameModeAddon { .listener(new StartSafetyListener(this)) .defaultSetting(false) .build(); - private long configLastModified; @Override public void onLoad() { @@ -94,29 +92,17 @@ public void onLoad() { } private boolean loadSettings() { - // Load settings again to get worlds settings = configObject.loadConfigObject(); if (settings == null) { + // Settings do not exist so disable // Disable logError("AOneBlock settings could not load! Addon disabled."); setState(State.DISABLED); return false; } else { - // Save the settings + // Save the initial settings configObject.saveConfigObject(settings); } - if (configLastModified == 0) { - // Start config.yml monitor - // TODO check if this works or not - final File configFile = new File(getDataFolder(), "config.yml"); - configLastModified = configFile.lastModified(); - Bukkit.getScheduler().runTaskTimer(getPlugin(), () -> { - if (configFile.lastModified() != configLastModified) { - configLastModified = configFile.lastModified(); - loadSettings(); - } - }, 20L, 20L); - } return true; } @@ -265,6 +251,7 @@ public WorldSettings getWorldSettings() { public void saveWorldSettings() { if (settings != null) { configObject.saveConfigObject(settings); + super.saveWorldSettings(); } } diff --git a/src/main/java/world/bentobox/aoneblock/listeners/BlockListener.java b/src/main/java/world/bentobox/aoneblock/listeners/BlockListener.java index da3a0fd6..c1bf6d00 100644 --- a/src/main/java/world/bentobox/aoneblock/listeners/BlockListener.java +++ b/src/main/java/world/bentobox/aoneblock/listeners/BlockListener.java @@ -74,11 +74,6 @@ public class BlockListener implements Listener { */ private final Database handler; - /** - * Oneblock cache. - */ - //private final Map cache; - /** * Phase checker class */ @@ -94,11 +89,6 @@ public class BlockListener implements Listener { */ public static final int MAX_LOOK_AHEAD = 5; - /** - * How often data is saved. - */ - public static final int SAVE_EVERY = 1; - private final Random random = new Random(); /** @@ -133,7 +123,6 @@ public void onNewIsland(IslandResettedEvent e) { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onDeletedIsland(IslandDeleteEvent e) { if (addon.inWorld(e.getIsland().getWorld())) { - //cache.remove(e.getIsland().getUniqueId()); handler.deleteID(e.getIsland().getUniqueId()); } } @@ -238,7 +227,6 @@ private void setUp(@NonNull Island island) { .thenRun(() -> island.getCenter().getBlock().setType(Material.GRASS_BLOCK)); // Create a database entry OneBlockIslands is = new OneBlockIslands(island.getUniqueId()); - //cache.put(island.getUniqueId(), is); handler.saveObjectAsync(is); addon.getHoloListener().setUp(island, is, true); } diff --git a/src/main/resources/addon.yml b/src/main/resources/addon.yml index 76ff4bd6..c85a889f 100755 --- a/src/main/resources/addon.yml +++ b/src/main/resources/addon.yml @@ -1,7 +1,7 @@ name: AOneBlock main: world.bentobox.aoneblock.AOneBlock version: ${version}${build.number} -api-version: 2.3.0 +api-version: 2.4.0 metrics: true icon: "STONE" repository: "BentoBoxWorld/AOneBlock" From 30bd435d0e2c09e11052f2a6069fbc95c788275a Mon Sep 17 00:00:00 2001 From: tastybento Date: Tue, 2 Jul 2024 11:38:41 -0700 Subject: [PATCH 4/4] Fix tests. --- pom.xml | 2 +- src/test/java/world/bentobox/aoneblock/AOneBlockTest.java | 2 +- .../commands/island/IslandSetCountCommandTest.java | 1 + .../bentobox/aoneblock/listeners/InfoListenerTest.java | 6 ++++++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 188598e4..222071be 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 2.0.9 1.20.4-R0.1-SNAPSHOT - 2.4.0-SNAPSHOT + 2.4.1-SNAPSHOT 2.6.2 1.3.0 diff --git a/src/test/java/world/bentobox/aoneblock/AOneBlockTest.java b/src/test/java/world/bentobox/aoneblock/AOneBlockTest.java index 9d588260..edb35e8d 100644 --- a/src/test/java/world/bentobox/aoneblock/AOneBlockTest.java +++ b/src/test/java/world/bentobox/aoneblock/AOneBlockTest.java @@ -130,6 +130,7 @@ private void deleteAll(File file) throws IOException { */ @Before public void setUp() throws Exception { + PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); // Set up plugin Whitebox.setInternalState(BentoBox.class, "instance", plugin); when(plugin.getLogger()).thenReturn(Logger.getAnonymousLogger()); @@ -171,7 +172,6 @@ public void setUp() throws Exception { .thenAnswer((Answer) invocation -> invocation.getArgument(0, String.class)); // Server - PowerMockito.mockStatic(Bukkit.class); Server server = mock(Server.class); when(Bukkit.getServer()).thenReturn(server); when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger()); diff --git a/src/test/java/world/bentobox/aoneblock/commands/island/IslandSetCountCommandTest.java b/src/test/java/world/bentobox/aoneblock/commands/island/IslandSetCountCommandTest.java index 58e50193..55fd9651 100644 --- a/src/test/java/world/bentobox/aoneblock/commands/island/IslandSetCountCommandTest.java +++ b/src/test/java/world/bentobox/aoneblock/commands/island/IslandSetCountCommandTest.java @@ -130,6 +130,7 @@ private void deleteAll(File file) throws IOException { */ @Before public void setUp() throws Exception { + PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); // Set up plugin BentoBox plugin = mock(BentoBox.class); Whitebox.setInternalState(BentoBox.class, "instance", plugin); diff --git a/src/test/java/world/bentobox/aoneblock/listeners/InfoListenerTest.java b/src/test/java/world/bentobox/aoneblock/listeners/InfoListenerTest.java index 3e0d987a..c8fb6e85 100644 --- a/src/test/java/world/bentobox/aoneblock/listeners/InfoListenerTest.java +++ b/src/test/java/world/bentobox/aoneblock/listeners/InfoListenerTest.java @@ -9,6 +9,7 @@ import java.util.UUID; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; @@ -19,6 +20,8 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import world.bentobox.aoneblock.AOneBlock; @@ -31,12 +34,14 @@ import world.bentobox.bentobox.managers.IslandsManager; import world.bentobox.bentobox.managers.LocalesManager; import world.bentobox.bentobox.managers.PlaceholdersManager; +import world.bentobox.bentobox.util.Util; /** * @author tastybento * */ @RunWith(PowerMockRunner.class) +@PrepareForTest({ Bukkit.class, Util.class }) public class InfoListenerTest { @Mock private BentoBox plugin; @@ -72,6 +77,7 @@ public class InfoListenerTest { */ @Before public void setUp() throws Exception { + PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS); when(addon.getPlugin()).thenReturn(plugin); when(plugin.getLocalesManager()).thenReturn(lm); when(lm.get(toString())).thenAnswer(invocation -> invocation.getArgument(0, String.class));