Optimize auto trim + command cost/confirmation

This commit is contained in:
Jesse Boyd 2016-05-22 05:29:19 +10:00
parent e2182260d9
commit b8afbe8a00
16 changed files with 325 additions and 745 deletions

View File

@ -44,7 +44,6 @@ import com.plotsquared.bukkit.listeners.PlayerEvents_1_8;
import com.plotsquared.bukkit.listeners.PlayerEvents_1_9;
import com.plotsquared.bukkit.listeners.PlotPlusListener;
import com.plotsquared.bukkit.listeners.WorldEvents;
import com.plotsquared.bukkit.listeners.worldedit.WEListener;
import com.plotsquared.bukkit.titles.DefaultTitle_19;
import com.plotsquared.bukkit.util.BukkitChatManager;
import com.plotsquared.bukkit.util.BukkitChunkManager;
@ -387,7 +386,6 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
public boolean initWorldEdit() {
if (getServer().getPluginManager().getPlugin("WorldEdit") != null) {
worldEdit = (WorldEditPlugin) getServer().getPluginManager().getPlugin("WorldEdit");
getServer().getPluginManager().registerEvents(new WEListener(), this);
return true;
}
return false;

View File

@ -1,18 +1,15 @@
package com.plotsquared.bukkit.listeners;
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.object.ChunkLoc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefClass;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefField;
import com.intellectualcrafters.plot.util.ReflectionUtils.RefMethod;
import com.intellectualcrafters.plot.util.TaskManager;
import com.intellectualcrafters.plot.util.UUIDHandler;
import java.lang.reflect.Method;
import java.util.HashSet;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
@ -31,9 +28,8 @@ import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Map.Entry;
import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass;
public class ChunkListener implements Listener {
@ -43,7 +39,7 @@ public class ChunkListener implements Listener {
public ChunkListener() {
if (Settings.CHUNK_PROCESSOR_GC || Settings.CHUNK_PROCESSOR_TRIM_ON_SAVE) {
if (Settings.CHUNK_PROCESSOR_GC) {
try {
RefClass classChunk = getRefClass("{nms}.Chunk");
RefClass classCraftChunk = getRefClass("{cb}.CraftChunk");
@ -52,130 +48,60 @@ public class ChunkListener implements Listener {
} catch (Throwable ignored) {
PS.debug("PlotSquared/Server not compatible for chunk processor trim/gc");
Settings.CHUNK_PROCESSOR_GC = false;
Settings.CHUNK_PROCESSOR_TRIM_ON_SAVE = false;
}
}
if (!Settings.CHUNK_PROCESSOR_GC) {
return;
}
TaskManager.runTask(new Runnable() {
for (World world : Bukkit.getWorlds()) {
world.setAutoSave(false);
}
TaskManager.runTaskRepeat(new Runnable() {
@Override
public void run() {
int distance = Bukkit.getViewDistance() + 2;
HashMap<String, HashMap<ChunkLoc, Integer>> players = new HashMap<>();
for (Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
PlotPlayer pp = entry.getValue();
Location location = pp.getLocation();
String world = location.getWorld();
if (!PS.get().hasPlotArea(world)) {
continue;
}
HashMap<ChunkLoc, Integer> map = players.get(world);
if (map == null) {
map = new HashMap<>();
players.put(world, map);
}
ChunkLoc origin = new ChunkLoc(location.getX() >> 4, location.getZ() >> 4);
Integer val = map.get(origin);
int check;
if (val != null) {
if (val == distance) {
try {
HashSet<Chunk> toUnload = new HashSet<>();
for (World world : Bukkit.getWorlds()) {
String worldName = world.getName();
if (!PS.get().hasPlotArea(worldName)) {
continue;
}
check = distance - val;
} else {
check = distance;
map.put(origin, distance);
}
for (int x = -distance; x <= distance; x++) {
if (x >= check || -x >= check) {
continue;
}
for (int z = -distance; z <= distance; z++) {
if (z >= check || -z >= check) {
Object w = world.getClass().getDeclaredMethod("getHandle").invoke(world);
Object chunkMap = w.getClass().getDeclaredMethod("getPlayerChunkMap").invoke(w);
Method methodIsChunkInUse = chunkMap.getClass().getDeclaredMethod("isChunkInUse", int.class, int.class);
Chunk[] chunks = world.getLoadedChunks();
for (Chunk chunk : chunks) {
if ((boolean) methodIsChunkInUse.invoke(chunkMap, chunk.getX(), chunk.getZ())) {
continue;
}
int weight = distance - Math.max(Math.abs(x), Math.abs(z));
ChunkLoc chunk = new ChunkLoc(x + origin.x, z + origin.z);
val = map.get(chunk);
if (val == null || val < weight) {
map.put(chunk, weight);
int x = chunk.getX();
int z = chunk.getZ();
if (!shouldSave(worldName, x, z)) {
unloadChunk(worldName, chunk, false);
continue;
}
}
}
}
int time = 300;
for (World world : Bukkit.getWorlds()) {
String name = world.getName();
if (!PS.get().hasPlotArea(name)) {
continue;
}
boolean autoSave = world.isAutoSave();
if (autoSave) {
world.setAutoSave(false);
}
HashMap<ChunkLoc, Integer> map = players.get(name);
if (map == null || map.isEmpty()) {
continue;
}
Chunk[] chunks = world.getLoadedChunks();
ArrayDeque<Chunk> toUnload = new ArrayDeque<>();
for (Chunk chunk : chunks) {
int x = chunk.getX();
int z = chunk.getZ();
if (!map.containsKey(new ChunkLoc(x, z))) {
toUnload.add(chunk);
}
}
if (!toUnload.isEmpty()) {
long start = System.currentTimeMillis();
Chunk chunk;
while ((chunk = toUnload.poll()) != null && System.currentTimeMillis() - start < 5) {
if (!Settings.CHUNK_PROCESSOR_TRIM_ON_SAVE || !unloadChunk(name, chunk)) {
if (chunk.isLoaded()) {
chunk.unload(true, false);
}
}
}
if (!toUnload.isEmpty()) {
time = 1;
}
if (toUnload.isEmpty()) {
return;
}
if (!Settings.CHUNK_PROCESSOR_TRIM_ON_SAVE && autoSave) {
world.setAutoSave(true);
long start = System.currentTimeMillis();
for (Chunk chunk : toUnload) {
if (System.currentTimeMillis() - start > 5) {
return;
}
chunk.unload(true, false);
}
} catch (Throwable e) {
e.printStackTrace();
}
TaskManager.runTaskLater(this, time);
}
});
}, 1);
}
public boolean unloadChunk(String world, Chunk chunk) {
int X = chunk.getX();
int Z = chunk.getZ();
int x = X << 4;
int z = Z << 4;
int x2 = x + 15;
int z2 = z + 15;
Plot plot = new Location(world, x, 1, z).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return false;
}
plot = new Location(world, x2, 1, z2).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return false;
}
plot = new Location(world, x2, 1, z).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return false;
}
plot = new Location(world, x, 1, z2).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return false;
}
plot = new Location(world, x + 7, 1, z + 7).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
public boolean unloadChunk(String world, Chunk chunk, boolean safe) {
if (safe && shouldSave(world, chunk.getX(), chunk.getZ())) {
return false;
}
Object c = this.methodGetHandleChunk.of(chunk).call();
@ -185,14 +111,42 @@ public class ChunkListener implements Listener {
}
return true;
}
public boolean shouldSave(String world, int X, int Z) {
int x = X << 4;
int z = Z << 4;
int x2 = x + 15;
int z2 = z + 15;
Plot plot = new Location(world, x, 1, z).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return true;
}
plot = new Location(world, x2, 1, z2).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return true;
}
plot = new Location(world, x2, 1, z).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return true;
}
plot = new Location(world, x, 1, z2).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return true;
}
plot = new Location(world, x + 7, 1, z + 7).getOwnedPlotAbs();
if (plot != null && plot.hasOwner()) {
return true;
}
return false;
}
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event) {
if (Settings.CHUNK_PROCESSOR_TRIM_ON_SAVE) {
if (Settings.CHUNK_PROCESSOR_GC) {
Chunk chunk = event.getChunk();
String world = chunk.getWorld().getName();
if (PS.get().hasPlotArea(world)) {
if (unloadChunk(world, chunk)) {
if (unloadChunk(world, chunk, true)) {
return;
}
}

View File

@ -1,330 +0,0 @@
package com.plotsquared.bukkit.listeners.worldedit;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.SetQueue;
import com.plotsquared.bukkit.BukkitMain;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.listener.WEManager;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.selections.Selection;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public class WEListener implements Listener {
public final Set<String> other = new HashSet<>(Arrays.asList("undo", "redo"));
private final Set<String> rad1 = new HashSet<>(
Arrays.asList("forestgen", "pumpkins", "drain", "fixwater", "fixlava", "replacenear", "snow", "thaw", "ex", "butcher", "size"));
private final Set<String> rad2 = new HashSet<>(Arrays.asList("fill", "fillr", "removenear", "remove"));
private final Set<String> rad2_1 = new HashSet<>(Arrays.asList("hcyl", "cyl"));
private final Set<String> rad2_2 = new HashSet<>(Arrays.asList("sphere", "pyramid"));
private final Set<String> rad2_3 = Collections.singleton("brush smooth");
private final Set<String> rad3_1 = Collections.singleton("brush gravity");
private final Set<String> rad3_2 = new HashSet<>(Arrays.asList("brush sphere", "brush cylinder"));
private final Set<String> region = new HashSet<>(
Arrays.asList("move", "set", "replace", "overlay", "walls", "outline", "deform", "hollow", "smooth", "naturalize", "paste", "count",
"distr",
"regen", "copy", "cut", "green", "setbiome"));
private final Set<String> regionExtend = Collections.singleton("stack");
private final Set<String> restricted = Collections.singleton("up");
public String reduceCmd(String cmd, boolean single) {
if (cmd.startsWith("/worldedit:/")) {
return cmd.substring(12);
}
if (cmd.startsWith("/worldedit:")) {
return cmd.substring(11);
}
if (cmd.startsWith("//")) {
return cmd.substring(2);
}
if (single && cmd.startsWith("/")) {
return cmd.substring(1);
}
return cmd;
}
public int getInt(String s) {
try {
int max = 0;
String[] split = s.split(",");
for (String rad : split) {
int val = Integer.parseInt(rad);
if (val > max) {
max = val;
}
}
return max;
} catch (NumberFormatException ignored) {
return 0;
}
}
public boolean checkVolume(PlotPlayer player, long volume, long max, Cancellable e) {
if (volume > max) {
MainUtil.sendMessage(player, C.WORLDEDIT_VOLUME.s().replaceAll("%current%", String.valueOf(volume)).replaceAll("%max%", String.valueOf(max)));
e.setCancelled(true);
}
if (Permissions.hasPermission(player, "plots.worldedit.bypass")) {
MainUtil.sendMessage(player, C.WORLDEDIT_BYPASS);
}
return true;
}
public boolean checkSelection(Player p, PlotPlayer pp, int modifier, long max, Cancellable e) {
Selection selection = BukkitMain.worldEdit.getSelection(p);
if (selection == null) {
return true;
}
BlockVector pos1 = selection.getNativeMinimumPoint().toBlockVector();
BlockVector pos2 = selection.getNativeMaximumPoint().toBlockVector();
HashSet<RegionWrapper> mask = WEManager.getMask(pp);
RegionWrapper region = new RegionWrapper(pos1.getBlockX(), pos2.getBlockX(), pos1.getBlockZ(), pos2.getBlockZ());
if (Settings.REQUIRE_SELECTION) {
String arg = null;
if (!WEManager.regionContains(region, mask)) {
arg = "pos1 + pos2";
} else if (!WEManager.maskContains(mask, pos1.getBlockX(), pos1.getBlockY(), pos1.getBlockZ())) {
arg = "pos1";
} else if (!WEManager.maskContains(mask, pos2.getBlockX(), pos2.getBlockY(), pos2.getBlockZ())) {
arg = "pos2";
}
if (arg != null) {
e.setCancelled(true);
MainUtil.sendMessage(pp, C.REQUIRE_SELECTION_IN_MASK, arg);
if (Permissions.hasPermission(pp, "plots.worldedit.bypass")) {
MainUtil.sendMessage(pp, C.WORLDEDIT_BYPASS);
}
return true;
}
if (!WEManager.regionContains(region, mask)) {
MainUtil.sendMessage(pp, C.REQUIRE_SELECTION_IN_MASK, "pos1 + pos2");
e.setCancelled(true);
if (Permissions.hasPermission(pp, "plots.worldedit.bypass")) {
MainUtil.sendMessage(pp, C.WORLDEDIT_BYPASS);
}
return true;
}
}
long volume = Math.abs((pos1.getBlockX() - pos2.getBlockX()) * (pos1.getBlockY() - pos2.getBlockY()) * (pos1.getBlockZ() - pos2.getBlockZ()))
* modifier;
return checkVolume(pp, volume, max, e);
}
public boolean delay(final Player player, final String command, boolean delayed) {
if (!Settings.QUEUE_COMMANDS || !Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT) {
return false;
}
boolean free = SetQueue.IMP.addTask(null);
if (free) {
if (delayed) {
MainUtil.sendMessage(BukkitUtil.getPlayer(player), C.WORLDEDIT_RUN, command);
Bukkit.getServer().dispatchCommand(player, command.substring(1));
} else {
return false;
}
} else {
if (!delayed) {
MainUtil.sendMessage(BukkitUtil.getPlayer(player), C.WORLDEDIT_DELAYED);
}
SetQueue.IMP.addTask(new Runnable() {
@Override
public void run() {
delay(player, command, true);
}
});
}
return true;
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public boolean onPlayerCommand(PlayerCommandPreprocessEvent e) {
WorldEditPlugin worldedit = BukkitMain.worldEdit;
if (worldedit == null) {
HandlerList.unregisterAll(this);
return true;
}
Player p = e.getPlayer();
PlotPlayer pp = BukkitUtil.getPlayer(p);
if (!PS.get().hasPlotArea(p.getWorld().getName())) {
return true;
}
String message = e.getMessage();
String cmd = message.toLowerCase();
String[] split = cmd.split(" ");
long maxVolume = Settings.WE_MAX_VOLUME;
long maxIterations = Settings.WE_MAX_ITERATIONS;
if (pp.getAttribute("worldedit")) {
return true;
}
boolean single = true;
if (split.length >= 2) {
String reduced = reduceCmd(split[0], single);
String reduced2 = reduceCmd(split[0] + ' ' + split[1], single);
if (this.rad1.contains(reduced)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
long volume = getInt(split[1]) * 256;
return checkVolume(pp, volume, maxVolume, e);
}
if (this.rad2.contains(reduced)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
if (split.length >= 3) {
long volume = getInt(split[2]) * 256;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (this.rad2_1.contains(reduced)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
if (split.length >= 4) {
long volume = getInt(split[2]) * getInt(split[3]);
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (this.rad2_2.contains(reduced)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
if (split.length >= 3) {
long radius = getInt(split[2]);
long volume = radius * radius;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (this.rad2_3.contains(reduced2)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
if (split.length >= 3) {
if (split.length == 4) {
int iterations = getInt(split[3]);
if (iterations > maxIterations) {
MainUtil.sendMessage(pp,
C.WORLDEDIT_ITERATIONS.s().replaceAll("%current%", String.valueOf(iterations)).replaceAll("%max%",
String.valueOf(maxIterations)));
e.setCancelled(true);
if (Permissions.hasPermission(pp, "plots.worldedit.bypass")) {
MainUtil.sendMessage(pp, C.WORLDEDIT_BYPASS);
}
return true;
}
}
long radius = getInt(split[2]);
long volume = radius * radius;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (this.rad3_1.contains(reduced2)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
if (split.length >= 3) {
int i = 2;
if (split[i].equalsIgnoreCase("-h")) {
i = 3;
}
long radius = getInt(split[i]);
long volume = radius * radius;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (this.rad3_2.contains(reduced2)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
if (split.length >= 4) {
int i = 3;
if (split[i].equalsIgnoreCase("-h")) {
i = 4;
}
long radius = getInt(split[i]);
long volume = radius * radius;
return checkVolume(pp, volume, maxVolume, e);
}
return true;
}
if (this.regionExtend.contains(reduced)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
return checkSelection(p, pp, getInt(split[1]), maxVolume, e);
}
}
String reduced = reduceCmd(split[0], single);
if (Settings.WE_BLACKLIST.contains(reduced)) {
MainUtil.sendMessage(pp, C.WORLDEDIT_UNSAFE);
e.setCancelled(true);
if (Permissions.hasPermission(pp, "plots.worldedit.bypass")) {
MainUtil.sendMessage(pp, C.WORLDEDIT_BYPASS);
}
}
if (this.restricted.contains(reduced)) {
Plot plot = pp.getCurrentPlot();
if ((plot != null) && plot.isAdded(pp.getUUID())) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
return true;
}
e.setCancelled(true);
MainUtil.sendMessage(pp, C.NO_PLOT_PERMS);
if (Permissions.hasPermission(pp, "plots.worldedit.bypass")) {
MainUtil.sendMessage(pp, C.WORLDEDIT_BYPASS);
}
return true;
}
if (this.region.contains(reduced)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
return checkSelection(p, pp, 1, maxVolume, e);
}
if (this.other.contains(reduced)) {
if (delay(p, message, false)) {
e.setCancelled(true);
return true;
}
}
return true;
}
}

View File

@ -43,7 +43,7 @@ public interface Configuration extends ConfigurationSection {
*
* <p>This method will not hold a reference to the specified Configuration,
* nor will it automatically update if that Configuration ever changes. If
* you require this, you should set the default source with {@link
* you check this, you should set the default source with {@link
* #setDefaults(Configuration)}.</p>
*
* @param defaults A configuration holding a list of defaults to copy.

View File

@ -1903,7 +1903,7 @@ public class PS {
this.config.set("clear.ignore-if-modified", null);
// Done
options.put("approval.ratings.require-done", Settings.REQUIRE_DONE);
options.put("approval.ratings.check-done", Settings.REQUIRE_DONE);
options.put("approval.done.counts-towards-limit", Settings.DONE_COUNTS_TOWARDS_LIMIT);
options.put("approval.done.restrict-building", Settings.DONE_RESTRICTS_BUILDING);
options.put("approval.done.required-for-download", Settings.DOWNLOAD_REQUIRES_DONE);
@ -1932,18 +1932,13 @@ public class PS {
options.put("teleport.delay", Settings.TELEPORT_DELAY);
// WorldEdit
options.put("worldedit.require-selection-in-mask", Settings.REQUIRE_SELECTION);
options.put("worldedit.queue-commands", Settings.QUEUE_COMMANDS);
options.put("worldedit.enable-for-helpers", Settings.WE_ALLOW_HELPER);
options.put("worldedit.max-volume", Settings.WE_MAX_VOLUME);
options.put("worldedit.max-iterations", Settings.WE_MAX_ITERATIONS);
options.put("worldedit.blacklist", Arrays.asList("cs", ".s", "restore", "snapshot", "delchunks", "listchunks"));
// Chunk processor
options.put("chunk-processor.enabled", Settings.CHUNK_PROCESSOR);
options.put("chunk-processor.auto-unload", Settings.CHUNK_PROCESSOR_GC);
options.put("chunk-processor.experimental-fast-async-worldedit", Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT);
options.put("chunk-processor.auto-trim", Settings.CHUNK_PROCESSOR_TRIM_ON_SAVE);
options.put("chunk-processor.max-blockstates", Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES);
options.put("chunk-processor.max-entities", Settings.CHUNK_PROCESSOR_MAX_ENTITIES);
options.put("chunk-processor.disable-physics", Settings.CHUNK_PROCESSOR_DISABLE_PHYSICS);
@ -2011,7 +2006,7 @@ public class PS {
Settings.AUTO_CLEAR_CONFIRMATION = this.config.getBoolean("clear.auto.confirmation"); // TODO FIXME
// Done
Settings.REQUIRE_DONE = this.config.getBoolean("approval.ratings.require-done");
Settings.REQUIRE_DONE = this.config.getBoolean("approval.ratings.check-done");
Settings.DONE_COUNTS_TOWARDS_LIMIT = this.config.getBoolean("approval.done.counts-towards-limit");
Settings.DONE_RESTRICTS_BUILDING = this.config.getBoolean("approval.done.restrict-building");
Settings.DOWNLOAD_REQUIRES_DONE = this.config.getBoolean("approval.done.required-for-download");
@ -2042,17 +2037,11 @@ public class PS {
Settings.TELEPORT_ON_DEATH = this.config.getBoolean("teleport.on_death");
// WorldEdit
Settings.QUEUE_COMMANDS = this.config.getBoolean("worldedit.queue-commands");
Settings.REQUIRE_SELECTION = this.config.getBoolean("worldedit.require-selection-in-mask");
Settings.WE_ALLOW_HELPER = this.config.getBoolean("worldedit.enable-for-helpers");
Settings.WE_MAX_VOLUME = this.config.getLong("worldedit.max-volume");
Settings.WE_MAX_ITERATIONS = this.config.getLong("worldedit.max-iterations");
Settings.WE_BLACKLIST = this.config.getStringList("worldedit.blacklist");
// Chunk processor
Settings.CHUNK_PROCESSOR = this.config.getBoolean("chunk-processor.enabled");
Settings.CHUNK_PROCESSOR_GC = this.config.getBoolean("chunk-processor.auto-unload");
Settings.CHUNK_PROCESSOR_TRIM_ON_SAVE = this.config.getBoolean("chunk-processor.auto-trim");
Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT = this.config.getBoolean("chunk-processor.experimental-fast-async-worldedit");
Settings.CHUNK_PROCESSOR_MAX_BLOCKSTATES = this.config.getInt("chunk-processor.max-blockstates");
Settings.CHUNK_PROCESSOR_MAX_ENTITIES = this.config.getInt("chunk-processor.max-entities");

View File

@ -2,13 +2,14 @@ package com.intellectualcrafters.plot.commands;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RunnableVal2;
import com.intellectualcrafters.plot.object.RunnableVal3;
import com.intellectualcrafters.plot.util.EventUtil;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.plotsquared.general.commands.Argument;
import com.plotsquared.general.commands.Command;
import com.plotsquared.general.commands.CommandDeclaration;
import java.util.Iterator;
import java.util.Set;
@ -22,67 +23,57 @@ import java.util.UUID;
category = CommandCategory.SETTINGS,
permission = "plots.add",
requiredType = RequiredType.PLAYER)
public class Add extends SubCommand {
public class Add extends Command {
public Add() {
super(Argument.PlayerName);
super(MainCommand.getInstance(), true);
}
@Override
public boolean onCommand(PlotPlayer plr, String[] args) {
Location loc = plr.getLocation();
Plot plot = loc.getPlotAbs();
if (plot == null) {
return !sendMessage(plr, C.NOT_IN_PLOT);
}
if (!plot.hasOwner()) {
MainUtil.sendMessage(plr, C.PLOT_UNOWNED);
return false;
}
if (!plot.isOwner(plr.getUUID()) && !Permissions.hasPermission(plr, "plots.admin.command.add")) {
MainUtil.sendMessage(plr, C.NO_PLOT_PERMS);
return true;
}
Set<UUID> uuids = MainUtil.getUUIDsFromString(args[0]);
if (uuids == null || uuids.isEmpty()) {
MainUtil.sendMessage(plr, C.INVALID_PLAYER, args[0]);
return false;
}
public void execute(final PlotPlayer player, String[] args, RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
final Plot plot = check(player.getCurrentPlot(), C.NOT_IN_PLOT);
checkTrue(plot.hasOwner(), C.PLOT_UNOWNED);
checkTrue(plot.isOwner(player.getUUID()) || Permissions.hasPermission(player, "plots.admin.command.trust"), C.NO_PLOT_PERMS);
checkTrue(args.length == 1, C.COMMAND_SYNTAX, getUsage());
final Set<UUID> uuids = MainUtil.getUUIDsFromString(args[0]);
checkTrue(uuids != null && !uuids.isEmpty(), C.INVALID_PLAYER, args[0]);
Iterator<UUID> iter = uuids.iterator();
int size = plot.getTrusted().size() + plot.getMembers().size();
while (iter.hasNext()) {
UUID uuid = iter.next();
if (uuid == DBFunc.everyone && !(Permissions.hasPermission(plr, "plots.add.everyone") || Permissions.hasPermission(plr, "plots.admin.command.add"))) {
MainUtil.sendMessage(plr, C.INVALID_PLAYER, MainUtil.getName(uuid));
if (uuid == DBFunc.everyone && !(Permissions.hasPermission(player, "plots.trust.everyone") || Permissions.hasPermission(player, "plots.admin.command.trust"))) {
MainUtil.sendMessage(player, C.INVALID_PLAYER, MainUtil.getName(uuid));
iter.remove();
continue;
}
if (plot.isOwner(uuid)) {
MainUtil.sendMessage(plr, C.ALREADY_OWNER, MainUtil.getName(uuid));
MainUtil.sendMessage(player, C.ALREADY_OWNER, MainUtil.getName(uuid));
iter.remove();
continue;
}
if (plot.getMembers().contains(uuid)) {
MainUtil.sendMessage(plr, C.ALREADY_ADDED, MainUtil.getName(uuid));
MainUtil.sendMessage(player, C.ALREADY_ADDED, MainUtil.getName(uuid));
iter.remove();
continue;
}
if (plot.removeTrusted(uuid)) {
plot.addMember(uuid);
} else {
if ((plot.getMembers().size() + plot.getTrusted().size()) >= plot.getArea().MAX_PLOT_MEMBERS) {
MainUtil.sendMessage(plr, C.PLOT_MAX_MEMBERS);
iter.remove();
continue;
size += plot.getTrusted().contains(uuid) ? 0 : 1;
}
checkTrue(!uuids.isEmpty(), null);
checkTrue(size <= plot.getArea().MAX_PLOT_MEMBERS, C.PLOT_MAX_MEMBERS);
confirm.run(this, new Runnable() {
@Override // Success
public void run() {
for (UUID uuid : uuids) {
if (!plot.removeTrusted(uuid)) {
if (plot.getDenied().contains(uuid)) {
plot.removeDenied(uuid);
}
}
plot.addMember(uuid);
EventUtil.manager.callMember(player, plot, uuid, true);
MainUtil.sendMessage(player, C.MEMBER_ADDED);
}
if (plot.getDenied().contains(uuid)) {
plot.removeDenied(uuid);
}
plot.addMember(uuid);
}
EventUtil.manager.callMember(plr, plot, uuid, true);
}
if (!uuids.isEmpty()) {
MainUtil.sendMessage(plr, C.MEMBER_ADDED);
}
return true;
}, null);
}
}
}

View File

@ -1,17 +1,17 @@
package com.intellectualcrafters.plot.commands;
import com.google.common.base.Optional;
import com.intellectualcrafters.plot.PS;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.flag.Flags;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RunnableVal2;
import com.intellectualcrafters.plot.object.RunnableVal3;
import com.intellectualcrafters.plot.util.EconHandler;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.UUIDHandler;
import com.plotsquared.general.commands.Command;
import com.plotsquared.general.commands.CommandDeclaration;
import java.util.Set;
@CommandDeclaration(
@ -22,67 +22,51 @@ import java.util.Set;
permission = "plots.buy",
category = CommandCategory.CLAIMING,
requiredType = RequiredType.NONE)
public class Buy extends SubCommand {
public class Buy extends Command {
public Buy() {
super(MainCommand.getInstance(), true);
}
@Override
public boolean onCommand(PlotPlayer plr, String[] args) {
if (EconHandler.manager == null) {
return sendMessage(plr, C.ECON_DISABLED);
}
Location loc = plr.getLocation();
String world = loc.getWorld();
if (!PS.get().hasPlotArea(world)) {
return sendMessage(plr, C.NOT_IN_PLOT_WORLD);
}
Set<Plot> plots;
Plot plot;
if (args.length > 0) {
try {
plot = MainUtil.getPlotFromString(plr, world, true);
if (plot == null) {
return false;
}
plots = plot.getConnectedPlots();
} catch (Exception ignored) {
return sendMessage(plr, C.NOT_VALID_PLOT_ID);
}
public void execute(final PlotPlayer player, String[] args, RunnableVal3<Command, Runnable, Runnable> confirm, final RunnableVal2<Command, CommandResult> whenDone) {
check(EconHandler.manager, C.ECON_DISABLED);
final Plot plot;
if (args.length != 0) {
check(args.length == 1, C.COMMAND_SYNTAX, getUsage());
plot = check(MainUtil.getPlotFromString(player, args[0], true), null);
} else {
plot = loc.getPlotAbs();
plots = plot != null ? plot.getConnectedPlots() : null;
}
if (plots == null) {
return sendMessage(plr, C.NOT_IN_PLOT);
}
if (!plot.hasOwner()) {
return sendMessage(plr, C.PLOT_UNOWNED);
}
int currentPlots = plr.getPlotCount() + plots.size();
if (currentPlots > plr.getAllowedPlots()) {
return sendMessage(plr, C.CANT_CLAIM_MORE_PLOTS);
plot = check(player.getCurrentPlot(), C.NOT_IN_PLOT);
}
check(plot.hasOwner(), C.PLOT_UNOWNED);
check(!plot.isOwner(player.getUUID()), C.CANNOT_BUY_OWN);
Set<Plot> plots = plot.getConnectedPlots();
check(player.getPlotCount() + plots.size() <= player.getAllowedPlots(), C.CANT_CLAIM_MORE_PLOTS);
Optional<Double> flag = plot.getFlag(Flags.PRICE);
if (!flag.isPresent()) {
return sendMessage(plr, C.NOT_FOR_SALE);
}
if (plot.isOwner(plr.getUUID())) {
return sendMessage(plr, C.CANNOT_BUY_OWN);
}
double price = flag.get();
if ((EconHandler.manager != null) && (price > 0d)) {
if (EconHandler.manager.getMoney(plr) < price) {
return sendMessage(plr, C.CANNOT_AFFORD_PLOT, "" + price);
check(flag.isPresent(), C.NOT_FOR_SALE);
final double price = flag.get();
check(player.getMoney() >= price, C.CANNOT_AFFORD_PLOT);
player.withdraw(price);
confirm.run(this, new Runnable() {
@Override // Success
public void run() {
C.REMOVED_BALANCE.send(player, price);
EconHandler.manager.depositMoney(UUIDHandler.getUUIDWrapper().getOfflinePlayer(plot.owner), price);
PlotPlayer owner = UUIDHandler.getPlayer(plot.owner);
if (owner != null) {
C.PLOT_SOLD.send(owner, plot.getId(), player.getName(), price);
}
plot.removeFlag(Flags.PRICE);
plot.setOwner(player.getUUID());
C.CLAIMED.send(player);
whenDone.run(Buy.this, CommandResult.SUCCESS);
}
EconHandler.manager.withdrawMoney(plr, price);
sendMessage(plr, C.REMOVED_BALANCE, price + "");
EconHandler.manager.depositMoney(UUIDHandler.getUUIDWrapper().getOfflinePlayer(plot.owner), price);
PlotPlayer owner = UUIDHandler.getPlayer(plot.owner);
if (owner != null) {
sendMessage(plr, C.PLOT_SOLD, plot.getId() + "", plr.getName(), price + "");
}, new Runnable() {
@Override // Failure
public void run() {
player.deposit(price);
whenDone.run(Buy.this, CommandResult.FAILURE);
}
plot.removeFlag(Flags.PRICE);
}
plot.setOwner(plr.getUUID());
MainUtil.sendMessage(plr, C.CLAIMED);
return true;
});
}
}

View File

@ -4,72 +4,40 @@ import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.flag.FlagManager;
import com.intellectualcrafters.plot.flag.Flags;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.util.CmdConfirm;
import com.intellectualcrafters.plot.object.RunnableVal2;
import com.intellectualcrafters.plot.object.RunnableVal3;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.SetQueue;
import com.intellectualcrafters.plot.util.TaskManager;
import com.plotsquared.general.commands.Command;
import com.plotsquared.general.commands.CommandDeclaration;
import java.util.Set;
@CommandDeclaration(command = "clear",
description = "Clear a plot",
permission = "plots.clear",
category = CommandCategory.APPEARANCE,
usage = "/plot clear [id]",
usage = "/plot clear",
aliases = "reset",
confirmation = true)
public class Clear extends SubCommand {
public class Clear extends Command {
// Note: To clear a specific plot use /plot <plot> clear
// The syntax also works with any command: /plot <plot> <command>
public Clear() {
super(MainCommand.getInstance(), true);
}
@Override
public boolean onCommand(final PlotPlayer plr, String[] args) {
Location loc = plr.getLocation();
final Plot plot;
if (args.length == 1) {
if (args[0].equalsIgnoreCase("mine")) {
Set<Plot> plots = plr.getPlots();
if (!plots.isEmpty()) {
plot = plots.iterator().next();
} else {
MainUtil.sendMessage(plr, C.NO_PLOTS);
return false;
}
} else {
plot = MainUtil.getPlotFromString(plr, args[0], true);
}
if (plot == null) {
MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot clear [X;Z|mine]");
return false;
}
} else if (args.length == 0) {
plot = loc.getPlotAbs();
if (plot == null) {
MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot clear [X;Z|mine]");
C.NOT_IN_PLOT.send(plr);
return false;
}
} else {
MainUtil.sendMessage(plr, C.COMMAND_SYNTAX, "/plot clear [X;Z|mine]");
return false;
}
if ((!plot.hasOwner() || !plot.isOwner(plr.getUUID())) && !Permissions.hasPermission(plr, "plots.admin.command.clear")) {
return sendMessage(plr, C.NO_PLOT_PERMS);
}
if (plot.getRunning() != 0) {
MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER);
return false;
}
if (plot.getFlag(Flags.DONE).isPresent()
&& (!Permissions.hasPermission(plr, "plots.continue") || (Settings.DONE_COUNTS_TOWARDS_LIMIT && (plr.getAllowedPlots() >= plr
.getPlotCount())))) {
MainUtil.sendMessage(plr, C.DONE_ALREADY_DONE);
return false;
}
Runnable runnable = new Runnable() {
public void execute(final PlotPlayer player, String[] args, RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
checkTrue(args.length == 0, C.COMMAND_SYNTAX, getUsage());
final Plot plot = check(player.getCurrentPlot(), C.NOT_IN_PLOT);
checkTrue(plot.isOwner(player.getUUID()) || Permissions.hasPermission(player, "plots.admin.command.clear"), C.NO_PLOT_PERMS);
checkTrue(plot.getRunning() == 0, C.WAIT_FOR_TIMER);
checkTrue((!Flags.DONE.isSet(plot) || Permissions.hasPermission(player, "plots.continue")) && (!Settings.DONE_COUNTS_TOWARDS_LIMIT || player.getAllowedPlots() >= player.getPlotCount() + plot.getConnectedPlots().size()), C.DONE_ALREADY_DONE);
confirm.run(this, new Runnable() {
@Override
public void run() {
final long start = System.currentTimeMillis();
@ -88,23 +56,17 @@ public class Clear extends SubCommand {
if (plot.getFlag(Flags.ANALYSIS).isPresent()) {
FlagManager.removePlotFlag(plot, Flags.ANALYSIS);
}
MainUtil.sendMessage(plr, C.CLEARING_DONE, "" + (System.currentTimeMillis() - start));
MainUtil.sendMessage(player, C.CLEARING_DONE, "" + (System.currentTimeMillis() - start));
}
});
}
});
if (!result) {
MainUtil.sendMessage(plr, C.WAIT_FOR_TIMER);
MainUtil.sendMessage(player, C.WAIT_FOR_TIMER);
} else {
plot.addRunning();
}
}
};
if (hasConfirmation(plr)) {
CmdConfirm.addPending(plr, "/plot clear " + plot.getId(), runnable);
} else {
TaskManager.runTask(runnable);
}
return true;
}, null);
}
}

View File

@ -128,46 +128,58 @@ public class MainCommand extends Command {
args = tmp;
}
}
getInstance().execute(player, args, new RunnableVal3<Command, Runnable, Runnable>() {
@Override
public void run(final Command cmd, final Runnable success, final Runnable failure) {
if (cmd.hasConfirmation(player) ) {
CmdConfirm.addPending(player, cmd.getUsage(), new Runnable() {
@Override
public void run() {
if (EconHandler.manager != null) {
PlotArea area = player.getApplicablePlotArea();
if (area != null) {
Double price = area.PRICES.get(cmd.getFullId());
if (price != null && EconHandler.manager.getMoney(player) < price) {
failure.run();
return;
try {
getInstance().execute(player, args, new RunnableVal3<Command, Runnable, Runnable>() {
@Override
public void run(final Command cmd, final Runnable success, final Runnable failure) {
if (cmd.hasConfirmation(player)) {
CmdConfirm.addPending(player, cmd.getUsage(), new Runnable() {
@Override
public void run() {
if (EconHandler.manager != null) {
PlotArea area = player.getApplicablePlotArea();
if (area != null) {
Double price = area.PRICES.get(cmd.getFullId());
if (price != null && EconHandler.manager.getMoney(player) < price) {
if (failure != null) {
failure.run();
}
return;
}
}
}
if (success != null) {
success.run();
}
}
});
return;
}
if (EconHandler.manager != null) {
PlotArea area = player.getApplicablePlotArea();
if (area != null) {
Double price = area.PRICES.get(cmd.getFullId());
if (price != null && EconHandler.manager.getMoney(player) < price) {
if (failure != null) {
failure.run();
}
return;
}
success.run();
}
});
return;
}
if (EconHandler.manager != null) {
PlotArea area = player.getApplicablePlotArea();
if (area != null) {
Double price = area.PRICES.get(cmd.getFullId());
if (price != null && EconHandler.manager.getMoney(player) < price) {
failure.run();
return;
}
}
if (success != null) {
success.run();
}
}
success.run();
}
}, new RunnableVal2<Command, CommandResult>() {
@Override
public void run(Command cmd, CommandResult result) {
// Post command stuff!?
}
});
}, new RunnableVal2<Command, CommandResult>() {
@Override
public void run(Command cmd, CommandResult result) {
// Post command stuff!?
}
});
} catch (CommandException e) {
e.perform(player);
}
// Always true
return true;
}
@ -191,8 +203,7 @@ public class MainCommand extends Command {
if (args.length >= 2) {
PlotArea area = player.getApplicablePlotArea();
Plot newPlot = Plot.fromString(area, args[0]);
if (newPlot != null && (player instanceof ConsolePlayer || newPlot.getArea().equals(area) || Permissions
.hasPermission(player, C.PERMISSION_ADMIN)) && !newPlot.isDenied(player.getUUID())) {
if (newPlot != null && (player instanceof ConsolePlayer || newPlot.getArea().equals(area) || Permissions.hasPermission(player, C.PERMISSION_ADMIN)) && !newPlot.isDenied(player.getUUID())) {
// Save meta
loc = player.getMeta("location");
plot = player.getMeta("lastplot");
@ -206,7 +217,7 @@ public class MainCommand extends Command {
}
super.execute(player, args, confirm, whenDone);
// Reset command scope //
if (tp) {
if (tp && !(player instanceof ConsolePlayer)) {
if (loc == null) {
player.deleteMeta("location");
} else {

View File

@ -2,16 +2,18 @@ package com.intellectualcrafters.plot.commands;
import com.intellectualcrafters.plot.config.C;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.Plot;
import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RunnableVal2;
import com.intellectualcrafters.plot.object.RunnableVal3;
import com.intellectualcrafters.plot.util.EventUtil;
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions;
import com.plotsquared.general.commands.Argument;
import com.plotsquared.general.commands.Command;
import com.plotsquared.general.commands.CommandDeclaration;
import java.util.*;
import java.util.Iterator;
import java.util.Set;
import java.util.UUID;
@CommandDeclaration(
command = "trust",
@ -20,64 +22,57 @@ import java.util.Set;
usage = "/plot trust <player>",
description = "Allow a player to build in a plot",
category = CommandCategory.SETTINGS)
public class Trust extends SubCommand {
public class Trust extends Command {
public Trust() {
super(Argument.PlayerName);
super(MainCommand.getInstance(), true);
}
@Override
public boolean onCommand(PlotPlayer plr, String[] args) {
Location loc = plr.getLocation();
Plot plot = loc.getPlotAbs();
if (plot == null) {
return !sendMessage(plr, C.NOT_IN_PLOT);
}
if (!plot.hasOwner()) {
MainUtil.sendMessage(plr, C.PLOT_UNOWNED);
return false;
}
if (!plot.isOwner(plr.getUUID()) && !Permissions.hasPermission(plr, "plots.admin.command.trust")) {
MainUtil.sendMessage(plr, C.NO_PLOT_PERMS);
return true;
}
Set<UUID> uuids = MainUtil.getUUIDsFromString(args[0]);
if (uuids == null || uuids.isEmpty()) {
MainUtil.sendMessage(plr, C.INVALID_PLAYER, args[0]);
return false;
}
public void execute(final PlotPlayer player, String[] args, RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
final Plot plot = check(player.getCurrentPlot(), C.NOT_IN_PLOT);
checkTrue(plot.hasOwner(), C.PLOT_UNOWNED);
checkTrue(plot.isOwner(player.getUUID()) || Permissions.hasPermission(player, "plots.admin.command.trust"), C.NO_PLOT_PERMS);
checkTrue(args.length == 1, C.COMMAND_SYNTAX, getUsage());
final Set<UUID> uuids = MainUtil.getUUIDsFromString(args[0]);
checkTrue(uuids != null && !uuids.isEmpty(), C.INVALID_PLAYER, args[0]);
Iterator<UUID> iter = uuids.iterator();
int size = plot.getTrusted().size() + plot.getMembers().size();
while (iter.hasNext()) {
UUID uuid = iter.next();
if (uuid == DBFunc.everyone && !(Permissions.hasPermission(plr, "plots.trust.everyone") || Permissions.hasPermission(plr, "plots.admin.command.trust"))) {
MainUtil.sendMessage(plr, C.INVALID_PLAYER, MainUtil.getName(uuid));
if (uuid == DBFunc.everyone && !(Permissions.hasPermission(player, "plots.trust.everyone") || Permissions.hasPermission(player, "plots.admin.command.trust"))) {
MainUtil.sendMessage(player, C.INVALID_PLAYER, MainUtil.getName(uuid));
iter.remove();
continue;
}
if (plot.isOwner(uuid)) {
MainUtil.sendMessage(plr, C.ALREADY_OWNER, MainUtil.getName(uuid));
MainUtil.sendMessage(player, C.ALREADY_OWNER, MainUtil.getName(uuid));
iter.remove();
continue;
}
if (plot.getTrusted().contains(uuid)) {
MainUtil.sendMessage(plr, C.ALREADY_ADDED, MainUtil.getName(uuid));
MainUtil.sendMessage(player, C.ALREADY_ADDED, MainUtil.getName(uuid));
iter.remove();
continue;
}
if (plot.removeMember(uuid)) {
plot.addTrusted(uuid);
} else {
if ((plot.getMembers().size() + plot.getTrusted().size()) >= plot.getArea().MAX_PLOT_MEMBERS) {
MainUtil.sendMessage(plr, C.PLOT_MAX_MEMBERS);
continue;
size += plot.getMembers().contains(uuid) ? 0 : 1;
}
checkTrue(!uuids.isEmpty(), null);
checkTrue(size <= plot.getArea().MAX_PLOT_MEMBERS, C.PLOT_MAX_MEMBERS);
confirm.run(this, new Runnable() {
@Override // Success
public void run() {
for (UUID uuid : uuids) {
if (!plot.removeMember(uuid)) {
if (plot.getDenied().contains(uuid)) {
plot.removeDenied(uuid);
}
}
plot.addTrusted(uuid);
EventUtil.manager.callTrusted(player, plot, uuid, true);
MainUtil.sendMessage(player, C.TRUSTED_ADDED);
}
if (plot.getDenied().contains(uuid)) {
plot.removeDenied(uuid);
}
plot.addTrusted(uuid);
}
EventUtil.manager.callTrusted(plr, plot, uuid, true);
}
if (!uuids.isEmpty()) {
MainUtil.sendMessage(plr, C.TRUSTED_ADDED);
}
return true;
}, null);
}
}

View File

@ -1,6 +1,5 @@
package com.intellectualcrafters.plot.config;
import java.util.ArrayList;
import java.util.List;
/**
@ -50,7 +49,6 @@ public class Settings {
*/
public static boolean CHUNK_PROCESSOR = false;
public static boolean EXPERIMENTAL_FAST_ASYNC_WORLDEDIT = false;
public static boolean CHUNK_PROCESSOR_TRIM_ON_SAVE = false;
public static boolean CHUNK_PROCESSOR_GC = false;
public static int CHUNK_PROCESSOR_MAX_BLOCKSTATES = 4096;
public static int CHUNK_PROCESSOR_MAX_ENTITIES = 512;
@ -65,14 +63,9 @@ public class Settings {
*/
public static int MAX_AUTO_SIZE = 4;
/**
* Default worldedit-require-selection-in-mask: false
* Default worldedit-check-selection-in-mask: false
*/
public static boolean REQUIRE_SELECTION = true;
public static boolean QUEUE_COMMANDS = false;
public static boolean WE_ALLOW_HELPER = false;
public static long WE_MAX_VOLUME = 500000;
public static long WE_MAX_ITERATIONS = 1000;
public static List<String> WE_BLACKLIST = new ArrayList<>();
/**
* Teleport to path on login
*/

View File

@ -31,7 +31,18 @@ public class Flags {
public static final BooleanFlag NOTIFY_ENTER = new BooleanFlag("notify-enter");
public static final LongFlag TIME = new LongFlag("time");
public static final PlotWeatherFlag WEATHER = new PlotWeatherFlag("weather");
public static final DoubleFlag PRICE = new DoubleFlag("price");
public static final DoubleFlag PRICE = new DoubleFlag("price") {
@Override
public Double parseValue(String input) {
Double value = super.parseValue(input);
return value != null && value > 0 ? value : null;
}
@Override
public String getValueDescription() {
return "Flag value must be a positive number.";
}
};
public static final BooleanFlag EXPLOSION = new BooleanFlag("explosion");
public static final BooleanFlag GRASS_GROW = new BooleanFlag("grass-grow");
public static final BooleanFlag VINE_GROW = new BooleanFlag("vine-grow");

View File

@ -27,7 +27,7 @@ public abstract class ClassicPlotWorld extends SquarePlotWorld {
/**
* CONFIG NODE | DEFAULT VALUE | DESCRIPTION | CONFIGURATION TYPE | REQUIRED FOR INITIAL SETUP.
*
* <p>Set the last boolean to false if you do not require a specific config node to be set while using the setup
* <p>Set the last boolean to false if you do not check a specific config node to be set while using the setup
* command - this may be useful if a config value can be changed at a later date, and has no impact on the actual
* world generation</p>
*/

View File

@ -5,20 +5,13 @@ import com.intellectualcrafters.plot.commands.RequiredType;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.util.PlotGameMode;
import com.intellectualcrafters.plot.util.PlotWeather;
import java.util.HashMap;
import java.util.UUID;
public class ConsolePlayer extends PlotPlayer {
private static ConsolePlayer instance;
private final HashMap<String, Object> meta;
/**
* Direct access is deprecated.
*/
@Deprecated
public ConsolePlayer() {
private ConsolePlayer() {
PlotArea area = PS.get().getFirstPlotArea();
Location loc;
if (area != null) {
@ -27,7 +20,6 @@ public class ConsolePlayer extends PlotPlayer {
} else {
loc = new Location("world", 0, 0, 0);
}
this.meta = new HashMap<>();
setMeta("location", loc);
}
@ -46,12 +38,12 @@ public class ConsolePlayer extends PlotPlayer {
@Override
public Location getLocation() {
return (Location) getMeta("location");
return this.<Location>getMeta("location");
}
@Override
public Location getLocationFull() {
return (Location) getMeta("location");
return getLocation();
}
@Override
@ -71,8 +63,7 @@ public class ConsolePlayer extends PlotPlayer {
@Override
public void teleport(Location location) {
Plot plot = location.getPlot();
setMeta("lastplot", plot);
setMeta("lastplot", location.getPlot());
setMeta("location", location);
}
@ -100,21 +91,6 @@ public class ConsolePlayer extends PlotPlayer {
@Override
public void removeAttribute(String key) {}
@Override
public void setMeta(String key, Object value) {
this.meta.put(key, value);
}
@Override
public Object getMeta(String key) {
return this.meta.get(key);
}
@Override
public Object deleteMeta(String key) {
return this.meta.remove(key);
}
@Override
public RequiredType getSuperCaller() {
return RequiredType.CONSOLE;

View File

@ -5,6 +5,7 @@ import com.intellectualcrafters.plot.commands.RequiredType;
import com.intellectualcrafters.plot.config.Settings;
import com.intellectualcrafters.plot.database.DBFunc;
import com.intellectualcrafters.plot.flag.Flags;
import com.intellectualcrafters.plot.util.EconHandler;
import com.intellectualcrafters.plot.util.EventUtil;
import com.intellectualcrafters.plot.util.ExpireManager;
import com.intellectualcrafters.plot.util.Permissions;
@ -449,4 +450,20 @@ public abstract class PlotPlayer implements CommandCaller {
}
public abstract void stopSpectating();
public double getMoney() {
return EconHandler.manager == null ? 0 : EconHandler.manager.getMoney(this);
}
public void withdraw(double amount) {
if (EconHandler.manager != null) {
EconHandler.manager.withdrawMoney(this, amount);
}
}
public void deposit(double amount) {
if (EconHandler.manager != null) {
EconHandler.manager.depositMoney(this, amount);
}
}
}

View File

@ -271,7 +271,7 @@ public abstract class Command {
* @return
*/
public void execute(PlotPlayer player, String[] args, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) {
RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
if (args.length == 0 || args[0] == null) {
if (this.parent == null) {
MainCommand.getInstance().help.displayHelp(player, null, 0);
@ -537,4 +537,33 @@ public abstract class Command {
FAILURE,
SUCCESS
}
public void checkTrue(boolean mustBeTrue, C message, Object... args) {
if (!mustBeTrue) {
throw new CommandException(message, args);
}
}
public <T extends Object> T check(T object, C message, Object... args) {
if (object == null) {
throw new CommandException(message, args);
}
return object;
}
public static class CommandException extends RuntimeException {
private final Object[] args;
private final C message;
public CommandException(C message, Object... args) {
this.message = message;
this.args = args;
}
public void perform(PlotPlayer player) {
if (player != null && message != null) {
message.send(player, args);
}
}
}
}