diff --git a/src/main/java/com/plotsquared/bukkit/listeners/worldedit/ProcessedWEExtent.java b/src/main/java/com/plotsquared/bukkit/listeners/worldedit/ProcessedWEExtent.java index b878673ec..af64ef1a7 100644 --- a/src/main/java/com/plotsquared/bukkit/listeners/worldedit/ProcessedWEExtent.java +++ b/src/main/java/com/plotsquared/bukkit/listeners/worldedit/ProcessedWEExtent.java @@ -1,5 +1,6 @@ package com.plotsquared.bukkit.listeners.worldedit; +import java.lang.reflect.Field; import java.util.HashSet; import com.intellectualcrafters.plot.PS; @@ -27,11 +28,20 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { boolean BSblocked = false; boolean Eblocked = false; private String world; + private int max; + private int count; + private Extent parent; - public ProcessedWEExtent(String world, HashSet mask, Extent extent) { - super(extent); + public ProcessedWEExtent(String world, HashSet mask, int max, Extent child, Extent parent) { + super(child); this.mask = mask; this.world = world; + if (max == -1) { + max = Integer.MAX_VALUE; + } + this.max = max; + this.count = 0; + this.parent = parent; } @Override @@ -82,6 +92,19 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { PS.debug("&cPlotSquared detected unsafe WorldEdit: " + (location.getBlockX()) + "," + (location.getBlockZ())); } if (WEManager.maskContains(mask, location.getBlockX(), location.getBlockZ())) { + if (count++ > max) { + if (parent != null) { + try { + Field field = AbstractDelegateExtent.class.getDeclaredField("extent"); + field.setAccessible(true); + field.set(parent, new NullExtent()); + } catch (Exception e) { + e.printStackTrace(); + } + parent = null; + } + return false; + } return super.setBlock(location, block); } break; @@ -91,6 +114,19 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { int y = location.getBlockY(); int z = location.getBlockZ(); if (WEManager.maskContains(mask, location.getBlockX(), location.getBlockZ())) { + if (count++ > max) { + if (parent != null) { + try { + Field field = AbstractDelegateExtent.class.getDeclaredField("extent"); + field.setAccessible(true); + field.set(parent, new NullExtent()); + } catch (Exception e) { + e.printStackTrace(); + } + parent = null; + } + return false; + } switch(id) { case 0: case 2: diff --git a/src/main/java/com/plotsquared/bukkit/listeners/worldedit/WESubscriber.java b/src/main/java/com/plotsquared/bukkit/listeners/worldedit/WESubscriber.java index 6a5db5250..b3dbd1fe7 100644 --- a/src/main/java/com/plotsquared/bukkit/listeners/worldedit/WESubscriber.java +++ b/src/main/java/com/plotsquared/bukkit/listeners/worldedit/WESubscriber.java @@ -1,7 +1,10 @@ package com.plotsquared.bukkit.listeners.worldedit; +import java.lang.reflect.Field; import java.util.HashSet; +import org.bukkit.entity.Player; + import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.config.Settings; @@ -10,16 +13,34 @@ import com.intellectualcrafters.plot.object.RegionWrapper; import com.intellectualcrafters.plot.util.MainUtil; import com.intellectualcrafters.plot.util.Permissions; import com.intellectualcrafters.plot.util.UUIDHandler; +import com.plotsquared.bukkit.BukkitMain; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.EditSession.Stage; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.bukkit.BukkitPlayer; import com.sk89q.worldedit.event.extent.EditSessionEvent; import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.extent.AbstractDelegateExtent; +import com.sk89q.worldedit.extent.ChangeSetExtent; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.cache.LastAccessExtentCache; +import com.sk89q.worldedit.extent.inventory.BlockBagExtent; +import com.sk89q.worldedit.extent.reorder.MultiStageReorder; +import com.sk89q.worldedit.extent.validation.DataValidatorExtent; +import com.sk89q.worldedit.extent.world.BlockQuirkExtent; +import com.sk89q.worldedit.extent.world.ChunkLoadingExtent; +import com.sk89q.worldedit.extent.world.FastModeExtent; +import com.sk89q.worldedit.extent.world.SurvivalModeExtent; import com.sk89q.worldedit.util.eventbus.EventHandler.Priority; import com.sk89q.worldedit.util.eventbus.Subscribe; +import com.sk89q.worldedit.world.World; public class WESubscriber { @Subscribe(priority=Priority.VERY_EARLY) public void onEditSession(EditSessionEvent event) { - String world = event.getWorld().getName(); + World worldObj = event.getWorld(); + String world = worldObj.getName(); if (!PS.get().isPlotWorld(world)) { return; } @@ -41,7 +62,53 @@ public class WESubscriber { return; } if (Settings.CHUNK_PROCESSOR) { - event.setExtent(new ProcessedWEExtent(world, mask, event.getExtent())); + if (Settings.EXPERIMENTAL_FAST_ASYNC_WORLDEDIT) { + try { + AbstractDelegateExtent extent = (AbstractDelegateExtent) event.getExtent(); + ChangeSetExtent history = null; + MultiStageReorder reorder = null; + boolean fast = ((BukkitMain) PS.get().IMP).worldEdit.getWorldEdit().getSession(name).hasFastMode(); + while (extent.getExtent() != null && extent.getExtent() instanceof AbstractDelegateExtent) { + AbstractDelegateExtent tmp = (AbstractDelegateExtent) extent.getExtent(); + if (tmp.getExtent() != null && tmp.getExtent() instanceof AbstractDelegateExtent) { + if (tmp instanceof ChangeSetExtent) { + history = (ChangeSetExtent) tmp; + } + if (tmp instanceof MultiStageReorder) { + reorder = (MultiStageReorder) tmp; + } + extent = tmp; + } + else { + break; + } + } + int max = event.getMaxBlocks(); + Field field = AbstractDelegateExtent.class.getDeclaredField("extent"); + field.setAccessible(true); + if (history == null) { + ExtentWrapper wrapper = new ExtentWrapper(event.getExtent()); + event.setExtent(wrapper); + field.set(extent, new ProcessedWEExtent(world, mask, max, new FastModeExtent(worldObj, true), wrapper)); + } + else { + if (fast) { + event.setExtent(new ExtentWrapper(extent)); + } + else { + ExtentWrapper wrapper = new ExtentWrapper(history); + event.setExtent(wrapper); + field.set(history, reorder); + field.set(reorder, new ProcessedWEExtent(world, mask, max, new FastModeExtent(worldObj, true), wrapper)); + } + } + return; + } + catch (Exception e) { + e.printStackTrace(); + } + } + event.setExtent(new ProcessedWEExtent(world, mask, event.getMaxBlocks(), event.getExtent(), event.getExtent())); } else { event.setExtent(new WEExtent(mask, event.getExtent())); diff --git a/target/PlotSquared-Bukkit.jar b/target/PlotSquared-Bukkit.jar index 5405230fb..3275a4135 100644 Binary files a/target/PlotSquared-Bukkit.jar and b/target/PlotSquared-Bukkit.jar differ diff --git a/target/PlotSquared-Sponge.jar b/target/PlotSquared-Sponge.jar index 5f93da102..bedcddfe7 100644 Binary files a/target/PlotSquared-Sponge.jar and b/target/PlotSquared-Sponge.jar differ