Refactor region commands and make the necessary ones run in the background.

This commit is contained in:
sk89q 2014-08-14 21:24:32 -07:00
parent a35cb9277e
commit 28c538e981
13 changed files with 1228 additions and 1720 deletions

View File

@ -30,7 +30,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
class AsyncCommandHelper {
public class AsyncCommandHelper {
private final ListenableFuture<?> future;
private final WorldGuardPlugin plugin;

View File

@ -30,7 +30,7 @@
/**
* Command-related utility methods.
*/
final class CommandUtils {
public final class CommandUtils {
private CommandUtils() {
}
@ -41,7 +41,7 @@ private CommandUtils() {
* @param owner the owner object
* @return a name
*/
static String getOwnerName(@Nullable Object owner) {
public static String getOwnerName(@Nullable Object owner) {
if (owner == null) {
return "?";
} else if (owner instanceof Player) {
@ -62,7 +62,7 @@ static String getOwnerName(@Nullable Object owner) {
* @param sender the sender
* @return a function
*/
static Function<String, ?> messageFunction(final CommandSender sender) {
public static Function<String, ?> messageFunction(final CommandSender sender) {
return new Function<String, Object>() {
@Override
public Object apply(@Nullable String s) {

View File

@ -28,14 +28,14 @@
import static com.google.common.base.Preconditions.checkNotNull;
class FutureProgressListener implements Runnable {
public class FutureProgressListener implements Runnable {
private static final Timer timer = new Timer();
private static final int MESSAGE_DELAY = 1000;
private final MessageTimerTask task;
FutureProgressListener(CommandSender sender, String message) {
public FutureProgressListener(CommandSender sender, String message) {
checkNotNull(sender);
checkNotNull(message);

View File

@ -28,7 +28,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
class MessageFutureCallback<V> implements FutureCallback<V> {
public class MessageFutureCallback<V> implements FutureCallback<V> {
private final WorldGuardPlugin plugin;
private final CommandSender sender;
@ -57,7 +57,7 @@ public void onFailure(@Nullable Throwable throwable) {
sender.sendMessage(ChatColor.RED + failure + ": " + plugin.convertThrowable(throwable));
}
static class Builder {
public static class Builder {
private final WorldGuardPlugin plugin;
private final CommandSender sender;
@Nullable
@ -65,7 +65,7 @@ static class Builder {
@Nullable
private String failure;
Builder(WorldGuardPlugin plugin, CommandSender sender) {
public Builder(WorldGuardPlugin plugin, CommandSender sender) {
checkNotNull(plugin);
checkNotNull(sender);

View File

@ -25,7 +25,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
class MessageTimerTask extends TimerTask {
public class MessageTimerTask extends TimerTask {
private final CommandSender sender;
private final String message;

View File

@ -19,6 +19,8 @@
package com.sk89q.worldguard.bukkit.commands;
import com.sk89q.worldguard.bukkit.commands.region.MemberCommands;
import com.sk89q.worldguard.bukkit.commands.region.RegionCommands;
import org.bukkit.command.CommandSender;
import com.sk89q.minecraft.util.commands.Command;
@ -35,7 +37,7 @@ public ProtectionCommands(WorldGuardPlugin plugin) {
}
@Command(aliases = {"region", "regions", "rg"}, desc = "Region management commands")
@NestedCommand({RegionCommands.class, RegionMemberCommands.class})
@NestedCommand({RegionCommands.class, MemberCommands.class})
public void region(CommandContext args, CommandSender sender) {}
@Command(aliases = {"worldguard", "wg"}, desc = "WorldGuard commands")

View File

@ -1,59 +0,0 @@
/*
* 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;
/**
* Used for /rg list.
*/
class RegionListEntry implements Comparable<RegionListEntry> {
private final String id;
private final int index;
boolean isOwner;
boolean isMember;
public 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

@ -17,15 +17,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.commands;
package com.sk89q.worldguard.bukkit.commands.region;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.commands.AsyncCommandHelper;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.util.DomainInputResolver;
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;
@ -36,13 +38,11 @@
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
// @TODO: A lot of code duplication here! Need to fix.
public class RegionMemberCommands {
public class MemberCommands extends RegionCommandsBase {
private final WorldGuardPlugin plugin;
public RegionMemberCommands(WorldGuardPlugin plugin) {
public MemberCommands(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
@ -52,42 +52,16 @@ public RegionMemberCommands(WorldGuardPlugin plugin) {
desc = "Add a member to a region",
min = 2)
public void addMember(CommandContext args, CommandSender sender) throws CommandException {
final World world;
Player player = null;
LocalPlayer localPlayer = null;
if (sender instanceof Player) {
player = (Player) sender;
localPlayer = plugin.wrapPlayer(player);
}
if (args.hasFlag('w')) {
world = plugin.matchWorld(sender, args.getFlag('w'));
} else {
if (player != null) {
world = player.getWorld();
} else {
throw new CommandException("No world specified. Use -w <worldname>.");
}
}
World world = checkWorld(args, sender, 'w'); // Get the world
String id = args.getString(0);
RegionManager manager = plugin.getGlobalRegionManager().get(world);
ProtectedRegion region = manager.matchRegion(id);
if (region == null) {
throw new CommandException("Could not find a region by that ID.");
}
RegionManager manager = checkRegionManager(plugin, world);
ProtectedRegion region = checkExistingRegion(manager, id, true);
id = region.getId();
if (localPlayer != null) {
if (region.isOwner(localPlayer)) {
plugin.checkPermission(sender, "worldguard.region.addmember.own." + id.toLowerCase());
} else if (region.isMember(localPlayer)) {
plugin.checkPermission(sender, "worldguard.region.addmember.member." + id.toLowerCase());
} else {
plugin.checkPermission(sender, "worldguard.region.addmember." + id.toLowerCase());
}
// Check permissions
if (!getPermissionModel(sender).mayAddMembers(region)) {
throw new CommandPermissionsException();
}
// Resolve members asynchronously
@ -113,38 +87,28 @@ public void addMember(CommandContext args, CommandSender sender) throws CommandE
desc = "Add an owner to a region",
min = 2)
public void addOwner(CommandContext args, CommandSender sender) throws CommandException {
final World world;
World world = checkWorld(args, sender, 'w'); // Get the world
Player player = null;
LocalPlayer localPlayer = null;
if (sender instanceof Player) {
player = (Player) sender;
localPlayer = plugin.wrapPlayer(player);
}
if (args.hasFlag('w')) {
world = plugin.matchWorld(sender, args.getFlag('w'));
} else {
if (player != null) {
world = player.getWorld();
} else {
throw new CommandException("No world specified. Use -w <worldname>.");
}
}
String id = args.getString(0);
RegionManager manager = plugin.getGlobalRegionManager().get(world);
ProtectedRegion region = manager.matchRegion(id);
if (region == null) {
throw new CommandException("Could not find a region by that ID.");
}
RegionManager manager = checkRegionManager(plugin, world);
ProtectedRegion region = checkExistingRegion(manager, id, true);
id = region.getId();
Boolean flag = region.getFlag(DefaultFlag.BUYABLE);
DefaultDomain owners = region.getOwners();
if (localPlayer != null) {
if (flag != null && flag && owners != null && owners.size() == 0) {
// TODO: Move this to an event
if (!plugin.hasPermission(player, "worldguard.region.unlimited")) {
int maxRegionCount = plugin.getGlobalStateManager().get(world).getMaxRegionCount(player);
if (maxRegionCount >= 0 && manager.getRegionCountOfPlayer(localPlayer)
@ -154,12 +118,9 @@ public void addOwner(CommandContext args, CommandSender sender) throws CommandEx
}
plugin.checkPermission(sender, "worldguard.region.addowner.unclaimed." + id.toLowerCase());
} else {
if (region.isOwner(localPlayer)) {
plugin.checkPermission(sender, "worldguard.region.addowner.own." + id.toLowerCase());
} else if (region.isMember(localPlayer)) {
plugin.checkPermission(sender, "worldguard.region.addowner.member." + id.toLowerCase());
} else {
plugin.checkPermission(sender, "worldguard.region.addowner." + id.toLowerCase());
// Check permissions
if (!getPermissionModel(sender).mayAddOwners(region)) {
throw new CommandPermissionsException();
}
}
}
@ -187,42 +148,14 @@ public void addOwner(CommandContext args, CommandSender sender) throws CommandEx
desc = "Remove an owner to a region",
min = 1)
public void removeMember(CommandContext args, CommandSender sender) throws CommandException {
final World world;
Player player = null;
LocalPlayer localPlayer = null;
if (sender instanceof Player) {
player = (Player) sender;
localPlayer = plugin.wrapPlayer(player);
}
if (args.hasFlag('w')) {
world = plugin.matchWorld(sender, args.getFlag('w'));
} else {
if (player != null) {
world = player.getWorld();
} else {
throw new CommandException("No world specified. Use -w <worldname>.");
}
}
World world = checkWorld(args, sender, 'w'); // Get the world
String id = args.getString(0);
RegionManager manager = checkRegionManager(plugin, world);
ProtectedRegion region = checkExistingRegion(manager, id, true);
RegionManager manager = plugin.getGlobalRegionManager().get(world);
ProtectedRegion region = manager.matchRegion(id);
if (region == null) {
throw new CommandException("Could not find a region by that ID.");
}
id = region.getId();
if (localPlayer != null) {
if (region.isOwner(localPlayer)) {
plugin.checkPermission(sender, "worldguard.region.removemember.own." + id.toLowerCase());
} else if (region.isMember(localPlayer)) {
plugin.checkPermission(sender, "worldguard.region.removemember.member." + id.toLowerCase());
} else {
plugin.checkPermission(sender, "worldguard.region.removemember." + id.toLowerCase());
}
// Check permissions
if (!getPermissionModel(sender).mayRemoveMembers(region)) {
throw new CommandPermissionsException();
}
ListenableFuture<?> future;
@ -259,44 +192,15 @@ public void removeMember(CommandContext args, CommandSender sender) throws Comma
flags = "naw:",
desc = "Remove an owner to a region",
min = 1)
public void removeOwner(CommandContext args,
CommandSender sender) throws CommandException {
final World world;
Player player = null;
LocalPlayer localPlayer = null;
if (sender instanceof Player) {
player = (Player) sender;
localPlayer = plugin.wrapPlayer(player);
}
if (args.hasFlag('w')) {
world = plugin.matchWorld(sender, args.getFlag('w'));
} else {
if (player != null) {
world = player.getWorld();
} else {
throw new CommandException("No world specified. Use -w <worldname>.");
}
}
public void removeOwner(CommandContext args, CommandSender sender) throws CommandException {
World world = checkWorld(args, sender, 'w'); // Get the world
String id = args.getString(0);
RegionManager manager = checkRegionManager(plugin, world);
ProtectedRegion region = checkExistingRegion(manager, id, true);
RegionManager manager = plugin.getGlobalRegionManager().get(world);
ProtectedRegion region = manager.matchRegion(id);
if (region == null) {
throw new CommandException("Could not find a region by that ID.");
}
id = region.getId();
if (localPlayer != null) {
if (region.isOwner(localPlayer)) {
plugin.checkPermission(sender, "worldguard.region.removeowner.own." + id.toLowerCase());
} else if (region.isMember(localPlayer)) {
plugin.checkPermission(sender, "worldguard.region.removeowner.member." + id.toLowerCase());
} else {
plugin.checkPermission(sender, "worldguard.region.removeowner." + id.toLowerCase());
}
// Check permissions
if (!getPermissionModel(sender).mayRemoveOwners(region)) {
throw new CommandPermissionsException();
}
ListenableFuture<?> future;

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.commands;
package com.sk89q.worldguard.bukkit.commands.region;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
@ -25,20 +25,20 @@
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.Location;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bukkit.BukkitUtil;
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.LocalPlayer;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.commands.task.RegionAdd;
import com.sk89q.worldguard.bukkit.commands.task.RegionManagerReload;
import com.sk89q.worldguard.bukkit.commands.task.RegionmanagerSave;
import com.sk89q.worldguard.bukkit.commands.AsyncCommandHelper;
import com.sk89q.worldguard.bukkit.commands.CommandUtils;
import com.sk89q.worldguard.bukkit.commands.FutureProgressListener;
import com.sk89q.worldguard.bukkit.commands.MessageFutureCallback.Builder;
import com.sk89q.worldguard.bukkit.commands.task.RegionAdder;
import com.sk89q.worldguard.bukkit.commands.task.RegionLister;
import com.sk89q.worldguard.bukkit.commands.task.RegionManagerReloader;
import com.sk89q.worldguard.bukkit.commands.task.RegionManagerSaver;
import com.sk89q.worldguard.bukkit.commands.task.RegionRemover;
import com.sk89q.worldguard.bukkit.permission.RegionPermissionModel;
import com.sk89q.worldguard.bukkit.util.LoggerToChatHandler;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
@ -48,12 +48,8 @@
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.regions.GlobalProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;
import com.sk89q.worldguard.protection.util.migrator.MigrationException;
import com.sk89q.worldguard.protection.util.migrator.UUIDMigrator;
import org.bukkit.Bukkit;
@ -64,282 +60,24 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Implements the /region commands for WorldGuard.
*/
public final class RegionCommands {
public final class RegionCommands extends RegionCommandsBase {
private final WorldGuardPlugin plugin;
public RegionCommands(WorldGuardPlugin plugin) {
checkNotNull(plugin);
this.plugin = plugin;
}
/**
* Get the permission model to lookup permissions.
*
* @param sender the sender
* @return the permission model
*/
private 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
*/
private static World getWorld(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
*/
private static String validateRegionId(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
*/
private static ProtectedRegion findExistingRegion(RegionManager regionManager, String id, boolean allowGlobal) throws CommandException {
// Validate the id
validateRegionId(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
*/
private static ProtectedRegion findRegionStandingIn(RegionManager regionManager, Player player) throws CommandException {
return findRegionStandingIn(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
*/
private static ProtectedRegion findRegionStandingIn(RegionManager regionManager, Player player, boolean allowGlobal) throws CommandException {
ApplicableRegionSet set = regionManager.getApplicableRegions(
player.getLocation());
if (set.size() == 0) {
if (allowGlobal) {
ProtectedRegion global = findExistingRegion(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, and " +
"WorldGuard is not sure what you want.\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
*/
private static Selection getSelection(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;
}
/**
* 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
*/
private static ProtectedRegion createRegionFromSelection(Player player, String id) throws CommandException {
Selection selection = getSelection(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.");
}
}
/**
* Set a player's selection to a given region.
*
* @param player the player
* @param region the region
* @throws CommandException thrown on a command error
*/
private 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
*/
private static <V> void setFlag(ProtectedRegion region, Flag<V> flag, CommandSender sender, String value) throws InvalidFlagFormat {
region.setFlag(flag, flag.parseInput(WorldGuardPlugin.inst(), sender, value));
}
/**
* Defines a new region.
*
@ -360,43 +98,18 @@ public void define(CommandContext args, CommandSender sender) throws CommandExce
throw new CommandPermissionsException();
}
// Get and validate the region ID
String id = validateRegionId(args.getString(0), false);
String id = checkRegionId(args.getString(0), false);
// Can't replace regions with this command
final RegionManager manager = plugin.getRegionContainer().get(player.getWorld());
RegionManager manager = checkRegionManager(plugin, player.getWorld());
if (manager != null) {
if (manager.hasRegion(id)) {
throw new CommandException("A region with that ID already exists. To change the shape, use /region redefine " + id);
}
checkRegionDoesNotExist(manager, id, true);
// Make a region from the user's selection
final ProtectedRegion region = createRegionFromSelection(player, id);
// Issue a warning about height
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).)");
}
// Hint
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 " + id + " passthrough allow" +
ChatColor.GRAY + ")");
}
RegionAdd task = new RegionAdd(plugin, manager, region);
// Add the list of region owners
if (args.argsLength() > 1) {
task.setLocatorPolicy(args.hasFlag('n') ? UserLocatorPolicy.NAME_ONLY : UserLocatorPolicy.UUID_ONLY);
task.setOwnersInput(args.getSlice(2));
}
ProtectedRegion region = checkRegionFromSelection(player, id);
warnAboutDimensions(player, region);
informNewUser(player, manager, region);
RegionAdder task = new RegionAdder(plugin, manager, region);
task.addOwnersFromCommand(args, 2);
ListenableFuture<?> future = plugin.getExecutorService().submit(task);
AsyncCommandHelper.wrap(future, plugin, player)
@ -406,9 +119,6 @@ public void define(CommandContext args, CommandSender sender) throws CommandExce
.thenRespondWith(
"A new region has been made named '%s'.",
"Failed to add the region '%s'");
} else {
throw new CommandException("Either region support is disabled or region data failed to load in the target world.");
}
}
/**
@ -426,43 +136,23 @@ public void redefine(CommandContext args, CommandSender sender) throws CommandEx
Player player = plugin.checkPlayer(sender);
World world = player.getWorld();
// Get and validate the region ID
String id = validateRegionId(args.getString(0), false);
String id = checkRegionId(args.getString(0), false);
// Lookup the existing region
RegionManager manager = plugin.getRegionContainer().get(world);
RegionManager manager = checkRegionManager(plugin, world);
if (manager != null) {
ProtectedRegion existing = findExistingRegion(manager, id, false);
ProtectedRegion existing = checkExistingRegion(manager, id, false);
// Check permissions
if (!getPermissionModel(sender).mayRedefine(existing)) {
throw new CommandPermissionsException();
}
// Make a region from the user's selection
ProtectedRegion region = createRegionFromSelection(player, id);
ProtectedRegion region = checkRegionFromSelection(player, id);
region.copyFrom(existing);
// Copy details from the old region to the new one
region.setMembers(existing.getMembers());
region.setOwners(existing.getOwners());
region.setFlags(existing.getFlags());
region.setPriority(existing.getPriority());
try {
region.setParent(existing.getParent());
} catch (CircularInheritanceException ignore) {
// This should not be thrown
}
// Issue a warning about height
int height = region.getMaximumPoint().getBlockY() - region.getMinimumPoint().getBlockY();
if (height <= 2) {
sender.sendMessage(ChatColor.GOLD +
"(Warning: The height of the region was " + (height + 1) + " block(s).)");
}
RegionAdd task = new RegionAdd(plugin, manager, region);
warnAboutDimensions(sender, region);
RegionAdder task = new RegionAdder(plugin, manager, region);
ListenableFuture<?> future = plugin.getExecutorService().submit(task);
AsyncCommandHelper.wrap(future, plugin, player)
@ -472,9 +162,6 @@ public void redefine(CommandContext args, CommandSender sender) throws CommandEx
.thenRespondWith(
"Region '%s' has been updated with a new area.",
"Failed to update the region '%s'");
} else {
throw new CommandException("Either region support is disabled or region data failed to load in the target world.");
}
}
/**
@ -501,24 +188,12 @@ public void claim(CommandContext args, CommandSender sender) throws CommandExcep
throw new CommandPermissionsException();
}
// Get and validate the region ID
String id = validateRegionId(args.getString(0), false);
String id = checkRegionId(args.getString(0), false);
// Can't replace existing regions
RegionManager manager = plugin.getGlobalRegionManager().get(player.getWorld());
RegionManager manager = checkRegionManager(plugin, player.getWorld());
if (manager != null) {
if (manager.hasRegion(id)) {
throw new CommandException("That region already exists. Please choose a different name.");
}
// Make a region from the user's selection
ProtectedRegion region = createRegionFromSelection(player, id);
// Get the list of region owners
/*if (args.argsLength() > 1) {
region.setOwners(RegionDBUtil.parseDomainString(args.getSlice(1), 1));
}*/
checkRegionDoesNotExist(manager, id, false);
ProtectedRegion region = checkRegionFromSelection(player, id);
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(player.getWorld());
@ -569,7 +244,7 @@ public void claim(CommandContext args, CommandSender sender) throws CommandExcep
region.getOwners().addPlayer(player.getName());
RegionAdd task = new RegionAdd(plugin, manager, region);
RegionAdder task = new RegionAdder(plugin, manager, region);
ListenableFuture<?> future = plugin.getExecutorService().submit(task);
AsyncCommandHelper.wrap(future, plugin, player)
@ -579,9 +254,6 @@ public void claim(CommandContext args, CommandSender sender) throws CommandExcep
.thenRespondWith(
"A new region has been claimed named '%s'.",
"Failed to claim the region '%s'");
} else {
throw new CommandException("Either region support is disabled or region data failed to load in the target world.");
}
}
/**
@ -598,14 +270,14 @@ public void claim(CommandContext args, CommandSender sender) throws CommandExcep
public void select(CommandContext args, CommandSender sender) throws CommandException {
Player player = plugin.checkPlayer(sender);
World world = player.getWorld();
RegionManager regionManager = plugin.getGlobalRegionManager().get(world);
RegionManager manager = checkRegionManager(plugin, world);
ProtectedRegion existing;
// If no arguments were given, get the region that the player is inside
if (args.argsLength() == 0) {
existing = findRegionStandingIn(regionManager, player);
existing = checkRegionStandingIn(manager, player);
} else {
existing = findExistingRegion(regionManager, args.getString(0), false);
existing = checkExistingRegion(manager, args.getString(0), false);
}
// Check permissions
@ -630,11 +302,11 @@ public void select(CommandContext args, CommandSender sender) throws CommandExce
desc = "Get information about a region",
min = 0, max = 1)
public void info(CommandContext args, CommandSender sender) throws CommandException {
World world = getWorld(args, sender, 'w'); // Get the world
World world = checkWorld(args, sender, 'w'); // Get the world
RegionPermissionModel permModel = getPermissionModel(sender);
// Lookup the existing region
RegionManager regionManager = plugin.getGlobalRegionManager().get(world);
RegionManager manager = checkRegionManager(plugin, world);
ProtectedRegion existing;
if (args.argsLength() == 0) { // Get region from where the player is
@ -643,9 +315,9 @@ public void info(CommandContext args, CommandSender sender) throws CommandExcept
"the region with /region info -w world_name region_name.");
}
existing = findRegionStandingIn(regionManager, (Player) sender, true);
existing = checkRegionStandingIn(manager, (Player) sender, true);
} else { // Get region from the ID
existing = findExistingRegion(regionManager, args.getString(0), true);
existing = checkExistingRegion(manager, args.getString(0), true);
}
// Check permissions
@ -675,7 +347,7 @@ public void info(CommandContext args, CommandSender sender) throws CommandExcept
// Send a response message
Futures.addCallback(future,
new MessageFutureCallback.Builder(plugin, sender)
new Builder(plugin, sender)
.onFailure("Failed to fetch region information")
.build());
}
@ -690,10 +362,10 @@ public void info(CommandContext args, CommandSender sender) throws CommandExcept
@Command(aliases = {"list"},
usage = "[page]",
desc = "Get a list of regions",
flags = "p:w:",
flags = "np:w:",
max = 1)
public void list(CommandContext args, CommandSender sender) throws CommandException {
World world = getWorld(args, sender, 'w'); // Get the world
World world = checkWorld(args, sender, 'w'); // Get the world
String ownedBy;
// Get page
@ -717,49 +389,20 @@ public void list(CommandContext args, CommandSender sender) throws CommandExcept
}
}
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
Map<String, ProtectedRegion> regions = mgr.getRegions();
RegionManager manager = checkRegionManager(plugin, world);
// 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?
RegionLister task = new RegionLister(plugin, manager, sender);
task.setPage(page);
if (ownedBy != null) {
entry.isOwner = regions.get(id).isOwner(ownedBy);
entry.isMember = regions.get(id).isMember(ownedBy);
if (!entry.isOwner && !entry.isMember) {
continue; // Skip
}
task.filterOwnedByName(ownedBy, args.hasFlag('n'));
}
entries.add(entry);
}
ListenableFuture<?> future = plugin.getExecutorService().submit(task);
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
+ (ownedBy == null ? "Regions (page " : "Regions for " + ownedBy + " (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));
}
}
AsyncCommandHelper.wrap(future, plugin, sender)
.registerWithSupervisor("Getting list of regions...")
.sendMessageAfterDelay("(Please wait... fetching region list...)")
.thenTellErrorsOnly("Failed to fetch region list");
}
/**
@ -775,16 +418,15 @@ public void list(CommandContext args, CommandSender sender) throws CommandExcept
desc = "Set flags",
min = 2)
public void flag(CommandContext args, CommandSender sender) throws CommandException {
World world = getWorld(args, sender, 'w'); // Get the world
World world = checkWorld(args, sender, 'w'); // Get the world
String flagName = args.getString(1);
String value = args.argsLength() >= 3 ? args.getJoinedStrings(2) : null;
RegionGroup groupValue = null;
RegionPermissionModel permModel = getPermissionModel(sender);
// Lookup the existing region
RegionManager regionManager = plugin.getGlobalRegionManager().get(world);
ProtectedRegion existing = findExistingRegion(regionManager,
args.getString(0), true);
RegionManager manager = checkRegionManager(plugin, world);
ProtectedRegion existing = checkExistingRegion(manager, args.getString(0), true);
// Check permissions
if (!permModel.maySetFlag(existing)) {
@ -913,15 +555,13 @@ public void flag(CommandContext args, CommandSender sender) throws CommandExcept
flags = "w:",
desc = "Set the priority of a region",
min = 2, max = 2)
public void setPriority(CommandContext args, CommandSender sender)
throws CommandException {
World world = getWorld(args, sender, 'w'); // Get the world
public void setPriority(CommandContext args, CommandSender sender) throws CommandException {
World world = checkWorld(args, sender, 'w'); // Get the world
int priority = args.getInteger(1);
// Lookup the existing region
RegionManager regionManager = plugin.getGlobalRegionManager().get(world);
ProtectedRegion existing = findExistingRegion(regionManager,
args.getString(0), false);
RegionManager manager = checkRegionManager(plugin, world);
ProtectedRegion existing = checkExistingRegion(manager, args.getString(0), false);
// Check permissions
if (!getPermissionModel(sender).maySetPriority(existing)) {
@ -948,17 +588,17 @@ public void setPriority(CommandContext args, CommandSender sender)
desc = "Set the parent of a region",
min = 1, max = 2)
public void setParent(CommandContext args, CommandSender sender) throws CommandException {
World world = getWorld(args, sender, 'w'); // Get the world
World world = checkWorld(args, sender, 'w'); // Get the world
ProtectedRegion parent;
ProtectedRegion child;
// Lookup the existing region
RegionManager regionManager = plugin.getGlobalRegionManager().get(world);
RegionManager manager = checkRegionManager(plugin, world);
// Get parent and child
child = findExistingRegion(regionManager, args.getString(0), false);
child = checkExistingRegion(manager, args.getString(0), false);
if (args.argsLength() == 2) {
parent = findExistingRegion(regionManager, args.getString(1), false);
parent = checkExistingRegion(manager, args.getString(1), false);
} else {
parent = null;
}
@ -974,6 +614,7 @@ public void setParent(CommandContext args, CommandSender sender) throws CommandE
// Tell the user what's wrong
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(parent, null);
printout.append(ChatColor.RED);
assert parent != null;
printout.append("Uh oh! Setting '" + parent.getId() + "' to be the parent " +
"of '" + child.getId() + "' would cause circular inheritance.\n");
printout.append(ChatColor.GRAY);
@ -1012,21 +653,26 @@ public void setParent(CommandContext args, CommandSender sender) throws CommandE
desc = "Remove a region",
min = 1, max = 1)
public void remove(CommandContext args, CommandSender sender) throws CommandException {
World world = getWorld(args, sender, 'w'); // Get the world
World world = checkWorld(args, sender, 'w'); // Get the world
// Lookup the existing region
RegionManager regionManager = plugin.getGlobalRegionManager().get(world);
ProtectedRegion existing = findExistingRegion(regionManager,
args.getString(0), true);
RegionManager manager = checkRegionManager(plugin, world);
ProtectedRegion existing = checkExistingRegion(manager, args.getString(0), true);
// Check permissions
if (!getPermissionModel(sender).mayDelete(existing)) {
throw new CommandPermissionsException();
}
regionManager.removeRegion(existing.getId());
RegionRemover task = new RegionRemover(manager, existing);
sender.sendMessage(ChatColor.YELLOW + "Region '" + existing.getId() + "' removed.");
AsyncCommandHelper.wrap(plugin.getExecutorService().submit(task), plugin, sender)
.formatUsing(existing.getId())
.registerWithSupervisor("Removing the region '%s'...")
.sendMessageAfterDelay("(Please wait... removing '%s'...)")
.thenRespondWith(
"The region named '%s' has been removed.",
"Failed to remove the region '%s'");
}
/**
@ -1043,7 +689,7 @@ public void remove(CommandContext args, CommandSender sender) throws CommandExce
public void load(CommandContext args, final CommandSender sender) throws CommandException {
World world = null;
try {
world = getWorld(args, sender, 'w'); // Get the world
world = checkWorld(args, sender, 'w'); // Get the world
} catch (CommandException e) {
// assume the user wants to reload all worlds
}
@ -1054,13 +700,13 @@ public void load(CommandContext args, final CommandSender sender) throws Command
}
if (world != null) {
RegionManager manager = plugin.getGlobalRegionManager().get(world);
RegionManager manager = checkRegionManager(plugin, world);
if (manager == null) {
throw new CommandException("No region manager exists for world '" + world.getName() + "'.");
}
ListenableFuture<?> future = plugin.getExecutorService().submit(new RegionManagerReload(manager));
ListenableFuture<?> future = plugin.getExecutorService().submit(new RegionManagerReloader(manager));
AsyncCommandHelper.wrap(future, plugin, sender)
.forRegionDataLoad(world, false);
@ -1069,13 +715,13 @@ public void load(CommandContext args, final CommandSender sender) throws Command
List<RegionManager> managers = new ArrayList<RegionManager>();
for (World w : Bukkit.getServer().getWorlds()) {
RegionManager manager = plugin.getGlobalRegionManager().get(w);
RegionManager manager = plugin.getRegionContainer().get(w);
if (manager != null) {
managers.add(manager);
}
}
ListenableFuture<?> future = plugin.getExecutorService().submit(new RegionManagerReload(managers));
ListenableFuture<?> future = plugin.getExecutorService().submit(new RegionManagerReloader(managers));
AsyncCommandHelper.wrap(future, plugin, sender)
.registerWithSupervisor("Loading regions for all worlds")
@ -1100,7 +746,7 @@ public void load(CommandContext args, final CommandSender sender) throws Command
public void save(CommandContext args, final CommandSender sender) throws CommandException {
World world = null;
try {
world = getWorld(args, sender, 'w'); // Get the world
world = checkWorld(args, sender, 'w'); // Get the world
} catch (CommandException e) {
// assume user wants to save all worlds
}
@ -1111,13 +757,13 @@ public void save(CommandContext args, final CommandSender sender) throws Command
}
if (world != null) {
RegionManager manager = plugin.getGlobalRegionManager().get(world);
RegionManager manager = checkRegionManager(plugin, world);
if (manager == null) {
throw new CommandException("No region manager exists for world '" + world.getName() + "'.");
}
ListenableFuture<?> future = plugin.getExecutorService().submit(new RegionmanagerSave(manager));
ListenableFuture<?> future = plugin.getExecutorService().submit(new RegionManagerSaver(manager));
AsyncCommandHelper.wrap(future, plugin, sender)
.forRegionDataSave(world, false);
@ -1126,13 +772,13 @@ public void save(CommandContext args, final CommandSender sender) throws Command
List<RegionManager> managers = new ArrayList<RegionManager>();
for (World w : Bukkit.getServer().getWorlds()) {
RegionManager manager = plugin.getGlobalRegionManager().get(w);
RegionManager manager = plugin.getRegionContainer().get(w);
if (manager != null) {
managers.add(manager);
}
}
ListenableFuture<?> future = plugin.getExecutorService().submit(new RegionmanagerSave(managers));
ListenableFuture<?> future = plugin.getExecutorService().submit(new RegionManagerSaver(managers));
AsyncCommandHelper.wrap(future, plugin, sender)
.registerWithSupervisor("Saving regions for all worlds")
@ -1235,7 +881,7 @@ public void migrateUuid(CommandContext args, CommandSender sender) throws Comman
try {
UUIDMigrator migrator = new UUIDMigrator(plugin.getProfileService(), plugin.getLogger());
migrator.readConfiguration(plugin.getGlobalStateManager());
List<RegionManager> managers = plugin.getGlobalRegionManager().getLoaded();
List<RegionManager> managers = plugin.getRegionContainer().getLoaded();
// Try migration
if (migrator.migrate(managers)) {
@ -1279,9 +925,8 @@ public void teleport(CommandContext args, CommandSender sender) throws CommandEx
Location teleportLocation;
// Lookup the existing region
RegionManager regionManager = plugin.getGlobalRegionManager().get(player.getWorld());
ProtectedRegion existing = findExistingRegion(regionManager,
args.getString(0), false);
RegionManager regionManager = checkRegionManager(plugin, player.getWorld());
ProtectedRegion existing = checkExistingRegion(regionManager, args.getString(0), false);
// Check permissions
if (!getPermissionModel(sender).mayTeleportTo(existing)) {

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.commands;
package com.sk89q.worldguard.bukkit.commands.region;
import com.sk89q.squirrelid.cache.ProfileCache;
import com.sk89q.worldedit.BlockVector;
@ -39,7 +39,7 @@
* Create a region printout, as used in /region info to show information about
* a region.
*/
class RegionPrintoutBuilder implements Callable<String> {
public class RegionPrintoutBuilder implements Callable<String> {
private final ProtectedRegion region;
@Nullable
@ -52,7 +52,7 @@ class RegionPrintoutBuilder implements Callable<String> {
* @param region the region
* @param cache a profile cache, or {@code null}
*/
RegionPrintoutBuilder(ProtectedRegion region, @Nullable ProfileCache cache) {
public RegionPrintoutBuilder(ProtectedRegion region, @Nullable ProfileCache cache) {
this.region = region;
this.cache = cache;
}

View File

@ -28,16 +28,16 @@
import static com.google.common.base.Preconditions.checkNotNull;
public class RegionManagerReload implements Callable<Collection<RegionManager>> {
public class RegionManagerReloader implements Callable<Collection<RegionManager>> {
private final Collection<RegionManager> managers;
public RegionManagerReload(Collection<RegionManager> managers) {
public RegionManagerReloader(Collection<RegionManager> managers) {
checkNotNull(managers);
this.managers = managers;
}
public RegionManagerReload(RegionManager... manager) {
public RegionManagerReloader(RegionManager... manager) {
this(Arrays.asList(manager));
}

View File

@ -28,16 +28,16 @@
import static com.google.common.base.Preconditions.checkNotNull;
public class RegionmanagerSave implements Callable<Collection<RegionManager>> {
public class RegionManagerSaver implements Callable<Collection<RegionManager>> {
private final Collection<RegionManager> managers;
public RegionmanagerSave(Collection<RegionManager> managers) {
public RegionManagerSaver(Collection<RegionManager> managers) {
checkNotNull(managers);
this.managers = managers;
}
public RegionmanagerSave(RegionManager... manager) {
public RegionManagerSaver(RegionManager... manager) {
this(Arrays.asList(manager));
}

View File

@ -124,6 +124,22 @@ public boolean maySetFlag(ProtectedRegion region, Flag<?> flag) {
"flag.flags." + flag.getName().toLowerCase(), region);
}
public boolean mayAddMembers(ProtectedRegion region) {
return hasPatternPermission("addmember", region);
}
public boolean mayAddOwners(ProtectedRegion region) {
return hasPatternPermission("addowner", region);
}
public boolean mayRemoveMembers(ProtectedRegion region) {
return hasPatternPermission("removemember", region);
}
public boolean mayRemoveOwners(ProtectedRegion region) {
return hasPatternPermission("removeowner", region);
}
/**
* Checks to see if the given sender has permission to modify the given region
* using the region permission pattern.