mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2024-11-24 03:25:24 +01:00
Don't remove child regions without warning.
Also add some missing files. Fixes WORLDGUARD-2311.
This commit is contained in:
parent
28c538e981
commit
5d6dad4c6d
@ -48,6 +48,7 @@
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroup;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
|
||||
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.CircularInheritanceException;
|
||||
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"},
|
||||
usage = "<id>",
|
||||
flags = "w:",
|
||||
flags = "fuw:",
|
||||
desc = "Remove a region",
|
||||
min = 1, max = 1)
|
||||
public void remove(CommandContext args, CommandSender sender) throws CommandException {
|
||||
World world = checkWorld(args, sender, 'w'); // Get the world
|
||||
boolean removeChildren = args.hasFlag('f');
|
||||
boolean unsetParent = args.hasFlag('u');
|
||||
|
||||
// Lookup the existing region
|
||||
RegionManager manager = checkRegionManager(plugin, world);
|
||||
@ -666,6 +669,14 @@ public void remove(CommandContext args, CommandSender sender) throws CommandExce
|
||||
|
||||
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)
|
||||
.formatUsing(existing.getId())
|
||||
.registerWithSupervisor("Removing the region '%s'...")
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user