Abstracted the commands away from the Bukkit platform (#391)

* Start work on abstracting commands out of worldedit-legacy

* A lot more work towards abstract commands

* Move a lot of code to WorldEdit

* Setup the exception converter

* Use WorldEdit styling and move more of the RegionContainer across.

* Abstract away the debug commands and a few other things - Only the matcher to go.

* It compiles

* It now seems to run fine

* Fixed version typo
This commit is contained in:
Matthew Miller 2018-12-26 14:32:35 +10:00 committed by GitHub
parent 803c2055c3
commit fdd9064170
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 2118 additions and 3716 deletions

View File

@ -8,7 +8,6 @@
compile 'org.flywaydb:flyway-core:3.0'
compile 'org.khelekore:prtree:1.5.0'
compile 'net.sf.opencsv:opencsv:2.0'
compile 'com.googlecode.json-simple:json-simple:1.1.1'
compile 'com.google.code.findbugs:jsr305:1.3.9'
}

View File

@ -20,6 +20,7 @@
package com.sk89q.worldguard;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldguard.domains.Association;
import com.sk89q.worldguard.protection.association.RegionAssociable;
@ -115,6 +116,20 @@ default Association getAssociation(List<ProtectedRegion> regions) {
*/
void setSaturation(double saturation);
/**
* Gets the exhaustion of this player.
*
* @return The exhaustion
*/
float getExhaustion();
/**
* Sets the exhaustion of this player.
*
* @param exhaustion The exhaustion
*/
void setExhaustion(float exhaustion);
/**
* Gets the players weather
*
@ -160,4 +175,26 @@ default Association getAssociation(List<ProtectedRegion> regions) {
* Resets the players time to normal.
*/
void resetPlayerTime();
// TODO Move this to WorldEdit's Entity class - honestly most of this class could be a Facet
/**
* Gets the number of ticks the player is on fire for.
*
* @return The number of fire ticks
*/
int getFireTicks();
/**
* Sets the number of ticks the player is on fire for.
*
* @param fireTicks The fire ticks
*/
void setFireTicks(int fireTicks);
/**
* Sets the target of the compass
*
* @param location The location
*/
void setCompassTarget(Location location);
}

View File

