Prevents more shenanigans
Prevents players from leashing entities in clear regions Removes all entities riding, being ridden by and leashed to a player when moving across clear region borders Adds bypass permissions for mob spawning and entity interaction Adds a debug option Splits listeners into three classes Prevents more shenanigans I've forgotten
This commit is contained in:
parent
487e2682c3
commit
282cc50df6
@ -1,9 +1,15 @@
|
|||||||
package net.knarcraft.clearonworldguard;
|
package net.knarcraft.clearonworldguard;
|
||||||
|
|
||||||
|
import net.knarcraft.clearonworldguard.config.Configuration;
|
||||||
|
import net.knarcraft.clearonworldguard.listener.BlockListener;
|
||||||
|
import net.knarcraft.clearonworldguard.listener.EntityListener;
|
||||||
|
import net.knarcraft.clearonworldguard.listener.PlayerListener;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,16 +19,21 @@ import java.util.logging.Logger;
|
|||||||
public final class ClearOnWorldGuard extends JavaPlugin {
|
public final class ClearOnWorldGuard extends JavaPlugin {
|
||||||
|
|
||||||
private static ClearOnWorldGuard instance;
|
private static ClearOnWorldGuard instance;
|
||||||
|
private boolean debugMode;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
instance = this;
|
instance = this;
|
||||||
this.saveDefaultConfig();
|
this.saveDefaultConfig();
|
||||||
this.reloadConfig();
|
this.reloadConfig();
|
||||||
FileConfiguration configuration = this.getConfig();
|
FileConfiguration fileConfiguration = this.getConfig();
|
||||||
|
|
||||||
// Register the WorldGuard listener
|
// Register the WorldGuard listener
|
||||||
Bukkit.getPluginManager().registerEvents(new WorldGuardListener(configuration), this);
|
Configuration configuration = new Configuration(fileConfiguration);
|
||||||
|
Bukkit.getPluginManager().registerEvents(new PlayerListener(configuration), this);
|
||||||
|
Bukkit.getPluginManager().registerEvents(new EntityListener(configuration), this);
|
||||||
|
Bukkit.getPluginManager().registerEvents(new BlockListener(configuration), this);
|
||||||
|
this.debugMode = configuration.debugEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,4 +45,26 @@ public final class ClearOnWorldGuard extends JavaPlugin {
|
|||||||
return instance.getLogger();
|
return instance.getLogger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a debug message
|
||||||
|
*
|
||||||
|
* @param message <p>The message to debug</p>
|
||||||
|
*/
|
||||||
|
public static void logDebugMessage(@NotNull String message) {
|
||||||
|
if (instance.debugMode) {
|
||||||
|
logger().log(Level.INFO, message);
|
||||||
|
} else {
|
||||||
|
logger().log(Level.FINEST, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an instance of this plugin
|
||||||
|
*
|
||||||
|
* @return <p>An instance of this plugin</p>
|
||||||
|
*/
|
||||||
|
public static ClearOnWorldGuard getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,506 +0,0 @@
|
|||||||
package net.knarcraft.clearonworldguard;
|
|
||||||
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
|
||||||
import com.sk89q.worldguard.WorldGuard;
|
|
||||||
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
|
||||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
|
||||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
|
||||||
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
|
||||||
import com.sk89q.worldguard.protection.regions.RegionQuery;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.block.Action;
|
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
|
||||||
import org.bukkit.event.block.BlockBurnEvent;
|
|
||||||
import org.bukkit.event.block.BlockDispenseArmorEvent;
|
|
||||||
import org.bukkit.event.block.BlockDispenseEvent;
|
|
||||||
import org.bukkit.event.block.BlockDropItemEvent;
|
|
||||||
import org.bukkit.event.block.BlockExpEvent;
|
|
||||||
import org.bukkit.event.block.BlockFormEvent;
|
|
||||||
import org.bukkit.event.block.BlockIgniteEvent;
|
|
||||||
import org.bukkit.event.block.BlockPistonExtendEvent;
|
|
||||||
import org.bukkit.event.block.BlockPistonRetractEvent;
|
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
|
||||||
import org.bukkit.event.block.BlockSpreadEvent;
|
|
||||||
import org.bukkit.event.block.TNTPrimeEvent;
|
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
|
||||||
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
|
||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
|
||||||
import org.bukkit.event.entity.EntityDeathEvent;
|
|
||||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
|
||||||
import org.bukkit.event.entity.EntityPickupItemEvent;
|
|
||||||
import org.bukkit.event.entity.ExplosionPrimeEvent;
|
|
||||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
|
||||||
import org.bukkit.event.entity.ProjectileLaunchEvent;
|
|
||||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
import org.bukkit.event.player.PlayerMoveEvent;
|
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
|
||||||
import org.bukkit.inventory.meta.SpawnEggMeta;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A listener that listens to players entering and leaving WorldGuard regions
|
|
||||||
*/
|
|
||||||
public class WorldGuardListener implements Listener {
|
|
||||||
|
|
||||||
private final RegionContainer regionContainer = WorldGuard.getInstance().getPlatform().getRegionContainer();
|
|
||||||
private final RegionQuery query = regionContainer.createQuery();
|
|
||||||
private final Map<World, Set<ProtectedRegion>> protectedRegions = new HashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instantiates a new WorldGuard listener
|
|
||||||
*/
|
|
||||||
public WorldGuardListener(@NotNull FileConfiguration configuration) {
|
|
||||||
ConfigurationSection worldsSection = configuration.getConfigurationSection("clearRegions");
|
|
||||||
if (worldsSection == null) {
|
|
||||||
ClearOnWorldGuard.logger().log(Level.WARNING, "Unable to find clearRegions sections in the " +
|
|
||||||
"configuration file!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Set<String> worlds = worldsSection.getKeys(false);
|
|
||||||
|
|
||||||
for (String worldId : worlds) {
|
|
||||||
// Parse every world identifier
|
|
||||||
World world;
|
|
||||||
try {
|
|
||||||
UUID worldUUID = UUID.fromString(worldId);
|
|
||||||
world = Bukkit.getWorld(worldUUID);
|
|
||||||
} catch (IllegalArgumentException exception) {
|
|
||||||
world = Bukkit.getWorld(worldId);
|
|
||||||
}
|
|
||||||
if (world == null) {
|
|
||||||
ClearOnWorldGuard.logger().log(Level.WARNING, "The specified world: \"" + worldId + "\" is invalid.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
loadRegions(world, worldsSection, worldId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads clear regions for a world
|
|
||||||
*
|
|
||||||
* @param world <p>The world to load regions for</p>
|
|
||||||
* @param worldsSection <p>The configuration section listing all worlds and regions</p>
|
|
||||||
* @param worldId <p>The user-specified identifier for the currently processed world</p>
|
|
||||||
*/
|
|
||||||
private void loadRegions(@NotNull World world, @NotNull ConfigurationSection worldsSection, @NotNull String worldId) {
|
|
||||||
// Get a region manager for the world
|
|
||||||
RegionManager regionManager = regionContainer.get(BukkitAdapter.adapt(world));
|
|
||||||
if (regionManager == null) {
|
|
||||||
ClearOnWorldGuard.logger().log(Level.WARNING, "Unable to get region manager for world: " +
|
|
||||||
world.getName());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<ProtectedRegion> regions = new HashSet<>();
|
|
||||||
List<String> regionNames = worldsSection.getStringList(worldId);
|
|
||||||
for (String regionName : regionNames) {
|
|
||||||
// Register the region if it's valid
|
|
||||||
ProtectedRegion region = regionManager.getRegion(regionName);
|
|
||||||
if (region == null) {
|
|
||||||
ClearOnWorldGuard.logger().log(Level.WARNING, "Region name " + regionName + " is invalid");
|
|
||||||
} else {
|
|
||||||
regions.add(region);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
protectedRegions.put(world, regions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
||||||
public void onMove(@NotNull PlayerMoveEvent event) {
|
|
||||||
if (event.getTo() == null || event.getFrom().getWorld() == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearIfClearRegionChange(event.getFrom(), event.getTo(), event.getPlayer());
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
|
||||||
public void onTeleport(@NotNull PlayerTeleportEvent event) {
|
|
||||||
Location fromLocation = event.getFrom();
|
|
||||||
Location toLocation = event.getTo();
|
|
||||||
|
|
||||||
if (toLocation == null || fromLocation.equals(toLocation)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
clearIfClearRegionChange(fromLocation, toLocation, event.getPlayer());
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onItemDrop(@NotNull PlayerDropItemEvent event) {
|
|
||||||
// Prevent a player from dropping an item while inside a clear region
|
|
||||||
if (isInClearRegion(event.getPlayer())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onXpBottle(@NotNull ProjectileLaunchEvent event) {
|
|
||||||
// Prevent a player from using an XP bottle in a clear region
|
|
||||||
if (isInClearRegion(event.getEntity())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onTNT(@NotNull TNTPrimeEvent event) {
|
|
||||||
// Prevent TNT from being primed in a clear region, or by a player in a clear region
|
|
||||||
Entity primingEntity = event.getPrimingEntity();
|
|
||||||
if (primingEntity != null && isInClearRegion(primingEntity)) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Block primingBlock = event.getPrimingBlock();
|
|
||||||
if (primingBlock != null && isInClearRegion(primingBlock)) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onBlockPlace(@NotNull BlockPlaceEvent event) {
|
|
||||||
// Prevent placing a block outside a clear region
|
|
||||||
if (isInDifferentClearRegions(event.getPlayer().getLocation(), event.getBlockPlaced().getLocation())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onBlockBreak(@NotNull BlockBreakEvent event) {
|
|
||||||
// Prevent breaking a block outside a clear region, while in the clear region
|
|
||||||
if (isInDifferentClearRegions(event.getPlayer().getLocation(), event.getBlock().getLocation())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevent item drops when the item is destroyed
|
|
||||||
if (isInClearRegion(event.getBlock())) {
|
|
||||||
event.setDropItems(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onExplosionPrime(@NotNull ExplosionPrimeEvent event) {
|
|
||||||
Location location = event.getEntity().getLocation();
|
|
||||||
float radius = event.getRadius();
|
|
||||||
if (isInClearRegion(location) ||
|
|
||||||
isInClearRegion(location.clone().add(radius, radius, radius)) ||
|
|
||||||
isInClearRegion(location.clone().add(-radius, radius, radius)) ||
|
|
||||||
isInClearRegion(location.clone().add(-radius, radius, -radius)) ||
|
|
||||||
isInClearRegion(location.clone().add(radius, radius, -radius)) ||
|
|
||||||
isInClearRegion(location.clone().add(radius, -radius, radius)) ||
|
|
||||||
isInClearRegion(location.clone().add(-radius, -radius, radius)) ||
|
|
||||||
isInClearRegion(location.clone().add(-radius, -radius, -radius)) ||
|
|
||||||
isInClearRegion(location.clone().add(radius, -radius, -radius))) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
event.getEntity().remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onEntityExplode(@NotNull EntityExplodeEvent event) {
|
|
||||||
// Prevent explosions in clear regions
|
|
||||||
if (isInClearRegion(event.getEntity())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onEntityChangeBlock(@NotNull EntityChangeBlockEvent event) {
|
|
||||||
// Prevent entities from changing blocks in clear regions
|
|
||||||
if (isInClearRegion(event.getBlock())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onCreatureSpawn(@NotNull CreatureSpawnEvent event) {
|
|
||||||
// Prevent creatures from spawning
|
|
||||||
if (isInClearRegion(event.getLocation()) && event.getEntityType() != EntityType.ARMOR_STAND) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onBlockItemDrop(@NotNull BlockDropItemEvent event) {
|
|
||||||
// Block item drops for indirectly destroyed items
|
|
||||||
if (isInClearRegion(event.getBlock())) {
|
|
||||||
event.getItems().clear();
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
|
||||||
public void onBlockXP(@NotNull BlockExpEvent event) {
|
|
||||||
// Prevent dropping XP in clear regions
|
|
||||||
if (isInClearRegion(event.getBlock())) {
|
|
||||||
event.setExpToDrop(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onEntityDamage(@NotNull EntityDamageEvent event) {
|
|
||||||
// Prevent entity damage in clear regions
|
|
||||||
if (isInClearRegion(event.getEntity())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onDeath(@NotNull EntityDeathEvent event) {
|
|
||||||
// Prevent mob loot and XP
|
|
||||||
if (isInClearRegion(event.getEntity())) {
|
|
||||||
event.setDroppedExp(0);
|
|
||||||
event.getDrops().clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onDispense(@NotNull BlockDispenseEvent event) {
|
|
||||||
// Prevent dispensers from dispensing and droppers from dropping
|
|
||||||
if (isInClearRegion(event.getBlock())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onArmorDispense(@NotNull BlockDispenseArmorEvent event) {
|
|
||||||
// Prevent dispensers from dispensing armors in clear regions
|
|
||||||
if (isInClearRegion(event.getBlock())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onBurn(@NotNull BlockBurnEvent event) {
|
|
||||||
// Prevent blocks from burning in clear areas
|
|
||||||
Block block = event.getBlock();
|
|
||||||
if (isInClearRegion(block)) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onIgnite(@NotNull BlockIgniteEvent event) {
|
|
||||||
// Prevent ignition in clear areas, unless done by flint and steel
|
|
||||||
Block block = event.getBlock();
|
|
||||||
if (isInClearRegion(block) && event.getCause() != BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
|
||||||
public void onDeath(@NotNull PlayerDeathEvent event) {
|
|
||||||
// Prevent deaths in clear regions from causing items to be kept or dropped
|
|
||||||
if (isInClearRegion(event.getEntity())) {
|
|
||||||
event.setKeepInventory(false);
|
|
||||||
event.setKeepLevel(true);
|
|
||||||
event.getEntity().getInventory().clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onItemPickup(@NotNull EntityPickupItemEvent event) {
|
|
||||||
// Prevent item pickup in clear regions
|
|
||||||
if (!(event.getEntity() instanceof Player player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isInClearRegion(player)) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onBlockSpread(@NotNull BlockSpreadEvent event) {
|
|
||||||
// Prevent block spread in clear regions
|
|
||||||
if (isInClearRegion(event.getSource())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onBlockForm(@NotNull BlockFormEvent event) {
|
|
||||||
// Prevent block forming in clear regions
|
|
||||||
if (isInClearRegion(event.getBlock())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onPistonExtend(@NotNull BlockPistonExtendEvent event) {
|
|
||||||
// Prevent pistons from pushing blocks across the clear region border
|
|
||||||
Block piston = event.getBlock();
|
|
||||||
List<Block> blocks = event.getBlocks();
|
|
||||||
for (Block block : blocks) {
|
|
||||||
if (isInDifferentClearRegions(piston.getLocation(), block.getLocation())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onPistonRetract(@NotNull BlockPistonRetractEvent event) {
|
|
||||||
// Prevent pistons from pulling blocks across the clear region border
|
|
||||||
Block piston = event.getBlock();
|
|
||||||
List<Block> blocks = event.getBlocks();
|
|
||||||
for (Block block : blocks) {
|
|
||||||
if (isInDifferentClearRegions(piston.getLocation(), block.getLocation())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
public void onInteract(@NotNull PlayerInteractEvent event) {
|
|
||||||
// Prevent interacting with blocks outside the clear region, such as chests
|
|
||||||
Block clicked = event.getClickedBlock();
|
|
||||||
if (clicked != null && isInDifferentClearRegions(event.getPlayer().getLocation(), clicked.getLocation())) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Block changing the creature in a spawner
|
|
||||||
if (event.getAction() == Action.RIGHT_CLICK_BLOCK && clicked != null && clicked.getType() == Material.SPAWNER &&
|
|
||||||
isInClearRegion(clicked)) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Block usage of spawn eggs
|
|
||||||
ItemStack item = event.getItem();
|
|
||||||
if (item != null && isInClearRegion(event.getPlayer()) && item.hasItemMeta()) {
|
|
||||||
ItemMeta meta = event.getItem().getItemMeta();
|
|
||||||
if (meta instanceof SpawnEggMeta) {
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the given player's inventory if they are leaving or entering a clear region
|
|
||||||
*
|
|
||||||
* @param fromLocation <p>The location the player moved or teleported from</p>
|
|
||||||
* @param toLocation <p>The location the player moved or teleported to</p>
|
|
||||||
* @param player <p>The player that's moving</p>
|
|
||||||
*/
|
|
||||||
private void clearIfClearRegionChange(@NotNull Location fromLocation, @NotNull Location toLocation,
|
|
||||||
@NotNull Player player) {
|
|
||||||
if (isInDifferentClearRegions(fromLocation, toLocation)) {
|
|
||||||
player.getInventory().clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the given locations are in different clear regions
|
|
||||||
*
|
|
||||||
* <p>If location1 is in a clear region and location2 is not, or if location1 is in a different clear region than
|
|
||||||
* region2, or if region 1 is in an additional clear region, this will return true.</p>
|
|
||||||
*
|
|
||||||
* @param location1 <p>The first location to check</p>
|
|
||||||
* @param location2 <p>The second location to check</p>
|
|
||||||
* @return <p>True if the two locations are in different clear regions</p>
|
|
||||||
*/
|
|
||||||
private boolean isInDifferentClearRegions(@NotNull Location location1, @NotNull Location location2) {
|
|
||||||
World fromWorld = location1.getWorld();
|
|
||||||
if (fromWorld == null) {
|
|
||||||
ClearOnWorldGuard.logger().log(Level.WARNING, "Unable to check region change, as location " +
|
|
||||||
location1 + " has no world.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ApplicableRegionSet setFrom = query.getApplicableRegions(BukkitAdapter.adapt(location1));
|
|
||||||
ApplicableRegionSet setTo = query.getApplicableRegions(BukkitAdapter.adapt(location2));
|
|
||||||
|
|
||||||
Set<ProtectedRegion> fromRegions = getOccupiedClearRegions(fromWorld, setFrom.getRegions());
|
|
||||||
Set<ProtectedRegion> toRegions = getOccupiedClearRegions(fromWorld, setTo.getRegions());
|
|
||||||
|
|
||||||
// If the player is in one or more clear regions, clear unless the clear regions are the same
|
|
||||||
return (!fromRegions.isEmpty() || !toRegions.isEmpty()) && !fromRegions.equals(toRegions);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the given block is in a clear region
|
|
||||||
*
|
|
||||||
* @param entity <p>The entity to check</p>
|
|
||||||
* @return <p>True if the block is in a clear region</p>
|
|
||||||
*/
|
|
||||||
private boolean isInClearRegion(@NotNull Entity entity) {
|
|
||||||
return isInClearRegion(entity.getLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the given block is in a clear region
|
|
||||||
*
|
|
||||||
* @param block <p>The block to check</p>
|
|
||||||
* @return <p>True if the block is in a clear region</p>
|
|
||||||
*/
|
|
||||||
private boolean isInClearRegion(@NotNull Block block) {
|
|
||||||
return isInClearRegion(block.getLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the given location is in a clear region
|
|
||||||
*
|
|
||||||
* @param location <p>The location to check</p>
|
|
||||||
* @return <p>True if the location is in a clear region</p>
|
|
||||||
*/
|
|
||||||
private boolean isInClearRegion(@NotNull Location location) {
|
|
||||||
World playerWorld = location.getWorld();
|
|
||||||
if (playerWorld == null) {
|
|
||||||
ClearOnWorldGuard.logger().log(Level.WARNING, "Unable to check region change, as location " +
|
|
||||||
location + " has no world.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ApplicableRegionSet setFrom = query.getApplicableRegions(BukkitAdapter.adapt(location));
|
|
||||||
Set<ProtectedRegion> fromRegions = getOccupiedClearRegions(playerWorld, setFrom.getRegions());
|
|
||||||
return !fromRegions.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all regions set as clear regions the player currently occupies
|
|
||||||
*
|
|
||||||
* @param playerWorld <p>The world the player is currently in</p>
|
|
||||||
* @param playerRegions <p>The regions the player is in or will be in</p>
|
|
||||||
* @return <p>All clear regions found in playerRegions</p>
|
|
||||||
*/
|
|
||||||
private Set<ProtectedRegion> getOccupiedClearRegions(@NotNull World playerWorld,
|
|
||||||
@NotNull Set<ProtectedRegion> playerRegions) {
|
|
||||||
Set<ProtectedRegion> possibleRegions = protectedRegions.get(playerWorld);
|
|
||||||
Set<ProtectedRegion> result = new HashSet<>();
|
|
||||||
for (ProtectedRegion region : playerRegions) {
|
|
||||||
if (possibleRegions.contains(region)) {
|
|
||||||
result.add(region);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,124 @@
|
|||||||
|
package net.knarcraft.clearonworldguard.config;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import com.sk89q.worldguard.WorldGuard;
|
||||||
|
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||||
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||||
|
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
||||||
|
import com.sk89q.worldguard.protection.regions.RegionQuery;
|
||||||
|
import net.knarcraft.clearonworldguard.ClearOnWorldGuard;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A configuration that keeps track of loaded clear regions
|
||||||
|
*/
|
||||||
|
public class Configuration {
|
||||||
|
|
||||||
|
private final RegionContainer regionContainer = WorldGuard.getInstance().getPlatform().getRegionContainer();
|
||||||
|
private final RegionQuery regionQuery = regionContainer.createQuery();
|
||||||
|
private final Map<World, Set<ProtectedRegion>> protectedRegions = new HashMap<>();
|
||||||
|
private final boolean debugEnabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new configuration
|
||||||
|
*
|
||||||
|
* @param configuration <p>The file configuration to read</p>
|
||||||
|
*/
|
||||||
|
public Configuration(@NotNull FileConfiguration configuration) {
|
||||||
|
debugEnabled = Boolean.parseBoolean(configuration.getString("debug"));
|
||||||
|
ConfigurationSection worldsSection = configuration.getConfigurationSection("clearRegions");
|
||||||
|
if (worldsSection == null) {
|
||||||
|
ClearOnWorldGuard.logger().log(Level.WARNING, "Unable to find clearRegions sections in the " +
|
||||||
|
"configuration file!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Set<String> worlds = worldsSection.getKeys(false);
|
||||||
|
|
||||||
|
for (String worldId : worlds) {
|
||||||
|
// Parse every world identifier
|
||||||
|
World world;
|
||||||
|
try {
|
||||||
|
UUID worldUUID = UUID.fromString(worldId);
|
||||||
|
world = Bukkit.getWorld(worldUUID);
|
||||||
|
} catch (IllegalArgumentException exception) {
|
||||||
|
world = Bukkit.getWorld(worldId);
|
||||||
|
}
|
||||||
|
if (world == null) {
|
||||||
|
ClearOnWorldGuard.logger().log(Level.WARNING, "The specified world: \"" + worldId + "\" is invalid.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadRegions(world, worldsSection, worldId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads clear regions for a world
|
||||||
|
*
|
||||||
|
* @param world <p>The world to load regions for</p>
|
||||||
|
* @param worldsSection <p>The configuration section listing all worlds and regions</p>
|
||||||
|
* @param worldId <p>The user-specified identifier for the currently processed world</p>
|
||||||
|
*/
|
||||||
|
private void loadRegions(@NotNull World world, @NotNull ConfigurationSection worldsSection, @NotNull String worldId) {
|
||||||
|
// Get a region manager for the world
|
||||||
|
RegionManager regionManager = regionContainer.get(BukkitAdapter.adapt(world));
|
||||||
|
if (regionManager == null) {
|
||||||
|
ClearOnWorldGuard.logger().log(Level.WARNING, "Unable to get region manager for world: " +
|
||||||
|
world.getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<ProtectedRegion> regions = new HashSet<>();
|
||||||
|
List<String> regionNames = worldsSection.getStringList(worldId);
|
||||||
|
for (String regionName : regionNames) {
|
||||||
|
// Register the region if it's valid
|
||||||
|
ProtectedRegion region = regionManager.getRegion(regionName);
|
||||||
|
if (region == null) {
|
||||||
|
ClearOnWorldGuard.logger().log(Level.WARNING, "Region name " + regionName + " is invalid");
|
||||||
|
} else {
|
||||||
|
regions.add(region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
protectedRegions.put(world, regions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all protected regions for the given world
|
||||||
|
*
|
||||||
|
* @return <p>All protected regions for the given world</p>
|
||||||
|
*/
|
||||||
|
public @NotNull Set<ProtectedRegion> getProtectedRegions(@NotNull World world) {
|
||||||
|
return this.protectedRegions.get(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a region query
|
||||||
|
*
|
||||||
|
* @return <p>A region query</p>
|
||||||
|
*/
|
||||||
|
public @NotNull RegionQuery getRegionQuery() {
|
||||||
|
return regionQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether debug mode is enabled
|
||||||
|
*
|
||||||
|
* @return <p>True if debug mode is enabled</p>
|
||||||
|
*/
|
||||||
|
public boolean debugEnabled() {
|
||||||
|
return this.debugEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,183 @@
|
|||||||
|
package net.knarcraft.clearonworldguard.listener;
|
||||||
|
|
||||||
|
import net.knarcraft.clearonworldguard.ClearOnWorldGuard;
|
||||||
|
import net.knarcraft.clearonworldguard.config.Configuration;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.event.block.BlockBurnEvent;
|
||||||
|
import org.bukkit.event.block.BlockDispenseArmorEvent;
|
||||||
|
import org.bukkit.event.block.BlockDispenseEvent;
|
||||||
|
import org.bukkit.event.block.BlockDropItemEvent;
|
||||||
|
import org.bukkit.event.block.BlockExpEvent;
|
||||||
|
import org.bukkit.event.block.BlockFormEvent;
|
||||||
|
import org.bukkit.event.block.BlockIgniteEvent;
|
||||||
|
import org.bukkit.event.block.BlockPistonExtendEvent;
|
||||||
|
import org.bukkit.event.block.BlockPistonRetractEvent;
|
||||||
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
import org.bukkit.event.block.BlockSpreadEvent;
|
||||||
|
import org.bukkit.event.block.TNTPrimeEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listeners for block events
|
||||||
|
*/
|
||||||
|
public class BlockListener extends WorldGuardListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new WorldGuard listener
|
||||||
|
*
|
||||||
|
* @param configuration <p>The configuration to get regions and settings from</p>
|
||||||
|
*/
|
||||||
|
public BlockListener(@NotNull Configuration configuration) {
|
||||||
|
super(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onBlockItemDrop(@NotNull BlockDropItemEvent event) {
|
||||||
|
// Block item drops for indirectly destroyed items
|
||||||
|
if (isInClearRegion(event.getBlock())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented block " + event.getBlock() + " from dropping as an item");
|
||||||
|
event.getItems().clear();
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void onBlockXP(@NotNull BlockExpEvent event) {
|
||||||
|
// Prevent dropping XP in clear regions
|
||||||
|
if (isInClearRegion(event.getBlock())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented block " + event.getBlock() + " from dropping any XP");
|
||||||
|
event.setExpToDrop(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onDispense(@NotNull BlockDispenseEvent event) {
|
||||||
|
// Prevent dispensers from dispensing and droppers from dropping
|
||||||
|
if (isInClearRegion(event.getBlock())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented dispenser " + event.getBlock() + " from dispensing");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onArmorDispense(@NotNull BlockDispenseArmorEvent event) {
|
||||||
|
// Prevent dispensers from dispensing armors in clear regions
|
||||||
|
if (isInClearRegion(event.getBlock())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented armor from dispensing from " + event.getBlock());
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onBurn(@NotNull BlockBurnEvent event) {
|
||||||
|
// Prevent blocks from burning in clear areas
|
||||||
|
Block block = event.getBlock();
|
||||||
|
if (isInClearRegion(block)) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented block " + event.getBlock() + " from burning");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onIgnite(@NotNull BlockIgniteEvent event) {
|
||||||
|
// Prevent ignition in clear areas, unless done by flint and steel
|
||||||
|
Block block = event.getBlock();
|
||||||
|
if (isInClearRegion(block) && event.getCause() != BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented block " + event.getBlock() + " from igniting");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onBlockSpread(@NotNull BlockSpreadEvent event) {
|
||||||
|
// Prevent block spread in clear regions
|
||||||
|
if (isInClearRegion(event.getSource())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented block " + event.getBlock() + " from spreading");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onBlockForm(@NotNull BlockFormEvent event) {
|
||||||
|
// Prevent block forming in clear regions
|
||||||
|
if (isInClearRegion(event.getBlock())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented block " + event.getBlock() + " from forming");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onPistonExtend(@NotNull BlockPistonExtendEvent event) {
|
||||||
|
// Prevent pistons from pushing blocks across the clear region border
|
||||||
|
Block piston = event.getBlock();
|
||||||
|
List<Block> blocks = event.getBlocks();
|
||||||
|
for (Block block : blocks) {
|
||||||
|
if (isInDifferentClearRegions(piston.getLocation(), block.getLocation())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented piston " + piston + " from extending");
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onPistonRetract(@NotNull BlockPistonRetractEvent event) {
|
||||||
|
// Prevent pistons from pulling blocks across the clear region border
|
||||||
|
Block piston = event.getBlock();
|
||||||
|
List<Block> blocks = event.getBlocks();
|
||||||
|
for (Block block : blocks) {
|
||||||
|
if (isInDifferentClearRegions(piston.getLocation(), block.getLocation())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented piston " + piston + " from retracting");
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onBlockPlace(@NotNull BlockPlaceEvent event) {
|
||||||
|
// Prevent placing a block outside a clear region
|
||||||
|
if (isInDifferentClearRegions(event.getPlayer().getLocation(), event.getBlockPlaced().getLocation())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented block " + event.getBlock() + " from being placed");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onBlockBreak(@NotNull BlockBreakEvent event) {
|
||||||
|
// Prevent breaking a block outside a clear region, while in the clear region
|
||||||
|
Block block = event.getBlock();
|
||||||
|
if (isInDifferentClearRegions(event.getPlayer().getLocation(), block.getLocation())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented block " + block + " from being broken");
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent item drops when the item is destroyed
|
||||||
|
if (isInClearRegion(block)) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented block " + block + " from dropping items");
|
||||||
|
event.setDropItems(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onTNT(@NotNull TNTPrimeEvent event) {
|
||||||
|
// Prevent TNT from being primed in a clear region, or by a player in a clear region
|
||||||
|
Entity primingEntity = event.getPrimingEntity();
|
||||||
|
Block block = event.getBlock();
|
||||||
|
Block primingBlock = event.getPrimingBlock();
|
||||||
|
if ((primingEntity != null && isInClearRegion(primingEntity)) || isInClearRegion(block) ||
|
||||||
|
(primingBlock != null && isInClearRegion(primingBlock))) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented TNT " + event.getBlock() + " from being primed by entity " +
|
||||||
|
primingEntity + " or block " + primingBlock);
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,192 @@
|
|||||||
|
package net.knarcraft.clearonworldguard.listener;
|
||||||
|
|
||||||
|
import net.knarcraft.clearonworldguard.ClearOnWorldGuard;
|
||||||
|
import net.knarcraft.clearonworldguard.config.Configuration;
|
||||||
|
import net.knarcraft.clearonworldguard.property.Permission;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.entity.Vehicle;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
import org.bukkit.event.entity.EntityChangeBlockEvent;
|
||||||
|
import org.bukkit.event.entity.EntityCombustEvent;
|
||||||
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
|
import org.bukkit.event.entity.EntityDeathEvent;
|
||||||
|
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||||
|
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||||
|
import org.bukkit.event.entity.ExplosionPrimeEvent;
|
||||||
|
import org.bukkit.event.entity.ProjectileLaunchEvent;
|
||||||
|
import org.bukkit.event.vehicle.VehicleDestroyEvent;
|
||||||
|
import org.bukkit.event.vehicle.VehicleMoveEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.spigotmc.event.entity.EntityMountEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listeners for entity events
|
||||||
|
*/
|
||||||
|
public class EntityListener extends WorldGuardListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new WorldGuard listener
|
||||||
|
*
|
||||||
|
* @param configuration <p>The configuration to get regions and settings from</p>
|
||||||
|
*/
|
||||||
|
public EntityListener(@NotNull Configuration configuration) {
|
||||||
|
super(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onEntityExplode(@NotNull EntityExplodeEvent event) {
|
||||||
|
// Prevent explosions in clear regions
|
||||||
|
if (isInClearRegion(event.getEntity())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented entity " + event.getEntity() + " from exploding");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onEntityMount(@NotNull EntityMountEvent event) {
|
||||||
|
// Prevent entity mounting in clear regions
|
||||||
|
Entity entity = event.getEntity();
|
||||||
|
Entity mount = event.getMount();
|
||||||
|
|
||||||
|
// Don't restrict NPCs
|
||||||
|
if (entity instanceof Player player && player.hasMetadata("NPC")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((isInClearRegion(entity) || isInClearRegion(mount)) &&
|
||||||
|
!entity.hasPermission(Permission.BYPASS_ENTITY_INTERACTION.toString())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented entity " + entity + " from mounting " + mount);
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onEntityChangeBlock(@NotNull EntityChangeBlockEvent event) {
|
||||||
|
// Prevent entities from changing blocks in clear regions
|
||||||
|
if (isInClearRegion(event.getBlock())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented entity " + event.getEntity() + " from changing the block " +
|
||||||
|
event.getBlock());
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onCreatureSpawn(@NotNull CreatureSpawnEvent event) {
|
||||||
|
// Prevent creatures from spawning, unless it's intentional
|
||||||
|
CreatureSpawnEvent.SpawnReason spawnReason = event.getSpawnReason();
|
||||||
|
if (isInClearRegion(event.getLocation()) && (event.getEntityType() != EntityType.ARMOR_STAND &&
|
||||||
|
spawnReason != CreatureSpawnEvent.SpawnReason.COMMAND) &&
|
||||||
|
spawnReason != CreatureSpawnEvent.SpawnReason.SPAWNER_EGG
|
||||||
|
) {
|
||||||
|
if (spawnReason != CreatureSpawnEvent.SpawnReason.NATURAL &&
|
||||||
|
spawnReason != CreatureSpawnEvent.SpawnReason.BEEHIVE) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented creature " + event.getEntity() + " from spawning with " +
|
||||||
|
"spawn reason " + event.getSpawnReason());
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onEntityDamage(@NotNull EntityDamageByEntityEvent event) {
|
||||||
|
// Prevent entity damage from players in clear regions
|
||||||
|
if (!(event.getDamager() instanceof Player player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((isInClearRegion(event.getEntity()) || isInClearRegion(player)) &&
|
||||||
|
!player.hasPermission(Permission.BYPASS_ENTITY_INTERACTION.toString())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented entity " + event.getEntity() + " from being damaged");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onEntityDeath(@NotNull EntityDeathEvent event) {
|
||||||
|
// Prevent mob loot and XP
|
||||||
|
if (isInClearRegion(event.getEntity())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented entity " + event.getEntity() + " from dropping items");
|
||||||
|
event.setDroppedExp(0);
|
||||||
|
event.getDrops().clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onItemPickup(@NotNull EntityPickupItemEvent event) {
|
||||||
|
// Prevent item pickup in clear regions
|
||||||
|
if (isInClearRegion(event.getEntity())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented entity " + event.getEntity() + " from picking up an item");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onVehicleDestroy(@NotNull VehicleDestroyEvent event) {
|
||||||
|
// Prevent destroyed vehicles from dropping as items
|
||||||
|
if (isInClearRegion(event.getVehicle())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented vehicle " + event.getVehicle() + " from dropping as an item");
|
||||||
|
event.setCancelled(true);
|
||||||
|
clearInventoriesAndRemoveRecursively(event.getVehicle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void onVehicleMove(@NotNull VehicleMoveEvent event) {
|
||||||
|
// Prevent chest minecarts or similar from leaving the clear region
|
||||||
|
if (event.getFrom().equals(event.getTo())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vehicle vehicle = event.getVehicle();
|
||||||
|
|
||||||
|
if (isInDifferentClearRegions(event.getFrom(), event.getTo())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Destroyed vehicle " + vehicle + " crossing a clear region border");
|
||||||
|
clearInventoriesAndRemoveRecursively(vehicle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onProjectileLaunch(@NotNull ProjectileLaunchEvent event) {
|
||||||
|
// Prevent a player from using an XP bottle in a clear region
|
||||||
|
if (isInClearRegion(event.getEntity())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented projectile " + event.getEntity());
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onExplosionPrime(@NotNull ExplosionPrimeEvent event) {
|
||||||
|
// Prevent explosion from priming if any exploded blocks are in a clear region
|
||||||
|
Location location = event.getEntity().getLocation();
|
||||||
|
float radius = event.getRadius();
|
||||||
|
if (isInClearRegion(location) ||
|
||||||
|
isInClearRegion(location.clone().add(radius, radius, radius)) ||
|
||||||
|
isInClearRegion(location.clone().add(-radius, radius, radius)) ||
|
||||||
|
isInClearRegion(location.clone().add(-radius, radius, -radius)) ||
|
||||||
|
isInClearRegion(location.clone().add(radius, radius, -radius)) ||
|
||||||
|
isInClearRegion(location.clone().add(radius, -radius, radius)) ||
|
||||||
|
isInClearRegion(location.clone().add(-radius, -radius, radius)) ||
|
||||||
|
isInClearRegion(location.clone().add(-radius, -radius, -radius)) ||
|
||||||
|
isInClearRegion(location.clone().add(radius, -radius, -radius))) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented " + event.getEntity() + " from being primed");
|
||||||
|
event.setCancelled(true);
|
||||||
|
event.getEntity().remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onCombust(@NotNull EntityCombustEvent event) {
|
||||||
|
// Prevent entities in clear regions from being put on fire
|
||||||
|
if (isInClearRegion(event.getEntity())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented " + event.getEntity() + " from combusting");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,147 @@
|
|||||||
|
package net.knarcraft.clearonworldguard.listener;
|
||||||
|
|
||||||
|
import net.knarcraft.clearonworldguard.ClearOnWorldGuard;
|
||||||
|
import net.knarcraft.clearonworldguard.config.Configuration;
|
||||||
|
import net.knarcraft.clearonworldguard.property.Permission;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
|
import org.bukkit.event.entity.PlayerLeashEntityEvent;
|
||||||
|
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.inventory.meta.SpawnEggMeta;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listeners for player events
|
||||||
|
*/
|
||||||
|
public class PlayerListener extends WorldGuardListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new WorldGuard listener
|
||||||
|
*
|
||||||
|
* @param configuration <p>The configuration to get regions and settings from</p>
|
||||||
|
*/
|
||||||
|
public PlayerListener(@NotNull Configuration configuration) {
|
||||||
|
super(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onLeash(@NotNull PlayerLeashEntityEvent event) {
|
||||||
|
// Prevent leashing of entities while in a clear region
|
||||||
|
if (isInClearRegion(event.getPlayer()) &&
|
||||||
|
!event.getPlayer().hasPermission(Permission.BYPASS_ENTITY_INTERACTION.toString())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented " + event.getEntity() + " from being leashed by " +
|
||||||
|
event.getPlayer());
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onMove(@NotNull PlayerMoveEvent event) {
|
||||||
|
Location from = event.getFrom();
|
||||||
|
Location to = event.getTo();
|
||||||
|
if (to == null || from.getWorld() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
// Prevent player from smuggling items in a chest boat or similar
|
||||||
|
if (isInDifferentClearRegions(from, to)) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Cleared items and vehicles of player " + player);
|
||||||
|
clearInventoriesAndRemoveRecursively(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
|
public void onTeleport(@NotNull PlayerTeleportEvent event) {
|
||||||
|
Location fromLocation = event.getFrom();
|
||||||
|
Location toLocation = event.getTo();
|
||||||
|
|
||||||
|
if (toLocation == null || fromLocation.equals(toLocation)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clearIfClearRegionChange(fromLocation, toLocation, event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onItemDrop(@NotNull PlayerDropItemEvent event) {
|
||||||
|
// Prevent a player from dropping an item while inside a clear region
|
||||||
|
if (isInClearRegion(event.getPlayer())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented player " + event.getPlayer() + " from dropping an item");
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
public void onPlayerDeath(@NotNull PlayerDeathEvent event) {
|
||||||
|
// Prevent deaths in clear regions from causing items to be kept or dropped
|
||||||
|
if (isInClearRegion(event.getEntity())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented player " + event.getEntity() + " from dropping or keeping " +
|
||||||
|
"items on death");
|
||||||
|
event.setKeepInventory(false);
|
||||||
|
event.setKeepLevel(true);
|
||||||
|
event.getEntity().getInventory().clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onInteract(@NotNull PlayerInteractEvent event) {
|
||||||
|
// Prevent interacting with blocks outside the clear region, such as chests
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
Block clicked = event.getClickedBlock();
|
||||||
|
if (clicked != null && isInDifferentClearRegions(player.getLocation(), clicked.getLocation())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented player " + player + " from interacting across a clear" +
|
||||||
|
" region border");
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block changing the creature in a spawner
|
||||||
|
if (event.getAction() == Action.RIGHT_CLICK_BLOCK && clicked != null && clicked.getType() == Material.SPAWNER &&
|
||||||
|
isInClearRegion(clicked) && !player.hasPermission(Permission.BYPASS_MOB_SPAWNING.toString())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented player " + player + " from interacting with mob spawner " +
|
||||||
|
clicked);
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block usage of spawn eggs
|
||||||
|
ItemStack item = event.getItem();
|
||||||
|
if (item != null && isInClearRegion(player) && item.hasItemMeta()) {
|
||||||
|
ItemMeta meta = event.getItem().getItemMeta();
|
||||||
|
if (meta instanceof SpawnEggMeta && !player.hasPermission(Permission.BYPASS_MOB_SPAWNING.toString())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented player " + player + " from using the spawn egg " + item);
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
public void onEntityInteract(@NotNull PlayerInteractEntityEvent event) {
|
||||||
|
// Allow interactions with human NPCs
|
||||||
|
if (event.getRightClicked() instanceof HumanEntity && !(event.getRightClicked() instanceof Player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prevent entity interaction, such as trading or putting chests on donkeys
|
||||||
|
if ((isInClearRegion(event.getPlayer()) || isInClearRegion(event.getRightClicked())) &&
|
||||||
|
!event.getPlayer().hasPermission(Permission.BYPASS_ENTITY_INTERACTION.toString())) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Prevented player " + event.getPlayer() +
|
||||||
|
" from interacting with entity " + event.getRightClicked());
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,194 @@
|
|||||||
|
package net.knarcraft.clearonworldguard.listener;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
|
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||||
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||||
|
import net.knarcraft.clearonworldguard.ClearOnWorldGuard;
|
||||||
|
import net.knarcraft.clearonworldguard.config.Configuration;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Creature;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A listener that listens to players entering and leaving WorldGuard regions
|
||||||
|
*/
|
||||||
|
public abstract class WorldGuardListener implements Listener {
|
||||||
|
|
||||||
|
private final Configuration configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new WorldGuard listener
|
||||||
|
*
|
||||||
|
* @param configuration <p>The configuration to get regions and settings from</p>
|
||||||
|
*/
|
||||||
|
public WorldGuardListener(@NotNull Configuration configuration) {
|
||||||
|
this.configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively clears and removes entities connected together
|
||||||
|
*
|
||||||
|
* @param startEntity <p>The entity to start with</p>
|
||||||
|
*/
|
||||||
|
protected void clearInventoriesAndRemoveRecursively(@NotNull Entity startEntity) {
|
||||||
|
List<Entity> processed = new ArrayList<>();
|
||||||
|
Queue<Entity> queue = new LinkedList<>();
|
||||||
|
queue.add(startEntity);
|
||||||
|
|
||||||
|
while (!queue.isEmpty()) {
|
||||||
|
Entity entity = queue.remove();
|
||||||
|
// Prevent duplicate processing
|
||||||
|
if (processed.contains(entity)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queue the entity's vehicle
|
||||||
|
if (entity.isInsideVehicle()) {
|
||||||
|
queue.add(entity.getVehicle());
|
||||||
|
}
|
||||||
|
// Queue the entity's passengers
|
||||||
|
queue.addAll(entity.getPassengers());
|
||||||
|
|
||||||
|
// Add any nearby creatures leashed to the entity
|
||||||
|
Collection<Entity> nearbyEntities = entity.getWorld().getNearbyEntities(entity.getLocation(), 10, 10, 10);
|
||||||
|
for (Entity nearby : nearbyEntities) {
|
||||||
|
if (nearby instanceof Creature creature && creature.isLeashed() && creature.getLeashHolder().equals(entity)) {
|
||||||
|
queue.add(nearby);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear inventory if necessary
|
||||||
|
if (entity instanceof InventoryHolder inventoryHolder) {
|
||||||
|
inventoryHolder.getInventory().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
processed.add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eject and remove every entity
|
||||||
|
for (Entity entity : processed) {
|
||||||
|
if (!(entity instanceof Player)) {
|
||||||
|
entity.eject();
|
||||||
|
entity.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the given player's inventory if they are leaving or entering a clear region
|
||||||
|
*
|
||||||
|
* @param fromLocation <p>The location the player moved or teleported from</p>
|
||||||
|
* @param toLocation <p>The location the player moved or teleported to</p>
|
||||||
|
* @param player <p>The player that's moving</p>
|
||||||
|
*/
|
||||||
|
protected void clearIfClearRegionChange(@NotNull Location fromLocation, @NotNull Location toLocation,
|
||||||
|
@NotNull Player player) {
|
||||||
|
if (isInDifferentClearRegions(fromLocation, toLocation)) {
|
||||||
|
ClearOnWorldGuard.logDebugMessage("Cleared inventory of player " + player);
|
||||||
|
player.getInventory().clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given locations are in different clear regions
|
||||||
|
*
|
||||||
|
* <p>If location1 is in a clear region and location2 is not, or if location1 is in a different clear region than
|
||||||
|
* region2, or if region 1 is in an additional clear region, this will return true.</p>
|
||||||
|
*
|
||||||
|
* @param location1 <p>The first location to check</p>
|
||||||
|
* @param location2 <p>The second location to check</p>
|
||||||
|
* @return <p>True if the two locations are in different clear regions</p>
|
||||||
|
*/
|
||||||
|
protected boolean isInDifferentClearRegions(@NotNull Location location1, @NotNull Location location2) {
|
||||||
|
World fromWorld = location1.getWorld();
|
||||||
|
if (fromWorld == null) {
|
||||||
|
ClearOnWorldGuard.logger().log(Level.WARNING, "Unable to check region change, as location " +
|
||||||
|
location1 + " has no world.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicableRegionSet setFrom = configuration.getRegionQuery().getApplicableRegions(BukkitAdapter.adapt(location1));
|
||||||
|
ApplicableRegionSet setTo = configuration.getRegionQuery().getApplicableRegions(BukkitAdapter.adapt(location2));
|
||||||
|
|
||||||
|
Set<ProtectedRegion> fromRegions = getOccupiedClearRegions(fromWorld, setFrom.getRegions());
|
||||||
|
Set<ProtectedRegion> toRegions = getOccupiedClearRegions(fromWorld, setTo.getRegions());
|
||||||
|
|
||||||
|
// If the player is in one or more clear regions, clear unless the clear regions are the same
|
||||||
|
return (!fromRegions.isEmpty() || !toRegions.isEmpty()) && !fromRegions.equals(toRegions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given block is in a clear region
|
||||||
|
*
|
||||||
|
* @param entity <p>The entity to check</p>
|
||||||
|
* @return <p>True if the block is in a clear region</p>
|
||||||
|
*/
|
||||||
|
protected boolean isInClearRegion(@NotNull Entity entity) {
|
||||||
|
return isInClearRegion(entity.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given block is in a clear region
|
||||||
|
*
|
||||||
|
* @param block <p>The block to check</p>
|
||||||
|
* @return <p>True if the block is in a clear region</p>
|
||||||
|
*/
|
||||||
|
protected boolean isInClearRegion(@NotNull Block block) {
|
||||||
|
return isInClearRegion(block.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given location is in a clear region
|
||||||
|
*
|
||||||
|
* @param location <p>The location to check</p>
|
||||||
|
* @return <p>True if the location is in a clear region</p>
|
||||||
|
*/
|
||||||
|
protected boolean isInClearRegion(@NotNull Location location) {
|
||||||
|
World playerWorld = location.getWorld();
|
||||||
|
if (playerWorld == null) {
|
||||||
|
ClearOnWorldGuard.logger().log(Level.WARNING, "Unable to check region change, as location " +
|
||||||
|
location + " has no world.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplicableRegionSet setFrom = configuration.getRegionQuery().getApplicableRegions(BukkitAdapter.adapt(location));
|
||||||
|
Set<ProtectedRegion> fromRegions = getOccupiedClearRegions(playerWorld, setFrom.getRegions());
|
||||||
|
return !fromRegions.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all regions set as clear regions the player currently occupies
|
||||||
|
*
|
||||||
|
* @param playerWorld <p>The world the player is currently in</p>
|
||||||
|
* @param playerRegions <p>The regions the player is in or will be in</p>
|
||||||
|
* @return <p>All clear regions found in playerRegions</p>
|
||||||
|
*/
|
||||||
|
private Set<ProtectedRegion> getOccupiedClearRegions(@NotNull World playerWorld,
|
||||||
|
@NotNull Set<ProtectedRegion> playerRegions) {
|
||||||
|
Set<ProtectedRegion> possibleRegions = configuration.getProtectedRegions(playerWorld);
|
||||||
|
Set<ProtectedRegion> result = new HashSet<>();
|
||||||
|
for (ProtectedRegion region : playerRegions) {
|
||||||
|
if (possibleRegions.contains(region)) {
|
||||||
|
result.add(region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package net.knarcraft.clearonworldguard.property;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A representation of manually checked permissions
|
||||||
|
*/
|
||||||
|
public enum Permission {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The permission for bypassing entity interaction restrictions
|
||||||
|
*/
|
||||||
|
BYPASS_ENTITY_INTERACTION("clearonworldguard.bypass.entityinteraction"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The permission for bypassing mob spawning restrictions
|
||||||
|
*/
|
||||||
|
BYPASS_MOB_SPAWNING("clearonworldguard.bypass.mobspawning"),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final String permissionString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new permission
|
||||||
|
*
|
||||||
|
* @param permissionString <p>The permission string this represents</p>
|
||||||
|
*/
|
||||||
|
Permission(@NotNull String permissionString) {
|
||||||
|
this.permissionString = permissionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return permissionString;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -5,3 +5,6 @@ clearRegions:
|
|||||||
world: [ ]
|
world: [ ]
|
||||||
world_nether: [ ]
|
world_nether: [ ]
|
||||||
world_the_end: [ ]
|
world_the_end: [ ]
|
||||||
|
|
||||||
|
# Whether to enable debug mode, which spams debug messages at log level INFO, rather than log level FINEST
|
||||||
|
debug: false
|
@ -4,3 +4,17 @@ main: net.knarcraft.clearonworldguard.ClearOnWorldGuard
|
|||||||
api-version: '1.20'
|
api-version: '1.20'
|
||||||
description: A custom KnarCraft plugin
|
description: A custom KnarCraft plugin
|
||||||
depend: [ WorldGuard ]
|
depend: [ WorldGuard ]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
clearonworldguard.bypass.*:
|
||||||
|
default: false
|
||||||
|
description: Gives all bypass permissions
|
||||||
|
children:
|
||||||
|
- clearonworldguard.bypass.mobspawning
|
||||||
|
- clearonworldguard.bypass.entityinteraction
|
||||||
|
clearonworldguard.bypass.mobspawning:
|
||||||
|
default: false
|
||||||
|
description: Allows a player to spawn mobs in clear regions
|
||||||
|
clearonworldguard.bypass.entityinteraction:
|
||||||
|
default: false
|
||||||
|
description: Allows a player to interact with mobs in a clear region
|
Loading…
Reference in New Issue
Block a user