WE delayed command execution + fix SBQ notify

This commit is contained in:
boy0001 2015-08-26 12:02:00 +10:00
parent dc37465c8a
commit 1872e147cb
3 changed files with 75 additions and 16 deletions

View File

@ -142,6 +142,8 @@ public enum C {
/* /*
* WorldEdit masks * WorldEdit masks
*/ */
WORLDEDIT_DELAYED("$2Please wait while we process your WorldEdit action...", "WorldEdit Masks"),
WORLDEDIT_RUN("$2Apologies for the delay. Now executing: %s", "WorldEdit Masks"),
REQUIRE_SELECTION_IN_MASK("$2%s of your selection is not within your plot mask. You can only make edits within your plot.", "WorldEdit Masks"), REQUIRE_SELECTION_IN_MASK("$2%s of your selection is not within your plot mask. You can only make edits within your plot.", "WorldEdit Masks"),
WORLDEDIT_VOLUME("$2You cannot select a volume of %current%. The maximum volume you can modify is %max%.", "WorldEdit Masks"), WORLDEDIT_VOLUME("$2You cannot select a volume of %current%. The maximum volume you can modify is %max%.", "WorldEdit Masks"),
WORLDEDIT_ITERATIONS("$2You cannot iterate %current% times. The maximum number of iterations allowed is %max%.", "WorldEdit Masks"), WORLDEDIT_ITERATIONS("$2You cannot iterate %current% times. The maximum number of iterations allowed is %max%.", "WorldEdit Masks"),

View File

@ -1,7 +1,7 @@
package com.intellectualcrafters.plot.util; package com.intellectualcrafters.plot.util;
import java.util.ArrayDeque;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry; import java.util.Map.Entry;
import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.PS;
@ -14,7 +14,7 @@ public class SetBlockQueue {
private volatile static int allocate = 25; private volatile static int allocate = 25;
private volatile static boolean running = false; private volatile static boolean running = false;
private volatile static boolean locked = false; private volatile static boolean locked = false;
private volatile static HashSet<Runnable> runnables; private volatile static ArrayDeque<Runnable> runnables;
private volatile static boolean slow = false; private volatile static boolean slow = false;
private static long last; private static long last;
private static int lastInt = 0; private static int lastInt = 0;
@ -32,15 +32,22 @@ public class SetBlockQueue {
slow = value; slow = value;
} }
public synchronized static void addNotify(Runnable whenDone) { public synchronized static boolean addNotify(Runnable whenDone) {
if (runnables == null) { if (runnables == null) {
TaskManager.runTask(whenDone); if (blocks == null) {
if (whenDone != null) {
whenDone.run();
}
slow = false; slow = false;
locked = false; locked = false;
return true;
} }
else { runnables = new ArrayDeque<>();
}
if (whenDone != null) {
runnables.add(whenDone); runnables.add(whenDone);
} }
return false;
} }
public synchronized static void init() { public synchronized static void init() {
@ -49,7 +56,7 @@ public class SetBlockQueue {
MainUtil.initCache(); MainUtil.initCache();
} }
blocks = new HashMap<>(); blocks = new HashMap<>();
runnables = new HashSet<>(); runnables = new ArrayDeque<>();
} }
if (!running) { if (!running) {
TaskManager.index.incrementAndGet(); TaskManager.index.incrementAndGet();
@ -62,17 +69,18 @@ public class SetBlockQueue {
} }
if (blocks == null || blocks.size() == 0) { if (blocks == null || blocks.size() == 0) {
PS.get().TASK.cancelTask(TaskManager.tasks.get(current)); PS.get().TASK.cancelTask(TaskManager.tasks.get(current));
if (runnables != null) { ArrayDeque<Runnable> tasks = runnables;
for (Runnable runnable : runnables) {
TaskManager.runTask(runnable);
}
}
lastInt = -1; lastInt = -1;
lastBlock = null; lastBlock = null;
runnables = null; runnables = null;
blocks = new HashMap<>(); blocks = null;
running = false; running = false;
slow = false; slow = false;
if (tasks != null) {
for (Runnable runnable : tasks) {
runnable.run();
}
}
return; return;
} }
long newLast = System.currentTimeMillis(); long newLast = System.currentTimeMillis();

View File

@ -3,7 +3,9 @@ package com.plotsquared.bukkit.listeners.worldedit;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -19,8 +21,10 @@ import com.intellectualcrafters.plot.object.PlotPlayer;
import com.intellectualcrafters.plot.object.RegionWrapper; import com.intellectualcrafters.plot.object.RegionWrapper;
import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.Permissions; import com.intellectualcrafters.plot.util.Permissions;
import com.intellectualcrafters.plot.util.SetBlockQueue;
import com.plotsquared.bukkit.BukkitMain; import com.plotsquared.bukkit.BukkitMain;
import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.bukkit.util.SetBlockFast;
import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.bukkit.selections.Selection; import com.sk89q.worldedit.bukkit.selections.Selection;
@ -39,6 +43,7 @@ public class WEListener implements Listener {
public final HashSet<String> unregioned = new HashSet<>(Arrays.asList("paste", "redo", "undo", "rotate", "flip", "generate", "schematic", "schem")); public final HashSet<String> unregioned = new HashSet<>(Arrays.asList("paste", "redo", "undo", "rotate", "flip", "generate", "schematic", "schem"));
public final HashSet<String> unsafe1 = new HashSet<>(Arrays.asList("cs", ".s", "restore", "snapshot", "delchunks", "listchunks")); public final HashSet<String> unsafe1 = new HashSet<>(Arrays.asList("cs", ".s", "restore", "snapshot", "delchunks", "listchunks"));
public final HashSet<String> restricted = new HashSet<>(Arrays.asList("up")); public final HashSet<String> restricted = new HashSet<>(Arrays.asList("up"));
public final HashSet<String> other = new HashSet<>(Arrays.asList("undo", "redo"));
public boolean checkCommand(List<String> list, String cmd) { public boolean checkCommand(List<String> list, String cmd) {
for (String identifier : list) { for (String identifier : list) {
@ -134,6 +139,36 @@ public class WEListener implements Listener {
return checkVolume(pp, volume, max, e); return checkVolume(pp, volume, max, e);
} }
private boolean set = false;
public boolean delay(final Player player, final String command, boolean delayed) {
if (!Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT || set) {
return false;
}
boolean free = SetBlockQueue.addNotify(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);
}
SetBlockQueue.addNotify(new Runnable() {
@Override
public void run() {
delay(player, command, true);
}
});
}
return true;
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public boolean onPlayerCommand(final PlayerCommandPreprocessEvent e) { public boolean onPlayerCommand(final PlayerCommandPreprocessEvent e) {
final Player p = e.getPlayer(); final Player p = e.getPlayer();
@ -141,23 +176,26 @@ public class WEListener implements Listener {
if (!PS.get().isPlotWorld(p.getWorld().getName())) { if (!PS.get().isPlotWorld(p.getWorld().getName())) {
return true; return true;
} }
String cmd = e.getMessage().toLowerCase(); String message = e.getMessage();
String cmd = message.toLowerCase();
boolean single = true; boolean single = true;
String[] split = cmd.split(" "); String[] split = cmd.split(" ");
long maxVolume = Settings.WE_MAX_VOLUME; long maxVolume = Settings.WE_MAX_VOLUME;
long maxIterations = Settings.WE_MAX_ITERATIONS; long maxIterations = Settings.WE_MAX_ITERATIONS;
if (pp.getAttribute("worldedit" )) { if (pp.getAttribute("worldedit")) {
return true; return true;
} }
if (split.length >= 2) { if (split.length >= 2) {
String reduced = reduceCmd(split[0], single); String reduced = reduceCmd(split[0], single);
String reduced2 = reduceCmd(split[0] + " " + split[1], single); String reduced2 = reduceCmd(split[0] + " " + split[1], single);
if (rad1.contains(reduced)) { if (rad1.contains(reduced)) {
if (delay(p, message, false)) { e.setCancelled(true); return true; }
long volume = getInt(split[1]) * 256; long volume = getInt(split[1]) * 256;
return checkVolume(pp, volume, maxVolume, e); return checkVolume(pp, volume, maxVolume, e);
} }
if (rad2.contains(reduced)) { if (rad2.contains(reduced)) {
if (delay(p, message, false)) { e.setCancelled(true); return true; }
if (split.length >= 3) { if (split.length >= 3) {
long volume = getInt(split[2]) * 256; long volume = getInt(split[2]) * 256;
return checkVolume(pp, volume, maxVolume, e); return checkVolume(pp, volume, maxVolume, e);
@ -165,6 +203,7 @@ public class WEListener implements Listener {
return true; return true;
} }
if (rad2_1.contains(reduced)) { if (rad2_1.contains(reduced)) {
if (delay(p, message, false)) { e.setCancelled(true); return true; }
if (split.length >= 4) { if (split.length >= 4) {
long volume = getInt(split[2]) * getInt(split[3]); long volume = getInt(split[2]) * getInt(split[3]);
return checkVolume(pp, volume, maxVolume, e); return checkVolume(pp, volume, maxVolume, e);
@ -172,6 +211,7 @@ public class WEListener implements Listener {
return true; return true;
} }
if (rad2_2.contains(reduced)) { if (rad2_2.contains(reduced)) {
if (delay(p, message, false)) { e.setCancelled(true); return true; }
if (split.length >= 3) { if (split.length >= 3) {
long radius = getInt(split[2]); long radius = getInt(split[2]);
long volume = radius * radius; long volume = radius * radius;
@ -180,6 +220,7 @@ public class WEListener implements Listener {
return true; return true;
} }
if (rad2_3.contains(reduced2)) { if (rad2_3.contains(reduced2)) {
if (delay(p, message, false)) { e.setCancelled(true); return true; }
if (split.length >= 3) { if (split.length >= 3) {
if (split.length == 4) { if (split.length == 4) {
int iterations = getInt(split[3]); int iterations = getInt(split[3]);
@ -199,6 +240,7 @@ public class WEListener implements Listener {
return true; return true;
} }
if (rad3_1.contains(reduced2)) { if (rad3_1.contains(reduced2)) {
if (delay(p, message, false)) { e.setCancelled(true); return true; }
if (split.length >= 3) { if (split.length >= 3) {
int i = 2; int i = 2;
if (split[i].equalsIgnoreCase("-h")) { if (split[i].equalsIgnoreCase("-h")) {
@ -211,6 +253,7 @@ public class WEListener implements Listener {
return true; return true;
} }
if (rad3_2.contains(reduced2)) { if (rad3_2.contains(reduced2)) {
if (delay(p, message, false)) { e.setCancelled(true); return true; }
if (split.length >= 4) { if (split.length >= 4) {
int i = 3; int i = 3;
if (split[i].equalsIgnoreCase("-h")) { if (split[i].equalsIgnoreCase("-h")) {
@ -223,6 +266,7 @@ public class WEListener implements Listener {
return true; return true;
} }
if (regionExtend.contains(reduced)) { if (regionExtend.contains(reduced)) {
if (delay(p, message, false)) { e.setCancelled(true); return true; }
return checkSelection(p, pp, getInt(split[1]), maxVolume, e); return checkSelection(p, pp, getInt(split[1]), maxVolume, e);
} }
} }
@ -237,6 +281,7 @@ public class WEListener implements Listener {
if (restricted.contains(reduced)) { if (restricted.contains(reduced)) {
Plot plot = MainUtil.getPlot(pp.getLocation()); Plot plot = MainUtil.getPlot(pp.getLocation());
if (plot != null && plot.isAdded(pp.getUUID())) { if (plot != null && plot.isAdded(pp.getUUID())) {
if (delay(p, message, false)) { e.setCancelled(true); return true; }
return true; return true;
} }
e.setCancelled(true); e.setCancelled(true);
@ -247,8 +292,12 @@ public class WEListener implements Listener {
return true; return true;
} }
if (region.contains(reduced)) { if (region.contains(reduced)) {
if (delay(p, message, false)) { e.setCancelled(true); return true; }
return checkSelection(p, pp, 1, maxVolume, e); return checkSelection(p, pp, 1, maxVolume, e);
} }
if (other.contains(reduced)) {
if (delay(p, message, false)) { e.setCancelled(true); return true; }
}
return true; return true;
} }
} }