mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2024-11-23 19:16:40 +01:00
Add support for UUIDs in region commands.
This commit is contained in:
parent
189fd15498
commit
81a727fe7f
8
pom.xml
8
pom.xml
@ -184,6 +184,14 @@
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sk89q</groupId>
|
||||
<artifactId>squirrelid</artifactId>
|
||||
<version>0.1.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
package com.sk89q.worldguard.bukkit;
|
||||
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.sk89q.bukkit.util.CommandsManagerRegistration;
|
||||
import com.sk89q.minecraft.util.commands.CommandException;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
|
||||
@ -27,6 +29,14 @@
|
||||
import com.sk89q.minecraft.util.commands.MissingNestedCommandException;
|
||||
import com.sk89q.minecraft.util.commands.SimpleInjector;
|
||||
import com.sk89q.minecraft.util.commands.WrappedCommandException;
|
||||
import com.sk89q.squirrelid.cache.HashMapCache;
|
||||
import com.sk89q.squirrelid.cache.ProfileCache;
|
||||
import com.sk89q.squirrelid.cache.SQLiteCache;
|
||||
import com.sk89q.squirrelid.resolver.BukkitPlayerService;
|
||||
import com.sk89q.squirrelid.resolver.CacheForwardingService;
|
||||
import com.sk89q.squirrelid.resolver.CombinedProfileService;
|
||||
import com.sk89q.squirrelid.resolver.HttpRepositoryService;
|
||||
import com.sk89q.squirrelid.resolver.ProfileService;
|
||||
import com.sk89q.wepif.PermissionsResolverManager;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
@ -40,6 +50,7 @@
|
||||
import com.sk89q.worldguard.protection.GlobalRegionManager;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.util.FatalConfigurationLoadingException;
|
||||
import com.sk89q.worldguard.util.concurrency.EvenMoreExecutors;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
@ -64,41 +75,23 @@
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.logging.Level;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
/**
|
||||
* The main class for WorldGuard as a Bukkit plugin.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class WorldGuardPlugin extends JavaPlugin {
|
||||
|
||||
/**
|
||||
* Current instance of this plugin.
|
||||
*/
|
||||
private static WorldGuardPlugin inst;
|
||||
|
||||
/**
|
||||
* Manager for commands. This automatically handles nested commands,
|
||||
* permissions checking, and a number of other fancy command things.
|
||||
* We just set it up and register commands against it.
|
||||
*/
|
||||
private final CommandsManager<CommandSender> commands;
|
||||
|
||||
/**
|
||||
* Handles the region databases for all worlds.
|
||||
*/
|
||||
private final GlobalRegionManager globalRegionManager;
|
||||
|
||||
/**
|
||||
* Handles all configuration.
|
||||
*/
|
||||
private final ConfigurationManager configuration;
|
||||
|
||||
/**
|
||||
* Used for scheduling flags.
|
||||
*/
|
||||
private FlagStateManager flagStateManager;
|
||||
private final ListeningExecutorService executorService = MoreExecutors.listeningDecorator(
|
||||
EvenMoreExecutors.newBoundedCachedThreadPool(0, 4, 20));
|
||||
private ProfileService profileService;
|
||||
private ProfileCache profileCache;
|
||||
|
||||
/**
|
||||
* Construct objects. Actual loading occurs when the plugin is enabled, so
|
||||
@ -205,6 +198,21 @@ public void run() {
|
||||
}
|
||||
worldListener.registerEvents();
|
||||
|
||||
File cacheDir = new File(getDataFolder(), "cache");
|
||||
cacheDir.mkdirs();
|
||||
try {
|
||||
profileCache = new SQLiteCache(new File(cacheDir, "profiles.sqlite"));
|
||||
} catch (IOException e) {
|
||||
getLogger().log(Level.WARNING, "Failed to initialize SQLite profile cache");
|
||||
profileCache = new HashMapCache();
|
||||
}
|
||||
|
||||
profileService = new CacheForwardingService(
|
||||
new CombinedProfileService(
|
||||
BukkitPlayerService.getInstance(),
|
||||
HttpRepositoryService.forMinecraft()),
|
||||
profileCache);
|
||||
|
||||
if (!configuration.hasCommandBookGodMode()) {
|
||||
// Check god mode for existing players, if any
|
||||
for (Player player : getServer().getOnlinePlayers()) {
|
||||
@ -216,9 +224,6 @@ public void run() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on plugin disable.
|
||||
*/
|
||||
@Override
|
||||
public void onDisable() {
|
||||
globalRegionManager.unload();
|
||||
@ -226,9 +231,6 @@ public void onDisable() {
|
||||
this.getServer().getScheduler().cancelTasks(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a command.
|
||||
*/
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String label,
|
||||
String[] args) {
|
||||
@ -293,6 +295,34 @@ public ConfigurationManager getGlobalStateManager() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the global executor service for internal usage (please use your
|
||||
* own executor service).
|
||||
*
|
||||
* @return the global executor service
|
||||
*/
|
||||
public ListeningExecutorService getExecutorService() {
|
||||
return executorService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the profile lookup service.
|
||||
*
|
||||
* @return the profile lookup service
|
||||
*/
|
||||
public ProfileService getProfileService() {
|
||||
return profileService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the profile cache.
|
||||
*
|
||||
* @return the profile cache
|
||||
*/
|
||||
public ProfileCache getProfileCache() {
|
||||
return profileCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a player is in a group.
|
||||
* This calls the corresponding method in PermissionsResolverManager
|
||||
|
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
import com.sk89q.worldguard.protection.databases.util.UnresolvedNamesException;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Timer;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Command-related utility methods.
|
||||
*/
|
||||
final class CommandUtils {
|
||||
|
||||
private static final Logger log = Logger.getLogger(CommandUtils.class.getCanonicalName());
|
||||
private static final Timer timer = new Timer();
|
||||
private static final int MESSAGE_DELAY = 1000;
|
||||
|
||||
private CommandUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a message that gets shown after a delay if the future has not
|
||||
* completed.
|
||||
*
|
||||
* @param future the future
|
||||
* @param sender the sender to send a message to
|
||||
* @param message the message to send (will be grey)
|
||||
*/
|
||||
static void progressCallback(ListenableFuture<?> future, CommandSender sender, String message) {
|
||||
checkNotNull(future);
|
||||
checkNotNull(sender);
|
||||
checkNotNull(message);
|
||||
|
||||
final MessageTimerTask task = new MessageTimerTask(sender, ChatColor.GRAY + message);
|
||||
timer.schedule(task, MESSAGE_DELAY);
|
||||
future.addListener(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
task.cancel();
|
||||
}
|
||||
}, MoreExecutors.sameThreadExecutor());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a callback to print a message to the user.
|
||||
*
|
||||
* @param sender the sender
|
||||
* @param successMessage a success message or {@code null} to print nothing
|
||||
* @param errorMessage an error message
|
||||
* @param <T> ignored type
|
||||
* @return a callback
|
||||
*/
|
||||
static <T> FutureCallback<T> messageCallback(final CommandSender sender, @Nullable final String successMessage, final String errorMessage) {
|
||||
checkNotNull(sender);
|
||||
checkNotNull(errorMessage);
|
||||
|
||||
return new FutureCallback<T>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable T o) {
|
||||
if (successMessage != null) {
|
||||
sender.sendMessage(ChatColor.YELLOW + successMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@Nullable Throwable throwable) {
|
||||
sender.sendMessage(ChatColor.RED + errorMessage + ": " + convertThrowable(throwable));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a function that accepts a string to send a message to the
|
||||
* given sender.
|
||||
*
|
||||
* @param sender the sender
|
||||
* @return a function
|
||||
*/
|
||||
static Function<String, ?> messageFunction(final CommandSender sender) {
|
||||
return new Function<String, Object>() {
|
||||
@Override
|
||||
public Object apply(@Nullable String s) {
|
||||
sender.sendMessage(s);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a function to add a prefix and suffix to the input string.
|
||||
*
|
||||
* @param prefix the prefix
|
||||
* @param suffix the suffix
|
||||
* @return a function
|
||||
*/
|
||||
static Function<String, String> messageAppender(final String prefix, final String suffix) {
|
||||
return new Function<String, String>() {
|
||||
@Override
|
||||
public String apply(@Nullable String s) {
|
||||
return prefix + s + suffix;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a callback to save a region manager on success.
|
||||
*
|
||||
* @param sender the sender
|
||||
* @param manager the region manager
|
||||
* @param world the world
|
||||
* @param silent true to not print a success message
|
||||
* @param <T> an ignored type
|
||||
* @return a callback
|
||||
*/
|
||||
static <T> FutureCallback<T> saveRegionsCallback(final CommandSender sender, final RegionManager manager, final World world, final boolean silent) {
|
||||
checkNotNull(sender);
|
||||
checkNotNull(manager);
|
||||
checkNotNull(world);
|
||||
|
||||
return new FutureCallback<T>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable T o) {
|
||||
ListenableFuture<?> future = manager.save(true);
|
||||
String successMessage = silent ? null : "Successfully saved the region data for '" + world.getName() + "'.";
|
||||
String failureMessage = "Failed to save the region data for '" + world.getName() + "'";
|
||||
Futures.addCallback(future, messageCallback(sender, successMessage, failureMessage));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@Nullable Throwable throwable) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the throwable into a somewhat friendly message.
|
||||
*
|
||||
* @param throwable the throwable
|
||||
* @return a message
|
||||
*/
|
||||
private static String convertThrowable(@Nullable Throwable throwable) {
|
||||
if (throwable instanceof CancellationException) {
|
||||
return "Task was cancelled";
|
||||
} else if (throwable instanceof InterruptedException) {
|
||||
return "Task was interrupted";
|
||||
} else if (throwable instanceof UnresolvedNamesException) {
|
||||
return throwable.getMessage();
|
||||
} else if (throwable instanceof Exception) {
|
||||
log.log(Level.WARNING, "WorldGuard encountered an unexpected error", throwable);
|
||||
return "Unexpected error occurred: " + ((Exception) throwable).getMessage();
|
||||
} else {
|
||||
return "Unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.TimerTask;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
class MessageTimerTask extends TimerTask {
|
||||
|
||||
private final CommandSender sender;
|
||||
private final String message;
|
||||
|
||||
MessageTimerTask(CommandSender sender, String message) {
|
||||
checkNotNull(sender);
|
||||
checkNotNull(message);
|
||||
|
||||
this.sender = sender;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
sender.sendMessage(message);
|
||||
}
|
||||
|
||||
}
|
@ -706,7 +706,7 @@ public void select(CommandContext args, CommandSender sender) throws CommandExce
|
||||
*/
|
||||
@Command(aliases = {"info", "i"},
|
||||
usage = "[id]",
|
||||
flags = "sw:",
|
||||
flags = "usw:",
|
||||
desc = "Get information about a region",
|
||||
min = 0, max = 1)
|
||||
public void info(CommandContext args, CommandSender sender) throws CommandException {
|
||||
@ -734,9 +734,11 @@ public void info(CommandContext args, CommandSender sender) throws CommandExcept
|
||||
}
|
||||
|
||||
// Print region information
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(existing);
|
||||
printout.appendRegionInfo();
|
||||
printout.send(sender);
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(existing, args.hasFlag('u') ? null : plugin.getProfileCache());
|
||||
ListenableFuture<?> future = Futures.transform(
|
||||
plugin.getExecutorService().submit(printout),
|
||||
CommandUtils.messageFunction(sender));
|
||||
Futures.addCallback(future, CommandUtils.messageCallback(sender, null, "Failed to retrieve region info"));
|
||||
|
||||
// Let the player also select the region
|
||||
if (args.hasFlag('s')) {
|
||||
@ -964,7 +966,7 @@ public void flag(CommandContext args, CommandSender sender) throws CommandExcept
|
||||
commitChanges(sender, regionManager, world, true); // Save to disk
|
||||
|
||||
// Print region information
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(existing);
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(existing, null);
|
||||
printout.append(ChatColor.GRAY);
|
||||
printout.append("(Current flags: ");
|
||||
printout.appendFlagsList(false);
|
||||
@ -1044,7 +1046,7 @@ public void setParent(CommandContext args, CommandSender sender) throws CommandE
|
||||
child.setParent(parent);
|
||||
} catch (CircularInheritanceException e) {
|
||||
// Tell the user what's wrong
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(parent);
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(parent, null);
|
||||
printout.append(ChatColor.RED);
|
||||
printout.append("Uh oh! Setting '" + parent.getId() + "' to be the parent " +
|
||||
"of '" + child.getId() + "' would cause circular inheritance.\n");
|
||||
@ -1060,7 +1062,7 @@ public void setParent(CommandContext args, CommandSender sender) throws CommandE
|
||||
commitChanges(sender, regionManager, world, true); // Save to disk
|
||||
|
||||
// Tell the user the current inheritance
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(child);
|
||||
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(child, null);
|
||||
printout.append(ChatColor.YELLOW);
|
||||
printout.append("Inheritance set for region '" + child.getId() + "'.\n");
|
||||
if (parent != null) {
|
||||
@ -1071,7 +1073,6 @@ public void setParent(CommandContext args, CommandSender sender) throws CommandE
|
||||
printout.append(")");
|
||||
}
|
||||
printout.send(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,26 +19,29 @@
|
||||
|
||||
package com.sk89q.worldguard.bukkit.commands;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
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.worldguard.LocalPlayer;
|
||||
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
|
||||
import com.sk89q.worldguard.protection.databases.RegionDBUtil;
|
||||
import com.sk89q.worldguard.protection.databases.util.DomainInputResolver;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import static com.google.common.util.concurrent.Futures.addCallback;
|
||||
import static com.sk89q.worldguard.bukkit.commands.CommandUtils.*;
|
||||
|
||||
// @TODO: A lot of code duplication here! Need to fix.
|
||||
|
||||
public class RegionMemberCommands {
|
||||
|
||||
private final WorldGuardPlugin plugin;
|
||||
|
||||
public RegionMemberCommands(WorldGuardPlugin plugin) {
|
||||
@ -47,7 +50,7 @@ public RegionMemberCommands(WorldGuardPlugin plugin) {
|
||||
|
||||
@Command(aliases = {"addmember", "addmember", "addmem", "am"},
|
||||
usage = "<id> <members...>",
|
||||
flags = "w:",
|
||||
flags = "nw:",
|
||||
desc = "Add a member to a region",
|
||||
min = 2)
|
||||
public void addMember(CommandContext args, CommandSender sender) throws CommandException {
|
||||
@ -89,22 +92,24 @@ public void addMember(CommandContext args, CommandSender sender) throws CommandE
|
||||
}
|
||||
}
|
||||
|
||||
RegionDBUtil.addToDomain(region.getMembers(), args.getParsedPaddedSlice(1, 0), 0);
|
||||
// Resolve members asynchronously
|
||||
DomainInputResolver resolver = new DomainInputResolver(
|
||||
plugin.getProfileService(), args.getParsedPaddedSlice(1, 0));
|
||||
resolver.setUseNames(args.hasFlag('n'));
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region '" + id + "' updated.");
|
||||
// Then add it to the members
|
||||
ListenableFuture<DefaultDomain> future = Futures.transform(
|
||||
plugin.getExecutorService().submit(resolver),
|
||||
resolver.createAddAllFunction(region.getMembers()));
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
progressCallback(future, sender, "(Please wait... resolving names into UUIDs...)");
|
||||
addCallback(future, messageCallback(sender, "Region '" + id + "' updated.", "Failed to add members"));
|
||||
addCallback(future, saveRegionsCallback(sender, mgr, world, true));
|
||||
}
|
||||
|
||||
@Command(aliases = {"addowner", "addowner", "ao"},
|
||||
usage = "<id> <owners...>",
|
||||
flags = "w:",
|
||||
flags = "nw:",
|
||||
desc = "Add an owner to a region",
|
||||
min = 2)
|
||||
public void addOwner(CommandContext args, CommandSender sender) throws CommandException {
|
||||
@ -159,22 +164,24 @@ public void addOwner(CommandContext args, CommandSender sender) throws CommandEx
|
||||
}
|
||||
}
|
||||
|
||||
RegionDBUtil.addToDomain(region.getOwners(), args.getParsedPaddedSlice(1, 0), 0);
|
||||
// Resolve owners asynchronously
|
||||
DomainInputResolver resolver = new DomainInputResolver(
|
||||
plugin.getProfileService(), args.getParsedPaddedSlice(1, 0));
|
||||
resolver.setUseNames(args.hasFlag('n'));
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region '" + id + "' updated.");
|
||||
// Then add it to the owners
|
||||
ListenableFuture<DefaultDomain> future = Futures.transform(
|
||||
plugin.getExecutorService().submit(resolver),
|
||||
resolver.createAddAllFunction(region.getOwners()));
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
progressCallback(future, sender, "(Please wait... resolving names into UUIDs...)");
|
||||
addCallback(future, messageCallback(sender, "Region '" + id + "' updated.", "Failed to add owners"));
|
||||
addCallback(future, saveRegionsCallback(sender, mgr, world, true));
|
||||
}
|
||||
|
||||
@Command(aliases = {"removemember", "remmember", "removemem", "remmem", "rm"},
|
||||
usage = "<id> <owners...>",
|
||||
flags = "aw:",
|
||||
flags = "naw:",
|
||||
desc = "Remove an owner to a region",
|
||||
min = 1)
|
||||
public void removeMember(CommandContext args, CommandSender sender) throws CommandException {
|
||||
@ -216,29 +223,36 @@ public void removeMember(CommandContext args, CommandSender sender) throws Comma
|
||||
}
|
||||
}
|
||||
|
||||
ListenableFuture<?> future;
|
||||
|
||||
if (args.hasFlag('a')) {
|
||||
region.getMembers().removeAll();
|
||||
|
||||
future = Futures.immediateFuture(null);
|
||||
} else {
|
||||
if (args.argsLength() < 2) {
|
||||
throw new CommandException("List some names to remove, or use -a to remove all.");
|
||||
}
|
||||
RegionDBUtil.removeFromDomain(region.getMembers(), args.getParsedPaddedSlice(1, 0), 0);
|
||||
|
||||
// Resolve members asynchronously
|
||||
DomainInputResolver resolver = new DomainInputResolver(
|
||||
plugin.getProfileService(), args.getParsedPaddedSlice(1, 0));
|
||||
resolver.setUseNames(args.hasFlag('n'));
|
||||
|
||||
// Then remove it from the members
|
||||
future = Futures.transform(
|
||||
plugin.getExecutorService().submit(resolver),
|
||||
resolver.createRemoveAllFunction(region.getMembers()));
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region '" + id + "' updated.");
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
progressCallback(future, sender, "(Please wait... resolving names into UUIDs...)");
|
||||
addCallback(future, messageCallback(sender, "Region '" + id + "' updated.", "Failed to remove members"));
|
||||
addCallback(future, saveRegionsCallback(sender, mgr, world, true));
|
||||
}
|
||||
|
||||
@Command(aliases = {"removeowner", "remowner", "ro"},
|
||||
usage = "<id> <owners...>",
|
||||
flags = "aw:",
|
||||
flags = "naw:",
|
||||
desc = "Remove an owner to a region",
|
||||
min = 1)
|
||||
public void removeOwner(CommandContext args,
|
||||
@ -281,23 +295,30 @@ public void removeOwner(CommandContext args,
|
||||
}
|
||||
}
|
||||
|
||||
ListenableFuture<?> future;
|
||||
|
||||
if (args.hasFlag('a')) {
|
||||
region.getOwners().removeAll();
|
||||
|
||||
future = Futures.immediateFuture(null);
|
||||
} else {
|
||||
if (args.argsLength() < 2) {
|
||||
throw new CommandException("List some names to remove, or use -a to remove all.");
|
||||
}
|
||||
RegionDBUtil.removeFromDomain(region.getOwners(), args.getParsedPaddedSlice(1, 0), 0);
|
||||
|
||||
// Resolve owners asynchronously
|
||||
DomainInputResolver resolver = new DomainInputResolver(
|
||||
plugin.getProfileService(), args.getParsedPaddedSlice(1, 0));
|
||||
resolver.setUseNames(args.hasFlag('n'));
|
||||
|
||||
// Then remove it from the owners
|
||||
future = Futures.transform(
|
||||
plugin.getExecutorService().submit(resolver),
|
||||
resolver.createRemoveAllFunction(region.getOwners()));
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.YELLOW
|
||||
+ "Region '" + id + "' updated.");
|
||||
|
||||
try {
|
||||
mgr.save();
|
||||
} catch (ProtectionDatabaseException e) {
|
||||
throw new CommandException("Failed to write regions: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
progressCallback(future, sender, "(Please wait... resolving names into UUIDs...)");
|
||||
addCallback(future, messageCallback(sender, "Region '" + id + "' updated.", "Failed to remove owners"));
|
||||
addCallback(future, saveRegionsCallback(sender, mgr, world, true));
|
||||
}
|
||||
}
|
||||
|
@ -19,36 +19,42 @@
|
||||
|
||||
package com.sk89q.worldguard.bukkit.commands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import com.sk89q.squirrelid.cache.ProfileCache;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
import com.sk89q.worldguard.protection.flags.DefaultFlag;
|
||||
import com.sk89q.worldguard.protection.flags.Flag;
|
||||
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* Create a region printout, as used in /region info to show information about
|
||||
* a region.
|
||||
*/
|
||||
public class RegionPrintoutBuilder {
|
||||
class RegionPrintoutBuilder implements Callable<String> {
|
||||
|
||||
private final ProtectedRegion region;
|
||||
@Nullable
|
||||
private final ProfileCache cache;
|
||||
private final StringBuilder builder = new StringBuilder();
|
||||
|
||||
/**
|
||||
* Create a new instance with a region to report on.
|
||||
*
|
||||
*
|
||||
* @param region the region
|
||||
* @param cache a profile cache, or {@code null}
|
||||
*/
|
||||
public RegionPrintoutBuilder(ProtectedRegion region) {
|
||||
RegionPrintoutBuilder(ProtectedRegion region, @Nullable ProfileCache cache) {
|
||||
this.region = region;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,11 +128,11 @@ public void appendFlagsList(boolean useColors) {
|
||||
|
||||
if(group == null) {
|
||||
builder.append(flag.getName()).append(": ")
|
||||
.append(String.valueOf(val));
|
||||
.append(val);
|
||||
} else {
|
||||
builder.append(flag.getName()).append(" -g ")
|
||||
.append(String.valueOf(group)).append(": ")
|
||||
.append(String.valueOf(val));
|
||||
.append(group).append(": ")
|
||||
.append(val);
|
||||
}
|
||||
|
||||
hasFlags = true;
|
||||
@ -192,7 +198,7 @@ public void appendParentTree(boolean useColors) {
|
||||
if (useColors) {
|
||||
builder.append(ChatColor.GRAY);
|
||||
}
|
||||
builder.append(" (parent, priority=" + cur.getPriority() + ")");
|
||||
builder.append(" (parent, priority=").append(cur.getPriority()).append(")");
|
||||
}
|
||||
|
||||
indent++;
|
||||
@ -206,29 +212,23 @@ public void appendParentTree(boolean useColors) {
|
||||
public void appendDomain() {
|
||||
builder.append(ChatColor.BLUE);
|
||||
builder.append("Owners: ");
|
||||
DefaultDomain owners = region.getOwners();
|
||||
if (owners.size() != 0) {
|
||||
builder.append(ChatColor.YELLOW);
|
||||
builder.append(owners.toUserFriendlyString());
|
||||
} else {
|
||||
builder.append(ChatColor.RED);
|
||||
builder.append("(no owners)");
|
||||
}
|
||||
|
||||
addDomainString(region.getOwners());
|
||||
newLine();
|
||||
|
||||
builder.append(ChatColor.BLUE);
|
||||
builder.append("Members: ");
|
||||
DefaultDomain members = region.getMembers();
|
||||
if (members.size() != 0) {
|
||||
addDomainString(region.getMembers());
|
||||
newLine();
|
||||
}
|
||||
|
||||
private void addDomainString(DefaultDomain domain) {
|
||||
if (domain.size() != 0) {
|
||||
builder.append(ChatColor.YELLOW);
|
||||
builder.append(members.toUserFriendlyString());
|
||||
builder.append(domain.toUserFriendlyString(cache));
|
||||
} else {
|
||||
builder.append(ChatColor.RED);
|
||||
builder.append("(no members)");
|
||||
builder.append("(none)");
|
||||
}
|
||||
|
||||
newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -240,16 +240,13 @@ public void appendBounds() {
|
||||
builder.append(ChatColor.BLUE);
|
||||
builder.append("Bounds:");
|
||||
builder.append(ChatColor.YELLOW);
|
||||
builder.append(" (" + min.getBlockX() + "," + min.getBlockY() + "," + min.getBlockZ() + ")");
|
||||
builder.append(" -> (" + max.getBlockX() + "," + max.getBlockY() + "," + max.getBlockZ() + ")");
|
||||
builder.append(" (").append(min.getBlockX()).append(",").append(min.getBlockY()).append(",").append(min.getBlockZ()).append(")");
|
||||
builder.append(" -> (").append(max.getBlockX()).append(",").append(max.getBlockY()).append(",").append(max.getBlockZ()).append(")");
|
||||
|
||||
newLine();
|
||||
}
|
||||
|
||||
/**
|
||||
* Append all the default fields used for /rg info.
|
||||
*/
|
||||
public void appendRegionInfo() {
|
||||
|
||||
private void appendRegionInformation() {
|
||||
builder.append(ChatColor.GRAY);
|
||||
builder.append("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
|
||||
builder.append(" Region Info ");
|
||||
@ -260,17 +257,28 @@ public void appendRegionInfo() {
|
||||
appendParents();
|
||||
appendDomain();
|
||||
appendBounds();
|
||||
|
||||
if (cache != null) {
|
||||
builder.append(ChatColor.GRAY).append("Any names suffixed by * are 'last seen names' and may not be up to date.");
|
||||
newLine();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
appendRegionInformation();
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the report to a {@link CommandSender}.
|
||||
*
|
||||
* @param sender the recepient
|
||||
*
|
||||
* @param sender the recipient
|
||||
*/
|
||||
public void send(CommandSender sender) {
|
||||
sender.sendMessage(toString());
|
||||
}
|
||||
|
||||
|
||||
public StringBuilder append(boolean b) {
|
||||
return builder.append(b);
|
||||
}
|
||||
|
@ -19,8 +19,12 @@
|
||||
|
||||
package com.sk89q.worldguard.domains;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.sk89q.squirrelid.Profile;
|
||||
import com.sk89q.squirrelid.cache.ProfileCache;
|
||||
import com.sk89q.worldguard.LocalPlayer;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
@ -28,6 +32,8 @@
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* A combination of a {@link PlayerDomain} and a {@link GroupDomain}.
|
||||
*/
|
||||
@ -58,6 +64,15 @@ public void removePlayer(String name) {
|
||||
playerDomain.removePlayer(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given player from the domain, identified by the player's UUID.
|
||||
*
|
||||
* @param uuid the UUID of the player
|
||||
*/
|
||||
public void removePlayer(UUID uuid) {
|
||||
playerDomain.removePlayer(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given player to the domain, identified by the player's UUID.
|
||||
*
|
||||
@ -86,6 +101,42 @@ public void addPlayer(LocalPlayer player) {
|
||||
playerDomain.addPlayer(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all the entries from another domain.
|
||||
*
|
||||
* @param other the other domain
|
||||
*/
|
||||
public void addAll(DefaultDomain other) {
|
||||
checkNotNull(other);
|
||||
for (String player : other.getPlayers()) {
|
||||
addPlayer(player);
|
||||
}
|
||||
for (UUID uuid : other.getUniqueIds()) {
|
||||
addPlayer(uuid);
|
||||
}
|
||||
for (String group : other.getGroups()) {
|
||||
addGroup(group);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all the entries from another domain.
|
||||
*
|
||||
* @param other the other domain
|
||||
*/
|
||||
public void removeAll(DefaultDomain other) {
|
||||
checkNotNull(other);
|
||||
for (String player : other.getPlayers()) {
|
||||
removePlayer(player);
|
||||
}
|
||||
for (UUID uuid : other.getUniqueIds()) {
|
||||
removePlayer(uuid);
|
||||
}
|
||||
for (String group : other.getGroups()) {
|
||||
removeGroup(group);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set of player names.
|
||||
*
|
||||
@ -165,11 +216,29 @@ public void removeAll() {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public String toPlayersString() {
|
||||
return toPlayersString(null);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public String toPlayersString(@Nullable ProfileCache cache) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
List<String> output = new ArrayList<String>();
|
||||
output.addAll(playerDomain.getPlayers());
|
||||
for (UUID uuid : playerDomain.getUniqueIds()) {
|
||||
output.add("uuid:" + uuid);
|
||||
|
||||
if (cache != null) {
|
||||
ImmutableMap<UUID, Profile> results = cache.getAllPresent(playerDomain.getUniqueIds());
|
||||
for (UUID uuid : playerDomain.getUniqueIds()) {
|
||||
Profile profile = results.get(uuid);
|
||||
if (profile != null) {
|
||||
output.add(profile.getName() + "*");
|
||||
} else {
|
||||
output.add("uuid:" + uuid);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (UUID uuid : playerDomain.getUniqueIds()) {
|
||||
output.add("uuid:" + uuid);
|
||||
}
|
||||
}
|
||||
Collections.sort(output, String.CASE_INSENSITIVE_ORDER);
|
||||
for (Iterator<String> it = output.iterator(); it.hasNext();) {
|
||||
@ -192,22 +261,40 @@ public String toGroupsString() {
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
|
||||
public String toUserFriendlyString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
if (playerDomain.size() > 0) {
|
||||
str.append(toPlayersString());
|
||||
}
|
||||
|
||||
|
||||
if (groupDomain.size() > 0) {
|
||||
if (str.length() > 0) {
|
||||
str.append("; ");
|
||||
}
|
||||
|
||||
|
||||
str.append(toGroupsString());
|
||||
}
|
||||
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
public String toUserFriendlyString(ProfileCache cache) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
if (playerDomain.size() > 0) {
|
||||
str.append(toPlayersString(cache));
|
||||
}
|
||||
|
||||
if (groupDomain.size() > 0) {
|
||||
if (str.length() > 0) {
|
||||
str.append("; ");
|
||||
}
|
||||
|
||||
str.append(toGroupsString());
|
||||
}
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,16 @@ public void removePlayer(String name) {
|
||||
names.remove(name.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given player from the domain, identified by the player's UUID.
|
||||
*
|
||||
* @param uuid the UUID of the player
|
||||
*/
|
||||
public void removePlayer(UUID uuid) {
|
||||
checkNotNull(uuid);
|
||||
uniqueIds.remove(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given player from the domain, identified by either the
|
||||
* player's name, the player's unique ID, or both.
|
||||
|
@ -47,14 +47,6 @@ protected AbstractJob(MySQLDatabaseImpl database, Connection conn) {
|
||||
this.logger = database.getLogger();
|
||||
}
|
||||
|
||||
static void closeQuietly(Connection connection) {
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
static void closeQuietly(ResultSet rs) {
|
||||
if (rs != null) {
|
||||
try {
|
||||
|
@ -19,19 +19,20 @@
|
||||
|
||||
package com.sk89q.worldguard.protection.databases;
|
||||
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
|
||||
/**
|
||||
* Various utility functions for parsing region databases.
|
||||
*
|
||||
* @author sk89q
|
||||
*/
|
||||
public class RegionDBUtil {
|
||||
|
||||
private static Pattern groupPattern = Pattern.compile("(?i)^[G]:(.+)$");
|
||||
|
||||
private RegionDBUtil() {
|
||||
|
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.protection.databases.util;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.sk89q.squirrelid.Profile;
|
||||
import com.sk89q.squirrelid.resolver.ProfileService;
|
||||
import com.sk89q.squirrelid.util.UUIDs;
|
||||
import com.sk89q.worldguard.domains.DefaultDomain;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Resolves input for a domain (i.e. "player1 player2 <uuid> g:group").
|
||||
*
|
||||
* <p>Unless {@link #getUseNames()} is true, names will be resolved into
|
||||
* UUIDs.</p>
|
||||
*/
|
||||
public class DomainInputResolver implements Callable<DefaultDomain> {
|
||||
|
||||
private static final Pattern GROUP_PATTERN = Pattern.compile("(?i)^[G]:(.+)$");
|
||||
|
||||
private final ProfileService profileService;
|
||||
private final String[] input;
|
||||
private boolean useNames = false;
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param profileService the profile service
|
||||
* @param input the input to parse
|
||||
*/
|
||||
public DomainInputResolver(ProfileService profileService, String[] input) {
|
||||
checkNotNull(profileService);
|
||||
checkNotNull(input);
|
||||
this.profileService = profileService;
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whether names should be used rather than UUIDs.
|
||||
*
|
||||
* @return true to use names
|
||||
*/
|
||||
public boolean getUseNames() {
|
||||
return useNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether names should be used rather than UUIDs.
|
||||
*
|
||||
* @param useNames true to use names
|
||||
*/
|
||||
public void setUseNames(boolean useNames) {
|
||||
this.useNames = useNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultDomain call() throws UnresolvedNamesException {
|
||||
DefaultDomain domain = new DefaultDomain();
|
||||
List<String> namesToQuery = new ArrayList<String>();
|
||||
|
||||
for (String s : input) {
|
||||
Matcher m = GROUP_PATTERN.matcher(s);
|
||||
if (m.matches()) {
|
||||
domain.addGroup(m.group(1));
|
||||
} else {
|
||||
try {
|
||||
domain.addPlayer(UUID.fromString(UUIDs.addDashes(s)));
|
||||
} catch (IllegalArgumentException e) {
|
||||
if (useNames) {
|
||||
domain.addPlayer(s);
|
||||
} else {
|
||||
namesToQuery.add(s.toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!namesToQuery.isEmpty()) {
|
||||
try {
|
||||
for (Profile profile : profileService.findAllByName(namesToQuery)) {
|
||||
namesToQuery.remove(profile.getName().toLowerCase());
|
||||
domain.addPlayer(profile.getUniqueId());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UnresolvedNamesException("The UUID lookup service failed so the names entered could not be turned into UUIDs");
|
||||
} catch (InterruptedException e) {
|
||||
throw new UnresolvedNamesException("UUID lookup was interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
if (!namesToQuery.isEmpty()) {
|
||||
throw new UnresolvedNamesException("Unable to resolve the names " + Joiner.on(", ").join(namesToQuery));
|
||||
}
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
public Function<DefaultDomain, DefaultDomain> createAddAllFunction(final DefaultDomain target) {
|
||||
return new Function<DefaultDomain, DefaultDomain>() {
|
||||
@Override
|
||||
public DefaultDomain apply(@Nullable DefaultDomain domain) {
|
||||
target.addAll(domain);
|
||||
return domain;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Function<DefaultDomain, DefaultDomain> createRemoveAllFunction(final DefaultDomain target) {
|
||||
return new Function<DefaultDomain, DefaultDomain>() {
|
||||
@Override
|
||||
public DefaultDomain apply(@Nullable DefaultDomain domain) {
|
||||
target.removeAll(domain);
|
||||
return domain;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.protection.databases.util;
|
||||
|
||||
/**
|
||||
* Thrown when there are unresolved names.
|
||||
*/
|
||||
public class UnresolvedNamesException extends Exception {
|
||||
|
||||
public UnresolvedNamesException() {
|
||||
}
|
||||
|
||||
public UnresolvedNamesException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public UnresolvedNamesException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public UnresolvedNamesException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user