diff --git a/pom.xml b/pom.xml index fc91f8455..696d9087e 100644 --- a/pom.xml +++ b/pom.xml @@ -321,6 +321,13 @@ RC-36 provided + + + com.github.LoneDev6 + api-itemsadder + 3.6.1 + provided + diff --git a/src/main/java/world/bentobox/bentobox/BentoBox.java b/src/main/java/world/bentobox/bentobox/BentoBox.java index 1fb0ed916..bea18a9c6 100644 --- a/src/main/java/world/bentobox/bentobox/BentoBox.java +++ b/src/main/java/world/bentobox/bentobox/BentoBox.java @@ -22,6 +22,7 @@ import world.bentobox.bentobox.api.user.Notifier; import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.commands.BentoBoxCommand; import world.bentobox.bentobox.database.DatabaseSetup; +import world.bentobox.bentobox.hooks.ItemsAdderHook; import world.bentobox.bentobox.hooks.MultiverseCoreHook; import world.bentobox.bentobox.hooks.MyWorldsHook; import world.bentobox.bentobox.hooks.SlimefunHook; @@ -235,6 +236,9 @@ public class BentoBox extends JavaPlugin implements Listener { // Register Slimefun hooksManager.registerHook(new SlimefunHook()); + // Register ItemsAdder + hooksManager.registerHook(new ItemsAdderHook(this)); + // TODO: re-enable after implementation //hooksManager.registerHook(new DynmapHook()); // TODO: re-enable after rework diff --git a/src/main/java/world/bentobox/bentobox/hooks/ItemsAdderHook.java b/src/main/java/world/bentobox/bentobox/hooks/ItemsAdderHook.java new file mode 100644 index 000000000..7cd52763b --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/hooks/ItemsAdderHook.java @@ -0,0 +1,111 @@ +package world.bentobox.bentobox.hooks; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityExplodeEvent; + +import dev.lone.itemsadder.api.CustomBlock; +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.api.flags.Flag; +import world.bentobox.bentobox.api.flags.FlagListener; +import world.bentobox.bentobox.api.flags.clicklisteners.CycleClick; +import world.bentobox.bentobox.api.hooks.Hook; +import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.managers.RanksManager; + +/** + * Hook to enable itemsadder blocks to be deleted when islands are deleted. + * It also includes a flag to track explosion access + */ +public class ItemsAdderHook extends Hook { + + /** + * This flag allows to switch which island member group can use explosive items from Items Adder. + */ + public final static Flag ITEMS_ADDER_EXPLOSIONS = + new Flag.Builder("ITEMS_ADDER_EXPLOSIONS", Material.TNT). + type(Flag.Type.PROTECTION). + defaultRank(RanksManager.MEMBER_RANK). + clickHandler(new CycleClick("ITEMS_ADDER_EXPLOSIONS", + RanksManager.VISITOR_RANK, RanksManager.OWNER_RANK)) + . + build(); + + private BentoBox plugin; + + public ItemsAdderHook(BentoBox plugin) { + super("ItemsAdder", Material.NETHER_STAR); + this.plugin = plugin; + } + + @Override + public boolean hook() { + // See if ItemsAdder is around + if (Bukkit.getPluginManager().getPlugin("ItemsAdder") == null) { + return false; + } + // Register listener + Bukkit.getPluginManager().registerEvents(new BlockInteractListener(), plugin); + plugin.getFlagsManager().registerFlag(ITEMS_ADDER_EXPLOSIONS); + return true; + } + + @Override + public String getFailureCause() { + return ""; // No errors + } + + /** + * Remove the CustomBlock at location + * @param location + */ + public void clearBlockInfo(Location location) { + CustomBlock.remove(location); + } + + class BlockInteractListener extends FlagListener { + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onExplosion(EntityExplodeEvent event) + { + if (!EntityType.PLAYER.equals(event.getEntityType())) { + // Ignore non-player explosions. + return; + } + + Player player = (Player) event.getEntity(); + + if (!player.hasPermission("XXXXXX")) { + // Ignore players that does not have magic XXXXXX permission. + return; + } + + // Use BentoBox flag processing system to validate usage. + // Technically not necessary as internally it should be cancelled by BentoBox. + + if (!this.checkIsland(event, player, event.getLocation(), ITEMS_ADDER_EXPLOSIONS)) { + // Remove any blocks from the explosion list if required + event.blockList().removeIf(block -> this.protect(player, block.getLocation())); + event.setCancelled(this.protect(player, event.getLocation())); + } + } + + + /** + * This method returns if the protection in given location is enabled or not. + * @param player Player who triggers explosion. + * @param location Location where explosion happens. + * @return {@code true} if location is protected, {@code false} otherwise. + */ + private boolean protect(Player player, Location location) + { + return plugin.getIslands().getProtectedIslandAt(location) + .map(island -> !island.isAllowed(User.getInstance(player), ITEMS_ADDER_EXPLOSIONS)).orElse(false); + } + } +} diff --git a/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java b/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java index 6b6a2800c..2e0c4fd8a 100644 --- a/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java +++ b/src/main/java/world/bentobox/bentobox/nms/CopyWorldRegenerator.java @@ -38,6 +38,7 @@ import io.papermc.lib.PaperLib; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.database.objects.IslandDeletion; +import world.bentobox.bentobox.hooks.ItemsAdderHook; import world.bentobox.bentobox.hooks.SlimefunHook; import world.bentobox.bentobox.util.MyBiomeGrid; @@ -194,10 +195,12 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator { if (x % 4 == 0 && y % 4 == 0 && z % 4 == 0) { toChunk.getBlock(x, y, z).setBiome(fromChunk.getBlock(x, y, z).getBiome()); } - // Delete any slimefun blocks + // Delete any 3rd party blocks Location loc = new Location(toChunk.getWorld(), baseX + x, y, baseZ + z); plugin.getHooks().getHook("Slimefun") - .ifPresent(sf -> ((SlimefunHook) sf).clearBlockInfo(loc, true)); + .ifPresent(hook -> ((SlimefunHook) hook).clearBlockInfo(loc, true)); + plugin.getHooks().getHook("ItemsAdder") + .ifPresent(hook -> ((ItemsAdderHook) hook).clearBlockInfo(loc)); } } } @@ -377,10 +380,12 @@ public abstract class CopyWorldRegenerator implements WorldRegenerator { if (x % 4 == 0 && y % 4 == 0 && z % 4 == 0) { chunk.getBlock(x, y, z).setBiome(biomeGrid.getBiome(x, y, z)); } - // Delete any slimefun blocks + // Delete any 3rd party blocks Location loc = new Location(chunk.getWorld(), baseX + x, y, baseZ + z); plugin.getHooks().getHook("Slimefun") .ifPresent(sf -> ((SlimefunHook) sf).clearBlockInfo(loc, true)); + plugin.getHooks().getHook("ItemsAdder") + .ifPresent(hook -> ((ItemsAdderHook) hook).clearBlockInfo(loc)); } } } diff --git a/src/main/java/world/bentobox/bentobox/nms/SimpleWorldRegenerator.java b/src/main/java/world/bentobox/bentobox/nms/SimpleWorldRegenerator.java index 218c72af7..418418b7f 100644 --- a/src/main/java/world/bentobox/bentobox/nms/SimpleWorldRegenerator.java +++ b/src/main/java/world/bentobox/bentobox/nms/SimpleWorldRegenerator.java @@ -22,6 +22,7 @@ import io.papermc.lib.PaperLib; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.database.objects.IslandDeletion; +import world.bentobox.bentobox.hooks.ItemsAdderHook; import world.bentobox.bentobox.hooks.SlimefunHook; import world.bentobox.bentobox.util.MyBiomeGrid; @@ -142,11 +143,12 @@ public abstract class SimpleWorldRegenerator implements WorldRegenerator { if (x % 4 == 0 && y % 4 == 0 && z % 4 == 0) { chunk.getBlock(x, y, z).setBiome(biomeGrid.getBiome(x, y, z)); } - // Delete any slimefun blocks + // Delete any 3rd party blocks Location loc = new Location(chunk.getWorld(), baseX + x, y, baseZ + z); - BentoBox.getInstance().logDebug(loc + " " + plugin.getHooks().getHook("Slimefun").isPresent()); plugin.getHooks().getHook("Slimefun") .ifPresent(sf -> ((SlimefunHook) sf).clearBlockInfo(loc, true)); + plugin.getHooks().getHook("ItemsAdder") + .ifPresent(hook -> ((ItemsAdderHook) hook).clearBlockInfo(loc)); } } }