Don't remove child regions without warning.

Also add some missing files.

Fixes WORLDGUARD-2311.
This commit is contained in:
sk89q 2014-08-14 21:41:44 -07:00
parent 28c538e981
commit 5d6dad4c6d
5 changed files with 803 additions and 1 deletions

View File

@ -48,6 +48,7 @@
import com.sk89q.worldguard.protection.flags.RegionGroup; import com.sk89q.worldguard.protection.flags.RegionGroup;
import com.sk89q.worldguard.protection.flags.RegionGroupFlag; import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
import com.sk89q.worldguard.protection.managers.RegionManager; import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.managers.RemovalStrategy;
import com.sk89q.worldguard.protection.regions.ProtectedRegion; import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException; import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
import com.sk89q.worldguard.protection.util.migrator.MigrationException; import com.sk89q.worldguard.protection.util.migrator.MigrationException;
@ -649,11 +650,13 @@ public void setParent(CommandContext args, CommandSender sender) throws CommandE
*/ */
@Command(aliases = {"remove", "delete", "del", "rem"}, @Command(aliases = {"remove", "delete", "del", "rem"},
usage = "<id>", usage = "<id>",
flags = "w:", flags = "fuw:",
desc = "Remove a region", desc = "Remove a region",
min = 1, max = 1) min = 1, max = 1)
public void remove(CommandContext args, CommandSender sender) throws CommandException { public void remove(CommandContext args, CommandSender sender) throws CommandException {
World world = checkWorld(args, sender, 'w'); // Get the world World world = checkWorld(args, sender, 'w'); // Get the world
boolean removeChildren = args.hasFlag('f');
boolean unsetParent = args.hasFlag('u');
// Lookup the existing region // Lookup the existing region
RegionManager manager = checkRegionManager(plugin, world); RegionManager manager = checkRegionManager(plugin, world);
@ -666,6 +669,14 @@ public void remove(CommandContext args, CommandSender sender) throws CommandExce
RegionRemover task = new RegionRemover(manager, existing); RegionRemover task = new RegionRemover(manager, existing);
if (removeChildren && unsetParent) {
throw new CommandException("You cannot use both -u (unset parent) and -f (remove children) together.");
} else if (removeChildren) {
task.setRemovalStrategy(RemovalStrategy.REMOVE_CHILDREN);
} else if (unsetParent) {
task.setRemovalStrategy(RemovalStrategy.UNSET_PARENT_IN_CHILDREN);
}
AsyncCommandHelper.wrap(plugin.getExecutorService().submit(task), plugin, sender) AsyncCommandHelper.wrap(plugin.getExecutorService().submit(task), plugin, sender)
.formatUsing(existing.getId()) .formatUsing(existing.getId())
.registerWithSupervisor("Removing the region '%s'...") .registerWithSupervisor("Removing the region '%s'...")

View File

@ -0,0 +1,358 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.commands.region;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.selections.CuboidSelection;
import com.sk89q.worldedit.bukkit.selections.Polygonal2DSelection;
import com.sk89q.worldedit.bukkit.selections.Selection;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.permission.RegionPermissionModel;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
class RegionCommandsBase {
/**
* Get the permission model to lookup permissions.
*
* @param sender the sender
* @return the permission model
*/
protected static RegionPermissionModel getPermissionModel(CommandSender sender) {
return new RegionPermissionModel(WorldGuardPlugin.inst(), sender);
}
/**
* Gets the world from the given flag, or falling back to the the current player
* if the sender is a player, otherwise reporting an error.
*
* @param args the arguments
* @param sender the sender
* @param flag the flag (such as 'w')
* @return a world
* @throws CommandException on error
*/
protected static World checkWorld(CommandContext args, CommandSender sender, char flag) throws CommandException {
if (args.hasFlag(flag)) {
return WorldGuardPlugin.inst().matchWorld(sender, args.getFlag(flag));
} else {
if (sender instanceof Player) {
return WorldGuardPlugin.inst().checkPlayer(sender).getWorld();
} else {
throw new CommandException("Please specify " + "the world with -" + flag + " world_name.");
}
}
}
/**
* Validate a region ID.
*
* @param id the id
* @param allowGlobal whether __global__ is allowed
* @return the id given
* @throws CommandException thrown on an error
*/
protected static String checkRegionId(String id, boolean allowGlobal) throws CommandException {
if (!ProtectedRegion.isValidId(id)) {
throw new CommandException(
"The region name of '" + id + "' contains characters that are not allowed.");
}
if (!allowGlobal && id.equalsIgnoreCase("__global__")) { // Sorry, no global
throw new CommandException(
"Sorry, you can't use __global__ here.");
}
return id;
}
/**
* Get a protected region by a given name, otherwise throw a
* {@link CommandException}.
*
* <p>This also validates the region ID.</p>
*
* @param regionManager the region manager
* @param id the name to search
* @param allowGlobal true to allow selecting __global__
* @throws CommandException thrown if no region is found by the given name
*/
protected static ProtectedRegion checkExistingRegion(RegionManager regionManager, String id, boolean allowGlobal) throws CommandException {
// Validate the id
checkRegionId(id, allowGlobal);
ProtectedRegion region = regionManager.getRegion(id);
// No region found!
if (region == null) {
// But we want a __global__, so let's create one
if (id.equalsIgnoreCase("__global__")) {
region = new GlobalProtectedRegion(id);
regionManager.addRegion(region);
return region;
}
throw new CommandException(
"No region could be found with the name of '" + id + "'.");
}
return region;
}
/**
* Get the region at the player's location, if possible.
*
* <p>If the player is standing in several regions, an error will be raised
* and a list of regions will be provided.</p>
*
* @param regionManager the region manager
* @param player the player
* @return a region
* @throws CommandException thrown if no region was found
*/
protected static ProtectedRegion checkRegionStandingIn(RegionManager regionManager, Player player) throws CommandException {
return checkRegionStandingIn(regionManager, player, false);
}
/**
* Get the region at the player's location, if possible.
*
* <p>If the player is standing in several regions, an error will be raised
* and a list of regions will be provided.</p>
*
* <p>If the player is not standing in any regions, the global region will
* returned if allowGlobal is true and it exists.</p>
*
* @param regionManager the region manager
* @param player the player
* @param allowGlobal whether to search for a global region if no others are found
* @return a region
* @throws CommandException thrown if no region was found
*/
protected static ProtectedRegion checkRegionStandingIn(RegionManager regionManager, Player player, boolean allowGlobal) throws CommandException {
ApplicableRegionSet set = regionManager.getApplicableRegions(player.getLocation());
if (set.size() == 0) {
if (allowGlobal) {
ProtectedRegion global = checkExistingRegion(regionManager, "__global__", true);
player.sendMessage(ChatColor.GRAY + "You're not standing in any " +
"regions. Using the global region for this world instead.");
return global;
}
throw new CommandException(
"You're not standing in a region." +
"Specify an ID if you want to select a specific region.");
} else if (set.size() > 1) {
StringBuilder builder = new StringBuilder();
boolean first = true;
for (ProtectedRegion region : set) {
if (!first) {
builder.append(", ");
}
first = false;
builder.append(region.getId());
}
throw new CommandException(
"You're standing in several regions (please pick one).\nYou're in: " + builder.toString());
}
return set.iterator().next();
}
/**
* Get a WorldEdit selection for a player, or emit an exception if there is none
* available.
*
* @param player the player
* @return the selection
* @throws CommandException thrown on an error
*/
protected static Selection checkSelection(Player player) throws CommandException {
WorldEditPlugin worldEdit = WorldGuardPlugin.inst().getWorldEdit();
Selection selection = worldEdit.getSelection(player);
if (selection == null) {
throw new CommandException(
"Please select an area first. " +
"Use WorldEdit to make a selection! " +
"(wiki: http://wiki.sk89q.com/wiki/WorldEdit).");
}
return selection;
}
/**
* Check that a region with the given ID does not already exist.
*
* @param manager the manager
* @param id the ID
* @throws CommandException thrown if the ID already exists
*/
protected static void checkRegionDoesNotExist(RegionManager manager, String id, boolean mayRedefine) throws CommandException {
if (manager.hasRegion(id)) {
throw new CommandException("A region with that name already exists. Please choose another name." +
(mayRedefine ? " To change the shape, use /region redefine " + id + "." : ""));
}
}
/**
* Check that the given region manager is not null.
*
* @param plugin the plugin
* @param world the world
* @throws CommandException thrown if the manager is null
*/
protected static RegionManager checkRegionManager(WorldGuardPlugin plugin, World world) throws CommandException {
RegionManager manager = plugin.getRegionContainer().get(world);
if (manager == null) {
throw new CommandException("Either region support is disabled or region data failed to load in the target world.");
}
return manager;
}
/**
* Create a {@link ProtectedRegion} from the player's selection.
*
* @param player the player
* @param id the ID of the new region
* @return a new region
* @throws CommandException thrown on an error
*/
protected static ProtectedRegion checkRegionFromSelection(Player player, String id) throws CommandException {
Selection selection = checkSelection(player);
// Detect the type of region from WorldEdit
if (selection instanceof Polygonal2DSelection) {
Polygonal2DSelection polySel = (Polygonal2DSelection) selection;
int minY = polySel.getNativeMinimumPoint().getBlockY();
int maxY = polySel.getNativeMaximumPoint().getBlockY();
return new ProtectedPolygonalRegion(id, polySel.getNativePoints(), minY, maxY);
} else if (selection instanceof CuboidSelection) {
BlockVector min = selection.getNativeMinimumPoint().toBlockVector();
BlockVector max = selection.getNativeMaximumPoint().toBlockVector();
return new ProtectedCuboidRegion(id, min, max);
} else {
throw new CommandException("Sorry, you can only use cuboids and polygons for WorldGuard regions.");
}
}
/**
* Warn the sender if the dimensions of the given region are worrying.
*
* @param sender the sender to send the message to
* @param region the region
*/
protected static void warnAboutDimensions(CommandSender sender, ProtectedRegion region) {
int height = region.getMaximumPoint().getBlockY() - region.getMinimumPoint().getBlockY();
if (height <= 2) {
sender.sendMessage(ChatColor.GRAY + "(Warning: The height of the region was " + (height + 1) + " block(s).)");
}
}
/**
* Inform a new user about automatic protection.
*
* @param sender the sender to send the message to
* @param manager the region manager
* @param region the region
*/
protected static void informNewUser(CommandSender sender, RegionManager manager, ProtectedRegion region) {
if (manager.getRegions().size() <= 2) {
sender.sendMessage(ChatColor.GRAY +
"(This region is NOW PROTECTED from modification from others. " +
"Don't want that? Use " +
ChatColor.AQUA + "/rg flag " + region.getId() + " passthrough allow" +
ChatColor.GRAY + ")");
}
}
/**
* Set a player's selection to a given region.
*
* @param player the player
* @param region the region
* @throws CommandException thrown on a command error
*/
protected static void setPlayerSelection(Player player, ProtectedRegion region) throws CommandException {
WorldEditPlugin worldEdit = WorldGuardPlugin.inst().getWorldEdit();
World world = player.getWorld();
// Set selection
if (region instanceof ProtectedCuboidRegion) {
ProtectedCuboidRegion cuboid = (ProtectedCuboidRegion) region;
Vector pt1 = cuboid.getMinimumPoint();
Vector pt2 = cuboid.getMaximumPoint();
CuboidSelection selection = new CuboidSelection(world, pt1, pt2);
worldEdit.setSelection(player, selection);
player.sendMessage(ChatColor.YELLOW + "Region selected as a cuboid.");
} else if (region instanceof ProtectedPolygonalRegion) {
ProtectedPolygonalRegion poly2d = (ProtectedPolygonalRegion) region;
Polygonal2DSelection selection = new Polygonal2DSelection(
world, poly2d.getPoints(),
poly2d.getMinimumPoint().getBlockY(),
poly2d.getMaximumPoint().getBlockY() );
worldEdit.setSelection(player, selection);
player.sendMessage(ChatColor.YELLOW + "Region selected as a polygon.");
} else if (region instanceof GlobalProtectedRegion) {
throw new CommandException(
"Can't select global regions! " +
"That would cover the entire world.");
} else {
throw new CommandException("Unknown region type: " +
region.getClass().getCanonicalName());
}
}
/**
* Utility method to set a flag.
*
* @param region the region
* @param flag the flag
* @param sender the sender
* @param value the value
* @throws InvalidFlagFormat thrown if the value is invalid
*/
protected static <V> void setFlag(ProtectedRegion region, Flag<V> flag, CommandSender sender, String value) throws InvalidFlagFormat {
region.setFlag(flag, flag.parseInput(WorldGuardPlugin.inst(), sender, value));
}
}

View File

@ -0,0 +1,108 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.commands.task;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.util.DomainInputResolver;
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;
import javax.annotation.Nullable;
import java.util.concurrent.Callable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Creates a new region.
*/
public class RegionAdder implements Callable<ProtectedRegion> {
private final WorldGuardPlugin plugin;
private final RegionManager manager;
private final ProtectedRegion region;
@Nullable
private String[] ownersInput;
private UserLocatorPolicy locatorPolicy = UserLocatorPolicy.UUID_ONLY;
/**
* Create a new instance.
*
* @param plugin the plugin
* @param manager the manage
* @param region the region
*/
public RegionAdder(WorldGuardPlugin plugin, RegionManager manager, ProtectedRegion region) {
checkNotNull(plugin);
checkNotNull(manager);
checkNotNull(region);
this.plugin = plugin;
this.manager = manager;
this.region = region;
}
/**
* Add the owners from the command's arguments.
*
* @param args the arguments
* @param namesIndex the index in the list of arguments to read the first name from
*/
public void addOwnersFromCommand(CommandContext args, int namesIndex) {
if (args.argsLength() >= namesIndex) {
setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_ONLY);
setOwnersInput(args.getSlice(namesIndex));
}
}
@Override
public ProtectedRegion call() throws Exception {
if (ownersInput != null) {
DomainInputResolver resolver = new DomainInputResolver(plugin.getProfileService(), ownersInput);
resolver.setLocatorPolicy(locatorPolicy);
DefaultDomain domain = resolver.call();
region.getOwners().addAll(domain);
}
manager.addRegion(region);
return region;
}
@Nullable
public String[] getOwnersInput() {
return ownersInput;
}
public void setOwnersInput(@Nullable String[] ownersInput) {
this.ownersInput = ownersInput;
}
public UserLocatorPolicy getLocatorPolicy() {
return locatorPolicy;
}
public void setLocatorPolicy(UserLocatorPolicy locatorPolicy) {
this.locatorPolicy = locatorPolicy;
}
}

View File

@ -0,0 +1,232 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.commands.task;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.squirrelid.Profile;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
public class RegionLister implements Callable<Integer> {
private static final Logger log = Logger.getLogger(RegionLister.class.getCanonicalName());
private final WorldGuardPlugin plugin;
private final CommandSender sender;
private final RegionManager manager;
private OwnerMatcher ownerMatcher;
private int page;
public RegionLister(WorldGuardPlugin plugin, RegionManager manager, CommandSender sender) {
checkNotNull(plugin);
checkNotNull(manager);
checkNotNull(sender);
this.plugin = plugin;
this.manager = manager;
this.sender = sender;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public void filterOwnedByPlayer(final Player player) {
ownerMatcher = new OwnerMatcher() {
@Override
public String getName() {
return player.getName();
}
@Override
public boolean isContainedWithin(DefaultDomain domain) throws CommandException {
return domain.contains(player.getUniqueId());
}
};
}
public void filterOwnedByName(String name, boolean nameOnly) {
if (nameOnly) {
filterOwnedByName(name);
} else {
filterOwnedByProfile(name);
}
}
private void filterOwnedByName(final String name) {
ownerMatcher = new OwnerMatcher() {
@Override
public String getName() {
return name;
}
@Override
public boolean isContainedWithin(DefaultDomain domain) throws CommandException {
return domain.contains(name);
}
};
}
private void filterOwnedByProfile(final String name) {
ownerMatcher = new OwnerMatcher() {
private UUID uniqueId;
@Override
public String getName() {
return name;
}
@Override
public boolean isContainedWithin(DefaultDomain domain) throws CommandException {
if (uniqueId == null) {
Profile profile;
try {
profile = plugin.getProfileService().findByName(name);
} catch (IOException e) {
log.log(Level.WARNING, "Failed UUID lookup of '" + name + "'", e);
throw new CommandException("Failed to lookup the UUID of '" + name + "'");
} catch (InterruptedException e) {
log.log(Level.WARNING, "Failed UUID lookup of '" + name + "'", e);
throw new CommandException("The lookup the UUID of '" + name + "' was interrupted");
}
if (profile == null) {
throw new CommandException("A user by the name of '" + name + "' does not seem to exist.");
}
uniqueId = profile.getUniqueId();
}
return domain.contains(uniqueId);
}
};
}
@Override
public Integer call() throws Exception {
Map<String, ProtectedRegion> regions = manager.getRegions();
// Build a list of regions to show
List<RegionListEntry> entries = new ArrayList<RegionListEntry>();
int index = 0;
for (String id : regions.keySet()) {
RegionListEntry entry = new RegionListEntry(id, index++);
// Filtering by owner?
ProtectedRegion region = regions.get(id);
if (ownerMatcher != null) {
entry.isOwner = ownerMatcher.isContainedWithin(region.getOwners());
entry.isMember = ownerMatcher.isContainedWithin(region.getMembers());
if (!entry.isOwner && !entry.isMember) {
continue; // Skip
}
}
entries.add(entry);
}
Collections.sort(entries);
final int totalSize = entries.size();
final int pageSize = 10;
final int pages = (int) Math.ceil(totalSize / (float) pageSize);
sender.sendMessage(ChatColor.RED
+ (ownerMatcher == null ? "Regions (page " : "Regions for " + ownerMatcher.getName() + " (page ")
+ (page + 1) + " of " + pages + "):");
if (page < pages) {
// Print
for (int i = page * pageSize; i < page * pageSize + pageSize; i++) {
if (i >= totalSize) {
break;
}
sender.sendMessage(ChatColor.YELLOW.toString() + entries.get(i));
}
}
return page;
}
private static interface OwnerMatcher {
public String getName();
public boolean isContainedWithin(DefaultDomain domain) throws CommandException;
}
private class RegionListEntry implements Comparable<RegionListEntry> {
private final String id;
private final int index;
boolean isOwner;
boolean isMember;
private RegionListEntry(String id, int index) {
this.id = id;
this.index = index;
}
@Override
public int compareTo(RegionListEntry o) {
if (isOwner != o.isOwner) {
return isOwner ? 1 : -1;
}
if (isMember != o.isMember) {
return isMember ? 1 : -1;
}
return id.compareTo(o.id);
}
@Override
public String toString() {
if (isOwner) {
return (index + 1) + ". +" + id;
} else if (isMember) {
return (index + 1) + ". -" + id;
} else {
return (index + 1) + ". " + id;
}
}
}
}

View File

@ -0,0 +1,93 @@
/*
* WorldGuard, a suite of tools for Minecraft
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.commands.task;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.managers.RemovalStrategy;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import javax.annotation.Nullable;
import java.util.Set;
import java.util.concurrent.Callable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Removes a region.
*/
public class RegionRemover implements Callable<Set<ProtectedRegion>> {
private final RegionManager manager;
private final ProtectedRegion region;
@Nullable
private RemovalStrategy removalStrategy;
/**
* Create a new instance.
*
* @param manager a region manager
* @param region the region to remove
*/
public RegionRemover(RegionManager manager, ProtectedRegion region) {
checkNotNull(manager);
checkNotNull(region);
this.manager = manager;
this.region = region;
}
/**
* GSet a parent removal strategy.
*
* @return a removal strategy or null (see{@link #setRemovalStrategy(RemovalStrategy)}
*/
@Nullable
public RemovalStrategy getRemovalStrategy() {
return removalStrategy;
}
/**
* Set a parent removal strategy. Set it to {@code null} to have the code
* check for children and throw an error if any are found.
*
* @param removalStrategy a removal strategy, or {@code null} to error if children exist
*/
public void setRemovalStrategy(@Nullable RemovalStrategy removalStrategy) {
this.removalStrategy = removalStrategy;
}
@Override
public Set<ProtectedRegion> call() throws Exception {
if (removalStrategy == null) {
for (ProtectedRegion test : manager.getRegions().values()) {
ProtectedRegion parent = test.getParent();
if (parent != null && parent.equals(region)) {
throw new CommandException(
"The region '" + region.getId() + "' has child regions. Use -f to force removal of children " +
"or -u to unset the parent value of these children.");
}
}
return manager.removeRegion(region.getId(), RemovalStrategy.UNSET_PARENT_IN_CHILDREN);
} else {
return manager.removeRegion(region.getId(), removalStrategy);
}
}
}