From b8afbe8a00406f1e10e048f413e42a3c919e213e Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Sun, 22 May 2016 05:29:19 +1000 Subject: [PATCH] Optimize auto trim + command cost/confirmation --- .../com/plotsquared/bukkit/BukkitMain.java | 2 - .../bukkit/listeners/ChunkListener.java | 184 ++++------ .../listeners/worldedit/WEListener.java | 330 ------------------ .../configuration/Configuration.java | 2 +- .../com/intellectualcrafters/plot/PS.java | 15 +- .../plot/commands/Add.java | 81 ++--- .../plot/commands/Buy.java | 100 +++--- .../plot/commands/Clear.java | 82 ++--- .../plot/commands/MainCommand.java | 85 +++-- .../plot/commands/Trust.java | 83 +++-- .../plot/config/Settings.java | 9 +- .../intellectualcrafters/plot/flag/Flags.java | 13 +- .../plot/generator/ClassicPlotWorld.java | 2 +- .../plot/object/ConsolePlayer.java | 34 +- .../plot/object/PlotPlayer.java | 17 + .../plotsquared/general/commands/Command.java | 31 +- 16 files changed, 325 insertions(+), 745 deletions(-) delete mode 100644 Bukkit/src/main/java/com/plotsquared/bukkit/listeners/worldedit/WEListener.java diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java index be60f8c23..d0ee8cb6d 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java @@ -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; diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listeners/ChunkListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listeners/ChunkListener.java index cbf45c664..ab68b1adc 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listeners/ChunkListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listeners/ChunkListener.java @@ -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> players = new HashMap<>(); - for (Entry entry : UUIDHandler.getPlayers().entrySet()) { - PlotPlayer pp = entry.getValue(); - Location location = pp.getLocation(); - String world = location.getWorld(); - if (!PS.get().hasPlotArea(world)) { - continue; - } - HashMap 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 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 map = players.get(name); - if (map == null || map.isEmpty()) { - continue; - } - Chunk[] chunks = world.getLoadedChunks(); - ArrayDeque 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; } } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listeners/worldedit/WEListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listeners/worldedit/WEListener.java deleted file mode 100644 index 45e2d5922..000000000 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listeners/worldedit/WEListener.java +++ /dev/null @@ -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 other = new HashSet<>(Arrays.asList("undo", "redo")); - private final Set rad1 = new HashSet<>( - Arrays.asList("forestgen", "pumpkins", "drain", "fixwater", "fixlava", "replacenear", "snow", "thaw", "ex", "butcher", "size")); - private final Set rad2 = new HashSet<>(Arrays.asList("fill", "fillr", "removenear", "remove")); - private final Set rad2_1 = new HashSet<>(Arrays.asList("hcyl", "cyl")); - private final Set rad2_2 = new HashSet<>(Arrays.asList("sphere", "pyramid")); - private final Set rad2_3 = Collections.singleton("brush smooth"); - private final Set rad3_1 = Collections.singleton("brush gravity"); - private final Set rad3_2 = new HashSet<>(Arrays.asList("brush sphere", "brush cylinder")); - private final Set 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 regionExtend = Collections.singleton("stack"); - private final Set 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 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; - } -} diff --git a/Core/src/main/java/com/intellectualcrafters/configuration/Configuration.java b/Core/src/main/java/com/intellectualcrafters/configuration/Configuration.java index c41a59555..71ad38983 100644 --- a/Core/src/main/java/com/intellectualcrafters/configuration/Configuration.java +++ b/Core/src/main/java/com/intellectualcrafters/configuration/Configuration.java @@ -43,7 +43,7 @@ public interface Configuration extends ConfigurationSection { * *

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)}.