@ -24,6 +24,7 @@
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.squirrelid.cache.HashMapCache;
import com.sk89q.squirrelid.cache.ProfileCache;
import com.sk89q.squirrelid.cache.SQLiteCache;
@ -32,14 +33,17 @@
import com.sk89q.squirrelid.resolver.CombinedProfileService;
import com.sk89q.squirrelid.resolver.HttpRepositoryService;
import com.sk89q.squirrelid.resolver.ProfileService;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.task.SimpleSupervisor;
import com.sk89q.worldedit.util.task.Supervisor;
import com.sk89q.worldedit.util.task.Task;
import com.sk89q.worldguard.internal.platform.WorldGuardPlatform;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.registry.FlagRegistry;
import com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry;
import com.sk89q.worldguard.util.WorldGuardExceptionConverter;
import com.sk89q.worldguard.util.concurrent.EvenMoreExecutors;
import com.sk89q.worldguard.util.task.SimpleSupervisor;
import com.sk89q.worldguard.util.task.Supervisor;
import com.sk89q.worldguard.util.task.Task;
import java.io.File;
import java.io.IOException;
@ -53,13 +57,16 @@ public class WorldGuard {
public static final Logger logger = Logger.getLogger(WorldGuard.class.getCanonicalName());
private static String version;
private static final WorldGuard instance = new WorldGuard();
private WorldGuardPlatform platform;
private final SimpleFlagRegistry flagRegistry = new SimpleFlagRegistry();
private final Supervisor supervisor = new SimpleSupervisor();
private ProfileCache profileCache;
private ProfileService profileService;
private ListeningExecutorService executorService;
private WorldGuardExceptionConverter exceptionConverter = new WorldGuardExceptionConverter(this);
public static WorldGuard getInstance() {
return instance;
@ -152,6 +159,30 @@ public ProfileCache getProfileCache() {
return profileCache;
}
/**
* Get the exception converter
*
* @return the exception converter
*/
public WorldGuardExceptionConverter getExceptionConverter() {
return exceptionConverter;
}
/**
* Checks to see if the sender is a player, otherwise throw an exception.
*
* @param sender The sender
* @return The player
* @throws CommandException if it isn't a player
*/
public LocalPlayer checkPlayer(Actor sender) throws CommandException {
if (sender instanceof LocalPlayer) {
return (LocalPlayer) sender;
} else {
throw new CommandException("A player is expected.");
}
}
/**
* Called when WorldGuard should be disabled.
*/
@ -181,4 +212,34 @@ public void disable() {
platform.unload();
}
/**
* Get the version.
*
* @return the version of WorldEdit
*/
public static String getVersion() {
if (version != null) {
return version;
}
Package p = WorldGuard.class.getPackage();
if (p == null) {
p = Package.getPackage("com.sk89q.worldguard");
}
if (p == null) {
version = "(unknown)";
} else {
version = p.getImplementationVersion();
if (version == null) {
version = "(unknown)";
}
}
return version;
}
}

View File

@ -33,6 +33,7 @@
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.sk89q.worldguard.commands.CommandUtils;
import java.io.BufferedReader;
import java.io.File;
@ -185,10 +186,10 @@ public void load(File file) throws IOException {
entry.setIgnorePermissions(parts[1].split(","));
} else if (parts[0].equalsIgnoreCase("message")) {
entry.setMessage(WorldGuard.getInstance().getPlatform().replaceColorMacros(parts[1].trim()));
entry.setMessage(CommandUtils.replaceColorMacros(parts[1].trim()));
} else if (parts[0].equalsIgnoreCase("comment")) {
entry.setComment(WorldGuard.getInstance().getPlatform().replaceColorMacros(parts[1].trim()));
entry.setComment(CommandUtils.replaceColorMacros(parts[1].trim()));
} else {
boolean found = false;

View File

@ -0,0 +1,114 @@
/*
* 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.commands;
import com.google.common.base.Function;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.formatting.Style;
import javax.annotation.Nullable;
/**
* Command-related utility methods.
*/
public final class CommandUtils {
private CommandUtils() {
}
/**
* Replace color macros in a string.
*
* @param str the string
* @return the new string
*/
public static String replaceColorMacros(String str) {
// TODO: Make this more efficient
str = str.replace("`r", Style.RED.toString());
str = str.replace("`R", Style.RED_DARK.toString());
str = str.replace("`y", Style.YELLOW.toString());
str = str.replace("`Y", Style.YELLOW_DARK.toString());
str = str.replace("`g", Style.GREEN.toString());
str = str.replace("`G", Style.GREEN_DARK.toString());
str = str.replace("`c", Style.CYAN.toString());
str = str.replace("`C", Style.CYAN_DARK.toString());
str = str.replace("`b", Style.BLUE.toString());
str = str.replace("`B", Style.BLUE_DARK.toString());
str = str.replace("`p", Style.PURPLE.toString());
str = str.replace("`P", Style.PURPLE_DARK.toString());
str = str.replace("`0", Style.BLACK.toString());
str = str.replace("`1", Style.GRAY_DARK.toString());
str = str.replace("`2", Style.GRAY.toString());
str = str.replace("`w", Style.WHITE.toString());
str = str.replace("`k", Style.RANDOMIZE.toString());
str = str.replace("`l", Style.BOLD.toString());
str = str.replace("`m", Style.STRIKETHROUGH.toString());
str = str.replace("`n", Style.UNDERLINE.toString());
str = str.replace("`o", Style.ITALIC.toString());
str = str.replace("`x", Style.RESET.toString());
// MC classic
str = Style.translateAlternateColorCodes('&', str);
return str;
}
/**
* Get the name of the given owner object.
*
* @param owner the owner object
* @return a name
*/
public static String getOwnerName(@Nullable Object owner) {
if (owner == null) {
return "?";
} else if (owner instanceof Actor) {
return ((Actor) owner).getName();
} else {
return "?";
}
}
/**
* Return a function that accepts a string to send a message to the
* given sender.
*
* @param sender the sender
* @return a function
*/
public static java.util.function.Function<String, ?> messageFunction(final Actor sender) {
return (Function<String, Object>) s -> {
sender.printRaw(s);
return null;
};
}
}

View File

@ -0,0 +1,71 @@
/*
* 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.commands;
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.CommandPermissions;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
public class DebuggingCommands {
private final WorldGuard worldGuard;
/**
* Create a new instance.
*
* @param worldGuard The worldGuard instance
*/
public DebuggingCommands(WorldGuard worldGuard) {
this.worldGuard = worldGuard;
}
@Command(aliases = {"testbreak"}, usage = "[player]", desc = "Simulate a block break", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void fireBreakEvent(CommandContext args, final Actor sender) throws CommandException {
LocalPlayer target = worldGuard.getPlatform().getMatcher().matchSinglePlayer(sender, args.getString(0));
worldGuard.getPlatform().getDebugHandler().testBreak(sender, target, args.hasFlag('t'), args.hasFlag('s'));
}
@Command(aliases = {"testplace"}, usage = "[player]", desc = "Simulate a block place", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void firePlaceEvent(CommandContext args, final Actor sender) throws CommandException {
LocalPlayer target = worldGuard.getPlatform().getMatcher().matchSinglePlayer(sender, args.getString(0));
worldGuard.getPlatform().getDebugHandler().testPlace(sender, target, args.hasFlag('t'), args.hasFlag('s'));
}
@Command(aliases = {"testinteract"}, usage = "[player]", desc = "Simulate a block interact", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void fireInteractEvent(CommandContext args, final Actor sender) throws CommandException {
LocalPlayer target = worldGuard.getPlatform().getMatcher().matchSinglePlayer(sender, args.getString(0));
worldGuard.getPlatform().getDebugHandler().testInteract(sender, target, args.hasFlag('t'), args.hasFlag('s'));
}
@Command(aliases = {"testdamage"}, usage = "[player]", desc = "Simulate an entity damage", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void fireDamageEvent(CommandContext args, final Actor sender) throws CommandException {
LocalPlayer target = worldGuard.getPlatform().getMatcher().matchSinglePlayer(sender, args.getString(0));
worldGuard.getPlatform().getDebugHandler().testDamage(sender, target, args.hasFlag('t'), args.hasFlag('s'));
}
}

View File

@ -0,0 +1,241 @@
/*
* 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.commands;
import com.google.common.collect.Lists;
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.CommandPermissions;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.session.Session;
import com.sk89q.worldguard.session.handler.GodMode;
public class GeneralCommands {
private final WorldGuard worldGuard;
public GeneralCommands(WorldGuard worldGuard) {
this.worldGuard = worldGuard;
}
@Command(aliases = {"god"}, usage = "[player]",
desc = "Enable godmode on a player", flags = "s", max = 1)
public void god(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
Iterable<? extends LocalPlayer> targets = null;
boolean included = false;
// Detect arguments based on the number of arguments provided
if (args.argsLength() == 0) {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(worldGuard.checkPlayer(sender));
// Check permissions!
sender.checkPermission("worldguard.god");
} else {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(sender, args.getString(0));
// Check permissions!
sender.checkPermission("worldguard.god.other");
}
for (LocalPlayer player : targets) {
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(player);
if (GodMode.set(player, session, true)) {
player.setFireTicks(0);
// Tell the user
if (player.equals(sender)) {
player.print("God mode enabled! Use /ungod to disable.");
// Keep track of this
included = true;
} else {
player.print("God enabled by " + sender.getDisplayName() + ".");
}
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
sender.print("Players now have god mode.");
}
}
@Command(aliases = {"ungod"}, usage = "[player]",
desc = "Disable godmode on a player", flags = "s", max = 1)
public void ungod(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
Iterable<? extends LocalPlayer> targets;
boolean included = false;
// Detect arguments based on the number of arguments provided
if (args.argsLength() == 0) {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(worldGuard.checkPlayer(sender));
// Check permissions!
sender.checkPermission("worldguard.god");
} else {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(sender, args.getString(0));
// Check permissions!
sender.checkPermission("worldguard.god.other");
}
for (LocalPlayer player : targets) {
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(player);
if (GodMode.set(player, session, false)) {
// Tell the user
if (player.equals(sender)) {
player.print("God mode disabled!");
// Keep track of this
included = true;
} else {
player.print("God disabled by " + sender.getDisplayName() + ".");
}
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
sender.print("Players no longer have god mode.");
}
}
@Command(aliases = {"heal"}, usage = "[player]", desc = "Heal a player", flags = "s", max = 1)
public void heal(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
Iterable<? extends LocalPlayer> targets = null;
boolean included = false;
// Detect arguments based on the number of arguments provided
if (args.argsLength() == 0) {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(worldGuard.checkPlayer(sender));
// Check permissions!
sender.checkPermission("worldguard.heal");
} else if (args.argsLength() == 1) {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(sender, args.getString(0));
// Check permissions!
sender.checkPermission("worldguard.heal.other");
}
for (LocalPlayer player : targets) {
player.setHealth(player.getMaxHealth());
player.setFoodLevel(20);
player.setSaturation(20);
player.setExhaustion(0);
// Tell the user
if (player.equals(sender)) {
player.print("Healed!");
// Keep track of this
included = true;
} else {
player.print("Healed by " + sender.getDisplayName() + ".");
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
sender.print("Players healed.");
}
}
@Command(aliases = {"slay"}, usage = "[player]", desc = "Slay a player", flags = "s", max = 1)
public void slay(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
Iterable<? extends LocalPlayer> targets = Lists.newArrayList();
boolean included = false;
// Detect arguments based on the number of arguments provided
if (args.argsLength() == 0) {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(worldGuard.checkPlayer(sender));
// Check permissions!
sender.checkPermission("worldguard.slay");
} else if (args.argsLength() == 1) {
targets = worldGuard.getPlatform().getMatcher().matchPlayers(sender, args.getString(0));
// Check permissions!
sender.checkPermission("worldguard.slay.other");
}
for (LocalPlayer player : targets) {
player.setHealth(0);
// Tell the user
if (player.equals(sender)) {
player.print("Slain!");
// Keep track of this
included = true;
} else {
player.print("Slain by " + sender.getDisplayName() + ".");
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
sender.print("Players slain.");
}
}
@Command(aliases = {"locate"}, usage = "[player]", desc = "Locate a player", max = 1)
@CommandPermissions({"worldguard.locate"})
public void locate(CommandContext args, Actor sender) throws CommandException {
LocalPlayer player = worldGuard.checkPlayer(sender);
if (args.argsLength() == 0) {
player.setCompassTarget(new Location(player.getWorld(), player.getWorld().getSpawnPosition().toVector3()));
sender.print("Compass reset to spawn.");
} else {
LocalPlayer target = worldGuard.getPlatform().getMatcher().matchSinglePlayer(sender, args.getString(0));
player.setCompassTarget(target.getLocation());
sender.print("Compass repointed.");
}
}
@Command(aliases = {"stack", ";"}, usage = "", desc = "Stack items", max = 0)
@CommandPermissions({"worldguard.stack"})
public void stack(CommandContext args, Actor sender) throws CommandException {
LocalPlayer player = worldGuard.checkPlayer(sender);
WorldGuard.getInstance().getPlatform().stackPlayerInventory(player);
player.print("Items compacted into stacks!");
}
}

View File

@ -17,30 +17,29 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
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;
package com.sk89q.worldguard.commands;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.NestedCommand;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.commands.region.MemberCommands;
import com.sk89q.worldguard.commands.region.RegionCommands;
public class ProtectionCommands {
@SuppressWarnings("unused")
private final WorldGuardPlugin plugin;
private final WorldGuard worldGuard;
public ProtectionCommands(WorldGuardPlugin plugin) {
this.plugin = plugin;
public ProtectionCommands(WorldGuard worldGuard) {
this.worldGuard = worldGuard;
}
@Command(aliases = {"region", "regions", "rg"}, desc = "Region management commands")
@NestedCommand({RegionCommands.class, MemberCommands.class})
public void region(CommandContext args, CommandSender sender) {}
public void region(CommandContext args, Actor sender) {}
@Command(aliases = {"worldguard", "wg"}, desc = "WorldGuard commands")
@NestedCommand({WorldGuardCommands.class})
public void worldGuard(CommandContext args, CommandSender sender) {}
public void worldGuard(CommandContext args, Actor sender) {}
}

View File

@ -17,57 +17,53 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.commands;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
package com.sk89q.worldguard.commands;
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.CommandPermissions;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.util.formatting.Style;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.config.WorldConfiguration;
import com.sk89q.worldguard.util.Entities;
public class ToggleCommands {
private final WorldGuardPlugin plugin;
private final WorldGuard worldGuard;
public ToggleCommands(WorldGuardPlugin plugin) {
this.plugin = plugin;
public ToggleCommands(WorldGuard worldGuard) {
this.worldGuard = worldGuard;
}
@Command(aliases = {"stopfire"}, usage = "[<world>]",
desc = "Disables all fire spread temporarily", max = 1)
@CommandPermissions({"worldguard.fire-toggle.stop"})
public void stopFire(CommandContext args, CommandSender sender) throws CommandException {
public void stopFire(CommandContext args, Actor sender) throws CommandException {
World world;
if (args.argsLength() == 0) {
world = plugin.checkPlayer(sender).getWorld();
world = worldGuard.checkPlayer(sender).getWorld();
} else {
world = plugin.matchWorld(sender, args.getString(0));
world = worldGuard.getPlatform().getMatcher().matchWorld(sender, args.getString(0));
}
BukkitWorldConfiguration wcfg =
(BukkitWorldConfiguration) WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(BukkitAdapter.adapt(world));
WorldConfiguration wcfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world);
if (!wcfg.fireSpreadDisableToggle) {
plugin.getServer().broadcastMessage(
ChatColor.YELLOW
worldGuard.getPlatform().broadcastNotification(
Style.YELLOW
+ "Fire spread has been globally disabled for '" + world.getName() + "' by "
+ plugin.toName(sender) + ".");
+ sender.getDisplayName() + ".");
} else {
sender.sendMessage(
ChatColor.YELLOW
+ "Fire spread was already globally disabled.");
sender.print("Fire spread was already globally disabled.");
}
wcfg.fireSpreadDisableToggle = true;
@ -76,26 +72,24 @@ public void stopFire(CommandContext args, CommandSender sender) throws CommandEx
@Command(aliases = {"allowfire"}, usage = "[<world>]",
desc = "Allows all fire spread temporarily", max = 1)
@CommandPermissions({"worldguard.fire-toggle.stop"})
public void allowFire(CommandContext args, CommandSender sender) throws CommandException {
public void allowFire(CommandContext args, Actor sender) throws CommandException {
World world;
if (args.argsLength() == 0) {
world = plugin.checkPlayer(sender).getWorld();
world = worldGuard.checkPlayer(sender).getWorld();
} else {
world = plugin.matchWorld(sender, args.getString(0));
world = worldGuard.getPlatform().getMatcher().matchWorld(sender, args.getString(0));
}
BukkitWorldConfiguration wcfg =
(BukkitWorldConfiguration) WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(BukkitAdapter.adapt(world));
WorldConfiguration wcfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world);
if (wcfg.fireSpreadDisableToggle) {
plugin.getServer().broadcastMessage(ChatColor.YELLOW
worldGuard.getPlatform().broadcastNotification(Style.YELLOW
+ "Fire spread has been globally for '" + world.getName() + "' re-enabled by "
+ plugin.toName(sender) + ".");
+ sender.getDisplayName() + ".");
} else {
sender.sendMessage(ChatColor.YELLOW
+ "Fire spread was already globally enabled.");
sender.print("Fire spread was already globally enabled.");
}
wcfg.fireSpreadDisableToggle = false;
@ -104,64 +98,57 @@ public void allowFire(CommandContext args, CommandSender sender) throws CommandE
@Command(aliases = {"halt-activity", "stoplag", "haltactivity"},
desc = "Attempts to cease as much activity in order to stop lag", flags = "cis", max = 0)
@CommandPermissions({"worldguard.halt-activity"})
public void stopLag(CommandContext args, CommandSender sender) throws CommandException {
public void stopLag(CommandContext args, Actor sender) throws CommandException {
ConfigurationManager configManager = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
if (args.hasFlag('i')) {
if (configManager.activityHaltToggle) {
sender.sendMessage(ChatColor.YELLOW
+ "ALL intensive server activity is not allowed.");
sender.print("ALL intensive server activity is not allowed.");
} else {
sender.sendMessage(ChatColor.YELLOW
+ "ALL intensive server activity is allowed.");
sender.print("ALL intensive server activity is allowed.");
}
} else {
configManager.activityHaltToggle = !args.hasFlag('c');
if (configManager.activityHaltToggle) {
if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.YELLOW
+ "ALL intensive server activity halted.");
if (!(sender instanceof LocalPlayer)) {
sender.print("ALL intensive server activity halted.");
}
if (!args.hasFlag('s')) {
plugin.getServer().broadcastMessage(ChatColor.YELLOW
worldGuard.getPlatform().broadcastNotification(Style.YELLOW
+ "ALL intensive server activity halted by "
+ plugin.toName(sender) + ".");
+ sender.getDisplayName() + ".");
} else {
sender.sendMessage(ChatColor.YELLOW
+ "(Silent) ALL intensive server activity halted by "
+ plugin.toName(sender) + ".");
sender.print("(Silent) ALL intensive server activity halted by " + sender.getDisplayName() + ".");
}
for (World world : plugin.getServer().getWorlds()) {
for (World world : WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getWorlds()) {
int removed = 0;
for (Entity entity : world.getEntities()) {
if (BukkitUtil.isIntensiveEntity(entity)) {
if (Entities.isIntensiveEntity(entity)) {
entity.remove();
removed++;
}
}
if (removed > 10) {
sender.sendMessage("" + removed + " entities (>10) auto-removed from "
sender.printRaw("" + removed + " entities (>10) auto-removed from "
+ world.getName());
}
}
} else {
if (!args.hasFlag('s')) {
plugin.getServer().broadcastMessage(ChatColor.YELLOW
worldGuard.getPlatform().broadcastNotification(Style.YELLOW
+ "ALL intensive server activity is now allowed.");
if (!(sender instanceof Player)) {
sender.sendMessage(ChatColor.YELLOW
+ "ALL intensive server activity is now allowed.");
if (!(sender instanceof LocalPlayer)) {
sender.print("ALL intensive server activity is now allowed.");
}
} else {
sender.sendMessage(ChatColor.YELLOW
+ "(Silent) ALL intensive server activity is now allowed.");
sender.print("(Silent) ALL intensive server activity is now allowed.");
}
}
}

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.commands;
import com.google.common.io.Files;
import com.google.common.util.concurrent.FutureCallback;
@ -29,37 +29,31 @@
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.NestedCommand;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.AsyncCommandHelper;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldedit.util.formatting.Style;
import com.sk89q.worldedit.util.paste.ActorCallbackPaste;
import com.sk89q.worldedit.util.report.ReportList;
import com.sk89q.worldedit.util.report.SystemInfoReport;
import com.sk89q.worldedit.util.task.Task;
import com.sk89q.worldedit.util.task.TaskStateComparator;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.util.logging.LoggerToChatHandler;
import com.sk89q.worldguard.bukkit.util.report.PerformanceReport;
import com.sk89q.worldguard.bukkit.util.report.PluginReport;
import com.sk89q.worldguard.bukkit.util.report.SchedulerReport;
import com.sk89q.worldguard.bukkit.util.report.ServerReport;
import com.sk89q.worldguard.bukkit.util.report.ServicesReport;
import com.sk89q.worldguard.bukkit.util.report.WorldReport;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.util.logging.LoggerToChatHandler;
import com.sk89q.worldguard.util.profiler.SamplerBuilder;
import com.sk89q.worldguard.util.profiler.SamplerBuilder.Sampler;
import com.sk89q.worldguard.util.profiler.ThreadIdFilter;
import com.sk89q.worldguard.util.profiler.ThreadNameFilter;
import com.sk89q.worldguard.util.report.ConfigReport;
import com.sk89q.worldguard.util.task.Task;
import com.sk89q.worldguard.util.task.TaskStateComparator;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.io.File;
import java.io.IOException;
import java.lang.management.ThreadInfo;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
@ -70,27 +64,26 @@
public class WorldGuardCommands {
private static final Logger log = Logger.getLogger(WorldGuardCommands.class.getCanonicalName());
private final WorldGuardPlugin plugin;
private final WorldGuard worldGuard;
@Nullable
private Sampler activeSampler;
public WorldGuardCommands(WorldGuardPlugin plugin) {
this.plugin = plugin;
public WorldGuardCommands(WorldGuard worldGuard) {
this.worldGuard = worldGuard;
}
@Command(aliases = {"version"}, desc = "Get the WorldGuard version", max = 0)
public void version(CommandContext args, CommandSender sender) throws CommandException {
sender.sendMessage(ChatColor.YELLOW
+ "WorldGuard " + plugin.getDescription().getVersion());
sender.sendMessage(ChatColor.YELLOW
+ "http://www.sk89q.com");
public void version(CommandContext args, Actor sender) throws CommandException {
sender.print("WorldGuard " + WorldGuard.getVersion());
sender.print("http://www.enginehub.org");
sender.printDebug("----------- Platforms -----------");
sender.printDebug(String.format("* %s (%s)", worldGuard.getPlatform().getPlatformName(), worldGuard.getPlatform().getPlatformVersion()));
}
@Command(aliases = {"reload"}, desc = "Reload WorldGuard configuration", max = 0)
@CommandPermissions({"worldguard.reload"})
public void reload(CommandContext args, CommandSender sender) throws CommandException {
public void reload(CommandContext args, Actor sender) throws CommandException {
// TODO: This is subject to a race condition, but at least other commands are not being processed concurrently
List<Task<?>> tasks = WorldGuard.getInstance().getSupervisor().getTasks();
if (!tasks.isEmpty()) {
@ -100,7 +93,7 @@ public void reload(CommandContext args, CommandSender sender) throws CommandExce
LoggerToChatHandler handler = null;
Logger minecraftLogger = null;
if (sender instanceof Player) {
if (sender instanceof LocalPlayer) {
handler = new LoggerToChatHandler(sender);
handler.setLevel(Level.ALL);
minecraftLogger = Logger.getLogger("com.sk89q.worldguard");
@ -116,10 +109,9 @@ public void reload(CommandContext args, CommandSender sender) throws CommandExce
}
WorldGuard.getInstance().getPlatform().getRegionContainer().reload();
// WGBukkit.cleanCache();
sender.sendMessage("WorldGuard configuration reloaded.");
sender.print("WorldGuard configuration reloaded.");
} catch (Throwable t) {
sender.sendMessage("Error while reloading: "
+ t.getMessage());
sender.printError("Error while reloading: " + t.getMessage());
} finally {
if (minecraftLogger != null) {
minecraftLogger.removeHandler(handler);
@ -129,29 +121,24 @@ public void reload(CommandContext args, CommandSender sender) throws CommandExce
@Command(aliases = {"report"}, desc = "Writes a report on WorldGuard", flags = "p", max = 0)
@CommandPermissions({"worldguard.report"})
public void report(CommandContext args, final CommandSender sender) throws CommandException {
public void report(CommandContext args, final Actor sender) throws CommandException, AuthorizationException {
ReportList report = new ReportList("Report");
worldGuard.getPlatform().addPlatformReports(report);
report.add(new SystemInfoReport());
report.add(new ServerReport());
report.add(new PluginReport());
report.add(new SchedulerReport());
report.add(new ServicesReport());
report.add(new WorldReport());
report.add(new PerformanceReport());
report.add(new ConfigReport());
String result = report.toString();
try {
File dest = new File(plugin.getDataFolder(), "report.txt");
File dest = new File(worldGuard.getPlatform().getConfigDir().toFile(), "report.txt");
Files.write(result, dest, Charset.forName("UTF-8"));
sender.sendMessage(ChatColor.YELLOW + "WorldGuard report written to " + dest.getAbsolutePath());
sender.print("WorldGuard report written to " + dest.getAbsolutePath());
} catch (IOException e) {
throw new CommandException("Failed to write report: " + e.getMessage());
}
if (args.hasFlag('p')) {
plugin.checkPermission(sender, "worldguard.report.pastebin");
CommandUtils.pastebin(plugin, sender, result, "WorldGuard report: %s.report");
sender.checkPermission("worldguard.report.pastebin");
ActorCallbackPaste.pastebin(worldGuard.getSupervisor(), sender, result, "WorldGuard report: %s.report", worldGuard.getExceptionConverter());
}
}
@ -159,13 +146,13 @@ public void report(CommandContext args, final CommandSender sender) throws Comma
desc = "Profile the CPU usage of the server", min = 0, max = 1,
flags = "t:p")
@CommandPermissions("worldguard.profile")
public void profile(final CommandContext args, final CommandSender sender) throws CommandException {
public void profile(final CommandContext args, final Actor sender) throws CommandException, AuthorizationException {
Predicate<ThreadInfo> threadFilter;
String threadName = args.getFlag('t');
final boolean pastebin;
if (args.hasFlag('p')) {
plugin.checkPermission(sender, "worldguard.report.pastebin");
sender.checkPermission("worldguard.report.pastebin");
pastebin = true;
} else {
pastebin = false;
@ -204,7 +191,7 @@ public void profile(final CommandContext args, final CommandSender sender) throw
sampler = activeSampler = builder.start();
}
AsyncCommandHelper.wrap(sampler.getFuture(), plugin, sender)
AsyncCommandHelper.wrap(sampler.getFuture(), worldGuard.getSupervisor(), sender, worldGuard.getExceptionConverter())
.formatUsing(minutes)
.registerWithSupervisor("Running CPU profiler for %d minute(s)...")
.sendMessageAfterDelay("(Please wait... profiling for %d minute(s)...)")
@ -222,15 +209,15 @@ public void onSuccess(Sampler result) {
String output = result.toString();
try {
File dest = new File(plugin.getDataFolder(), "profile.txt");
File dest = new File(worldGuard.getPlatform().getConfigDir().toFile(), "profile.txt");
Files.write(output, dest, Charset.forName("UTF-8"));
sender.sendMessage(ChatColor.YELLOW + "CPU profiling data written to " + dest.getAbsolutePath());
sender.print("CPU profiling data written to " + dest.getAbsolutePath());
} catch (IOException e) {
sender.sendMessage(ChatColor.RED + "Failed to write CPU profiling data: " + e.getMessage());
sender.printError("Failed to write CPU profiling data: " + e.getMessage());
}
if (pastebin) {
CommandUtils.pastebin(plugin, sender, output, "Profile result: %s.profile");
ActorCallbackPaste.pastebin(worldGuard.getSupervisor(), sender, output, "Profile result: %s.profile", worldGuard.getExceptionConverter());
}
}
@ -242,7 +229,7 @@ public void onFailure(Throwable throwable) {
@Command(aliases = {"stopprofile"}, usage = "",desc = "Stop a running profile", min = 0, max = 0)
@CommandPermissions("worldguard.profile")
public void stopProfile(CommandContext args, final CommandSender sender) throws CommandException {
public void stopProfile(CommandContext args, final Actor sender) throws CommandException {
synchronized (this) {
if (activeSampler == null) {
throw new CommandException("No CPU profile is currently running.");
@ -252,56 +239,55 @@ public void stopProfile(CommandContext args, final CommandSender sender) throws
activeSampler = null;
}
sender.sendMessage("The running CPU profile has been stopped.");
sender.print("The running CPU profile has been stopped.");
}
@Command(aliases = {"flushstates", "clearstates"},
usage = "[player]", desc = "Flush the state manager", max = 1)
@CommandPermissions("worldguard.flushstates")
public void flushStates(CommandContext args, CommandSender sender) throws CommandException {
public void flushStates(CommandContext args, Actor sender) throws CommandException {
if (args.argsLength() == 0) {
WorldGuard.getInstance().getPlatform().getSessionManager().resetAllStates();
sender.sendMessage("Cleared all states.");
sender.print("Cleared all states.");
} else {
Player player = plugin.getServer().getPlayer(args.getString(0));
LocalPlayer player = worldGuard.getPlatform().getMatcher().matchSinglePlayer(sender, args.getString(0));
if (player != null) {
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
WorldGuard.getInstance().getPlatform().getSessionManager().resetState(localPlayer);
sender.sendMessage("Cleared states for player \"" + localPlayer.getName() + "\".");
WorldGuard.getInstance().getPlatform().getSessionManager().resetState(player);
sender.print("Cleared states for player \"" + player.getName() + "\".");
}
}
}
@Command(aliases = {"running", "queue"}, desc = "List running tasks", max = 0)
@CommandPermissions("worldguard.running")
public void listRunningTasks(CommandContext args, CommandSender sender) throws CommandException {
public void listRunningTasks(CommandContext args, Actor sender) throws CommandException {
List<Task<?>> tasks = WorldGuard.getInstance().getSupervisor().getTasks();
if (!tasks.isEmpty()) {
Collections.sort(tasks, new TaskStateComparator());
tasks.sort(new TaskStateComparator());
StringBuilder builder = new StringBuilder();
builder.append(ChatColor.GRAY);
builder.append(Style.GRAY);
builder.append("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
builder.append(" Running tasks ");
builder.append("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
builder.append("\n").append(ChatColor.GRAY).append("Note: Some 'running' tasks may be waiting to be start.");
builder.append("\n").append(Style.GRAY).append("Note: Some 'running' tasks may be waiting to be start.");
for (Task task : tasks) {
builder.append("\n");
builder.append(ChatColor.BLUE).append("(").append(task.getState().name()).append(") ");
builder.append(ChatColor.YELLOW);
builder.append(Style.BLUE).append("(").append(task.getState().name()).append(") ");
builder.append(Style.YELLOW);
builder.append(CommandUtils.getOwnerName(task.getOwner()));
builder.append(": ");
builder.append(ChatColor.WHITE);
builder.append(Style.WHITE);
builder.append(task.getName());
}
sender.sendMessage(builder.toString());
sender.printRaw(builder.toString());
} else {
sender.sendMessage(ChatColor.YELLOW + "There are currently no running tasks.");
sender.print("There are currently no running tasks.");
}
}
@Command(aliases = {"debug"}, desc = "Debugging commands")
@NestedCommand({DebuggingCommands.class})
public void debug(CommandContext args, CommandSender sender) {}
public void debug(CommandContext args, Actor sender) {}
}

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.commands.region;
package com.sk89q.worldguard.commands.region;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
@ -25,28 +25,25 @@
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.bukkit.BukkitAdapter;
import com.sk89q.worldedit.command.util.AsyncCommandHelper;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
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;
import com.sk89q.worldguard.protection.flags.Flags;
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 com.sk89q.worldguard.protection.util.DomainInputResolver;
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;
public class MemberCommands extends RegionCommandsBase {
private final WorldGuardPlugin plugin;
private final WorldGuard worldGuard;
public MemberCommands(WorldGuardPlugin plugin) {
this.plugin = plugin;
public MemberCommands(WorldGuard worldGuard) {
this.worldGuard = worldGuard;
}
@Command(aliases = {"addmember", "addmember", "addmem", "am"},
@ -54,18 +51,18 @@ public MemberCommands(WorldGuardPlugin plugin) {
flags = "nw:",
desc = "Add a member to a region",
min = 2)
public void addMember(CommandContext args, CommandSender sender) throws CommandException {
public void addMember(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
String id = args.getString(0);
RegionManager manager = checkRegionManager(plugin, BukkitAdapter.adapt(world));
RegionManager manager = checkRegionManager(world);
ProtectedRegion region = checkExistingRegion(manager, id, true);
id = region.getId();
// Check permissions
if (!getPermissionModel(plugin.wrapCommandSender(sender)).mayAddMembers(region)) {
if (!getPermissionModel(sender).mayAddMembers(region)) {
throw new CommandPermissionsException();
}
@ -79,7 +76,7 @@ public void addMember(CommandContext args, CommandSender sender) throws CommandE
WorldGuard.getInstance().getExecutorService().submit(resolver),
resolver.createAddAllFunction(region.getMembers()));
AsyncCommandHelper.wrap(future, plugin, sender)
AsyncCommandHelper.wrap(future, worldGuard.getSupervisor(), sender, worldGuard.getExceptionConverter())
.formatUsing(region.getId(), world.getName())
.registerWithSupervisor("Adding members to the region '%s' on '%s'")
.sendMessageAfterDelay("(Please wait... querying player names...)")
@ -91,22 +88,19 @@ public void addMember(CommandContext args, CommandSender sender) throws CommandE
flags = "nw:",
desc = "Add an owner to a region",
min = 2)
public void addOwner(CommandContext args, CommandSender sender) throws CommandException {
public void addOwner(CommandContext args, Actor sender) throws CommandException, AuthorizationException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
com.sk89q.worldedit.world.World weWorld = BukkitAdapter.adapt(world);
Player player = null;
LocalPlayer localPlayer = null;
if (sender instanceof Player) {
player = (Player) sender;
localPlayer = plugin.wrapPlayer(player);
LocalPlayer player = null;
if (sender instanceof LocalPlayer) {
player = (LocalPlayer) sender;
}
String id = args.getString(0);
RegionManager manager = checkRegionManager(plugin, weWorld);
RegionManager manager = checkRegionManager(world);
ProtectedRegion region = checkExistingRegion(manager, id, true);
id = region.getId();
@ -114,20 +108,20 @@ public void addOwner(CommandContext args, CommandSender sender) throws CommandEx
Boolean flag = region.getFlag(Flags.BUYABLE);
DefaultDomain owners = region.getOwners();
if (localPlayer != null) {
if (player != 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 = ((BukkitWorldConfiguration) WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(weWorld)).getMaxRegionCount(player);
if (maxRegionCount >= 0 && manager.getRegionCountOfPlayer(localPlayer)
if (!sender.hasPermission("worldguard.region.unlimited")) {
int maxRegionCount = WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world).getMaxRegionCount(player);
if (maxRegionCount >= 0 && manager.getRegionCountOfPlayer(player)
>= maxRegionCount) {
throw new CommandException("You already own the maximum allowed amount of regions.");
}
}
plugin.checkPermission(sender, "worldguard.region.addowner.unclaimed." + id.toLowerCase());
sender.checkPermission("worldguard.region.addowner.unclaimed." + id.toLowerCase());
} else {
// Check permissions
if (!getPermissionModel(localPlayer).mayAddOwners(region)) {
if (!getPermissionModel(player).mayAddOwners(region)) {
throw new CommandPermissionsException();
}
}
@ -143,7 +137,7 @@ public void addOwner(CommandContext args, CommandSender sender) throws CommandEx
WorldGuard.getInstance().getExecutorService().submit(resolver),
resolver.createAddAllFunction(region.getOwners()));
AsyncCommandHelper.wrap(future, plugin, sender)
AsyncCommandHelper.wrap(future, worldGuard.getSupervisor(), sender, worldGuard.getExceptionConverter())
.formatUsing(region.getId(), world.getName())
.registerWithSupervisor("Adding owners to the region '%s' on '%s'")
.sendMessageAfterDelay("(Please wait... querying player names...)")
@ -155,16 +149,16 @@ public void addOwner(CommandContext args, CommandSender sender) throws CommandEx
flags = "naw:",
desc = "Remove an owner to a region",
min = 1)
public void removeMember(CommandContext args, CommandSender sender) throws CommandException {
public void removeMember(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
String id = args.getString(0);
RegionManager manager = checkRegionManager(plugin, BukkitAdapter.adapt(world));
RegionManager manager = checkRegionManager(world);
ProtectedRegion region = checkExistingRegion(manager, id, true);
// Check permissions
if (!getPermissionModel(plugin.wrapCommandSender(sender)).mayRemoveMembers(region)) {
if (!getPermissionModel(sender).mayRemoveMembers(region)) {
throw new CommandPermissionsException();
}
@ -190,7 +184,7 @@ public void removeMember(CommandContext args, CommandSender sender) throws Comma
resolver.createRemoveAllFunction(region.getMembers()));
}
AsyncCommandHelper.wrap(future, plugin, sender)
AsyncCommandHelper.wrap(future, worldGuard.getSupervisor(), sender, worldGuard.getExceptionConverter())
.formatUsing(region.getId(), world.getName())
.registerWithSupervisor("Removing members from the region '%s' on '%s'")
.sendMessageAfterDelay("(Please wait... querying player names...)")
@ -202,16 +196,16 @@ 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 {
public void removeOwner(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
String id = args.getString(0);
RegionManager manager = checkRegionManager(plugin, BukkitAdapter.adapt(world));
RegionManager manager = checkRegionManager(world);
ProtectedRegion region = checkExistingRegion(manager, id, true);
// Check permissions
if (!getPermissionModel(plugin.wrapCommandSender(sender)).mayRemoveOwners(region)) {
if (!getPermissionModel(sender).mayRemoveOwners(region)) {
throw new CommandPermissionsException();
}
@ -237,7 +231,7 @@ public void removeOwner(CommandContext args, CommandSender sender) throws Comman
resolver.createRemoveAllFunction(region.getOwners()));
}
AsyncCommandHelper.wrap(future, plugin, sender)
AsyncCommandHelper.wrap(future, worldGuard.getSupervisor(), sender, worldGuard.getExceptionConverter())
.formatUsing(region.getId(), world.getName())
.registerWithSupervisor("Removing owners from the region '%s' on '%s'")
.sendMessageAfterDelay("(Please wait... querying player names...)")

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.commands.region;
package com.sk89q.worldguard.commands.region;
import static com.google.common.base.Preconditions.checkNotNull;
@ -27,30 +27,30 @@
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.bukkit.BukkitAdapter;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.command.util.AsyncCommandHelper;
import com.sk89q.worldedit.command.util.FutureProgressListener;
import com.sk89q.worldedit.command.util.MessageFutureCallback.Builder;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.formatting.Style;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.bukkit.BukkitRegionContainer;
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
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.commands.CommandUtils;
import com.sk89q.worldguard.commands.task.RegionAdder;
import com.sk89q.worldguard.commands.task.RegionLister;
import com.sk89q.worldguard.commands.task.RegionManagerReloader;
import com.sk89q.worldguard.commands.task.RegionManagerSaver;
import com.sk89q.worldguard.commands.task.RegionRemover;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.config.WorldConfiguration;
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
import com.sk89q.worldguard.bukkit.util.logging.LoggerToChatHandler;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.FlagContext;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;
import com.sk89q.worldguard.protection.flags.RegionGroup;
import com.sk89q.worldguard.protection.flags.RegionGroupFlag;
@ -66,13 +66,10 @@
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.regions.RegionContainer;
import com.sk89q.worldguard.protection.util.DomainInputResolver.UserLocatorPolicy;
import com.sk89q.worldguard.util.Enums;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.sk89q.worldguard.util.logging.LoggerToChatHandler;
import java.util.ArrayList;
import java.util.Collections;
@ -86,11 +83,11 @@
public final class RegionCommands extends RegionCommandsBase {
private static final Logger log = Logger.getLogger(RegionCommands.class.getCanonicalName());
private final WorldGuardPlugin plugin;
private final WorldGuard worldGuard;
public RegionCommands(WorldGuardPlugin plugin) {
checkNotNull(plugin);
this.plugin = plugin;
public RegionCommands(WorldGuard worldGuard) {
checkNotNull(worldGuard);
this.worldGuard = worldGuard;
}
/**
@ -105,19 +102,18 @@ public RegionCommands(WorldGuardPlugin plugin) {
flags = "ng",
desc = "Defines a region",
min = 1)
public void define(CommandContext args, CommandSender sender) throws CommandException {
public void define(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
Player player = plugin.checkPlayer(sender);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
LocalPlayer player = worldGuard.checkPlayer(sender);
// Check permissions
if (!getPermissionModel(localPlayer).mayDefine()) {
if (!getPermissionModel(player).mayDefine()) {
throw new CommandPermissionsException();
}
String id = checkRegionId(args.getString(0), false);
RegionManager manager = checkRegionManager(plugin, localPlayer.getWorld());
RegionManager manager = checkRegionManager(player.getWorld());
checkRegionDoesNotExist(manager, id, true);
@ -127,7 +123,7 @@ public void define(CommandContext args, CommandSender sender) throws CommandExce
region = new GlobalProtectedRegion(id);
} else {
region = checkRegionFromSelection(player, id);
warnAboutDimensions(localPlayer, region);
warnAboutDimensions(player, region);
informNewUser(player, manager, region);
}
@ -135,7 +131,7 @@ public void define(CommandContext args, CommandSender sender) throws CommandExce
task.addOwnersFromCommand(args, 2);
ListenableFuture<?> future = WorldGuard.getInstance().getExecutorService().submit(task);
AsyncCommandHelper.wrap(future, plugin, player)
AsyncCommandHelper.wrap(future, worldGuard.getSupervisor(), player, worldGuard.getExceptionConverter())
.formatUsing(id)
.registerWithSupervisor("Adding the region '%s'...")
.sendMessageAfterDelay("(Please wait... adding '%s'...)")
@ -156,21 +152,19 @@ public void define(CommandContext args, CommandSender sender) throws CommandExce
desc = "Re-defines the shape of a region",
flags = "g",
min = 1, max = 1)
public void redefine(CommandContext args, CommandSender sender) throws CommandException {
public void redefine(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
Player player = plugin.checkPlayer(sender);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
World world = player.getWorld();
LocalPlayer player = worldGuard.checkPlayer(sender);
String id = checkRegionId(args.getString(0), false);
RegionManager manager = checkRegionManager(plugin, localPlayer.getWorld());
RegionManager manager = checkRegionManager(player.getWorld());
ProtectedRegion existing = checkExistingRegion(manager, id, false);
// Check permissions
if (!getPermissionModel(localPlayer).mayRedefine(existing)) {
if (!getPermissionModel(player).mayRedefine(existing)) {
throw new CommandPermissionsException();
}
@ -180,7 +174,7 @@ public void redefine(CommandContext args, CommandSender sender) throws CommandEx
region = new GlobalProtectedRegion(id);
} else {
region = checkRegionFromSelection(player, id);
warnAboutDimensions(localPlayer, region);
warnAboutDimensions(player, region);
informNewUser(player, manager, region);
}
@ -189,7 +183,7 @@ public void redefine(CommandContext args, CommandSender sender) throws CommandEx
RegionAdder task = new RegionAdder(manager, region);
ListenableFuture<?> future = WorldGuard.getInstance().getExecutorService().submit(task);
AsyncCommandHelper.wrap(future, plugin, player)
AsyncCommandHelper.wrap(future, worldGuard.getSupervisor(), player, worldGuard.getExceptionConverter())
.formatUsing(id)
.registerWithSupervisor("Updating the region '%s'...")
.sendMessageAfterDelay("(Please wait... updating '%s'...)")
@ -212,12 +206,11 @@ public void redefine(CommandContext args, CommandSender sender) throws CommandEx
usage = "<id>",
desc = "Claim a region",
min = 1, max = 1)
public void claim(CommandContext args, CommandSender sender) throws CommandException {
public void claim(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
Player player = plugin.checkPlayer(sender);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
RegionPermissionModel permModel = getPermissionModel(localPlayer);
LocalPlayer player = worldGuard.checkPlayer(sender);
RegionPermissionModel permModel = getPermissionModel(player);
// Check permissions
if (!permModel.mayClaim()) {
@ -226,19 +219,18 @@ public void claim(CommandContext args, CommandSender sender) throws CommandExcep
String id = checkRegionId(args.getString(0), false);
RegionManager manager = checkRegionManager(plugin, localPlayer.getWorld());
RegionManager manager = checkRegionManager(player.getWorld());
checkRegionDoesNotExist(manager, id, false);
ProtectedRegion region = checkRegionFromSelection(player, id);
BukkitWorldConfiguration wcfg =
(BukkitWorldConfiguration) WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(localPlayer.getWorld());
WorldConfiguration wcfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(player.getWorld());
// Check whether the player has created too many regions
if (!permModel.mayClaimRegionsUnbounded()) {
int maxRegionCount = wcfg.getMaxRegionCount(player);
if (maxRegionCount >= 0
&& manager.getRegionCountOfPlayer(localPlayer) >= maxRegionCount) {
&& manager.getRegionCountOfPlayer(player) >= maxRegionCount) {
throw new CommandException(
"You own too many regions, delete one first to claim a new one.");
}
@ -248,7 +240,7 @@ public void claim(CommandContext args, CommandSender sender) throws CommandExcep
// Check for an existing region
if (existing != null) {
if (!existing.getOwners().contains(localPlayer)) {
if (!existing.getOwners().contains(player)) {
throw new CommandException(
"This region already exists and you don't own it.");
}
@ -259,7 +251,7 @@ public void claim(CommandContext args, CommandSender sender) throws CommandExcep
// Check if this region overlaps any other region
if (regions.size() > 0) {
if (!regions.isOwnerOfAll(localPlayer)) {
if (!regions.isOwnerOfAll(player)) {
throw new CommandException("This region overlaps with someone else's region.");
}
} else {
@ -281,9 +273,8 @@ public void claim(CommandContext args, CommandSender sender) throws CommandExcep
}
if (region.volume() > wcfg.maxClaimVolume) {
player.sendMessage(ChatColor.RED + "This region is too large to claim.");
player.sendMessage(ChatColor.RED +
"Max. volume: " + wcfg.maxClaimVolume + ", your volume: " + region.volume());
player.printError("This region is too large to claim.");
player.printError("Max. volume: " + wcfg.maxClaimVolume + ", your volume: " + region.volume());
return;
}
}
@ -291,9 +282,9 @@ public void claim(CommandContext args, CommandSender sender) throws CommandExcep
RegionAdder task = new RegionAdder(manager, region);
task.setLocatorPolicy(UserLocatorPolicy.UUID_ONLY);
task.setOwnersInput(new String[]{player.getName()});
ListenableFuture<?> future = WorldGuard.getInstance().getExecutorService().submit(task);
ListenableFuture<?> future = worldGuard.getExecutorService().submit(task);
AsyncCommandHelper.wrap(future, plugin, player)
AsyncCommandHelper.wrap(future, worldGuard.getSupervisor(), player, worldGuard.getExceptionConverter())
.formatUsing(id)
.registerWithSupervisor("Claiming the region '%s'...")
.sendMessageAfterDelay("(Please wait... claiming '%s'...)")
@ -313,21 +304,20 @@ public void claim(CommandContext args, CommandSender sender) throws CommandExcep
usage = "[id]",
desc = "Load a region as a WorldEdit selection",
min = 0, max = 1)
public void select(CommandContext args, CommandSender sender) throws CommandException {
Player player = plugin.checkPlayer(sender);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
RegionManager manager = checkRegionManager(plugin, localPlayer.getWorld());
public void select(CommandContext args, Actor sender) throws CommandException {
LocalPlayer player = worldGuard.checkPlayer(sender);
RegionManager manager = checkRegionManager(player.getWorld());
ProtectedRegion existing;
// If no arguments were given, get the region that the player is inside
if (args.argsLength() == 0) {
existing = checkRegionStandingIn(manager, localPlayer);
existing = checkRegionStandingIn(manager, player);
} else {
existing = checkExistingRegion(manager, args.getString(0), false);
}
// Check permissions
if (!getPermissionModel(localPlayer).maySelect(existing)) {
if (!getPermissionModel(player).maySelect(existing)) {
throw new CommandPermissionsException();
}
@ -347,24 +337,22 @@ public void select(CommandContext args, CommandSender sender) throws CommandExce
flags = "usw:",
desc = "Get information about a region",
min = 0, max = 1)
public void info(CommandContext args, CommandSender sender) throws CommandException {
public void info(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
Actor actor = plugin.wrapCommandSender(sender);
RegionPermissionModel permModel = getPermissionModel(actor);
RegionPermissionModel permModel = getPermissionModel(sender);
// Lookup the existing region
RegionManager manager = checkRegionManager(plugin, BukkitAdapter.adapt(world));
RegionManager manager = checkRegionManager(world);
ProtectedRegion existing;
if (args.argsLength() == 0) { // Get region from where the player is
if (!(sender instanceof Player)) {
throw new CommandException("Please specify " +
"the region with /region info -w world_name region_name.");
if (!(sender instanceof LocalPlayer)) {
throw new CommandException("Please specify the region with /region info -w world_name region_name.");
}
existing = checkRegionStandingIn(manager, plugin.wrapPlayer((Player) sender), true);
existing = checkRegionStandingIn(manager, (LocalPlayer) sender, true);
} else { // Get region from the ID
existing = checkExistingRegion(manager, args.getString(0), true);
}
@ -381,7 +369,7 @@ public void info(CommandContext args, CommandSender sender) throws CommandExcept
throw new CommandPermissionsException();
}
setPlayerSelection(plugin.checkPlayer(sender), existing);
setPlayerSelection(worldGuard.checkPlayer(sender), existing);
}
// Print region information
@ -396,7 +384,8 @@ public void info(CommandContext args, CommandSender sender) throws CommandExcept
// Send a response message
Futures.addCallback(future,
new Builder(plugin, sender)
new Builder(sender)
.exceptionConverter(worldGuard.getExceptionConverter())
.onFailure("Failed to fetch region information")
.build());
}
@ -413,13 +402,12 @@ public void info(CommandContext args, CommandSender sender) throws CommandExcept
desc = "Get a list of regions",
flags = "np:w:",
max = 1)
public void list(CommandContext args, CommandSender sender) throws CommandException {
public void list(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
String ownedBy;
Actor actor = plugin.wrapCommandSender(sender);
// Get page
int page = args.getInteger(0, 1) - 1;
if (page < 0) {
@ -434,16 +422,16 @@ public void list(CommandContext args, CommandSender sender) throws CommandExcept
}
// Check permissions
if (!getPermissionModel(actor).mayList(ownedBy)) {
if (!getPermissionModel(sender).mayList(ownedBy)) {
ownedBy = sender.getName(); // assume they only want their own
if (!getPermissionModel(actor).mayList(ownedBy)) {
if (!getPermissionModel(sender).mayList(ownedBy)) {
throw new CommandPermissionsException();
}
}
RegionManager manager = checkRegionManager(plugin, BukkitAdapter.adapt(world));
RegionManager manager = checkRegionManager(world);
RegionLister task = new RegionLister(manager, actor);
RegionLister task = new RegionLister(manager, sender);
task.setPage(page);
if (ownedBy != null) {
task.filterOwnedByName(ownedBy, args.hasFlag('n'));
@ -451,7 +439,7 @@ public void list(CommandContext args, CommandSender sender) throws CommandExcept
ListenableFuture<?> future = WorldGuard.getInstance().getExecutorService().submit(task);
AsyncCommandHelper.wrap(future, plugin, sender)
AsyncCommandHelper.wrap(future, worldGuard.getSupervisor(), sender, worldGuard.getExceptionConverter())
.registerWithSupervisor("Getting list of regions...")
.sendMessageAfterDelay("(Please wait... fetching region list...)")
.thenTellErrorsOnly("Failed to fetch region list");
@ -469,7 +457,7 @@ public void list(CommandContext args, CommandSender sender) throws CommandExcept
flags = "g:w:e",
desc = "Set flags",
min = 2)
public void flag(CommandContext args, CommandSender sender) throws CommandException {
public void flag(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
@ -477,8 +465,7 @@ public void flag(CommandContext args, CommandSender sender) throws CommandExcept
String value = args.argsLength() >= 3 ? args.getJoinedStrings(2) : null;
RegionGroup groupValue = null;
FlagRegistry flagRegistry = WorldGuard.getInstance().getFlagRegistry();
Actor actor = plugin.wrapCommandSender(sender);
RegionPermissionModel permModel = getPermissionModel(actor);
RegionPermissionModel permModel = getPermissionModel(sender);
if (args.hasFlag('e')) {
if (value != null) {
@ -494,7 +481,7 @@ public void flag(CommandContext args, CommandSender sender) throws CommandExcept
}
// Lookup the existing region
RegionManager manager = checkRegionManager(plugin, BukkitAdapter.adapt(world));
RegionManager manager = checkRegionManager(world);
ProtectedRegion existing = checkExistingRegion(manager, args.getString(0), true);
// Check permissions
@ -527,9 +514,9 @@ public void flag(CommandContext args, CommandSender sender) throws CommandExcept
String flag = flagList.get(i);
if (i % 2 == 0) {
list.append(ChatColor.GRAY);
list.append(Style.GRAY);
} else {
list.append(ChatColor.RED);
list.append(Style.RED);
}
list.append(flag);
@ -538,8 +525,8 @@ public void flag(CommandContext args, CommandSender sender) throws CommandExcept
}
}
sender.sendMessage(ChatColor.RED + "Unknown flag specified: " + flagName);
sender.sendMessage(ChatColor.RED + "Available flags: " + list);
sender.printError("Unknown flag specified: " + flagName);
sender.printError("Available flags: " + list);
return;
}
@ -564,7 +551,7 @@ public void flag(CommandContext args, CommandSender sender) throws CommandExcept
// Parse the [-g group] separately so entire command can abort if parsing
// the [value] part throws an error.
try {
groupValue = groupFlag.parseInput(FlagContext.create().setSender(actor).setInput(group).setObject("region", existing).build());
groupValue = groupFlag.parseInput(FlagContext.create().setSender(sender).setInput(group).setObject("region", existing).build());
} catch (InvalidFlagFormat e) {
throw new CommandException(e.getMessage());
}
@ -575,14 +562,12 @@ public void flag(CommandContext args, CommandSender sender) throws CommandExcept
if (value != null) {
// Set the flag if [value] was given even if [-g group] was given as well
try {
setFlag(existing, foundFlag, actor, value);
setFlag(existing, foundFlag, sender, value);
} catch (InvalidFlagFormat e) {
throw new CommandException(e.getMessage());
}
sender.sendMessage(ChatColor.YELLOW
+ "Region flag " + foundFlag.getName() + " set on '" +
existing.getId() + "' to '" + ChatColor.stripColor(value) + "'.");
sender.print("Region flag " + foundFlag.getName() + " set on '" + existing.getId() + "' to '" + Style.stripColor(value) + "'.");
// No value? Clear the flag, if -g isn't specified
} else if (!args.hasFlag('g')) {
@ -595,9 +580,7 @@ public void flag(CommandContext args, CommandSender sender) throws CommandExcept
existing.setFlag(groupFlag, null);
}
sender.sendMessage(ChatColor.YELLOW
+ "Region flag " + foundFlag.getName() + " removed from '" +
existing.getId() + "'. (Any -g(roups) were also removed.)");
sender.print("Region flag " + foundFlag.getName() + " removed from '" + existing.getId() + "'. (Any -g(roups) were also removed.)");
}
// Now set the group
@ -607,19 +590,16 @@ public void flag(CommandContext args, CommandSender sender) throws CommandExcept
// If group set to the default, then clear the group flag
if (groupValue == groupFlag.getDefault()) {
existing.setFlag(groupFlag, null);
sender.sendMessage(ChatColor.YELLOW
+ "Region group flag for '" + foundFlag.getName() + "' reset to " +
"default.");
sender.print("Region group flag for '" + foundFlag.getName() + "' reset to default.");
} else {
existing.setFlag(groupFlag, groupValue);
sender.sendMessage(ChatColor.YELLOW
+ "Region group flag for '" + foundFlag.getName() + "' set.");
sender.print("Region group flag for '" + foundFlag.getName() + "' set.");
}
}
// Print region information
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(existing, null);
printout.append(ChatColor.GRAY);
printout.append(Style.GRAY);
printout.append("(Current flags: ");
printout.appendFlagsList(false);
printout.append(")");
@ -638,26 +618,24 @@ 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 {
public void setPriority(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
int priority = args.getInteger(1);
// Lookup the existing region
RegionManager manager = checkRegionManager(plugin, BukkitAdapter.adapt(world));
RegionManager manager = checkRegionManager(world);
ProtectedRegion existing = checkExistingRegion(manager, args.getString(0), false);
// Check permissions
if (!getPermissionModel(plugin.wrapCommandSender(sender)).maySetPriority(existing)) {
if (!getPermissionModel(sender).maySetPriority(existing)) {
throw new CommandPermissionsException();
}
existing.setPriority(priority);
sender.sendMessage(ChatColor.YELLOW
+ "Priority of '" + existing.getId() + "' set to "
+ priority + " (higher numbers override).");
sender.print("Priority of '" + existing.getId() + "' set to " + priority + " (higher numbers override).");
}
/**
@ -672,7 +650,7 @@ public void setPriority(CommandContext args, CommandSender sender) throws Comman
flags = "w:",
desc = "Set the parent of a region",
min = 1, max = 2)
public void setParent(CommandContext args, CommandSender sender) throws CommandException {
public void setParent(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
@ -680,7 +658,7 @@ public void setParent(CommandContext args, CommandSender sender) throws CommandE
ProtectedRegion child;
// Lookup the existing region
RegionManager manager = checkRegionManager(plugin, BukkitAdapter.adapt(world));
RegionManager manager = checkRegionManager(world);
// Get parent and child
child = checkExistingRegion(manager, args.getString(0), false);
@ -691,7 +669,7 @@ public void setParent(CommandContext args, CommandSender sender) throws CommandE
}
// Check permissions
if (!getPermissionModel(plugin.wrapCommandSender(sender)).maySetParent(child, parent)) {
if (!getPermissionModel(sender).maySetParent(child, parent)) {
throw new CommandPermissionsException();
}
@ -700,14 +678,14 @@ public void setParent(CommandContext args, CommandSender sender) throws CommandE
} catch (CircularInheritanceException e) {
// Tell the user what's wrong
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(parent, null);
printout.append(ChatColor.RED);
printout.append(Style.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);
printout.append(Style.GRAY);
printout.append("(Current inheritance on '" + parent.getId() + "':\n");
printout.appendParentTree(true);
printout.append(ChatColor.GRAY);
printout.append(Style.GRAY);
printout.append(")");
printout.send(sender);
return;
@ -715,13 +693,13 @@ public void setParent(CommandContext args, CommandSender sender) throws CommandE
// Tell the user the current inheritance
RegionPrintoutBuilder printout = new RegionPrintoutBuilder(child, null);
printout.append(ChatColor.YELLOW);
printout.append(Style.YELLOW);
printout.append("Inheritance set for region '" + child.getId() + "'.\n");
if (parent != null) {
printout.append(ChatColor.GRAY);
printout.append(Style.GRAY);
printout.append("(Current inheritance:\n");
printout.appendParentTree(true);
printout.append(ChatColor.GRAY);
printout.append(Style.GRAY);
printout.append(")");
}
printout.send(sender);
@ -739,7 +717,7 @@ public void setParent(CommandContext args, CommandSender sender) throws CommandE
flags = "fuw:",
desc = "Remove a region",
min = 1, max = 1)
public void remove(CommandContext args, CommandSender sender) throws CommandException {
public void remove(CommandContext args, Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = checkWorld(args, sender, 'w'); // Get the world
@ -747,11 +725,11 @@ public void remove(CommandContext args, CommandSender sender) throws CommandExce
boolean unsetParent = args.hasFlag('u');
// Lookup the existing region
RegionManager manager = checkRegionManager(plugin, BukkitAdapter.adapt(world));
RegionManager manager = checkRegionManager(world);
ProtectedRegion existing = checkExistingRegion(manager, args.getString(0), true);
// Check permissions
if (!getPermissionModel(plugin.wrapCommandSender(sender)).mayDelete(existing)) {
if (!getPermissionModel(sender).mayDelete(existing)) {
throw new CommandPermissionsException();
}
@ -765,7 +743,7 @@ public void remove(CommandContext args, CommandSender sender) throws CommandExce
task.setRemovalStrategy(RemovalStrategy.UNSET_PARENT_IN_CHILDREN);
}
AsyncCommandHelper.wrap(WorldGuard.getInstance().getExecutorService().submit(task), plugin, sender)
AsyncCommandHelper.wrap(WorldGuard.getInstance().getExecutorService().submit(task), worldGuard.getSupervisor(), sender, worldGuard.getExceptionConverter())
.formatUsing(existing.getId())
.registerWithSupervisor("Removing the region '%s'...")
.sendMessageAfterDelay("(Please wait... removing '%s'...)")
@ -785,7 +763,7 @@ public void remove(CommandContext args, CommandSender sender) throws CommandExce
usage = "[world]",
desc = "Reload regions from file",
flags = "w:")
public void load(CommandContext args, final CommandSender sender) throws CommandException {
public void load(CommandContext args, final Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = null;
@ -796,12 +774,12 @@ public void load(CommandContext args, final CommandSender sender) throws Command
}
// Check permissions
if (!getPermissionModel(plugin.wrapCommandSender(sender)).mayForceLoadRegions()) {
if (!getPermissionModel(sender).mayForceLoadRegions()) {
throw new CommandPermissionsException();
}
if (world != null) {
RegionManager manager = checkRegionManager(plugin, BukkitAdapter.adapt(world));
RegionManager manager = checkRegionManager(world);
if (manager == null) {
throw new CommandException("No region manager exists for world '" + world.getName() + "'.");
@ -809,14 +787,14 @@ public void load(CommandContext args, final CommandSender sender) throws Command
ListenableFuture<?> future = WorldGuard.getInstance().getExecutorService().submit(new RegionManagerReloader(manager));
AsyncCommandHelper.wrap(future, plugin, sender)
AsyncCommandHelper.wrap(future, worldGuard.getSupervisor(), sender, worldGuard.getExceptionConverter())
.forRegionDataLoad(world, false);
} else {
// Load regions for all worlds
List<RegionManager> managers = new ArrayList<>();
for (World w : Bukkit.getServer().getWorlds()) {
RegionManager manager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(w));
for (World w : WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getWorlds()) {
RegionManager manager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(w);
if (manager != null) {
managers.add(manager);
}
@ -824,7 +802,7 @@ public void load(CommandContext args, final CommandSender sender) throws Command
ListenableFuture<?> future = WorldGuard.getInstance().getExecutorService().submit(new RegionManagerReloader(managers));
AsyncCommandHelper.wrap(future, plugin, sender)
AsyncCommandHelper.wrap(future, worldGuard.getSupervisor(), sender, worldGuard.getExceptionConverter())
.registerWithSupervisor("Loading regions for all worlds")
.sendMessageAfterDelay("(Please wait... loading region data for all worlds...)")
.thenRespondWith(
@ -844,7 +822,7 @@ public void load(CommandContext args, final CommandSender sender) throws Command
usage = "[world]",
desc = "Re-save regions to file",
flags = "w:")
public void save(CommandContext args, final CommandSender sender) throws CommandException {
public void save(CommandContext args, final Actor sender) throws CommandException {
warnAboutSaveFailures(sender);
World world = null;
@ -855,12 +833,12 @@ public void save(CommandContext args, final CommandSender sender) throws Command
}
// Check permissions
if (!getPermissionModel(plugin.wrapCommandSender(sender)).mayForceSaveRegions()) {
if (!getPermissionModel(sender).mayForceSaveRegions()) {
throw new CommandPermissionsException();
}
if (world != null) {
RegionManager manager = checkRegionManager(plugin, BukkitAdapter.adapt(world));
RegionManager manager = checkRegionManager(world);
if (manager == null) {
throw new CommandException("No region manager exists for world '" + world.getName() + "'.");
@ -868,14 +846,14 @@ public void save(CommandContext args, final CommandSender sender) throws Command
ListenableFuture<?> future = WorldGuard.getInstance().getExecutorService().submit(new RegionManagerSaver(manager));
AsyncCommandHelper.wrap(future, plugin, sender)
AsyncCommandHelper.wrap(future, worldGuard.getSupervisor(), sender, worldGuard.getExceptionConverter())
.forRegionDataSave(world, false);
} else {
// Save for all worlds
List<RegionManager> managers = new ArrayList<>();
for (World w : Bukkit.getServer().getWorlds()) {
RegionManager manager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(BukkitAdapter.adapt(w));
for (World w : WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getWorlds()) {
RegionManager manager = WorldGuard.getInstance().getPlatform().getRegionContainer().get(w);
if (manager != null) {
managers.add(manager);
}
@ -883,7 +861,7 @@ public void save(CommandContext args, final CommandSender sender) throws Command
ListenableFuture<?> future = WorldGuard.getInstance().getExecutorService().submit(new RegionManagerSaver(managers));
AsyncCommandHelper.wrap(future, plugin, sender)
AsyncCommandHelper.wrap(future, worldGuard.getSupervisor(), sender, worldGuard.getExceptionConverter())
.registerWithSupervisor("Saving regions for all worlds")
.sendMessageAfterDelay("(Please wait... saving region data for all worlds...)")
.thenRespondWith(
@ -902,9 +880,9 @@ public void save(CommandContext args, final CommandSender sender) throws Command
@Command(aliases = {"migratedb"}, usage = "<from> <to>",
flags = "y",
desc = "Migrate from one Protection Database to another.", min = 2, max = 2)
public void migrateDB(CommandContext args, CommandSender sender) throws CommandException {
public void migrateDB(CommandContext args, Actor sender) throws CommandException {
// Check permissions
if (!getPermissionModel(plugin.wrapCommandSender(sender)).mayMigrateRegionStore()) {
if (!getPermissionModel(sender).mayMigrateRegionStore()) {
throw new CommandPermissionsException();
}
@ -945,7 +923,7 @@ public void migrateDB(CommandContext args, CommandSender sender) throws CommandE
LoggerToChatHandler handler = null;
Logger minecraftLogger = null;
if (sender instanceof Player) {
if (sender instanceof LocalPlayer) {
handler = new LoggerToChatHandler(sender);
handler.setLevel(Level.ALL);
minecraftLogger = Logger.getLogger("com.sk89q.worldguard");
@ -953,10 +931,10 @@ public void migrateDB(CommandContext args, CommandSender sender) throws CommandE
}
try {
BukkitRegionContainer container = (BukkitRegionContainer) WorldGuard.getInstance().getPlatform().getRegionContainer();
sender.sendMessage(ChatColor.YELLOW + "Now performing migration... this may take a while.");
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
sender.print("Now performing migration... this may take a while.");
container.migrate(migration);
sender.sendMessage(ChatColor.YELLOW +
sender.print(
"Migration complete! This only migrated the data. If you already changed your settings to use " +
"the target driver, then WorldGuard is now using the new data. If not, you have to adjust your " +
"configuration to use the new driver and then restart your server.");
@ -979,16 +957,16 @@ public void migrateDB(CommandContext args, CommandSender sender) throws CommandE
*/
@Command(aliases = {"migrateuuid"},
desc = "Migrate loaded databases to use UUIDs", max = 0)
public void migrateUuid(CommandContext args, CommandSender sender) throws CommandException {
public void migrateUuid(CommandContext args, Actor sender) throws CommandException {
// Check permissions
if (!getPermissionModel(plugin.wrapCommandSender(sender)).mayMigrateRegionNames()) {
if (!getPermissionModel(sender).mayMigrateRegionNames()) {
throw new CommandPermissionsException();
}
LoggerToChatHandler handler = null;
Logger minecraftLogger = null;
if (sender instanceof Player) {
if (sender instanceof LocalPlayer) {
handler = new LoggerToChatHandler(sender);
handler.setLevel(Level.ALL);
minecraftLogger = Logger.getLogger("com.sk89q.worldguard");
@ -997,13 +975,13 @@ public void migrateUuid(CommandContext args, CommandSender sender) throws Comman
try {
ConfigurationManager config = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
BukkitRegionContainer container = (BukkitRegionContainer) WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionDriver driver = container.getDriver();
UUIDMigration migration = new UUIDMigration(driver, WorldGuard.getInstance().getProfileService(), WorldGuard.getInstance().getFlagRegistry());
migration.setKeepUnresolvedNames(config.keepUnresolvedNames);
sender.sendMessage(ChatColor.YELLOW + "Now performing migration... this may take a while.");
sender.print("Now performing migration... this may take a while.");
container.migrate(migration);
sender.sendMessage(ChatColor.YELLOW + "Migration complete!");
sender.print("Migration complete!");
} catch (MigrationException e) {
log.log(Level.WARNING, "Failed to migrate", e);
throw new CommandException("Error encountered while migrating: " + e.getMessage());
@ -1026,17 +1004,16 @@ public void migrateUuid(CommandContext args, CommandSender sender) throws Comman
flags = "s",
desc = "Teleports you to the location associated with the region.",
min = 1, max = 1)
public void teleport(CommandContext args, CommandSender sender) throws CommandException {
Player player = plugin.checkPlayer(sender);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
public void teleport(CommandContext args, Actor sender) throws CommandException {
LocalPlayer player = worldGuard.checkPlayer(sender);
Location teleportLocation;
// Lookup the existing region
RegionManager regionManager = checkRegionManager(plugin, localPlayer.getWorld());
RegionManager regionManager = checkRegionManager(player.getWorld());
ProtectedRegion existing = checkExistingRegion(regionManager, args.getString(0), false);
// Check permissions
if (!getPermissionModel(localPlayer).mayTeleportTo(existing)) {
if (!getPermissionModel(player).mayTeleportTo(existing)) {
throw new CommandPermissionsException();
}
@ -1052,12 +1029,11 @@ public void teleport(CommandContext args, CommandSender sender) throws CommandEx
teleportLocation = existing.getFlag(Flags.TELE_LOC);
if (teleportLocation == null) {
throw new CommandException(
"The region has no teleport point associated.");
throw new CommandException("The region has no teleport point associated.");
}
}
player.teleport(BukkitAdapter.adapt(teleportLocation));
sender.sendMessage("Teleported you to the region '" + existing.getId() + "'.");
player.setLocation(teleportLocation);
sender.print("Teleported you to the region '" + existing.getId() + "'.");
}
}

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.commands.region;
package com.sk89q.worldguard.commands.region;
import com.google.common.base.Joiner;
import com.sk89q.minecraft.util.commands.CommandContext;
@ -32,9 +32,10 @@
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector;
import com.sk89q.worldedit.util.formatting.Style;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.internal.permission.RegionPermissionModel;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.Flag;
@ -46,10 +47,6 @@
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Set;
import java.util.stream.Collectors;
@ -79,12 +76,12 @@ protected static RegionPermissionModel getPermissionModel(Actor sender) {
* @return a world
* @throws CommandException on error
*/
protected static World checkWorld(CommandContext args, CommandSender sender, char flag) throws CommandException {
protected static World checkWorld(CommandContext args, Actor sender, char flag) throws CommandException {
if (args.hasFlag(flag)) {
return WorldGuardPlugin.inst().matchWorld(sender, args.getFlag(flag));
return WorldGuard.getInstance().getPlatform().getMatcher().matchWorld(sender, args.getFlag(flag));
} else {
if (sender instanceof Player) {
return WorldGuardPlugin.inst().checkPlayer(sender).getWorld();
if (sender instanceof LocalPlayer) {
return ((LocalPlayer) sender).getWorld();
} else {
throw new CommandException("Please specify " + "the world with -" + flag + " world_name.");
}
@ -217,10 +214,9 @@ protected static ProtectedRegion checkRegionStandingIn(RegionManager regionManag
* @return the selection
* @throws CommandException thrown on an error
*/
protected static Region checkSelection(Player player) throws CommandException {
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
protected static Region checkSelection(LocalPlayer player) throws CommandException {
try {
return WorldEdit.getInstance().getSessionManager().get(localPlayer).getRegionSelector(localPlayer.getWorld()).getRegion();
return WorldEdit.getInstance().getSessionManager().get(player).getRegionSelector(player.getWorld()).getRegion();
} catch (IncompleteRegionException e) {
throw new CommandException(
"Please select an area first. " +
@ -246,11 +242,10 @@ protected static void checkRegionDoesNotExist(RegionManager manager, String id,
/**
* Check that the given region manager is not null.
*
* @param plugin the plugin
* @param world the world
* @throws CommandException thrown if the manager is null
*/
protected static RegionManager checkRegionManager(WorldGuardPlugin plugin, com.sk89q.worldedit.world.World world) throws CommandException {
protected static RegionManager checkRegionManager(com.sk89q.worldedit.world.World world) throws CommandException {
if (!WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world).useRegions) {
throw new CommandException("Region support is disabled in the target world. " +
"It can be enabled per-world in WorldGuard's configuration files. " +
@ -273,7 +268,7 @@ protected static RegionManager checkRegionManager(WorldGuardPlugin plugin, com.s
* @return a new region
* @throws CommandException thrown on an error
*/
protected static ProtectedRegion checkRegionFromSelection(Player player, String id) throws CommandException {
protected static ProtectedRegion checkRegionFromSelection(LocalPlayer player, String id) throws CommandException {
Region selection = checkSelection(player);
// Detect the type of region from WorldEdit
@ -296,14 +291,14 @@ protected static ProtectedRegion checkRegionFromSelection(Player player, String
*
* @param sender the sender to send the message to
*/
protected static void warnAboutSaveFailures(CommandSender sender) {
protected static void warnAboutSaveFailures(Actor sender) {
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
Set<RegionManager> failures = container.getSaveFailures();
if (failures.size() > 0) {
String failingList = Joiner.on(", ").join(failures.stream().map(regionManager -> "'" + regionManager.getName() + "'").collect(Collectors.toList()));
sender.sendMessage(ChatColor.GOLD +
sender.printRaw(Style.YELLOW_DARK +
"(Warning: The background saving of region data is failing for these worlds: " + failingList + ". " +
"Your changes are getting lost. See the server log for more information.)");
}
@ -329,13 +324,13 @@ protected static void warnAboutDimensions(Actor sender, ProtectedRegion region)
* @param manager the region manager
* @param region the region
*/
protected static void informNewUser(CommandSender sender, RegionManager manager, ProtectedRegion region) {
protected static void informNewUser(Actor sender, RegionManager manager, ProtectedRegion region) {
if (manager.getRegions().size() <= 2) {
sender.sendMessage(ChatColor.GRAY +
sender.printRaw(Style.GRAY +
"(This region is NOW PROTECTED from modification from others. " +
"Don't want that? Use " +
ChatColor.AQUA + "/rg flag " + region.getId() + " passthrough allow" +
ChatColor.GRAY + ")");
Style.CYAN + "/rg flag " + region.getId() + " passthrough allow" +
Style.GRAY + ")");
}
}
@ -346,10 +341,8 @@ protected static void informNewUser(CommandSender sender, RegionManager manager,
* @param region the region
* @throws CommandException thrown on a command error
*/
protected static void setPlayerSelection(Player player, ProtectedRegion region) throws CommandException {
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
LocalSession session = WorldEdit.getInstance().getSessionManager().get(localPlayer);
protected static void setPlayerSelection(LocalPlayer player, ProtectedRegion region) throws CommandException {
LocalSession session = WorldEdit.getInstance().getSessionManager().get(player);
// Set selection
if (region instanceof ProtectedCuboidRegion) {
@ -357,17 +350,17 @@ protected static void setPlayerSelection(Player player, ProtectedRegion region)
BlockVector3 pt1 = cuboid.getMinimumPoint();
BlockVector3 pt2 = cuboid.getMaximumPoint();
session.setRegionSelector(localPlayer.getWorld(), new CuboidRegionSelector(localPlayer.getWorld(), pt1, pt2));
player.sendMessage(ChatColor.YELLOW + "Region selected as a cuboid.");
session.setRegionSelector(player.getWorld(), new CuboidRegionSelector(player.getWorld(), pt1, pt2));
player.print("Region selected as a cuboid.");
} else if (region instanceof ProtectedPolygonalRegion) {
ProtectedPolygonalRegion poly2d = (ProtectedPolygonalRegion) region;
Polygonal2DRegionSelector selector = new Polygonal2DRegionSelector(
localPlayer.getWorld(), poly2d.getPoints(),
player.getWorld(), poly2d.getPoints(),
poly2d.getMinimumPoint().getBlockY(),
poly2d.getMaximumPoint().getBlockY() );
session.setRegionSelector(localPlayer.getWorld(), selector);
player.sendMessage(ChatColor.YELLOW + "Region selected as a polygon.");
session.setRegionSelector(player.getWorld(), selector);
player.print("Region selected as a polygon.");
} else if (region instanceof GlobalProtectedRegion) {
throw new CommandException(

View File

@ -17,17 +17,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.commands.region;
package com.sk89q.worldguard.commands.region;
import com.sk89q.squirrelid.cache.ProfileCache;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.util.formatting.Style;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.domains.DefaultDomain;
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 java.util.ArrayList;
import java.util.List;
@ -69,16 +69,16 @@ private void newLine() {
* Add region name, type, and priority.
*/
public void appendBasics() {
builder.append(ChatColor.BLUE);
builder.append(Style.BLUE);
builder.append("Region: ");
builder.append(ChatColor.YELLOW);
builder.append(Style.YELLOW);
builder.append(region.getId());
builder.append(ChatColor.GRAY);
builder.append(Style.GRAY);
builder.append(" (type=");
builder.append(region.getType().getName());
builder.append(ChatColor.GRAY);
builder.append(Style.GRAY);
builder.append(", priority=");
builder.append(region.getPriority());
builder.append(")");
@ -90,7 +90,7 @@ public void appendBasics() {
* Add information about flags.
*/
public void appendFlags() {
builder.append(ChatColor.BLUE);
builder.append(Style.BLUE);
builder.append("FlagUtil: ");
appendFlagsList(true);
@ -118,7 +118,7 @@ public void appendFlagsList(boolean useColors) {
builder.append(", ");
} else {
if (useColors) {
builder.append(ChatColor.YELLOW);
builder.append(Style.YELLOW);
}
}
@ -129,11 +129,11 @@ public void appendFlagsList(boolean useColors) {
if (group == null) {
builder.append(flag.getName()).append(": ")
.append(ChatColor.stripColor(String.valueOf(val)));
.append(Style.stripColor(String.valueOf(val)));
} else {
builder.append(flag.getName()).append(" -g ")
.append(group).append(": ")
.append(ChatColor.stripColor(String.valueOf(val)));
.append(Style.stripColor(String.valueOf(val)));
}
hasFlags = true;
@ -141,7 +141,7 @@ public void appendFlagsList(boolean useColors) {
if (!hasFlags) {
if (useColors) {
builder.append(ChatColor.RED);
builder.append(Style.RED);
}
builder.append("(none)");
}
@ -180,7 +180,7 @@ public void appendParentTree(boolean useColors) {
while (it.hasPrevious()) {
ProtectedRegion cur = it.previous();
if (useColors) {
builder.append(ChatColor.GREEN);
builder.append(Style.GREEN);
}
// Put symbol for child
@ -197,7 +197,7 @@ public void appendParentTree(boolean useColors) {
// Put (parent)
if (!cur.equals(region)) {
if (useColors) {
builder.append(ChatColor.GRAY);
builder.append(Style.GRAY);
}
builder.append(" (parent, priority=").append(cur.getPriority()).append(")");
}
@ -211,12 +211,12 @@ public void appendParentTree(boolean useColors) {
* Add information about members.
*/
public void appendDomain() {
builder.append(ChatColor.BLUE);
builder.append(Style.BLUE);
builder.append("Owners: ");
addDomainString(region.getOwners());
newLine();
builder.append(ChatColor.BLUE);
builder.append(Style.BLUE);
builder.append("Members: ");
addDomainString(region.getMembers());
newLine();
@ -224,10 +224,10 @@ public void appendDomain() {
private void addDomainString(DefaultDomain domain) {
if (domain.size() != 0) {
builder.append(ChatColor.YELLOW);
builder.append(Style.YELLOW);
builder.append(domain.toUserFriendlyString(cache));
} else {
builder.append(ChatColor.RED);
builder.append(Style.RED);
builder.append("(none)");
}
}
@ -238,9 +238,9 @@ private void addDomainString(DefaultDomain domain) {
public void appendBounds() {
BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint();
builder.append(ChatColor.BLUE);
builder.append(Style.BLUE);
builder.append("Bounds:");
builder.append(ChatColor.YELLOW);
builder.append(Style.YELLOW);
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(")");
@ -248,7 +248,7 @@ public void appendBounds() {
}
private void appendRegionInformation() {
builder.append(ChatColor.GRAY);
builder.append(Style.GRAY);
builder.append("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
builder.append(" Region Info ");
builder.append("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
@ -260,7 +260,7 @@ private void appendRegionInformation() {
appendBounds();
if (cache != null) {
builder.append(ChatColor.GRAY).append("Any names suffixed by * are 'last seen names' and may not be up to date.");
builder.append(Style.GRAY).append("Any names suffixed by * are 'last seen names' and may not be up to date.");
newLine();
}
}
@ -272,12 +272,12 @@ public String call() throws Exception {
}
/**
* Send the report to a {@link CommandSender}.
* Send the report to a {@link Actor}.
*
* @param sender the recipient
*/
public void send(CommandSender sender) {
sender.sendMessage(toString());
public void send(Actor sender) {
sender.printRaw(toString());
}
public StringBuilder append(boolean b) {

View File

@ -21,6 +21,7 @@
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.registry.LegacyMapper;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.blacklist.Blacklist;
import com.sk89q.worldedit.util.report.Unreported;
@ -216,4 +217,20 @@ public String convertLegacyBlock(String legacy) {
return block;
}
public int getMaxRegionCount(LocalPlayer player) {
int max = -1;
for (String group : player.getGroups()) {
if (maxRegionCounts.containsKey(group)) {
int groupMax = maxRegionCounts.get(group);
if (max < groupMax) {
max = groupMax;
}
}
}
if (max <= -1) {
max = maxRegionCountPerPlayer;
}
return max;
}
}

View File

@ -17,28 +17,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.util.paste;
package com.sk89q.worldguard.internal.platform;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldguard.LocalPlayer;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public interface DebugHandler {
final class Pasters {
void testBreak(Actor sender, LocalPlayer target, boolean fromTarget, boolean stackTraceMode) throws CommandException;
private static final ListeningExecutorService executor =
MoreExecutors.listeningDecorator(
new ThreadPoolExecutor(0, Integer.MAX_VALUE,
2L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>()));
void testPlace(Actor sender, LocalPlayer target, boolean fromTarget, boolean stackTraceMode) throws CommandException;
private Pasters() {
}
static ListeningExecutorService getExecutor() {
return executor;
}
void testInteract(Actor sender, LocalPlayer target, boolean fromTarget, boolean stackTraceMode) throws CommandException;
void testDamage(Actor sender, LocalPlayer target, boolean fromTarget, boolean stackTraceMode) throws CommandException;
}

View File

@ -0,0 +1,173 @@
/*
* 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.internal.platform;
import com.google.common.collect.Lists;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.commands.CommandUtils;
import java.util.Iterator;
import java.util.List;
public interface StringMatcher {
/**
* Match a world.
*
* The filter string syntax is as follows:
* #main returns the main world
* #normal returns the first world with a normal environment
* #nether return the first world with a nether environment
* #player:[name] returns the world that a player named {@code name} is located in, if the player is online.
* [name] A world with the name {@code name}
*
* @param sender The sender requesting a match
* @param filter The filter string
* @return The resulting world
* @throws CommandException if no world matches
*/
World matchWorld(Actor sender, String filter) throws CommandException;
/**
* Match player names.
*
* The filter string uses the following format:
* @[name] looks up all players with the exact {@code name}
* *[name] matches any player whose name contains {@code name}
* [name] matches any player whose name starts with {@code name}
*
* @param filter The filter string to check.
* @return A {@link List} of players who match {@code filter}
*/
List<LocalPlayer> matchPlayerNames(String filter);
/**
* Checks if the given list of players is greater than size 0, otherwise
* throw an exception.
*
* @param players The {@link List} to check
* @return {@code players} as an {@link Iterable}
* @throws CommandException If {@code players} is empty
*/
default Iterable<? extends LocalPlayer> checkPlayerMatch(List<? extends LocalPlayer> players) throws CommandException {
// Check to see if there were any matches
if (players.size() == 0) {
throw new CommandException("No players matched query.");
}
return players;
}
/**
* Matches players based on the specified filter string
*
* The filter string format is as follows:
* * returns all the players currently online
* If {@code sender} is a {@link Player}:
* #world returns all players in the world that {@code sender} is in
* #near reaturns all players within 30 blocks of {@code sender}'s location
* Otherwise, the format is as specified in {@link #matchPlayerNames(String)}
*
* @param source The CommandSender who is trying to find a player
* @param filter The filter string for players
* @return iterator for players
* @throws CommandException if no matches are found
*/
Iterable<? extends LocalPlayer> matchPlayers(Actor source, String filter) throws CommandException;
/**
* Match only a single player.
*
* @param sender The {@link Actor} who is requesting a player match
* @param filter The filter string.
* @see #matchPlayers(LocalPlayer) for filter string syntax
* @return The single player
* @throws CommandException If more than one player match was found
*/
default LocalPlayer matchSinglePlayer(Actor sender, String filter) throws CommandException {
// This will throw an exception if there are no matches
Iterator<? extends LocalPlayer> players = matchPlayers(sender, filter).iterator();
LocalPlayer match = players.next();
// We don't want to match the wrong person, so fail if if multiple
// players were found (we don't want to just pick off the first one,
// as that may be the wrong player)
if (players.hasNext()) {
throw new CommandException("More than one player found! " +
"Use @<name> for exact matching.");
}
return match;
}
/**
* Match only a single player or console.
*
* The filter string syntax is as follows:
* #console, *console, or ! return the server console
* All syntax from {@link #matchSinglePlayer(Actor, String)}
* @param sender The sender trying to match a CommandSender
* @param filter The filter string
* @return The resulting CommandSender
* @throws CommandException if either zero or more than one player matched.
*/
Actor matchPlayerOrConsole(Actor sender, String filter) throws CommandException;
/**
* Get a single player as an iterator for players.
*
* @param player The player to return in an Iterable
* @return iterator for player
*/
default Iterable<LocalPlayer> matchPlayers(LocalPlayer player) {
return Lists.newArrayList(player);
}
/**
* Gets a world by name, if possible.
*
* @param worldName The name
* @return The world
*/
World getWorldByName(String worldName);
/**
* Replace macros in the text.
*
* The macros replaced are as follows:
* %name%: The name of {@code sender}.
* %id%: The unique name of the sender.
* %online%: The number of players currently online on the server
* If {@code sender} is a Player:
* %world%: The name of the world {@code sender} is located in
* %health%: The health of {@code sender}.
*
* @param sender The sender to check
* @param message The message to replace macros in
* @return The message with macros replaced
*/
String replaceMacros(Actor sender, String message);
}

View File

@ -19,9 +19,9 @@
package com.sk89q.worldguard.internal.platform;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.util.report.ReportList;
import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.protection.flags.FlagContext;
import com.sk89q.worldguard.protection.regions.RegionContainer;
@ -34,6 +34,20 @@
*/
public interface WorldGuardPlatform {
/**
* Gets the name of the platform.
*
* @return The platform name
*/
String getPlatformName();
/**
* Gets the version of the platform.
*
* @return The platform version
*/
String getPlatformVersion();
/**
* Notifies the platform when a flag context is created.
*
@ -50,37 +64,12 @@ public interface WorldGuardPlatform {
ConfigurationManager getGlobalStateManager();
/**
* Gets a world by name, if possible.
* Gets an instance of the matcher, which handles matching
* worlds, players, colours, etc from strings.
*
* @param worldName The name
* @return The world
* @return The matcher
*/
World getWorldByName(String worldName);
/**
* Replaces colour macros.
*
* @param string The string
* @return The replaced string
*/
String replaceColorMacros(String string);
/**
* Replace macros in the text.
*
* The macros replaced are as follows:
* %name%: The name of {@code sender}.
* %id%: The unique name of the sender.
* %online%: The number of players currently online on the server
* If {@code sender} is a Player:
* %world%: The name of the world {@code sender} is located in
* %health%: The health of {@code sender}.
*
* @param sender The sender to check
* @param message The message to replace macros in
* @return The message with macros replaced
*/
String replaceMacros(Actor sender, String message);
StringMatcher getMatcher();
/**
* Gets the session manager.
@ -115,6 +104,13 @@ public interface WorldGuardPlatform {
*/
RegionContainer getRegionContainer();
/**
* Gets the handler for debug commands.
*
* @return The debug handler
*/
DebugHandler getDebugHandler();
/**
* Gets the servers default game mode.
*
@ -128,4 +124,18 @@ public interface WorldGuardPlatform {
* @return The config directory
*/
Path getConfigDir();
/**
* Stack the inventory of the player
*
* @param localPlayer The player
*/
void stackPlayerInventory(LocalPlayer localPlayer);
/**
* Adds reports specific to this platform.
*
* @param report The reportlist
*/
void addPlatformReports(ReportList report);
}

View File

@ -35,7 +35,7 @@ class LazyLocation extends Location {
@Nullable
private static World findWorld(String worldName) {
return WorldGuard.getInstance().getPlatform().getWorldByName(worldName);
return WorldGuard.getInstance().getPlatform().getMatcher().getWorldByName(worldName);
}
public LazyLocation(String worldName, Vector3 position, float yaw, float pitch) {

View File

@ -19,16 +19,24 @@
package com.sk89q.worldguard.protection.regions;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.protection.managers.RegionContainerImpl;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.managers.migration.Migration;
import com.sk89q.worldguard.protection.managers.migration.MigrationException;
import com.sk89q.worldguard.protection.managers.migration.UUIDMigration;
import com.sk89q.worldguard.protection.managers.storage.RegionDriver;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import javax.annotation.Nullable;
@ -52,6 +60,20 @@ public abstract class RegionContainer {
public void initialize() {
ConfigurationManager config = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
container = new RegionContainerImpl(config.selectedRegionStoreDriver, WorldGuard.getInstance().getFlagRegistry());
loadWorlds();
// Migrate to UUIDs
autoMigrate();
}
/**
* Save data and unload.
*/
public void unload() {
synchronized (lock) {
container.unloadAll();
}
}
/**
@ -69,7 +91,12 @@ public RegionDriver getDriver() {
* <p>This method may block until the data for all loaded worlds has been
* unloaded and new data has been loaded.</p>
*/
public abstract void reload();
public void reload() {
synchronized (lock) {
unload();
loadWorlds();
}
}
/**
* Get the region manager for a world if one exists.
@ -116,4 +143,80 @@ public RegionQuery createQuery() {
return new RegionQuery(cache);
}
/**
* Execute a migration and block any loading of region data during
* the migration.
*
* @param migration the migration
* @throws MigrationException thrown by the migration on error
*/
public void migrate(Migration migration) throws MigrationException {
checkNotNull(migration);
synchronized (lock) {
try {
WorldGuard.logger.info("Unloading and saving region data that is currently loaded...");
unload();
migration.migrate();
} finally {
WorldGuard.logger.info("Loading region data for loaded worlds...");
loadWorlds();
}
}
}
/**
* Try loading the region managers for all currently loaded worlds.
*/
protected void loadWorlds() {
synchronized (lock) {
for (World world : WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getWorlds()) {
load(world);
}
}
}
/**
* Unload the region data for a world.
*
* @param world a world
*/
public void unload(World world) {
checkNotNull(world);
synchronized (lock) {
container.unload(world.getName());
}
}
/**
* Execute auto-migration.
*/
protected void autoMigrate() {
ConfigurationManager config = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
if (config.migrateRegionsToUuid) {
RegionDriver driver = getDriver();
UUIDMigration migrator = new UUIDMigration(driver, WorldGuard.getInstance().getProfileService(), WorldGuard.getInstance().getFlagRegistry());
migrator.setKeepUnresolvedNames(config.keepUnresolvedNames);
try {
migrate(migrator);
WorldGuard.logger.info("Regions saved after UUID migration! This won't happen again unless " +
"you change the relevant configuration option in WorldGuard's config.");
config.disableUuidMigration();
} catch (MigrationException e) {
WorldGuard.logger.log(Level.WARNING, "Failed to execute the migration", e);
}
}
}
/**
* Load the region data for a world if it has not been loaded already.
*
* @param world the world
* @return a region manager, either returned from the cache or newly loaded
*/
@Nullable protected abstract RegionManager load(World world);
}

View File

@ -0,0 +1,177 @@
package com.sk89q.worldguard.session;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.session.handler.EntryFlag;
import com.sk89q.worldguard.session.handler.ExitFlag;
import com.sk89q.worldguard.session.handler.FarewellFlag;
import com.sk89q.worldguard.session.handler.FeedFlag;
import com.sk89q.worldguard.session.handler.GameModeFlag;
import com.sk89q.worldguard.session.handler.GodMode;
import com.sk89q.worldguard.session.handler.GreetingFlag;
import com.sk89q.worldguard.session.handler.Handler;
import com.sk89q.worldguard.session.handler.HealFlag;
import com.sk89q.worldguard.session.handler.InvincibilityFlag;
import com.sk89q.worldguard.session.handler.NotifyEntryFlag;
import com.sk89q.worldguard.session.handler.NotifyExitFlag;
import com.sk89q.worldguard.session.handler.TimeLockFlag;
import com.sk89q.worldguard.session.handler.WaterBreathing;
import com.sk89q.worldguard.session.handler.WeatherLockFlag;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public abstract class AbstractSessionManager implements SessionManager {
public static final int RUN_DELAY = 20;
public static final long SESSION_LIFETIME = 10;
private final LoadingCache<WorldPlayerTuple, Boolean> bypassCache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterAccess(2, TimeUnit.SECONDS)
.build(new CacheLoader<WorldPlayerTuple, Boolean>() {
@Override
public Boolean load(@Nonnull WorldPlayerTuple tuple) throws Exception {
return tuple.getPlayer().hasPermission("worldguard.region.bypass." + tuple.getWorld().getName());
}
});
private final LoadingCache<CacheKey, Session> sessions = CacheBuilder.newBuilder()
.expireAfterAccess(SESSION_LIFETIME, TimeUnit.MINUTES)
.build(new CacheLoader<CacheKey, Session>() {
@Override
public Session load(@Nonnull CacheKey key) throws Exception {
return createSession(key.playerRef.get());
}
});
private LinkedList<Handler.Factory<? extends Handler>> handlers = new LinkedList<>();
private static final Set<Handler.Factory<? extends Handler>> defaultHandlers = new HashSet<>();
static {
Handler.Factory<?>[] factories = {
HealFlag.FACTORY,
FeedFlag.FACTORY,
NotifyEntryFlag.FACTORY,
NotifyExitFlag.FACTORY,
EntryFlag.FACTORY,
ExitFlag.FACTORY,
FarewellFlag.FACTORY,
GreetingFlag.FACTORY,
GameModeFlag.FACTORY,
InvincibilityFlag.FACTORY,
TimeLockFlag.FACTORY,
WeatherLockFlag.FACTORY,
GodMode.FACTORY,
WaterBreathing.FACTORY
};
defaultHandlers.addAll(Arrays.asList(factories));
}
public AbstractSessionManager() {
handlers.addAll(defaultHandlers);
}
@Override
public boolean registerHandler(Handler.Factory<? extends Handler> factory, @Nullable Handler.Factory<? extends Handler> after) {
if (factory == null) return false;
WorldGuard.logger.log(Level.INFO, "Registering session handler "
+ factory.getClass().getEnclosingClass().getName());
if (after == null) {
handlers.add(factory);
} else {
int index = handlers.indexOf(after);
if (index == -1) return false;
handlers.add(index, factory); // shifts "after" right one, and everything after "after" right one
}
return true;
}
@Override
public boolean unregisterHandler(Handler.Factory<? extends Handler> factory) {
if (defaultHandlers.contains(factory)) {
WorldGuard.logger.log(Level.WARNING, "Someone is unregistering a default WorldGuard handler: "
+ factory.getClass().getEnclosingClass().getName() + ". This may cause parts of WorldGuard to stop functioning");
} else {
WorldGuard.logger.log(Level.INFO, "Unregistering session handler "
+ factory.getClass().getEnclosingClass().getName());
}
return handlers.remove(factory);
}
@Override
public boolean hasBypass(LocalPlayer player, World world) {
return bypassCache.getUnchecked(new WorldPlayerTuple(world, player));
}
@Override
public void resetState(LocalPlayer player) {
checkNotNull(player, "player");
@Nullable Session session = sessions.getIfPresent(new CacheKey(player));
if (session != null) {
session.resetState(player);
}
}
@Override
@Nullable
public Session getIfPresent(LocalPlayer player) {
return sessions.getIfPresent(player);
}
@Override
public Session get(LocalPlayer player) {
return sessions.getUnchecked(new CacheKey(player));
}
@Override
public Session createSession(LocalPlayer player) {
Session session = new Session(this);
for (Handler.Factory<? extends Handler> factory : handlers) {
session.register(factory.create(session));
}
session.initialize(player);
return session;
}
protected static final class CacheKey {
final WeakReference<LocalPlayer> playerRef;
final UUID uuid;
CacheKey(LocalPlayer player) {
playerRef = new WeakReference<>(player);
uuid = player.getUniqueId();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CacheKey cacheKey = (CacheKey) o;
return uuid.equals(cacheKey.uuid);
}
@Override
public int hashCode() {
return uuid.hashCode();
}
}
}

View File

@ -23,6 +23,7 @@
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.commands.CommandUtils;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
@ -57,7 +58,7 @@ public boolean onCrossBoundary(LocalPlayer player, Location from, Location to, A
long now = System.currentTimeMillis();
if ((now - lastMessage) > MESSAGE_THRESHOLD && message != null && !message.isEmpty()) {
player.printRaw(WorldGuard.getInstance().getPlatform().replaceColorMacros(message));
player.printRaw(CommandUtils.replaceColorMacros(message));
lastMessage = now;
}

View File

@ -23,6 +23,7 @@
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.commands.CommandUtils;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.flags.StateFlag;
@ -60,7 +61,7 @@ private void sendMessage(LocalPlayer player) {
long now = System.currentTimeMillis();
if ((now - lastMessage) > MESSAGE_THRESHOLD && storedMessage != null && !storedMessage.isEmpty()) {
player.printRaw(WorldGuard.getInstance().getPlatform().replaceColorMacros(storedMessage));
player.printRaw(CommandUtils.replaceColorMacros(storedMessage));
lastMessage = now;
}
}

View File

@ -23,6 +23,7 @@
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.commands.CommandUtils;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
@ -74,8 +75,8 @@ public boolean onCrossBoundary(LocalPlayer player, Location from, Location to, A
for (String message : lastMessageStack) {
if (!messages.contains(message)) {
String effective = WorldGuard.getInstance().getPlatform().replaceColorMacros(message);
effective = WorldGuard.getInstance().getPlatform().replaceMacros(player, effective);
String effective = CommandUtils.replaceColorMacros(message);
effective = WorldGuard.getInstance().getPlatform().getMatcher().replaceMacros(player, effective);
for (String mess : effective.replaceAll("\\\\n", "\n").split("\\n")) {
player.printRaw(mess);
}

View File

@ -23,6 +23,7 @@
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.commands.CommandUtils;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
@ -55,8 +56,8 @@ public boolean onCrossBoundary(LocalPlayer player, Location from, Location to, A
for (String message : messages) {
if (!lastMessageStack.contains(message)) {
String effective = WorldGuard.getInstance().getPlatform().replaceColorMacros(message);
effective = WorldGuard.getInstance().getPlatform().replaceMacros(player, effective);
String effective = CommandUtils.replaceColorMacros(message);
effective = WorldGuard.getInstance().getPlatform().getMatcher().replaceMacros(player, effective);
for (String mess : effective.replaceAll("\\\\n", "\n").split("\\n")) {
player.printRaw(mess);
}

View File

@ -0,0 +1,48 @@
/*
* 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.util;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.metadata.EntityProperties;
public class Entities {
private Entities() {
}
/**
* Returns whether an entity should be removed for the halt activity mode.
*
* @param entity The entity
* @return true if it's to be removed
*/
public static boolean isIntensiveEntity(Entity entity) {
EntityProperties properties = entity.getFacet(EntityProperties.class);
return properties != null
&& (properties.isItem()
|| properties.isTNT()
|| properties.isExperienceOrb()
|| properties.isFallingBlock()
|| (properties.isLiving()
&& !(properties.isTamed())
&& !(properties.isPlayerDerived())
&& !properties.isArmorStand()));
}
}

View File

@ -0,0 +1,91 @@
/*
* 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.util;
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.util.command.parametric.ExceptionConverterHelper;
import com.sk89q.worldedit.util.command.parametric.ExceptionMatch;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.protection.managers.storage.StorageException;
import com.sk89q.worldguard.protection.util.UnresolvedNamesException;
import java.util.concurrent.CancellationException;
import java.util.concurrent.RejectedExecutionException;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WorldGuardExceptionConverter extends ExceptionConverterHelper {
private static final Pattern numberFormat = Pattern.compile("^For input string: \"(.*)\"$");
private final WorldGuard worldGuard;
public WorldGuardExceptionConverter(WorldGuard worldGuard) {
checkNotNull(worldGuard);
this.worldGuard = worldGuard;
}
@ExceptionMatch
public void convert(NumberFormatException e) throws CommandException {
final Matcher matcher = numberFormat.matcher(e.getMessage());
if (matcher.matches()) {
throw new CommandException("Number expected; string \"" + matcher.group(1)
+ "\" given.");
} else {
throw new CommandException("Number expected; string given.");
}
}
@ExceptionMatch
public void convert(StorageException e) throws CommandException {
WorldGuard.logger.log(Level.WARNING, "Error loading/saving regions", e);
throw new CommandException("Region data could not be loaded/saved: " + e.getMessage());
}
@ExceptionMatch
public void convert(RejectedExecutionException e) throws CommandException {
throw new CommandException("There are currently too many tasks queued to add yours. Use /wg running to list queued and running tasks.", e);
}
@ExceptionMatch
public void convert(CancellationException e) throws CommandException {
throw new CommandException("WorldGuard: Task was cancelled.", e);
}
@ExceptionMatch
public void convert(InterruptedException e) throws CommandException {
throw new CommandException("WorldGuard: Task was interrupted.", e);
}
@ExceptionMatch
public void convert(WorldEditException e) throws CommandException {
throw new CommandException(e.getMessage(), e);
}
@ExceptionMatch
public void convert(UnresolvedNamesException e) throws CommandException {
throw new CommandException(e.getMessage(), e);
}
}

View File

@ -17,10 +17,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.util.logging;
package com.sk89q.worldguard.util.logging;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.formatting.Style;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
@ -32,14 +32,14 @@ public class LoggerToChatHandler extends Handler {
/**
* Player.
*/
private CommandSender player;
private Actor player;
/**
* Construct the object.
*
* @param player
*/
public LoggerToChatHandler(CommandSender player) {
public LoggerToChatHandler(Actor player) {
this.player = player;
}
@ -62,7 +62,6 @@ public void flush() {
*/
@Override
public void publish(LogRecord record) {
player.sendMessage(ChatColor.GRAY + record.getLevel().getName() + ": "
+ ChatColor.WHITE + record.getMessage());
player.printDebug(record.getLevel().getName() + ": " + Style.WHITE + record.getMessage());
}
}

View File

@ -1,490 +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.util.net;
import com.sk89q.worldguard.util.io.Closer;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HttpRequest implements Closeable {
private static final int CONNECT_TIMEOUT = 1000 * 5;
private static final int READ_TIMEOUT = 1000 * 5;
private static final int READ_BUFFER_SIZE = 1024 * 8;
private final Map<String, String> headers = new HashMap<>();
private final String method;
private final URL url;
private String contentType;
private byte[] body;
private HttpURLConnection conn;
private InputStream inputStream;
private long contentLength = -1;
private long readBytes = 0;
/**
* Create a new HTTP request.
*
* @param method the method
* @param url the URL
*/
private HttpRequest(String method, URL url) {
this.method = method;
this.url = url;
}
/**
* Submit data.
*
* @return this object
*/
public HttpRequest body(String data) {
body = data.getBytes();
return this;
}
/**
* Submit form data.
*
* @param form the form
* @return this object
*/
public HttpRequest bodyForm(Form form) {
contentType = "application/x-www-form-urlencoded";
body = form.toString().getBytes();
return this;
}
/**
* Add a header.
*
* @param key the header key
* @param value the header value
* @return this object
*/
public HttpRequest header(String key, String value) {
if (key.equalsIgnoreCase("Content-Type")) {
contentType = value;
} else {
headers.put(key, value);
}
return this;
}
/**
* Execute the request.
* <p/>
* After execution, {@link #close()} should be called.
*
* @return this object
* @throws java.io.IOException on I/O error
*/
public HttpRequest execute() throws IOException {
boolean successful = false;
try {
if (conn != null) {
throw new IllegalArgumentException("Connection already executed");
}
conn = (HttpURLConnection) reformat(url).openConnection();
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Java)");
if (body != null) {
conn.setRequestProperty("Content-Type", contentType);
conn.setRequestProperty("Content-Length", Integer.toString(body.length));
conn.setDoInput(true);
}
for (Map.Entry<String, String> entry : headers.entrySet()) {
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
conn.setRequestMethod(method);
conn.setUseCaches(false);
conn.setDoOutput(true);
conn.setConnectTimeout(CONNECT_TIMEOUT);
conn.setReadTimeout(READ_TIMEOUT);
conn.connect();
if (body != null) {
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.write(body);
out.flush();
out.close();
}
inputStream = conn.getResponseCode() == HttpURLConnection.HTTP_OK ?
conn.getInputStream() : conn.getErrorStream();
successful = true;
} finally {
if (!successful) {
close();
}
}
return this;
}
/**
* Require that the response code is one of the given response codes.
*
* @param codes a list of codes
* @return this object
* @throws java.io.IOException if there is an I/O error or the response code is not expected
*/
public HttpRequest expectResponseCode(int... codes) throws IOException {
int responseCode = getResponseCode();
for (int code : codes) {
if (code == responseCode) {
return this;
}
}
close();
throw new IOException("Did not get expected response code, got " + responseCode + " for " + url);
}
/**
* Get the response code.
*
* @return the response code
* @throws java.io.IOException on I/O error
*/
public int getResponseCode() throws IOException {
if (conn == null) {
throw new IllegalArgumentException("No connection has been made");
}
return conn.getResponseCode();
}
/**
* Get the input stream.
*
* @return the input stream
*/
public InputStream getInputStream() {
return inputStream;
}
/**
* Buffer the returned response.
*
* @return the buffered response
* @throws java.io.IOException on I/O error
* @throws InterruptedException on interruption
*/
public BufferedResponse returnContent() throws IOException, InterruptedException {
if (inputStream == null) {
throw new IllegalArgumentException("No input stream available");
}
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int b = 0;
while ((b = inputStream.read()) != -1) {
bos.write(b);
}
return new BufferedResponse(bos.toByteArray());
} finally {
close();
}
}
/**
* Save the result to a file.
*
* @param file the file
* @return this object
* @throws java.io.IOException on I/O error
* @throws InterruptedException on interruption
*/
public HttpRequest saveContent(File file) throws IOException, InterruptedException {
Closer closer = Closer.create();
try {
FileOutputStream fos = closer.register(new FileOutputStream(file));
BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
saveContent(bos);
} finally {
closer.close();
}
return this;
}
/**
* Save the result to an output stream.
*
* @param out the output stream
* @return this object
* @throws java.io.IOException on I/O error
* @throws InterruptedException on interruption
*/
public HttpRequest saveContent(OutputStream out) throws IOException, InterruptedException {
BufferedInputStream bis;
try {
String field = conn.getHeaderField("Content-Length");
if (field != null) {
long len = Long.parseLong(field);
if (len >= 0) { // Let's just not deal with really big numbers
contentLength = len;
}
}
} catch (NumberFormatException ignored) {
}
try {
bis = new BufferedInputStream(inputStream);
byte[] data = new byte[READ_BUFFER_SIZE];
int len = 0;
while ((len = bis.read(data, 0, READ_BUFFER_SIZE)) >= 0) {
out.write(data, 0, len);
readBytes += len;
}
} finally {
close();
}
return this;
}
@Override
public void close() throws IOException {
if (conn != null) conn.disconnect();
}
/**
* Perform a GET request.
*
* @param url the URL
* @return a new request object
*/
public static HttpRequest get(URL url) {
return request("GET", url);
}
/**
* Perform a POST request.
*
* @param url the URL
* @return a new request object
*/
public static HttpRequest post(URL url) {
return request("POST", url);
}
/**
* Perform a request.
*
* @param method the method
* @param url the URL
* @return a new request object
*/
public static HttpRequest request(String method, URL url) {
return new HttpRequest(method, url);
}
/**
* Create a new {@link java.net.URL} and throw a {@link RuntimeException} if the URL
* is not valid.
*
* @param url the url
* @return a URL object
* @throws RuntimeException if the URL is invalid
*/
public static URL url(String url) {
try {
return new URL(url);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
/**
* URL may contain spaces and other nasties that will cause a failure.
*
* @param existing the existing URL to transform
* @return the new URL, or old one if there was a failure
*/
private static URL reformat(URL existing) {
try {
URL url = new URL(existing.toString());
URI uri = new URI(
url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(),
url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();
return url;
} catch (MalformedURLException e) {
return existing;
} catch (URISyntaxException e) {
return existing;
}
}
/**
* Used with {@link #bodyForm(Form)}.
*/
public final static class Form {
public final List<String> elements = new ArrayList<>();
private Form() {
}
/**
* Add a key/value to the form.
*
* @param key the key
* @param value the value
* @return this object
*/
public Form add(String key, String value) {
try {
elements.add(URLEncoder.encode(key, "UTF-8") +
"=" + URLEncoder.encode(value, "UTF-8"));
return this;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
boolean first = true;
for (String element : elements) {
if (first) {
first = false;
} else {
builder.append("&");
}
builder.append(element);
}
return builder.toString();
}
/**
* Create a new form.
*
* @return a new form
*/
public static Form create() {
return new Form();
}
}
/**
* Used to buffer the response in memory.
*/
public class BufferedResponse {
private final byte[] data;
private BufferedResponse(byte[] data) {
this.data = data;
}
/**
* Return the result as bytes.
*
* @return the data
*/
public byte[] asBytes() {
return data;
}
/**
* Return the result as a string.
*
* @param encoding the encoding
* @return the string
* @throws java.io.IOException on I/O error
*/
public String asString(String encoding) throws IOException {
return new String(data, encoding);
}
/**
* Save the result to a file.
*
* @param file the file
* @return this object
* @throws java.io.IOException on I/O error
* @throws InterruptedException on interruption
*/
public BufferedResponse saveContent(File file) throws IOException, InterruptedException {
Closer closer = Closer.create();
file.getParentFile().mkdirs();
try {
FileOutputStream fos = closer.register(new FileOutputStream(file));
BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
saveContent(bos);
} finally {
closer.close();
}
return this;
}
/**
* Save the result to an output stream.
*
* @param out the output stream
* @return this object
* @throws java.io.IOException on I/O error
* @throws InterruptedException on interruption
*/
public BufferedResponse saveContent(OutputStream out) throws IOException, InterruptedException {
out.write(data);
return this;
}
}
}

View File

@ -1,79 +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.util.paste;
import com.google.common.util.concurrent.ListenableFuture;
import com.sk89q.worldguard.util.net.HttpRequest;
import com.sk89q.worldguard.util.net.HttpRequest.Form;
import org.json.simple.JSONValue;
import java.io.IOException;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class EngineHubPaste implements Paster {
private static final Pattern URL_PATTERN = Pattern.compile("https?://.+$");
@Override
public ListenableFuture<URL> paste(String content) {
return Pasters.getExecutor().submit(new PasteTask(content));
}
private final class PasteTask implements Callable<URL> {
private final String content;
private PasteTask(String content) {
this.content = content;
}
@Override
public URL call() throws IOException, InterruptedException {
Form form = Form.create();
form.add("content", content);
form.add("from", "worldguard");
URL url = HttpRequest.url("http://paste.enginehub.org/paste");
String result = HttpRequest.post(url)
.bodyForm(form)
.execute()
.expectResponseCode(200)
.returnContent()
.asString("UTF-8").trim();
Object object = JSONValue.parse(result);
if (object instanceof Map) {
@SuppressWarnings("unchecked")
String urlString = String.valueOf(((Map<Object, Object>) object).get("url"));
Matcher m = URL_PATTERN.matcher(urlString);
if (m.matches()) {
return new URL(urlString);
}
}
throw new IOException("Failed to save paste; instead, got: " + result);
}
}
}

View File

@ -1,94 +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.util.paste;
import com.google.common.util.concurrent.ListenableFuture;
import com.sk89q.worldguard.util.net.HttpRequest;
import com.sk89q.worldguard.util.net.HttpRequest.Form;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.Callable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Pastebin implements Paster {
private static final Pattern URL_PATTERN = Pattern.compile("https?://pastebin.com/([^/]+)$");
private boolean mungingLinks = true;
public boolean isMungingLinks() {
return mungingLinks;
}
public void setMungingLinks(boolean mungingLinks) {
this.mungingLinks = mungingLinks;
}
@Override
public ListenableFuture<URL> paste(String content) {
if (mungingLinks) {
content = content.replaceAll("http://", "http_//");
}
return Pasters.getExecutor().submit(new PasteTask(content));
}
private final class PasteTask implements Callable<URL> {
private final String content;
private PasteTask(String content) {
this.content = content;
}
@Override
public URL call() throws IOException, InterruptedException {
Form form = Form.create();
form.add("api_option", "paste");
form.add("api_dev_key", "4867eae74c6990dbdef07c543cf8f805");
form.add("api_paste_code", content);
form.add("api_paste_private", "0");
form.add("api_paste_name", "");
form.add("api_paste_expire_date", "1W");
form.add("api_paste_format", "text");
form.add("api_user_key", "");
URL url = HttpRequest.url("http://pastebin.com/api/api_post.php");
String result = HttpRequest.post(url)
.bodyForm(form)
.execute()
.expectResponseCode(200)
.returnContent()
.asString("UTF-8").trim();
Matcher m = URL_PATTERN.matcher(result);
if (m.matches()) {
return new URL("http://pastebin.com/raw.php?i=" + m.group(1));
} else if (result.matches("^https?://.+")) {
return new URL(result);
} else {
throw new IOException("Failed to save paste; instead, got: " + result);
}
}
}
}

View File

@ -1,30 +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.util.paste;
import com.google.common.util.concurrent.ListenableFuture;
import java.net.URL;
public interface Paster {
ListenableFuture<URL> paste(String content);
}

View File

@ -1,74 +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.util.task;
import com.google.common.util.concurrent.AbstractFuture;
import javax.annotation.Nullable;
import java.util.Date;
import java.util.UUID;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An abstract task that stores a name and owner.
*
* @param <V> the type returned
*/
public abstract class AbstractTask<V> extends AbstractFuture<V> implements Task<V> {
private final UUID uniqueId = UUID.randomUUID();
private final String name;
private final Object owner;
private final Date creationDate = new Date();
/**
* Create a new instance.
*
* @param name the name
* @param owner the owner
*/
protected AbstractTask(String name, @Nullable Object owner) {
checkNotNull(name);
this.name = name;
this.owner = owner;
}
@Override
public UUID getUniqueId() {
return uniqueId;
}
@Override
public String getName() {
return name;
}
@Nullable
@Override
public Object getOwner() {
return owner;
}
@Override
public Date getCreationDate() {
return creationDate;
}
}

View File

@ -1,121 +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.util.task;
import com.google.common.util.concurrent.ListenableFuture;
import com.sk89q.worldguard.util.task.progress.Progress;
import javax.annotation.Nullable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* A task that wraps a {@code ListenableFuture}.
*
* <p>{@link State#SCHEDULED} is never returned because it is not possible
* to test whether the future has "started," so {@link State#RUNNING} is
* returned in its place.</p>
*
* <p>Use {@link #create(ListenableFuture, String, Object)} to create a new
* instance.</p>
*
* @param <V> the type returned
*/
public class FutureForwardingTask<V> extends AbstractTask<V> {
private final ListenableFuture<V> future;
private FutureForwardingTask(ListenableFuture<V> future, String name, @Nullable Object owner) {
super(name, owner);
checkNotNull(future);
this.future = future;
}
@Override
public void addListener(Runnable listener, Executor executor) {
future.addListener(listener, executor);
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return future.cancel(mayInterruptIfRunning);
}
@Override
public boolean isCancelled() {
return future.isCancelled();
}
@Override
public boolean isDone() {
return future.isDone();
}
@Override
public V get() throws InterruptedException, ExecutionException {
return future.get();
}
@Override
public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return future.get(timeout, unit);
}
@Override
public State getState() {
if (isCancelled()) {
return State.CANCELLED;
} else if (isDone()) {
try {
get();
return State.SUCCEEDED;
} catch (InterruptedException e) {
return State.CANCELLED;
} catch (ExecutionException e) {
return State.FAILED;
}
} else {
return State.RUNNING;
}
}
@Override
public Progress getProgress() {
return Progress.indeterminate();
}
/**
* Create a new instance.
*
* @param future the future
* @param name the name of the task
* @param owner the owner of the task, or {@code null}
* @param <V> the type returned by the future
* @return a new instance
*/
public static <V> com.sk89q.worldguard.util.task.FutureForwardingTask<V> create(ListenableFuture<V> future, String name, @Nullable Object owner) {
return new com.sk89q.worldguard.util.task.FutureForwardingTask<V>(future, name, owner);
}
}

View File

@ -1,62 +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.util.task;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An implementation of a {@code Supervisor}.
*/
public class SimpleSupervisor implements Supervisor {
private final List<Task<?>> monitored = new ArrayList<>();
private final Object lock = new Object();
@Override
public List<Task<?>> getTasks() {
synchronized (lock) {
return new ArrayList<>(monitored);
}
}
@Override
public void monitor(final Task<?> task) {
checkNotNull(task);
synchronized (lock) {
monitored.add(task);
}
task.addListener(new Runnable() {
@Override
public void run() {
synchronized (lock) {
monitored.remove(task);
}
}
}, MoreExecutors.directExecutor());
}
}

View File

@ -1,44 +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.util.task;
import java.util.List;
/**
* Manages running tasks and informs users of their progress, but does not
* execute the task.
*/
public interface Supervisor {
/**
* Get a list of running or queued tasks.
*
* @return a list of tasks
*/
List<Task<?>> getTasks();
/**
* Monitor the given task.
*
* @param task the task
*/
void monitor(Task<?> task);
}

View File

@ -1,97 +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.util.task;
import com.google.common.util.concurrent.ListenableFuture;
import com.sk89q.worldguard.util.task.progress.ProgressObservable;
import javax.annotation.Nullable;
import java.util.Date;
import java.util.UUID;
/**
* A task is a job that can be scheduled, run, or cancelled. Tasks can report
* on their own status. Tasks have owners.
*/
public interface Task<V> extends ListenableFuture<V>, ProgressObservable {
/**
* Get the unique ID of this task.
*
* @return this task's unique ID
*/
UUID getUniqueId();
/**
* Get the name of the task so it can be printed to the user.
*
* @return the name of the task
*/
String getName();
/**
* Get the owner of the task.
*
* @return an owner object, if one is known or valid, otherwise {@code null}
*/
@Nullable
Object getOwner();
/**
* Get the state of the task.
*
* @return the state of the task
*/
State getState();
/**
* Get the time at which the task was created.
*
* @return a date
*/
Date getCreationDate();
/**
* Represents the state of a task.
*/
public enum State {
/**
* The task has been scheduled to run but is not running yet.
*/
SCHEDULED,
/**
* The task has been cancelled and may be stopped or will stop.
*/
CANCELLED,
/**
* The task is currently running.
*/
RUNNING,
/**
* The task has failed.
*/
FAILED,
/**
* The task has succeeded.
*/
SUCCEEDED
}
}

View File

@ -1,43 +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.util.task;
import java.util.Comparator;
/**
* Compares task states according to the order of the {@link com.sk89q.worldguard.util.task.Task.State}
* enumeration.
*/
public class TaskStateComparator implements Comparator<com.sk89q.worldguard.util.task.Task<?>> {
@Override
public int compare(com.sk89q.worldguard.util.task.Task<?> o1, Task<?> o2) {
int ordinal1 = o1.getState().ordinal();
int ordinal2 = o2.getState().ordinal();
if (ordinal1 < ordinal2) {
return -1;
} else if (ordinal1 > ordinal2) {
return 1;
} else {
return 0;
}
}
}

View File

@ -1,183 +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.util.task.progress;
import java.util.Arrays;
import java.util.Collection;
/**
* A progress object describes the progress of an operation, specifying
* either a percentage of completion or a status of indeterminacy.
*
* <p>Progress objects are immutable.</p>
*
* <p>To create a new instance, use one of the static constructors
* on this class.</p>
*/
public abstract class Progress {
/**
* Create a new instance.
*/
private Progress() {
}
/**
* Return whether the current progress is indeterminate.
*
* @return true if indeterminate
*/
public abstract boolean isIndeterminate();
/**
* Get the progress percentage.
*
* <p>If {@link #isIndeterminate()} returns {@code true}, the behavior
* of this method is undefined.</p>
*
* @return a number in the range [0, 1]
*/
public abstract double getProgress();
/**
* Get a static progress object that is indeterminate.
*
* @return a progress object
*/
public static com.sk89q.worldguard.util.task.progress.Progress indeterminate() {
return INDETERMINATE;
}
/**
* Get a static progress object that is complete.
*
* @return a progress object
*/
public static com.sk89q.worldguard.util.task.progress.Progress completed() {
return COMPLETED;
}
/**
* Create a new progress object with the given percentage.
*
* @param value the percentage, which will be clamped to [0, 1]
* @return a progress object
*/
public static com.sk89q.worldguard.util.task.progress.Progress of(double value) {
if (value < 0) {
value = 0;
} else if (value > 1) {
value = 1;
}
final double finalValue = value;
return new com.sk89q.worldguard.util.task.progress.Progress() {
@Override
public boolean isIndeterminate() {
return false;
}
@Override
public double getProgress() {
return finalValue;
}
};
}
/**
* Create a new progress object with progress split equally between the
* given progress objects.
*
* @param objects an array of progress objects
* @return a new progress value
*/
public static com.sk89q.worldguard.util.task.progress.Progress split(com.sk89q.worldguard.util.task.progress.Progress... objects) {
return split(Arrays.asList(objects));
}
/**
* Create a new progress object with progress split equally between the
* given progress objects.
*
* @param progress a collection of progress objects
* @return a new progress value
*/
public static com.sk89q.worldguard.util.task.progress.Progress split(Collection<com.sk89q.worldguard.util.task.progress.Progress> progress) {
int count = 0;
double total = 0;
for (com.sk89q.worldguard.util.task.progress.Progress p : progress) {
if (p.isIndeterminate()) {
return indeterminate();
}
total += p.getProgress();
}
return of(total / count);
}
/**
* Create a new progress object with progress split equally between the
* given {@link com.sk89q.worldguard.util.task.progress.ProgressObservable}s.
*
* @param observables an array of observables
* @return a new progress value
*/
public static com.sk89q.worldguard.util.task.progress.Progress splitObservables(com.sk89q.worldguard.util.task.progress.ProgressObservable... observables) {
return splitObservables(Arrays.asList(observables));
}
/**
* Create a new progress object with progress split equally between the
* given {@link com.sk89q.worldguard.util.task.progress.ProgressObservable}s.
*
* @param observables a collection of observables
* @return a new progress value
*/
public static com.sk89q.worldguard.util.task.progress.Progress splitObservables(Collection<? extends com.sk89q.worldguard.util.task.progress.ProgressObservable> observables) {
int count = 0;
double total = 0;
for (ProgressObservable observable : observables) {
com.sk89q.worldguard.util.task.progress.Progress p = observable.getProgress();
if (p.isIndeterminate()) {
return indeterminate();
}
total += p.getProgress();
}
return of(total / count);
}
private static final com.sk89q.worldguard.util.task.progress.Progress COMPLETED = of(1);
private static final com.sk89q.worldguard.util.task.progress.Progress INDETERMINATE = new com.sk89q.worldguard.util.task.progress.Progress() {
@Override
public boolean isIndeterminate() {
return true;
}
@Override
public double getProgress() {
return 0;
}
};
}

View File

@ -1,100 +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.util.task.progress;
import java.util.Iterator;
import java.util.List;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An iterator that keeps track of how many entries have been visited and
* calculates a "percent completed" using a provided total count.
*
* <p>The returned progress percentage will always be between 0 or 1
* (inclusive). If the iterator returns more entries than the total count,
* then 100% will be returned for the progress.</p>
*
* @param <V> the type
*/
public class ProgressIterator<V> implements Iterator<V>, ProgressObservable {
private final Iterator<V> iterator;
private final int count;
private int visited = 0;
/**
* Create a new instance.
*
* @param iterator the iterator
* @param count the count
*/
private ProgressIterator(Iterator<V> iterator, int count) {
checkNotNull(iterator);
this.iterator = iterator;
this.count = count;
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public V next() {
V value = iterator.next();
visited++;
return value;
}
@Override
public void remove() {
iterator.remove();
}
@Override
public Progress getProgress() {
return Progress.of(count > 0 ? Math.min(1, Math.max(0, (visited / (double) count))) : 1);
}
/**
* Create a new instance.
*
* @param iterator the iterator
* @param count the number of objects
* @param <V> the type
* @return an instance
*/
public static <V> com.sk89q.worldguard.util.task.progress.ProgressIterator<V> create(Iterator<V> iterator, int count) {
return new com.sk89q.worldguard.util.task.progress.ProgressIterator<V>(iterator, count);
}
/**
* Create a new instance from a list.
*
* @param list a list
* @param <V> the type
* @return an instance
*/
public static <V> com.sk89q.worldguard.util.task.progress.ProgressIterator<V> create(List<V> list) {
return create(list.iterator(), list.size());
}
}

View File

@ -1,34 +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.util.task.progress;
/**
* An object that is able to report on its progress.
*/
public interface ProgressObservable {
/**
* Get the current percentage of completion.
*
* @return a progress object
*/
Progress getProgress();
}

View File

@ -32,6 +32,12 @@ compile project(':worldguard-core')
}
}
jar {
manifest {
attributes("Implementation-Version": version)
}
}
shadowJar {
dependencies {
include(dependency(':worldguard-core'))

View File

@ -17,12 +17,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.commands;
package com.sk89q.worldguard.bukkit;
import com.sk89q.minecraft.util.commands.*;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.event.debug.*;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.formatting.Style;
import com.sk89q.worldedit.util.paste.ActorCallbackPaste;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.event.debug.CancelLogging;
import com.sk89q.worldguard.bukkit.event.debug.LoggingBlockBreakEvent;
import com.sk89q.worldguard.bukkit.event.debug.LoggingBlockPlaceEvent;
import com.sk89q.worldguard.bukkit.event.debug.LoggingEntityDamageByEntityEvent;
import com.sk89q.worldguard.bukkit.event.debug.LoggingPlayerInteractEvent;
import com.sk89q.worldguard.bukkit.util.report.CancelReport;
import com.sk89q.worldguard.internal.platform.DebugHandler;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@ -34,68 +45,22 @@
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.util.BlockIterator;
import java.util.logging.Logger;
public class DebuggingCommands {
public class BukkitDebugHandler implements DebugHandler {
private static final Logger log = Logger.getLogger(DebuggingCommands.class.getCanonicalName());
private static final Logger log = Logger.getLogger(BukkitDebugHandler.class.getCanonicalName());
private static final int MAX_TRACE_DISTANCE = 20;
private final WorldGuardPlugin plugin;
/**
* Create a new instance.
*
* @param plugin The plugin instance
*/
public DebuggingCommands(WorldGuardPlugin plugin) {
BukkitDebugHandler(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
@Command(aliases = {"testbreak"}, usage = "[player]", desc = "Simulate a block break", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void fireBreakEvent(CommandContext args, final CommandSender sender) throws CommandException {
Player target = plugin.matchSinglePlayer(sender, args.getString(0));
Block block = traceBlock(sender, target, args.hasFlag('t'));
sender.sendMessage(ChatColor.AQUA + "Testing BLOCK BREAK at " + ChatColor.DARK_AQUA + block);
LoggingBlockBreakEvent event = new LoggingBlockBreakEvent(block, target);
testEvent(sender, target, event, args.hasFlag('s'));
}
@Command(aliases = {"testplace"}, usage = "[player]", desc = "Simulate a block place", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void firePlaceEvent(CommandContext args, final CommandSender sender) throws CommandException {
Player target = plugin.matchSinglePlayer(sender, args.getString(0));
Block block = traceBlock(sender, target, args.hasFlag('t'));
sender.sendMessage(ChatColor.AQUA + "Testing BLOCK PLACE at " + ChatColor.DARK_AQUA + block);
LoggingBlockPlaceEvent event = new LoggingBlockPlaceEvent(block, block.getState(), block.getRelative(BlockFace.DOWN), target.getItemInHand(), target, true);
testEvent(sender, target, event, args.hasFlag('s'));
}
@Command(aliases = {"testinteract"}, usage = "[player]", desc = "Simulate a block interact", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void fireInteractEvent(CommandContext args, final CommandSender sender) throws CommandException {
Player target = plugin.matchSinglePlayer(sender, args.getString(0));
Block block = traceBlock(sender, target, args.hasFlag('t'));
sender.sendMessage(ChatColor.AQUA + "Testing BLOCK INTERACT at " + ChatColor.DARK_AQUA + block);
LoggingPlayerInteractEvent event = new LoggingPlayerInteractEvent(target, Action.RIGHT_CLICK_BLOCK, target.getItemInHand(), block, BlockFace.SOUTH);
testEvent(sender, target, event, args.hasFlag('s'));
}
@Command(aliases = {"testdamage"}, usage = "[player]", desc = "Simulate an entity damage", min = 1, max = 1, flags = "ts")
@CommandPermissions("worldguard.debug.event")
public void fireDamageEvent(CommandContext args, final CommandSender sender) throws CommandException {
Player target = plugin.matchSinglePlayer(sender, args.getString(0));
Entity entity = traceEntity(sender, target, args.hasFlag('t'));
sender.sendMessage(ChatColor.AQUA + "Testing ENTITY DAMAGE on " + ChatColor.DARK_AQUA + entity);
LoggingEntityDamageByEntityEvent event = new LoggingEntityDamageByEntityEvent(target, entity, DamageCause.ENTITY_ATTACK, 1);
testEvent(sender, target, event, args.hasFlag('s'));
}
/**
* Simulate an event and print its report.
*
@ -105,7 +70,8 @@ public void fireDamageEvent(CommandContext args, final CommandSender sender) thr
* @param stacktraceMode Whether stack traces should be generated and posted
* @param <T> The type of event
*/
private <T extends Event & CancelLogging> void testEvent(CommandSender receiver, Player target, T event, boolean stacktraceMode) throws CommandPermissionsException {
private <T extends Event & CancelLogging> void testEvent(CommandSender receiver, Player target, T event, boolean stacktraceMode) throws
CommandPermissionsException {
boolean isConsole = receiver instanceof ConsoleCommandSender;
if (!receiver.equals(target)) {
@ -128,7 +94,9 @@ private <T extends Event & CancelLogging> void testEvent(CommandSender receiver,
log.info("Event report for " + receiver.getName() + ":\n\n" + result);
plugin.checkPermission(receiver, "worldguard.debug.pastebin");
CommandUtils.pastebin(plugin, receiver, result, "Event debugging report: %s.txt");
ActorCallbackPaste
.pastebin(WorldGuard.getInstance().getSupervisor(), plugin.wrapCommandSender(receiver), result,
"Event debugging report: %s.txt", WorldGuard.getInstance().getExceptionConverter());
} else {
receiver.sendMessage(result.replaceAll("(?m)^", ChatColor.AQUA.toString()));
@ -217,4 +185,46 @@ private Entity traceEntity(CommandSender sender, Player target, boolean fromTarg
throw new CommandException("Not currently looking at an entity that is close enough.");
}
@Override
public void testBreak(Actor sender, LocalPlayer target, boolean fromTarget, boolean stackTraceMode) throws CommandException {
CommandSender bukkitSender = plugin.unwrapActor(sender);
Player bukkitTarget = BukkitAdapter.adapt(target);
Block block = traceBlock(bukkitSender, bukkitTarget, fromTarget);
sender.printRaw(Style.CYAN + "Testing BLOCK BREAK at " + Style.CYAN_DARK + block);
LoggingBlockBreakEvent event = new LoggingBlockBreakEvent(block, bukkitTarget);
testEvent(bukkitSender, bukkitTarget, event, stackTraceMode);
}
@Override
public void testPlace(Actor sender, LocalPlayer target, boolean fromTarget, boolean stackTraceMode) throws CommandException {
CommandSender bukkitSender = plugin.unwrapActor(sender);
Player bukkitTarget = BukkitAdapter.adapt(target);
Block block = traceBlock(bukkitSender, bukkitTarget, fromTarget);
sender.printRaw(Style.CYAN + "Testing BLOCK PLACE at " + Style.CYAN_DARK + block);
LoggingBlockPlaceEvent event = new LoggingBlockPlaceEvent(block, block.getState(), block.getRelative(BlockFace.DOWN), bukkitTarget.getItemInHand(), bukkitTarget, true);
testEvent(bukkitSender, bukkitTarget, event, stackTraceMode);
}
@Override
public void testInteract(Actor sender, LocalPlayer target, boolean fromTarget, boolean stackTraceMode) throws CommandException {
CommandSender bukkitSender = plugin.unwrapActor(sender);
Player bukkitTarget = BukkitAdapter.adapt(target);
Block block = traceBlock(bukkitSender, bukkitTarget, fromTarget);
sender.printRaw(Style.CYAN + "Testing BLOCK INTERACT at " + Style.CYAN_DARK + block);
LoggingPlayerInteractEvent event = new LoggingPlayerInteractEvent(bukkitTarget, Action.RIGHT_CLICK_BLOCK, bukkitTarget.getItemInHand(), block, BlockFace.SOUTH);
testEvent(bukkitSender, bukkitTarget, event, stackTraceMode);
}
@Override
public void testDamage(Actor sender, LocalPlayer target, boolean fromTarget, boolean stackTraceMode) throws CommandException {
CommandSender bukkitSender = plugin.unwrapActor(sender);
Player bukkitTarget = BukkitAdapter.adapt(target);
Entity entity = traceEntity(bukkitSender, bukkitTarget, fromTarget);
sender.printRaw(Style.CYAN + "Testing ENTITY DAMAGE on " + Style.CYAN_DARK + entity);
LoggingEntityDamageByEntityEvent event = new LoggingEntityDamageByEntityEvent(bukkitTarget, entity, EntityDamageEvent.DamageCause.ENTITY_ATTACK, 1);
testEvent(bukkitSender, bukkitTarget, event, stackTraceMode);
}
}

View File

@ -102,6 +102,16 @@ public void setSaturation(double saturation) {
}
@Override
public float getExhaustion() {
return 0;
}
@Override
public void setExhaustion(float exhaustion) {
}
@Override
public WeatherType getPlayerWeather() {
return WeatherTypes.CLEAR;
@ -202,6 +212,11 @@ public Location getLocation() {
return null;
}
@Override
public void setCompassTarget(Location location) {
}
@Override
public SessionKey getSessionKey() {
return null;

View File

@ -19,7 +19,9 @@
package com.sk89q.worldguard.bukkit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldedit.world.weather.WeatherTypes;
import com.sk89q.worldguard.LocalPlayer;
@ -30,8 +32,8 @@
public class BukkitPlayer extends com.sk89q.worldedit.bukkit.BukkitPlayer implements LocalPlayer {
private final WorldGuardPlugin plugin;
private final String name;
private final boolean silenced;
private String name;
public BukkitPlayer(WorldGuardPlugin plugin, Player player) {
this(plugin, player, false);
@ -40,13 +42,15 @@ public BukkitPlayer(WorldGuardPlugin plugin, Player player) {
BukkitPlayer(WorldGuardPlugin plugin, Player player, boolean silenced) {
super((WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit"), player);
this.plugin = plugin;
// getName() takes longer than before in newer versions of Minecraft
this.name = player == null ? null : player.getName();
this.silenced = silenced;
}
@Override
public String getName() {
if (this.name == null) {
// getName() takes longer than before in newer versions of Minecraft
this.name = getPlayer().getName();
}
return name;
}
@ -105,6 +109,16 @@ public void setSaturation(double saturation) {
getPlayer().setSaturation((float) saturation);
}
@Override
public float getExhaustion() {
return getPlayer().getExhaustion();
}
@Override
public void setExhaustion(float exhaustion) {
getPlayer().setExhaustion(exhaustion);
}
@Override
public WeatherType getPlayerWeather() {
return null;
@ -140,6 +154,21 @@ public void resetPlayerTime() {
getPlayer().resetPlayerTime();
}
@Override
public int getFireTicks() {
return getPlayer().getFireTicks();
}
@Override
public void setFireTicks(int fireTicks) {
getPlayer().setFireTicks(fireTicks);
}
@Override
public void setCompassTarget(Location location) {
getPlayer().setCompassTarget(BukkitAdapter.adapt(location));
}
@Override
public String[] getGroups() {
return plugin.getGroups(getPlayer());
@ -148,7 +177,7 @@ public String[] getGroups() {
@Override
public void printRaw(String msg) {
if (!silenced) {
getPlayer().sendMessage(msg);
super.printRaw(msg);
}
}

View File

@ -22,18 +22,15 @@
import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.config.WorldConfiguration;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.managers.migration.Migration;
import com.sk89q.worldguard.protection.managers.migration.MigrationException;
import com.sk89q.worldguard.protection.managers.migration.UUIDMigration;
import com.sk89q.worldguard.protection.managers.storage.RegionDriver;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkLoadEvent;
@ -43,15 +40,11 @@
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
public class BukkitRegionContainer extends RegionContainer {
private static final Logger log = Logger.getLogger(BukkitRegionContainer.class.getCanonicalName());
/**
* Invalidation frequency in ticks.
*/
@ -71,21 +64,15 @@ public BukkitRegionContainer(WorldGuardPlugin plugin) {
@Override
public void initialize() {
super.initialize();
loadWorlds();
// Migrate to UUIDs
autoMigrate();
Bukkit.getPluginManager().registerEvents(new Listener() {
@EventHandler
public void onWorldLoad(WorldLoadEvent event) {
load(event.getWorld());
load(BukkitAdapter.adapt(event.getWorld()));
}
@EventHandler
public void onWorldUnload(WorldUnloadEvent event) {
unload(event.getWorld());
unload(BukkitAdapter.adapt(event.getWorld()));
}
@EventHandler
@ -110,60 +97,12 @@ public void onChunkUnload(ChunkUnloadEvent event) {
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, cache::invalidateAll, CACHE_INVALIDATION_INTERVAL, CACHE_INVALIDATION_INTERVAL);
}
/**
* Save data and unload.
*/
void unload() {
synchronized (lock) {
container.unloadAll();
}
}
/**
* Get the region store driver.
*
* @return the driver
*/
public RegionDriver getDriver() {
return container.getDriver();
}
/**
* Try loading the region managers for all currently loaded worlds.
*/
private void loadWorlds() {
synchronized (lock) {
for (World world : Bukkit.getServer().getWorlds()) {
load(world);
}
}
}
/**
* Reload the region container.
*
* <p>This method may block until the data for all loaded worlds has been
* unloaded and new data has been loaded.</p>
*/
public void reload() {
synchronized (lock) {
unload();
loadWorlds();
}
}
/**
* Load the region data for a world if it has not been loaded already.
*
* @param world the world
* @return a region manager, either returned from the cache or newly loaded
*/
@Override
@Nullable
private RegionManager load(World world) {
protected RegionManager load(World world) {
checkNotNull(world);
BukkitWorldConfiguration config =
(BukkitWorldConfiguration) WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(BukkitAdapter.adapt(world));
WorldConfiguration config = WorldGuard.getInstance().getPlatform().getGlobalStateManager().get(world);
if (!config.useRegions) {
return null;
}
@ -176,7 +115,7 @@ private RegionManager load(World world) {
if (manager != null) {
// Bias the region data for loaded chunks
List<BlockVector2> positions = new ArrayList<>();
for (Chunk chunk : world.getLoadedChunks()) {
for (Chunk chunk : ((BukkitWorld) world).getWorld().getLoadedChunks()) {
positions.add(BlockVector2.at(chunk.getX(), chunk.getZ()));
}
manager.loadChunks(positions);
@ -186,62 +125,4 @@ private RegionManager load(World world) {
return manager;
}
/**
* Unload the region data for a world.
*
* @param world a world
*/
void unload(World world) {
checkNotNull(world);
synchronized (lock) {
container.unload(world.getName());
}
}
/**
* Execute a migration and block any loading of region data during
* the migration.
*
* @param migration the migration
* @throws MigrationException thrown by the migration on error
*/
public void migrate(Migration migration) throws MigrationException {
checkNotNull(migration);
synchronized (lock) {
try {
log.info("Unloading and saving region data that is currently loaded...");
unload();
migration.migrate();
} finally {
log.info("Loading region data for loaded worlds...");
loadWorlds();
}
}
}
/**
* Execute auto-migration.
*/
private void autoMigrate() {
ConfigurationManager config = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
if (config.migrateRegionsToUuid) {
RegionDriver driver = getDriver();
UUIDMigration migrator = new UUIDMigration(driver, WorldGuard.getInstance().getProfileService(), WorldGuard.getInstance().getFlagRegistry());
migrator.setKeepUnresolvedNames(config.keepUnresolvedNames);
try {
migrate(migrator);
log.info("Regions saved after UUID migration! This won't happen again unless " +
"you change the relevant configuration option in WorldGuard's config.");
config.disableUuidMigration();
} catch (MigrationException e) {
log.log(Level.WARNING, "Failed to execute the migration", e);
}
}
}
}

View File

@ -0,0 +1,242 @@
/*
* 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;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.commands.CommandUtils;
import com.sk89q.worldguard.internal.platform.StringMatcher;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
public class BukkitStringMatcher implements StringMatcher {
@Override
public World matchWorld(Actor sender, String filter) throws CommandException {
List<? extends World> worlds = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getWorlds();
// Handle special hash tag groups
if (filter.charAt(0) == '#') {
// #main for the main world
if (filter.equalsIgnoreCase("#main")) {
return worlds.get(0);
// #normal for the first normal world
} else if (filter.equalsIgnoreCase("#normal")) {
for (World world : worlds) {
if (BukkitAdapter.adapt(world).getEnvironment() == org.bukkit.World.Environment.NORMAL) {
return world;
}
}
throw new CommandException("No normal world found.");
// #nether for the first nether world
} else if (filter.equalsIgnoreCase("#nether")) {
for (World world : worlds) {
if (BukkitAdapter.adapt(world).getEnvironment() == org.bukkit.World.Environment.NETHER) {
return world;
}
}
throw new CommandException("No nether world found.");
// #end for the first nether world
} else if (filter.equalsIgnoreCase("#end")) {
for (World world : worlds) {
if (BukkitAdapter.adapt(world).getEnvironment() == org.bukkit.World.Environment.THE_END) {
return world;
}
}
throw new CommandException("No end world found.");
// Handle getting a world from a player
} else if (filter.matches("^#player$")) {
String[] parts = filter.split(":", 2);
// They didn't specify an argument for the player!
if (parts.length == 1) {
throw new CommandException("Argument expected for #player.");
}
return matchPlayers(sender, parts[1]).iterator().next().getWorld();
} else {
throw new CommandException("Invalid identifier '" + filter + "'.");
}
}
for (World world : worlds) {
if (world.getName().equals(filter)) {
return world;
}
}
throw new CommandException("No world by that exact name found.");
}
@Override
public List<LocalPlayer> matchPlayerNames(String filter) {
List<LocalPlayer> wgPlayers = Bukkit.getServer().getOnlinePlayers().stream().map(player -> WorldGuardPlugin.inst().wrapPlayer(player)).collect(Collectors.toList());
filter = filter.toLowerCase();
// Allow exact name matching
if (filter.charAt(0) == '@' && filter.length() >= 2) {
filter = filter.substring(1);
for (LocalPlayer player : wgPlayers) {
if (player.getName().equalsIgnoreCase(filter)) {
List<LocalPlayer> list = new ArrayList<>();
list.add(player);
return list;
}
}
return new ArrayList<>();
// Allow partial name matching
} else if (filter.charAt(0) == '*' && filter.length() >= 2) {
filter = filter.substring(1);
List<LocalPlayer> list = new ArrayList<>();
for (LocalPlayer player : wgPlayers) {
if (player.getName().toLowerCase().contains(filter)) {
list.add(player);
}
}
return list;
// Start with name matching
} else {
List<LocalPlayer> list = new ArrayList<>();
for (LocalPlayer player : wgPlayers) {
if (player.getName().toLowerCase().startsWith(filter)) {
list.add(player);
}
}
return list;
}
}
@Override
public Iterable<? extends LocalPlayer> matchPlayers(Actor source, String filter) throws CommandException {
if (Bukkit.getServer().getOnlinePlayers().isEmpty()) {
throw new CommandException("No players matched query.");
}
List<LocalPlayer> wgPlayers = Bukkit.getServer().getOnlinePlayers().stream().map(player -> WorldGuardPlugin.inst().wrapPlayer(player)).collect(Collectors.toList());
if (filter.equals("*")) {
return checkPlayerMatch(wgPlayers);
}
// Handle special hash tag groups
if (filter.charAt(0) == '#') {
// Handle #world, which matches player of the same world as the
// calling source
if (filter.equalsIgnoreCase("#world")) {
List<LocalPlayer> players = new ArrayList<>();
LocalPlayer sourcePlayer = WorldGuard.getInstance().checkPlayer(source);
World sourceWorld = sourcePlayer.getWorld();
for (LocalPlayer player : wgPlayers) {
if (player.getWorld().equals(sourceWorld)) {
players.add(player);
}
}
return checkPlayerMatch(players);
// Handle #near, which is for nearby players.
} else if (filter.equalsIgnoreCase("#near")) {
List<LocalPlayer> players = new ArrayList<>();
LocalPlayer sourcePlayer = WorldGuard.getInstance().checkPlayer(source);
World sourceWorld = sourcePlayer.getWorld();
Vector3 sourceVector = sourcePlayer.getLocation().toVector();
for (LocalPlayer player : wgPlayers) {
if (player.getWorld().equals(sourceWorld) && player.getLocation().toVector().distanceSq(sourceVector) < 900) {
players.add(player);
}
}
return checkPlayerMatch(players);
} else {
throw new CommandException("Invalid group '" + filter + "'.");
}
}
List<LocalPlayer> players = matchPlayerNames(filter);
return checkPlayerMatch(players);
}
@Override
public Actor matchPlayerOrConsole(Actor sender, String filter) throws CommandException {
// Let's see if console is wanted
if (filter.equalsIgnoreCase("#console")
|| filter.equalsIgnoreCase("*console*")
|| filter.equalsIgnoreCase("!")) {
return WorldGuardPlugin.inst().wrapCommandSender(Bukkit.getServer().getConsoleSender());
}
return matchSinglePlayer(sender, filter);
}
@Override
public World getWorldByName(String worldName) {
return BukkitAdapter.adapt(Bukkit.getServer().getWorld(worldName));
}
public String replaceMacros(Actor sender, String message) {
Collection<? extends Player> online = Bukkit.getServer().getOnlinePlayers();
message = message.replace("%name%", sender.getName());
message = message.replace("%id%", sender.getUniqueId().toString());
message = message.replace("%online%", String.valueOf(online.size()));
if (sender instanceof LocalPlayer) {
LocalPlayer player = (LocalPlayer) sender;
World world = (World) player.getExtent();
message = message.replace("%world%", world.getName());
message = message.replace("%health%", String.valueOf(player.getHealth()));
}
return message;
}
}

View File

@ -25,18 +25,8 @@
import com.sk89q.worldguard.blacklist.target.BlockTarget;
import com.sk89q.worldguard.blacklist.target.ItemTarget;
import com.sk89q.worldguard.blacklist.target.Target;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.Tameable;
import org.bukkit.inventory.ItemStack;
public class BukkitUtil {
@ -65,69 +55,6 @@ public static int getPotionEffectBits(ItemStack item) {
return item.getDurability() & 0x3F;
}
/**
* Replace color macros in a string. The macros are in the form of `[char]
* where char represents the color. R is for red, Y is for yellow,
* G is for green, C is for cyan, B is for blue, and P is for purple.
* The uppercase versions of those are the darker shades, while the
* lowercase versions are the lighter shades. For white, it's 'w', and
* 0-2 are black, dark grey, and grey, respectively.
*
* @param str
* @return color-coded string
*/
public static String replaceColorMacros(String str) {
str = str.replace("&r", ChatColor.RED.toString());
str = str.replace("&R", ChatColor.DARK_RED.toString());
str = str.replace("&y", ChatColor.YELLOW.toString());
str = str.replace("&Y", ChatColor.GOLD.toString());
str = str.replace("&g", ChatColor.GREEN.toString());
str = str.replace("&G", ChatColor.DARK_GREEN.toString());
str = str.replace("&c", ChatColor.AQUA.toString());
str = str.replace("&C", ChatColor.DARK_AQUA.toString());
str = str.replace("&b", ChatColor.BLUE.toString());
str = str.replace("&B", ChatColor.DARK_BLUE.toString());
str = str.replace("&p", ChatColor.LIGHT_PURPLE.toString());
str = str.replace("&P", ChatColor.DARK_PURPLE.toString());
str = str.replace("&0", ChatColor.BLACK.toString());
str = str.replace("&1", ChatColor.DARK_GRAY.toString());
str = str.replace("&2", ChatColor.GRAY.toString());
str = str.replace("&w", ChatColor.WHITE.toString());
str = str.replace("&k", ChatColor.MAGIC.toString());
str = str.replace("&l", ChatColor.BOLD.toString());
str = str.replace("&m", ChatColor.STRIKETHROUGH.toString());
str = str.replace("&n", ChatColor.UNDERLINE.toString());
str = str.replace("&o", ChatColor.ITALIC.toString());
str = str.replace("&x", ChatColor.RESET.toString());
return str;
}
/**
* Returns whether an entity should be removed for the halt activity mode.
*
* @param entity The entity
* @return true if it's to be removed
*/
public static boolean isIntensiveEntity(Entity entity) {
return entity instanceof Item
|| entity instanceof TNTPrimed
|| entity instanceof ExperienceOrb
|| entity instanceof FallingBlock
|| (entity instanceof LivingEntity
&& !(entity instanceof Tameable)
&& !(entity instanceof Player)
&& !(entity instanceof ArmorStand));
}
/**
* Get a blacklist target for the given block.
*

View File

@ -35,11 +35,10 @@
import com.sk89q.worldguard.blacklist.target.TargetMatcherParseException;
import com.sk89q.worldguard.blacklist.target.TargetMatcherParser;
import com.sk89q.worldguard.bukkit.chest.BukkitSignChestProtection;
import com.sk89q.worldguard.bukkit.commands.CommandUtils;
import com.sk89q.worldguard.bukkit.internal.TargetMatcherSet;
import com.sk89q.worldguard.chest.ChestProtection;
import com.sk89q.worldguard.commands.CommandUtils;
import com.sk89q.worldguard.config.YamlWorldConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffectType;
import org.yaml.snakeyaml.parser.ParserException;
@ -383,10 +382,12 @@ public void loadConfiguration() {
config.save();
}
@Override
public Blacklist getBlacklist() {
return this.blacklist;
}
@Override
public String getWorldName() {
return this.worldName;
}
@ -433,19 +434,4 @@ public ChestProtection getChestProtection() {
return chestProtection;
}
public int getMaxRegionCount(Player player) {
int max = -1;
for (String group : plugin.getGroups(player)) {
if (maxRegionCounts.containsKey(group)) {
int groupMax = maxRegionCounts.get(group);
if (max < groupMax) {
max = groupMax;
}
}
}
if (max <= -1) {
max = maxRegionCountPerPlayer;
}
return max;
}
}

View File

@ -19,25 +19,31 @@
package com.sk89q.worldguard.bukkit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.util.report.ReportList;
import com.sk89q.worldedit.world.gamemode.GameMode;
import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.protection.events.flags.FlagContextCreateEvent;
import com.sk89q.worldguard.bukkit.session.BukkitSessionManager;
import com.sk89q.worldguard.bukkit.util.report.PerformanceReport;
import com.sk89q.worldguard.bukkit.util.report.PluginReport;
import com.sk89q.worldguard.bukkit.util.report.SchedulerReport;
import com.sk89q.worldguard.bukkit.util.report.ServerReport;
import com.sk89q.worldguard.bukkit.util.report.ServicesReport;
import com.sk89q.worldguard.bukkit.util.report.WorldReport;
import com.sk89q.worldguard.internal.platform.DebugHandler;
import com.sk89q.worldguard.internal.platform.StringMatcher;
import com.sk89q.worldguard.internal.platform.WorldGuardPlatform;
import com.sk89q.worldguard.protection.flags.FlagContext;
import com.sk89q.worldguard.bukkit.protection.events.flags.FlagContextCreateEvent;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import com.sk89q.worldguard.bukkit.session.BukkitSessionManager;
import com.sk89q.worldguard.session.SessionManager;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.permissions.Permissible;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Set;
public class BukkitWorldGuardPlatform implements WorldGuardPlatform {
@ -45,10 +51,22 @@ public class BukkitWorldGuardPlatform implements WorldGuardPlatform {
private SessionManager sessionManager;
private BukkitConfigurationManager configuration;
private BukkitRegionContainer regionContainer;
private BukkitDebugHandler debugHandler;
private StringMatcher stringMatcher;
public BukkitWorldGuardPlatform() {
}
@Override
public String getPlatformName() {
return "Bukkit-Official";
}
@Override
public String getPlatformVersion() {
return WorldGuardPlugin.inst().getDescription().getVersion();
}
@Override
public void notifyFlagContextCreate(FlagContext.FlagContextBuilder flagContextBuilder) {
Bukkit.getServer().getPluginManager().callEvent(new FlagContextCreateEvent(flagContextBuilder));
@ -60,31 +78,8 @@ public BukkitConfigurationManager getGlobalStateManager() {
}
@Override
public World getWorldByName(String worldName) {
return BukkitAdapter.adapt(Bukkit.getServer().getWorld(worldName));
}
@Override
public String replaceColorMacros(String string) {
return BukkitUtil.replaceColorMacros(string);
}
public String replaceMacros(Actor sender, String message) {
Collection<? extends Player> online = Bukkit.getServer().getOnlinePlayers();
message = message.replace("%name%", sender.getName());
message = message.replace("%id%", sender.getUniqueId().toString());
message = message.replace("%online%", String.valueOf(online.size()));
if (sender instanceof LocalPlayer) {
LocalPlayer player = (LocalPlayer) sender;
World world = (World) player.getExtent();
message = message.replace("%world%", world.getName());
message = message.replace("%health%", String.valueOf(player.getHealth()));
}
return message;
public StringMatcher getMatcher() {
return stringMatcher;
}
@Override
@ -107,11 +102,13 @@ public void broadcastNotification(String message) {
@Override
public void load() {
sessionManager = new BukkitSessionManager(WorldGuardPlugin.inst());
sessionManager = new BukkitSessionManager();
configuration = new BukkitConfigurationManager(WorldGuardPlugin.inst());
configuration.load();
regionContainer = new BukkitRegionContainer(WorldGuardPlugin.inst());
regionContainer.initialize();
debugHandler = new BukkitDebugHandler(WorldGuardPlugin.inst());
stringMatcher = new BukkitStringMatcher();
}
@Override
@ -125,6 +122,11 @@ public RegionContainer getRegionContainer() {
return this.regionContainer;
}
@Override
public DebugHandler getDebugHandler() {
return debugHandler;
}
@Override
public GameMode getDefaultGameMode() {
return GameModes.get(Bukkit.getServer().getDefaultGameMode().name().toLowerCase());
@ -134,4 +136,80 @@ public GameMode getDefaultGameMode() {
public Path getConfigDir() {
return WorldGuardPlugin.inst().getDataFolder().toPath();
}
@Override
public void stackPlayerInventory(LocalPlayer localPlayer) {
boolean ignoreMax = localPlayer.hasPermission("worldguard.stack.illegitimate");
boolean ignoreDamaged = localPlayer.hasPermission("worldguard.stack.damaged");
Player player = ((BukkitPlayer) localPlayer).getPlayer();
ItemStack[] items = player.getInventory().getContents();
int len = items.length;
int affected = 0;
for (int i = 0; i < len; i++) {
ItemStack item = items[i];
// Avoid infinite stacks and stacks with durability
if (item == null || item.getAmount() <= 0
|| (!ignoreMax && item.getMaxStackSize() == 1)) {
continue;
}
int max = ignoreMax ? 64 : item.getMaxStackSize();
if (item.getAmount() < max) {
int needed = max - item.getAmount(); // Number of needed items until max
// Find another stack of the same type
for (int j = i + 1; j < len; j++) {
ItemStack item2 = items[j];
// Avoid infinite stacks and stacks with durability
if (item2 == null || item2.getAmount() <= 0
|| (!ignoreMax && item.getMaxStackSize() == 1)) {
continue;
}
// Same type?
// Blocks store their color in the damage value
if (item2.getType() == item.getType() &&
(ignoreDamaged || item.getDurability() == item2.getDurability()) &&
((item.getItemMeta() == null && item2.getItemMeta() == null)
|| (item.getItemMeta() != null &&
item.getItemMeta().equals(item2.getItemMeta())))) {
// This stack won't fit in the parent stack
if (item2.getAmount() > needed) {
item.setAmount(max);
item2.setAmount(item2.getAmount() - needed);
break;
// This stack will
} else {
items[j] = null;
item.setAmount(item.getAmount() + item2.getAmount());
needed = max - item.getAmount();
}
affected++;
}
}
}
}
if (affected > 0) {
player.getInventory().setContents(items);
}
}
@Override
public void addPlatformReports(ReportList report) {
report.add(new ServerReport());
report.add(new PluginReport());
report.add(new SchedulerReport());
report.add(new ServicesReport());
report.add(new WorldReport());
report.add(new PerformanceReport());
}
}

View File

@ -20,7 +20,6 @@
package com.sk89q.worldguard.bukkit;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.sk89q.bukkit.util.CommandsManagerRegistration;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissionsException;
@ -36,9 +35,9 @@
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.commands.GeneralCommands;
import com.sk89q.worldguard.bukkit.commands.ProtectionCommands;
import com.sk89q.worldguard.bukkit.commands.ToggleCommands;
import com.sk89q.worldguard.commands.GeneralCommands;
import com.sk89q.worldguard.commands.ProtectionCommands;
import com.sk89q.worldguard.commands.ToggleCommands;
import com.sk89q.worldguard.bukkit.event.player.ProcessPlayerEvent;
import com.sk89q.worldguard.bukkit.listener.BlacklistListener;
import com.sk89q.worldguard.bukkit.listener.BlockedPotionsListener;
@ -66,20 +65,16 @@
import com.sk89q.worldguard.bukkit.util.logging.ClassSourceValidator;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry;
import com.sk89q.worldguard.protection.managers.storage.StorageException;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.util.UnresolvedNamesException;
import com.sk89q.worldguard.util.logging.RecordMessagePrefixer;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
@ -89,20 +84,10 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.RejectedExecutionException;
import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import javax.annotation.Nullable;
/**
* The main class for WorldGuard as a Bukkit plugin.
*/
@ -110,7 +95,7 @@ public class WorldGuardPlugin extends JavaPlugin {
private static WorldGuardPlugin inst;
private static BukkitWorldGuardPlatform platform;
private final CommandsManager<CommandSender> commands;
private final CommandsManager<Actor> commands;
private PlayerMoveListener playerMoveListener;
/**
@ -118,11 +103,11 @@ public class WorldGuardPlugin extends JavaPlugin {
* this merely instantiates the objects.
*/
public WorldGuardPlugin() {
final WorldGuardPlugin plugin = inst = this;
commands = new CommandsManager<CommandSender>() {
inst = this;
commands = new CommandsManager<Actor>() {
@Override
public boolean hasPermission(CommandSender player, String perm) {
return plugin.hasPermission(player, perm);
public boolean hasPermission(Actor player, String perm) {
return player.hasPermission(perm);
}
};
}
@ -151,7 +136,7 @@ public void onEnable() {
BukkitSessionManager sessionManager = (BukkitSessionManager) platform.getSessionManager();
// Set the proper command injector
commands.setInjector(new SimpleInjector(this));
commands.setInjector(new SimpleInjector(WorldGuard.getInstance()));
// Catch bad things being done by naughty plugins that include
// WorldGuard's classes
@ -234,7 +219,18 @@ public void onDisable() {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
try {
commands.execute(cmd.getName(), args, sender, sender);
Actor actor = wrapCommandSender(sender);
try {
commands.execute(cmd.getName(), args, actor, actor);
} catch (Throwable t) {
Throwable next = t;
do {
WorldGuard.getInstance().getExceptionConverter().convert(next);
next = next.getCause();
} while (next != null);
throw t;
}
} catch (CommandPermissionsException e) {
sender.sendMessage(ChatColor.RED + "You don't have permission.");
} catch (MissingNestedCommandException e) {
@ -243,7 +239,7 @@ public boolean onCommand(CommandSender sender, Command cmd, String label, String
sender.sendMessage(ChatColor.RED + e.getMessage());
sender.sendMessage(ChatColor.RED + e.getUsage());
} catch (WrappedCommandException e) {
sender.sendMessage(ChatColor.RED + convertThrowable(e.getCause()));
sender.sendMessage(ChatColor.RED + e.getCause().getMessage());
} catch (CommandException e) {
sender.sendMessage(ChatColor.RED + e.getMessage());
}
@ -251,34 +247,6 @@ public boolean onCommand(CommandSender sender, Command cmd, String label, String
return true;
}
/**
* Convert the throwable into a somewhat friendly message.
*
* @param throwable the throwable
* @return a message
*/
public String convertThrowable(@Nullable Throwable throwable) {
if (throwable instanceof NumberFormatException) {
return "Number expected, string received instead.";
} else if (throwable instanceof StorageException) {
WorldGuard.logger.log(Level.WARNING, "Error loading/saving regions", throwable);
return "Region data could not be loaded/saved: " + throwable.getMessage();
} else if (throwable instanceof RejectedExecutionException) {
return "There are currently too many tasks queued to add yours. Use /wg running to list queued and running tasks.";
} else if (throwable instanceof CancellationException) {
return "WorldGuard: Task was cancelled";
} else if (throwable instanceof InterruptedException) {
return "WorldGuard: Task was interrupted";
} else if (throwable instanceof UnresolvedNamesException) {
return throwable.getMessage();
} else if (throwable instanceof CommandException) {
return throwable.getMessage();
} else {
WorldGuard.logger.log(Level.WARNING, "WorldGuard encountered an unexpected error", throwable);
return "WorldGuard: An unexpected error occurred! Please see the server console.";
}
}
/**
* Check whether a player is in a group.
* This calls the corresponding method in PermissionsResolverManager
@ -311,37 +279,6 @@ public String[] getGroups(Player player) {
}
}
/**
* Gets the name of a command sender. This is a unique name and this
* method should never return a "display name".
*
* @param sender The sender to get the name of
* @return The unique name of the sender.
*/
public String toUniqueName(CommandSender sender) {
if (sender instanceof ConsoleCommandSender) {
return "*Console*";
} else {
return sender.getName();
}
}
/**
* Gets the name of a command sender. This play be a display name.
*
* @param sender The CommandSender to get the name of.
* @return The name of the given sender
*/
public String toName(CommandSender sender) {
if (sender instanceof ConsoleCommandSender) {
return "*Console*";
} else if (sender instanceof Player) {
return ((Player) sender).getDisplayName();
} else {
return sender.getName();
}
}
/**
* Checks permissions.
*
@ -383,297 +320,6 @@ public void checkPermission(CommandSender sender, String perm)
}
}
/**
* Checks to see if the sender is a player, otherwise throw an exception.
*
* @param sender The {@link CommandSender} to check
* @return {@code sender} casted to a player
* @throws CommandException if {@code sender} isn't a {@link Player}
*/
public Player checkPlayer(CommandSender sender)
throws CommandException {
if (sender instanceof Player) {
return (Player) sender;
} else {
throw new CommandException("A player is expected.");
}
}
/**
* Match player names.
*
* The filter string uses the following format:
* @[name] looks up all players with the exact {@code name}
* *[name] matches any player whose name contains {@code name}
* [name] matches any player whose name starts with {@code name}
*
* @param filter The filter string to check.
* @return A {@link List} of players who match {@code filter}
*/
public List<Player> matchPlayerNames(String filter) {
Collection<? extends Player> players = Bukkit.getServer().getOnlinePlayers();
filter = filter.toLowerCase();
// Allow exact name matching
if (filter.charAt(0) == '@' && filter.length() >= 2) {
filter = filter.substring(1);
for (Player player : players) {
if (player.getName().equalsIgnoreCase(filter)) {
List<Player> list = new ArrayList<>();
list.add(player);
return list;
}
}
return new ArrayList<>();
// Allow partial name matching
} else if (filter.charAt(0) == '*' && filter.length() >= 2) {
filter = filter.substring(1);
List<Player> list = new ArrayList<>();
for (Player player : players) {
if (player.getName().toLowerCase().contains(filter)) {
list.add(player);
}
}
return list;
// Start with name matching
} else {
List<Player> list = new ArrayList<>();
for (Player player : players) {
if (player.getName().toLowerCase().startsWith(filter)) {
list.add(player);
}
}
return list;
}
}
/**
* Checks if the given list of players is greater than size 0, otherwise
* throw an exception.
*
* @param players The {@link List} to check
* @return {@code players} as an {@link Iterable}
* @throws CommandException If {@code players} is empty
*/
protected Iterable<? extends Player> checkPlayerMatch(List<? extends Player> players)
throws CommandException {
// Check to see if there were any matches
if (players.size() == 0) {
throw new CommandException("No players matched query.");
}
return players;
}
/**
* Matches players based on the specified filter string
*
* The filter string format is as follows:
* * returns all the players currently online
* If {@code sender} is a {@link Player}:
* #world returns all players in the world that {@code sender} is in
* #near reaturns all players within 30 blocks of {@code sender}'s location
* Otherwise, the format is as specified in {@link #matchPlayerNames(String)}
*
* @param source The CommandSender who is trying to find a player
* @param filter The filter string for players
* @return iterator for players
* @throws CommandException if no matches are found
*/
public Iterable<? extends Player> matchPlayers(CommandSender source, String filter)
throws CommandException {
if (Bukkit.getServer().getOnlinePlayers().isEmpty()) {
throw new CommandException("No players matched query.");
}
if (filter.equals("*")) {
return checkPlayerMatch(Lists.newArrayList(Bukkit.getServer().getOnlinePlayers()));
}
// Handle special hash tag groups
if (filter.charAt(0) == '#') {
// Handle #world, which matches player of the same world as the
// calling source
if (filter.equalsIgnoreCase("#world")) {
List<Player> players = new ArrayList<>();
Player sourcePlayer = checkPlayer(source);
World sourceWorld = sourcePlayer.getWorld();
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
if (player.getWorld().equals(sourceWorld)) {
players.add(player);
}
}
return checkPlayerMatch(players);
// Handle #near, which is for nearby players.
} else if (filter.equalsIgnoreCase("#near")) {
List<Player> players = new ArrayList<>();
Player sourcePlayer = checkPlayer(source);
World sourceWorld = sourcePlayer.getWorld();
org.bukkit.util.Vector sourceVector
= sourcePlayer.getLocation().toVector();
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
if (player.getWorld().equals(sourceWorld)
&& player.getLocation().toVector().distanceSquared(
sourceVector) < 900) {
players.add(player);
}
}
return checkPlayerMatch(players);
} else {
throw new CommandException("Invalid group '" + filter + "'.");
}
}
List<Player> players = matchPlayerNames(filter);
return checkPlayerMatch(players);
}
/**
* Match only a single player.
*
* @param sender The {@link CommandSender} who is requesting a player match
* @param filter The filter string.
* @see #matchPlayers(org.bukkit.entity.Player) for filter string syntax
* @return The single player
* @throws CommandException If more than one player match was found
*/
public Player matchSinglePlayer(CommandSender sender, String filter)
throws CommandException {
// This will throw an exception if there are no matches
Iterator<? extends Player> players = matchPlayers(sender, filter).iterator();
Player match = players.next();
// We don't want to match the wrong person, so fail if if multiple
// players were found (we don't want to just pick off the first one,
// as that may be the wrong player)
if (players.hasNext()) {
throw new CommandException("More than one player found! " +
"Use @<name> for exact matching.");
}
return match;
}
/**
* Match only a single player or console.
*
* The filter string syntax is as follows:
* #console, *console, or ! return the server console
* All syntax from {@link #matchSinglePlayer(org.bukkit.command.CommandSender, String)}
* @param sender The sender trying to match a CommandSender
* @param filter The filter string
* @return The resulting CommandSender
* @throws CommandException if either zero or more than one player matched.
*/
public CommandSender matchPlayerOrConsole(CommandSender sender, String filter)
throws CommandException {
// Let's see if console is wanted
if (filter.equalsIgnoreCase("#console")
|| filter.equalsIgnoreCase("*console*")
|| filter.equalsIgnoreCase("!")) {
return getServer().getConsoleSender();
}
return matchSinglePlayer(sender, filter);
}
/**
* Get a single player as an iterator for players.
*
* @param player The player to return in an Iterable
* @return iterator for player
*/
public Iterable<Player> matchPlayers(Player player) {
return Arrays.asList(player);
}
/**
* Match a world.
*
* The filter string syntax is as follows:
* #main returns the main world
* #normal returns the first world with a normal environment
* #nether return the first world with a nether environment
* #player:[name] returns the world that a player named {@code name} is located in, if the player is online.
* [name] A world with the name {@code name}
*
* @param sender The sender requesting a match
* @param filter The filter string
* @return The resulting world
* @throws CommandException if no world matches
*/
public World matchWorld(CommandSender sender, String filter) throws CommandException {
List<World> worlds = getServer().getWorlds();
// Handle special hash tag groups
if (filter.charAt(0) == '#') {
// #main for the main world
if (filter.equalsIgnoreCase("#main")) {
return worlds.get(0);
// #normal for the first normal world
} else if (filter.equalsIgnoreCase("#normal")) {
for (World world : worlds) {
if (world.getEnvironment() == Environment.NORMAL) {
return world;
}
}
throw new CommandException("No normal world found.");
// #nether for the first nether world
} else if (filter.equalsIgnoreCase("#nether")) {
for (World world : worlds) {
if (world.getEnvironment() == Environment.NETHER) {
return world;
}
}
throw new CommandException("No nether world found.");
// Handle getting a world from a player
} else if (filter.matches("^#player$")) {
String parts[] = filter.split(":", 2);
// They didn't specify an argument for the player!
if (parts.length == 1) {
throw new CommandException("Argument expected for #player.");
}
return matchPlayers(sender, parts[1]).iterator().next().getWorld();
} else {
throw new CommandException("Invalid identifier '" + filter + "'.");
}
}
for (World world : worlds) {
if (world.getName().equals(filter)) {
return world;
}
}
throw new CommandException("No world by that exact name found.");
}
/**
* Gets a copy of the WorldEdit plugin.
*
@ -727,6 +373,16 @@ public Actor wrapCommandSender(CommandSender sender) {
return null;
}
public CommandSender unwrapActor(Actor sender) {
if (sender instanceof BukkitPlayer) {
return ((BukkitPlayer) sender).getPlayer();
} else if (sender instanceof BukkitCommandSender) {
return Bukkit.getConsoleSender(); // TODO Fix
} else {
throw new IllegalArgumentException("Unknown actor type. Please report");
}
}
/**
* Wrap a player as a LocalPlayer.
*

View File

@ -233,7 +233,7 @@ private static final class Builder {
private boolean indirect;
private Builder(int expectedSize) {
this.causes = new ArrayList<Object>(expectedSize);
this.causes = new ArrayList<>(expectedSize);
}
private void addAll(@Nullable Object... element) {
@ -250,7 +250,7 @@ private void addAll(@Nullable Object... element) {
} else if (o instanceof Projectile) {
addAll(((Projectile) o).getShooter());
} else if (o instanceof Vehicle) {
addAll(((Vehicle) o).getPassenger());
addAll(((Vehicle) o).getPassengers());
} else if (o instanceof Creature && ((Creature) o).getTarget() != null) {
indirect = true;
addAll(((Creature) o).getTarget());

View File

@ -1,136 +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;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.util.task.FutureForwardingTask;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
public class AsyncCommandHelper {
private final ListenableFuture<?> future;
private final WorldGuardPlugin plugin;
private final CommandSender sender;
@Nullable
private Object[] formatArgs;
private AsyncCommandHelper(ListenableFuture<?> future, WorldGuardPlugin plugin, CommandSender sender) {
checkNotNull(future);
checkNotNull(plugin);
checkNotNull(sender);
this.future = future;
this.plugin = plugin;
this.sender = sender;
}
public AsyncCommandHelper formatUsing(Object... args) {
this.formatArgs = args;
return this;
}
private String format(String message) {
if (formatArgs != null) {
return String.format(message, formatArgs);
} else {
return message;
}
}
public AsyncCommandHelper registerWithSupervisor(String description) {
WorldGuard.getInstance().getSupervisor().monitor(
FutureForwardingTask.create(
future, format(description), sender));
return this;
}
public AsyncCommandHelper sendMessageAfterDelay(String message) {
FutureProgressListener.addProgressListener(future, sender, format(message));
return this;
}
public AsyncCommandHelper thenRespondWith(String success, String failure) {
// Send a response message
Futures.addCallback(
future,
new MessageFutureCallback.Builder(plugin, sender)
.onSuccess(format(success))
.onFailure(format(failure))
.build());
return this;
}
public AsyncCommandHelper thenTellErrorsOnly(String failure) {
// Send a response message
Futures.addCallback(
future,
new MessageFutureCallback.Builder(plugin, sender)
.onFailure(format(failure))
.build());
return this;
}
public AsyncCommandHelper forRegionDataLoad(World world, boolean silent) {
checkNotNull(world);
formatUsing(world.getName());
registerWithSupervisor("Loading region data for '%s'");
if (silent) {
thenTellErrorsOnly("Failed to load regions '%s'");
} else {
sendMessageAfterDelay("(Please wait... loading the region data for '%s')");
thenRespondWith(
"Loaded region data for '%s'",
"Failed to load regions '%s'");
}
return this;
}
public AsyncCommandHelper forRegionDataSave(World world, boolean silent) {
checkNotNull(world);
formatUsing(world.getName());
registerWithSupervisor("Saving region data for '%s'");
if (silent) {
thenTellErrorsOnly("Failed to save regions '%s'");
} else {
sendMessageAfterDelay("(Please wait... saving the region data for '%s')");
thenRespondWith(
"Saved region data for '%s'",
"Failed to load regions '%s'");
}
return this;
}
public static AsyncCommandHelper wrap(ListenableFuture<?> future, WorldGuardPlugin plugin, CommandSender sender) {
return new AsyncCommandHelper(future, plugin, sender);
}
}

View File

@ -1,194 +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;
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.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.util.paste.EngineHubPaste;
import org.bukkit.ChatColor;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
/**
* Command-related utility methods.
*/
public final class CommandUtils {
private static final Logger log = Logger.getLogger(CommandUtils.class.getCanonicalName());
private CommandUtils() {
}
/**
* Replace color macros in a string.
*
* @param str the string
* @return the new string
*/
public static String replaceColorMacros(String str) {
// TODO: Make this more efficient
str = str.replace("`r", ChatColor.RED.toString());
str = str.replace("`R", ChatColor.DARK_RED.toString());
str = str.replace("`y", ChatColor.YELLOW.toString());
str = str.replace("`Y", ChatColor.GOLD.toString());
str = str.replace("`g", ChatColor.GREEN.toString());
str = str.replace("`G", ChatColor.DARK_GREEN.toString());
str = str.replace("`c", ChatColor.AQUA.toString());
str = str.replace("`C", ChatColor.DARK_AQUA.toString());
str = str.replace("`b", ChatColor.BLUE.toString());
str = str.replace("`B", ChatColor.DARK_BLUE.toString());
str = str.replace("`p", ChatColor.LIGHT_PURPLE.toString());
str = str.replace("`P", ChatColor.DARK_PURPLE.toString());
str = str.replace("`0", ChatColor.BLACK.toString());
str = str.replace("`1", ChatColor.DARK_GRAY.toString());
str = str.replace("`2", ChatColor.GRAY.toString());
str = str.replace("`w", ChatColor.WHITE.toString());
str = str.replace("`k", ChatColor.MAGIC.toString());
str = str.replace("`l", ChatColor.BOLD.toString());
str = str.replace("`m", ChatColor.STRIKETHROUGH.toString());
str = str.replace("`n", ChatColor.UNDERLINE.toString());
str = str.replace("`o", ChatColor.ITALIC.toString());
str = str.replace("`x", ChatColor.RESET.toString());
// MC classic
str = str.replace("&c", ChatColor.RED.toString());
str = str.replace("&4", ChatColor.DARK_RED.toString());
str = str.replace("&e", ChatColor.YELLOW.toString());
str = str.replace("&6", ChatColor.GOLD.toString());
str = str.replace("&a", ChatColor.GREEN.toString());
str = str.replace("&2", ChatColor.DARK_GREEN.toString());
str = str.replace("&b", ChatColor.AQUA.toString());
str = str.replace("&3", ChatColor.DARK_AQUA.toString());
str = str.replace("&9", ChatColor.BLUE.toString());
str = str.replace("&1", ChatColor.DARK_BLUE.toString());
str = str.replace("&d", ChatColor.LIGHT_PURPLE.toString());
str = str.replace("&5", ChatColor.DARK_PURPLE.toString());
str = str.replace("&0", ChatColor.BLACK.toString());
str = str.replace("&8", ChatColor.DARK_GRAY.toString());
str = str.replace("&7", ChatColor.GRAY.toString());
str = str.replace("&f", ChatColor.WHITE.toString());
str = str.replace("&k", ChatColor.MAGIC.toString());
str = str.replace("&l", ChatColor.BOLD.toString());
str = str.replace("&m", ChatColor.STRIKETHROUGH.toString());
str = str.replace("&n", ChatColor.UNDERLINE.toString());
str = str.replace("&o", ChatColor.ITALIC.toString());
str = str.replace("&x", ChatColor.RESET.toString());
str = str.replace("&r", ChatColor.RESET.toString());
return str;
}
/**
* Get the name of the given owner object.
*
* @param owner the owner object
* @return a name
*/
public static String getOwnerName(@Nullable Object owner) {
if (owner == null) {
return "?";
} else if (owner instanceof Player) {
return ((Player) owner).getName();
} else if (owner instanceof ConsoleCommandSender) {
return "*CONSOLE*";
} else if (owner instanceof BlockCommandSender) {
return ((BlockCommandSender) owner).getBlock().getLocation().toString();
} else {
return "?";
}
}
/**
* Return a function that accepts a string to send a message to the
* given sender.
*
* @param sender the sender
* @return a function
*/
public static java.util.function.Function<String, ?> messageFunction(final CommandSender sender) {
return (Function<String, Object>) s -> {
sender.sendMessage(s);
return null;
};
}
/**
* Submit data to a pastebin service and inform the sender of
* success or failure.
*
* @param plugin The plugin
* @param sender The sender
* @param content The content
* @param successMessage The message, formatted with {@link String#format(String, Object...)} on success
*/
public static void pastebin(WorldGuardPlugin plugin, final CommandSender sender, String content, final String successMessage) {
ListenableFuture<URL> future = new EngineHubPaste().paste(content);
AsyncCommandHelper.wrap(future, plugin, sender)
.registerWithSupervisor("Submitting content to a pastebin service...")
.sendMessageAfterDelay("(Please wait... sending output to pastebin...)");
Futures.addCallback(future, new FutureCallback<URL>() {
@Override
public void onSuccess(URL url) {
sender.sendMessage(ChatColor.YELLOW + String.format(successMessage, url));
}
@Override
public void onFailure(Throwable throwable) {
log.log(Level.WARNING, "Failed to submit pastebin", throwable);
sender.sendMessage(ChatColor.RED + "Failed to submit to a pastebin. Please see console for the error.");
}
});
}
}

View File

@ -1,55 +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;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import java.util.Timer;
import static com.google.common.base.Preconditions.checkNotNull;
public class FutureProgressListener implements Runnable {
private static final Timer timer = new Timer();
private static final int MESSAGE_DELAY = 1000;
private final MessageTimerTask task;
public FutureProgressListener(CommandSender sender, String message) {
checkNotNull(sender);
checkNotNull(message);
task = new MessageTimerTask(sender, ChatColor.GRAY + message);
timer.schedule(task, MESSAGE_DELAY);
}
@Override
public void run() {
task.cancel();
}
public static void addProgressListener(ListenableFuture<?> future, CommandSender sender, String message) {
future.addListener(new FutureProgressListener(sender, message), MoreExecutors.directExecutor());
}
}

View File

@ -1,315 +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;
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.CommandPermissions;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.session.Session;
import com.sk89q.worldguard.session.handler.GodMode;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class GeneralCommands {
private final WorldGuardPlugin plugin;
public GeneralCommands(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
@SuppressWarnings("deprecation")
@Command(aliases = {"god"}, usage = "[player]",
desc = "Enable godmode on a player", flags = "s", max = 1)
public void god(CommandContext args, CommandSender sender) throws CommandException {
ConfigurationManager config = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
Iterable<? extends Player> targets = null;
boolean included = false;
// Detect arguments based on the number of arguments provided
if (args.argsLength() == 0) {
targets = plugin.matchPlayers(plugin.checkPlayer(sender));
// Check permissions!
plugin.checkPermission(sender, "worldguard.god");
} else {
targets = plugin.matchPlayers(sender, args.getString(0));
// Check permissions!
plugin.checkPermission(sender, "worldguard.god.other");
}
for (Player player : targets) {
LocalPlayer localPlayer = plugin.wrapPlayer(player);
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(localPlayer);
if (GodMode.set(localPlayer, session, true)) {
player.setFireTicks(0);
// Tell the user
if (player.equals(sender)) {
player.sendMessage(ChatColor.YELLOW + "God mode enabled! Use /ungod to disable.");
// Keep track of this
included = true;
} else {
player.sendMessage(ChatColor.YELLOW + "God enabled by "
+ plugin.toName(sender) + ".");
}
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
sender.sendMessage(ChatColor.YELLOW + "Players now have god mode.");
}
}
@SuppressWarnings("deprecation")
@Command(aliases = {"ungod"}, usage = "[player]",
desc = "Disable godmode on a player", flags = "s", max = 1)
public void ungod(CommandContext args, CommandSender sender) throws CommandException {
ConfigurationManager config = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
Iterable<? extends Player> targets = null;
boolean included = false;
// Detect arguments based on the number of arguments provided
if (args.argsLength() == 0) {
targets = plugin.matchPlayers(plugin.checkPlayer(sender));
// Check permissions!
plugin.checkPermission(sender, "worldguard.god");
} else {
targets = plugin.matchPlayers(sender, args.getString(0));
// Check permissions!
plugin.checkPermission(sender, "worldguard.god.other");
}
for (Player player : targets) {
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
Session session = WorldGuard.getInstance().getPlatform().getSessionManager().get(localPlayer);
if (GodMode.set(localPlayer, session, false)) {
// Tell the user
if (player.equals(sender)) {
player.sendMessage(ChatColor.YELLOW + "God mode disabled!");
// Keep track of this
included = true;
} else {
player.sendMessage(ChatColor.YELLOW + "God disabled by "
+ plugin.toName(sender) + ".");
}
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
sender.sendMessage(ChatColor.YELLOW + "Players no longer have god mode.");
}
}
@Command(aliases = {"heal"}, usage = "[player]", desc = "Heal a player", flags = "s", max = 1)
public void heal(CommandContext args,CommandSender sender) throws CommandException {
Iterable<? extends Player> targets = null;
boolean included = false;
// Detect arguments based on the number of arguments provided
if (args.argsLength() == 0) {
targets = plugin.matchPlayers(plugin.checkPlayer(sender));
// Check permissions!
plugin.checkPermission(sender, "worldguard.heal");
} else if (args.argsLength() == 1) {
targets = plugin.matchPlayers(sender, args.getString(0));
// Check permissions!
plugin.checkPermission(sender, "worldguard.heal.other");
}
for (Player player : targets) {
player.setHealth(player.getMaxHealth());
player.setFoodLevel(20);
player.setSaturation(20);
player.setExhaustion(0);
// Tell the user
if (player.equals(sender)) {
player.sendMessage(ChatColor.YELLOW + "Healed!");
// Keep track of this
included = true;
} else {
player.sendMessage(ChatColor.YELLOW + "Healed by "
+ plugin.toName(sender) + ".");
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
sender.sendMessage(ChatColor.YELLOW.toString() + "Players healed.");
}
}
@Command(aliases = {"slay"}, usage = "[player]", desc = "Slay a player", flags = "s", max = 1)
public void slay(CommandContext args, CommandSender sender) throws CommandException {
Iterable<? extends Player> targets = null;
boolean included = false;
// Detect arguments based on the number of arguments provided
if (args.argsLength() == 0) {
targets = plugin.matchPlayers(plugin.checkPlayer(sender));
// Check permissions!
plugin.checkPermission(sender, "worldguard.slay");
} else if (args.argsLength() == 1) {
targets = plugin.matchPlayers(sender, args.getString(0));
// Check permissions!
plugin.checkPermission(sender, "worldguard.slay.other");
}
for (Player player : targets) {
player.setHealth(0);
// Tell the user
if (player.equals(sender)) {
player.sendMessage(ChatColor.YELLOW + "Slain!");
// Keep track of this
included = true;
} else {
player.sendMessage(ChatColor.YELLOW + "Slain by "
+ plugin.toName(sender) + ".");
}
}
// The player didn't receive any items, then we need to send the
// user a message so s/he know that something is indeed working
if (!included && args.hasFlag('s')) {
sender.sendMessage(ChatColor.YELLOW.toString() + "Players slain.");
}
}
@Command(aliases = {"locate"}, usage = "[player]", desc = "Locate a player", max = 1)
@CommandPermissions({"worldguard.locate"})
public void locate(CommandContext args, CommandSender sender) throws CommandException {
Player player = plugin.checkPlayer(sender);
if (args.argsLength() == 0) {
player.setCompassTarget(player.getWorld().getSpawnLocation());
sender.sendMessage(ChatColor.YELLOW.toString() + "Compass reset to spawn.");
} else {
Player target = plugin.matchSinglePlayer(sender, args.getString(0));
player.setCompassTarget(target.getLocation());
sender.sendMessage(ChatColor.YELLOW.toString() + "Compass repointed.");
}
}
@Command(aliases = {"stack", ";"}, usage = "", desc = "Stack items", max = 0)
@CommandPermissions({"worldguard.stack"})
public void stack(CommandContext args, CommandSender sender) throws CommandException {
Player player = plugin.checkPlayer(sender);
boolean ignoreMax = plugin.hasPermission(player, "worldguard.stack.illegitimate");
boolean ignoreDamaged = plugin.hasPermission(player, "worldguard.stack.damaged");
ItemStack[] items = player.getInventory().getContents();
int len = items.length;
int affected = 0;
for (int i = 0; i < len; i++) {
ItemStack item = items[i];
// Avoid infinite stacks and stacks with durability
if (item == null || item.getAmount() <= 0
|| (!ignoreMax && item.getMaxStackSize() == 1)) {
continue;
}
int max = ignoreMax ? 64 : item.getMaxStackSize();
if (item.getAmount() < max) {
int needed = max - item.getAmount(); // Number of needed items until max
// Find another stack of the same type
for (int j = i + 1; j < len; j++) {
ItemStack item2 = items[j];
// Avoid infinite stacks and stacks with durability
if (item2 == null || item2.getAmount() <= 0
|| (!ignoreMax && item.getMaxStackSize() == 1)) {
continue;
}
// Same type?
// Blocks store their color in the damage value
if (item2.getType() == item.getType() &&
(ignoreDamaged || item.getDurability() == item2.getDurability()) &&
((item.getItemMeta() == null && item2.getItemMeta() == null)
|| (item.getItemMeta() != null &&
item.getItemMeta().equals(item2.getItemMeta())))) {
// This stack won't fit in the parent stack
if (item2.getAmount() > needed) {
item.setAmount(max);
item2.setAmount(item2.getAmount() - needed);
break;
// This stack will
} else {
items[j] = null;
item.setAmount(item.getAmount() + item2.getAmount());
needed = max - item.getAmount();
}
affected++;
}
}
}
}
if (affected > 0) {
player.getInventory().setContents(items);
}
player.sendMessage(ChatColor.YELLOW + "Items compacted into stacks!");
}
}

View File

@ -1,103 +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;
import com.google.common.util.concurrent.FutureCallback;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
public class MessageFutureCallback<V> implements FutureCallback<V> {
private final WorldGuardPlugin plugin;
private final CommandSender sender;
@Nullable
private final String success;
@Nullable
private final String failure;
private MessageFutureCallback(WorldGuardPlugin plugin, CommandSender sender, @Nullable String success, @Nullable String failure) {
this.plugin = plugin;
this.sender = sender;
this.success = success;
this.failure = failure;
}
@Override
public void onSuccess(@Nullable V v) {
if (success != null) {
sender.sendMessage(ChatColor.YELLOW + success);
}
}
@Override
public void onFailure(@Nullable Throwable throwable) {
String failure = this.failure != null ? this.failure : "An error occurred";
sender.sendMessage(ChatColor.RED + failure + ": " + plugin.convertThrowable(throwable));
}
public static class Builder {
private final WorldGuardPlugin plugin;
private final CommandSender sender;
@Nullable
private String success;
@Nullable
private String failure;
public Builder(WorldGuardPlugin plugin, CommandSender sender) {
checkNotNull(plugin);
checkNotNull(sender);
this.plugin = plugin;
this.sender = sender;
}
public Builder onSuccess(@Nullable String message) {
this.success = message;
return this;
}
public Builder onFailure(@Nullable String message) {
this.failure = message;
return this;
}
public <V> MessageFutureCallback<V> build() {
return new MessageFutureCallback<V>(plugin, sender, success, failure);
}
}
public static <V> MessageFutureCallback<V> createRegionLoadCallback(WorldGuardPlugin plugin, CommandSender sender) {
return new Builder(plugin, sender)
.onSuccess("Successfully load the region data.")
.build();
}
public static <V> MessageFutureCallback<V> createRegionSaveCallback(WorldGuardPlugin plugin, CommandSender sender) {
return new Builder(plugin, sender)
.onSuccess("Successfully saved the region data.")
.build();
}
}

View File

@ -1,46 +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;
import org.bukkit.command.CommandSender;
import java.util.TimerTask;
import static com.google.common.base.Preconditions.checkNotNull;
public 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);
}
}

View File

@ -95,7 +95,7 @@ public void onBreakBlock(final BreakBlockEvent event) {
event.filter(testState(query, Flags.ENDERDRAGON_BLOCK_DAMAGE), config.explosionFlagCancellation);
}
if (event.getCause().find(Entities.enderCrystalType) != null) { // should be nullsafe even if enderCrystalType field is null
if (event.getCause().find(EntityType.ENDER_CRYSTAL) != null) { // EnderCrystal
event.filter(testState(query, Flags.OTHER_EXPLOSION), config.explosionFlagCancellation);
}
}

View File

@ -35,7 +35,9 @@
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.EnderCrystal;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Enderman;
import org.bukkit.entity.Entity;
@ -207,14 +209,14 @@ private void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
event.setCancelled(true);
return;
}
} else if (defender.getType() == Entities.armorStandType && !(attacker instanceof Player)) {
} else if (defender instanceof ArmorStand && !(attacker instanceof Player)) {
if (wcfg.blockEntityArmorStandDestroy) {
event.setCancelled(true);
return;
}
}
if (attacker != null && attacker.getType() == Entities.enderCrystalType) {
if (attacker instanceof EnderCrystal) {
// this isn't handled elsewhere because ender crystal explosions don't carry a player cause
// in the same way that creepers or tnt can
if (wcfg.useRegions && wcfg.explosionFlagCancellation) {
@ -341,7 +343,7 @@ private void onEntityDamageByProjectile(EntityDamageByEntityEvent event) {
event.setCancelled(true);
return;
}
} else if (defender.getType() == Entities.armorStandType && Entities.isNonPlayerCreature(attacker)) {
} else if (defender instanceof ArmorStand && Entities.isNonPlayerCreature(attacker)) {
if (wcfg.blockEntityArmorStandDestroy) {
event.setCancelled(true);
}

View File

@ -38,6 +38,7 @@
import com.sk89q.worldguard.session.MoveType;
import com.sk89q.worldguard.session.Session;
import com.sk89q.worldguard.session.handler.GameModeFlag;
import com.sk89q.worldguard.util.Entities;
import com.sk89q.worldguard.util.command.CommandFilter;
import org.bukkit.ChatColor;
import org.bukkit.Location;
@ -134,7 +135,7 @@ public void onPlayerJoin(PlayerJoinEvent event) {
int removed = 0;
for (Entity entity : world.getEntities()) {
if (BukkitUtil.isIntensiveEntity(entity)) {
if (Entities.isIntensiveEntity(BukkitAdapter.adapt(entity))) {
entity.remove();
removed++;
}

View File

@ -21,10 +21,10 @@
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.BukkitWorldConfiguration;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.config.ConfigurationManager;
import com.sk89q.worldguard.config.WorldConfiguration;
import com.sk89q.worldguard.util.Entities;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.event.EventHandler;
@ -63,7 +63,7 @@ public void onChunkLoad(ChunkLoadEvent event) {
int removed = 0;
for (Entity entity : event.getChunk().getEntities()) {
if (BukkitUtil.isIntensiveEntity(entity)) {
if (Entities.isIntensiveEntity(BukkitAdapter.adapt(entity))) {
entity.remove();
removed++;
}
@ -82,15 +82,15 @@ public void onWorldLoad(WorldLoadEvent event) {
/**
* Initialize the settings for the specified world
* @see BukkitWorldConfiguration#alwaysRaining
* @see BukkitWorldConfiguration#disableWeather
* @see BukkitWorldConfiguration#alwaysThundering
* @see BukkitWorldConfiguration#disableThunder
* @see WorldConfiguration#alwaysRaining
* @see WorldConfiguration#disableWeather
* @see WorldConfiguration#alwaysThundering
* @see WorldConfiguration#disableThunder
* @param world The specified world
*/
public void initWorld(World world) {
ConfigurationManager cfg = WorldGuard.getInstance().getPlatform().getGlobalStateManager();
BukkitWorldConfiguration wcfg = (BukkitWorldConfiguration) cfg.get(BukkitAdapter.adapt(world));
WorldConfiguration wcfg = cfg.get(BukkitAdapter.adapt(world));
if (wcfg.alwaysRaining && !wcfg.disableWeather) {
world.setStorm(true);
} else if (wcfg.disableWeather && !wcfg.alwaysRaining) {

View File

@ -19,100 +19,23 @@
package com.sk89q.worldguard.bukkit.session;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.BukkitPlayer;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.session.AbstractSessionManager;
import com.sk89q.worldguard.session.Session;
import com.sk89q.worldguard.session.SessionManager;
import com.sk89q.worldguard.session.WorldPlayerTuple;
import com.sk89q.worldguard.session.handler.*;
import com.sk89q.worldguard.session.handler.Handler.Factory;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Keeps tracks of sessions and also does session-related handling
* (flags, etc.).
*/
public class BukkitSessionManager implements SessionManager, Runnable, Listener {
public static final int RUN_DELAY = 20;
public static final long SESSION_LIFETIME = 10;
private final WorldGuardPlugin plugin;
private final LoadingCache<WorldPlayerTuple, Boolean> bypassCache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterAccess(2, TimeUnit.SECONDS)
.build(new CacheLoader<WorldPlayerTuple, Boolean>() {
@Override
public Boolean load(WorldPlayerTuple tuple) throws Exception {
return tuple.getPlayer().hasPermission("worldguard.region.bypass." + tuple.getWorld().getName());
}
});
private final LoadingCache<CacheKey, Session> sessions = CacheBuilder.newBuilder()
.expireAfterAccess(SESSION_LIFETIME, TimeUnit.MINUTES)
.build(new CacheLoader<CacheKey, Session>() {
@Override
public Session load(CacheKey key) throws Exception {
return createSession(key.playerRef.get());
}
});
/**
* Create a new instance.
*
* @param plugin The plugin
*/
public BukkitSessionManager(WorldGuardPlugin plugin) {
checkNotNull(plugin, "plugin");
this.plugin = plugin;
handlers.addAll(defaultHandlers);
}
/**
* Get the plugin.
*
* @return The plugin
*/
public WorldGuardPlugin getPlugin() {
return plugin;
}
/**
* Check whether a player has the region bypass permission.
*
* <p>The return value may be cached for a few seconds.</p>
*
* @param player The player
* @param world The world
* @return A value
*/
@Override
public boolean hasBypass(LocalPlayer player, World world) {
return bypassCache.getUnchecked(new WorldPlayerTuple(world, player));
}
public class BukkitSessionManager extends AbstractSessionManager implements Runnable, Listener {
/**
* Re-initialize handlers and clear "last position," "last state," etc.
@ -123,154 +46,17 @@ public void resetAllStates() {
Collection<? extends Player> players = Bukkit.getServer().getOnlinePlayers();
for (Player player : players) {
BukkitPlayer bukkitPlayer = new BukkitPlayer(WorldGuardPlugin.inst(), player);
Session session = sessions.getIfPresent(new CacheKey(bukkitPlayer));
Session session = getIfPresent(bukkitPlayer);
if (session != null) {
session.resetState(bukkitPlayer);
}
}
}
/**
* Re-initialize handlers and clear "last position," "last state," etc.
* information.
*
* @param player The player
*/
@Override
public void resetState(LocalPlayer player) {
checkNotNull(player, "player");
@Nullable Session session = sessions.getIfPresent(new CacheKey(player));
if (session != null) {
session.resetState(player);
}
}
private LinkedList<Factory<? extends Handler>> handlers = new LinkedList<>();
private static final Set<Factory<? extends Handler>> defaultHandlers = new HashSet<>();
static {
Factory<?>[] factories = {
HealFlag.FACTORY,
FeedFlag.FACTORY,
NotifyEntryFlag.FACTORY,
NotifyExitFlag.FACTORY,
EntryFlag.FACTORY,
ExitFlag.FACTORY,
FarewellFlag.FACTORY,
GreetingFlag.FACTORY,
GameModeFlag.FACTORY,
InvincibilityFlag.FACTORY,
TimeLockFlag.FACTORY,
WeatherLockFlag.FACTORY,
GodMode.FACTORY,
WaterBreathing.FACTORY
};
defaultHandlers.addAll(Arrays.asList(factories));
}
/**
* Register a handler with the BukkitSessionManager.
*
* You may specify another handler class to ensure your handler is always registered after that class.
* If that class is not already registered, this method will return false.
*
* For example, flags that always act on a player in a region (like {@link HealFlag} and {@link FeedFlag})
* should be registered earlier, whereas flags that only take effect when a player leaves the region (like
* {@link FarewellFlag} and {@link GreetingFlag}) should be registered after the {@link ExitFlag.Factory}.class handler factory.
*
* @param factory a factory which takes a session and returns an instance of your handler
* @param after the handler factory to insert the first handler after, to ensure a specific order when creating new sessions
*
* @return {@code true} (as specified by {@link Collection#add})
* {@code false} if after is not registered, or factory is null
*/
@Override
public boolean registerHandler(Factory<? extends Handler> factory, @Nullable Factory<? extends Handler> after) {
if (factory == null) return false;
WorldGuardPlugin.inst().getLogger().log(Level.INFO, "Registering session handler "
+ factory.getClass().getEnclosingClass().getName());
if (after == null) {
handlers.add(factory);
} else {
int index = handlers.indexOf(after);
if (index == -1) return false;
handlers.add(index, factory); // shifts "after" right one, and everything after "after" right one
}
return true;
}
/**
* Unregister a handler.
*
* This will prevent it from being added to newly created sessions only. Existing
* sessions with the handler will continue to use it.
*
* Will return false if the handler was not registered to begin with.
*
* @param factory the handler factory to unregister
* @return true if the handler was registered and is now unregistered, false otherwise
*/
@Override
public boolean unregisterHandler(Factory<? extends Handler> factory) {
if (defaultHandlers.contains(factory)) {
WorldGuardPlugin.inst().getLogger().log(Level.WARNING, "Someone is unregistering a default WorldGuard handler: "
+ factory.getClass().getEnclosingClass().getName() + ". This may cause parts of WorldGuard to stop functioning");
} else {
WorldGuardPlugin.inst().getLogger().log(Level.INFO, "Unregistering session handler "
+ factory.getClass().getEnclosingClass().getName());
}
return handlers.remove(factory);
}
/**
* Create a session for a player.
*
* @param player The player
* @return The new session
*/
@Override
public Session createSession(LocalPlayer player) {
Session session = new Session(this);
for (Factory<? extends Handler> factory : handlers) {
session.register(factory.create(session));
}
session.initialize(player);
return session;
}
/**
* Get a player's session, if one exists.
*
* @param player The player
* @return The session
*/
@Override
@Nullable
public Session getIfPresent(LocalPlayer player) {
return sessions.getIfPresent(player);
}
/**
* Get a player's session. A session will be created if there is no
* existing session for the player.
*
* <p>This method can only be called from the main thread. While the
* session manager itself is thread-safe, some of the handlers may
* require initialization that requires the server main thread.</p>
*
* @param player The player to get a session for
* @return The {@code player}'s session
*/
@Override
public Session get(LocalPlayer player) {
return sessions.getUnchecked(new CacheKey(player));
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
// Pre-load a session
get(new BukkitPlayer(WorldGuardPlugin.inst(), event.getPlayer()));
get(WorldGuardPlugin.inst().wrapPlayer(event.getPlayer()));
}
@Override
@ -279,29 +65,4 @@ public void run() {
get(new BukkitPlayer(WorldGuardPlugin.inst(), player)).tick(new BukkitPlayer(WorldGuardPlugin.inst(), player));
}
}
private static final class CacheKey {
private final WeakReference<LocalPlayer> playerRef;
private final UUID uuid;
private CacheKey(LocalPlayer player) {
playerRef = new WeakReference<>(player);
uuid = player.getUniqueId();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CacheKey cacheKey = (CacheKey) o;
return uuid.equals(cacheKey.uuid);
}
@Override
public int hashCode() {
return uuid.hashCode();
}
}
}

View File

@ -19,8 +19,28 @@
package com.sk89q.worldguard.bukkit.util;
import com.sk89q.worldguard.util.Enums;
import org.bukkit.entity.*;
import org.bukkit.entity.Ambient;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Creature;
import org.bukkit.entity.EnderCrystal;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Flying;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Monster;
import org.bukkit.entity.NPC;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Shulker;
import org.bukkit.entity.Slime;
import org.bukkit.entity.SpectralArrow;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.TippedArrow;
import org.bukkit.entity.Vehicle;
import org.bukkit.entity.WaterMob;
import org.bukkit.entity.minecart.ExplosiveMinecart;
import org.bukkit.projectiles.ProjectileSource;
@ -120,10 +140,6 @@ public static Entity getShooter(Entity entity) {
return entity;
}
private static final EntityType shulkerType =
Enums.findByValue(EntityType.class, "SHULKER");
/**
* Test whether an entity is hostile.
*
@ -135,7 +151,7 @@ public static boolean isHostile(Entity entity) {
|| entity instanceof Slime
|| entity instanceof Flying
|| entity instanceof EnderDragon
|| entity.getType() == shulkerType;
|| entity instanceof Shulker;
}
/**
@ -180,11 +196,6 @@ public static boolean isNonPlayerCreature(Entity entity) {
return entity instanceof LivingEntity && !(entity instanceof Player);
}
public static final EntityType armorStandType =
Enums.findByValue(EntityType.class, "ARMOR_STAND");
public static final EntityType enderCrystalType =
Enums.findByValue(EntityType.class, "ENDER_CRYSTAL");
/**
* Test whether using the given entity should be considered "building"
* rather than merely using an entity.
@ -194,19 +205,15 @@ public static boolean isNonPlayerCreature(Entity entity) {
*/
public static boolean isConsideredBuildingIfUsed(Entity entity) {
return entity instanceof Hanging
|| entity.getType() == armorStandType
|| entity.getType() == enderCrystalType;
|| entity instanceof ArmorStand
|| entity instanceof EnderCrystal;
}
private static final EntityType tippedArrow = Enums.findByValue(EntityType.class, "TIPPED_ARROW");
private static final EntityType spectralArrow = Enums.findByValue(EntityType.class, "SPECTRAL_ARROW");
public static boolean isPotionArrow(Entity entity) {
return (entity != null &&
(entity.getType() == tippedArrow || entity.getType() == spectralArrow));
return entity instanceof TippedArrow || entity instanceof SpectralArrow;
}
private static final EntityType aoeCloud = Enums.findByValue(EntityType.class, "AREA_EFFECT_CLOUD");
public static boolean isAoECloud(EntityType type) {
return type == aoeCloud;
return type == EntityType.AREA_EFFECT_CLOUD;
}
}

View File

@ -111,6 +111,16 @@ public void setSaturation(double saturation) {
}
@Override
public float getExhaustion() {
return 0;
}
@Override
public void setExhaustion(float exhaustion) {
}
@Override
public WeatherType getPlayerWeather() {
return null;
@ -146,6 +156,21 @@ public void resetPlayerTime() {
}
@Override
public int getFireTicks() {
return 0;
}
@Override
public void setFireTicks(int fireTicks) {
}
@Override
public void setCompassTarget(Location location) {
}
@Override
public void printRaw(String msg) {
System.out.println("-> TestPlayer{" + this.name + "}: " + msg);
@ -212,6 +237,10 @@ public Location getLocation() {
return null;
}
@Override public boolean setLocation(Location location) {
return false;
}
@Override
public boolean setLocation(Location location) {
return false;