* * @param defaults A configuration holding a list of defaults to copy. diff --git a/Core/src/main/java/com/intellectualcrafters/plot/PS.java b/Core/src/main/java/com/intellectualcrafters/plot/PS.java index 0a0c476b3..58e39a79e 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/PS.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/PS.java @@ -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"); diff --git a/Core/src/main/java/com/intellectualcrafters/plot/commands/Add.java b/Core/src/main/java/com/intellectualcrafters/plot/commands/Add.java index 2bba0b1a8..432b0a291 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/commands/Add.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/commands/Add.java @@ -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 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 confirm, RunnableVal2 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 uuids = MainUtil.getUUIDsFromString(args[0]); + checkTrue(uuids != null && !uuids.isEmpty(), C.INVALID_PLAYER, args[0]); Iterator 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); } -} +} \ No newline at end of file diff --git a/Core/src/main/java/com/intellectualcrafters/plot/commands/Buy.java b/Core/src/main/java/com/intellectualcrafters/plot/commands/Buy.java index 54ea00d04..478ccd45e 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/commands/Buy.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/commands/Buy.java @@ -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 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 confirm, final RunnableVal2 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 plots = plot.getConnectedPlots(); + check(player.getPlotCount() + plots.size() <= player.getAllowedPlots(), C.CANT_CLAIM_MORE_PLOTS); Optional 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; + }); } } diff --git a/Core/src/main/java/com/intellectualcrafters/plot/commands/Clear.java b/Core/src/main/java/com/intellectualcrafters/plot/commands/Clear.java index a7ee49994..a944c0960 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/commands/Clear.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/commands/Clear.java @@ -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 clear + // The syntax also works with any command: /plot + + 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 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 confirm, RunnableVal2 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); } } diff --git a/Core/src/main/java/com/intellectualcrafters/plot/commands/MainCommand.java b/Core/src/main/java/com/intellectualcrafters/plot/commands/MainCommand.java index 594469e75..7c40ab416 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/commands/MainCommand.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/commands/MainCommand.java @@ -128,46 +128,58 @@ public class MainCommand extends Command { args = tmp; } } - getInstance().execute(player, args, new RunnableVal3() { - @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() { + @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() { - @Override - public void run(Command cmd, CommandResult result) { - // Post command stuff!? - } - }); + }, new RunnableVal2() { + @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 { diff --git a/Core/src/main/java/com/intellectualcrafters/plot/commands/Trust.java b/Core/src/main/java/com/intellectualcrafters/plot/commands/Trust.java index 25ebd124a..226029697 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/commands/Trust.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/commands/Trust.java @@ -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 ", 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 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 confirm, RunnableVal2 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 uuids = MainUtil.getUUIDsFromString(args[0]); + checkTrue(uuids != null && !uuids.isEmpty(), C.INVALID_PLAYER, args[0]); Iterator 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); } } diff --git a/Core/src/main/java/com/intellectualcrafters/plot/config/Settings.java b/Core/src/main/java/com/intellectualcrafters/plot/config/Settings.java index 242700b29..708daf9d7 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/config/Settings.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/config/Settings.java @@ -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 WE_BLACKLIST = new ArrayList<>(); /** * Teleport to path on login */ diff --git a/Core/src/main/java/com/intellectualcrafters/plot/flag/Flags.java b/Core/src/main/java/com/intellectualcrafters/plot/flag/Flags.java index a69b340b9..f97b75325 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/flag/Flags.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/flag/Flags.java @@ -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"); diff --git a/Core/src/main/java/com/intellectualcrafters/plot/generator/ClassicPlotWorld.java b/Core/src/main/java/com/intellectualcrafters/plot/generator/ClassicPlotWorld.java index 4ac5d5ff5..bf0d77fce 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/generator/ClassicPlotWorld.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/generator/ClassicPlotWorld.java @@ -27,7 +27,7 @@ public abstract class ClassicPlotWorld extends SquarePlotWorld { /** * CONFIG NODE | DEFAULT VALUE | DESCRIPTION | CONFIGURATION TYPE | REQUIRED FOR INITIAL SETUP. * - *

Set the last boolean to false if you do not require a specific config node to be set while using the setup + *

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

*/ diff --git a/Core/src/main/java/com/intellectualcrafters/plot/object/ConsolePlayer.java b/Core/src/main/java/com/intellectualcrafters/plot/object/ConsolePlayer.java index 13e6d37d0..0ec7ae290 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/object/ConsolePlayer.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/object/ConsolePlayer.java @@ -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 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.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; diff --git a/Core/src/main/java/com/intellectualcrafters/plot/object/PlotPlayer.java b/Core/src/main/java/com/intellectualcrafters/plot/object/PlotPlayer.java index 4675a357e..82f71a4f2 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/object/PlotPlayer.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/object/PlotPlayer.java @@ -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); + } + } } diff --git a/Core/src/main/java/com/plotsquared/general/commands/Command.java b/Core/src/main/java/com/plotsquared/general/commands/Command.java index 8290b0257..e6226bf64 100644 --- a/Core/src/main/java/com/plotsquared/general/commands/Command.java +++ b/Core/src/main/java/com/plotsquared/general/commands/Command.java @@ -271,7 +271,7 @@ public abstract class Command { * @return */ public void execute(PlotPlayer player, String[] args, RunnableVal3 confirm, - RunnableVal2 whenDone) { + RunnableVal2 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 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); + } + } + } }