From 0da4f6f63ad29ab6747ca5c5314f931ef9204787 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Mon, 25 Apr 2016 02:20:26 +1000 Subject: [PATCH] Fixes #48 --- bukkit/build/resources/main/plugin.yml | 3 + .../com/boydti/fawe/bukkit/FaweBukkit.java | 1 - .../boydti/fawe/bukkit/v0/BukkitQueue_0.java | 1 + .../fawe/bukkit/v0/BukkitQueue_All.java | 6 - .../fawe/bukkit/v1_8/BukkitChunk_1_8.java | 1 - .../fawe/bukkit/v1_8/BukkitQueue_1_8.java | 3 +- .../fawe/bukkit/v1_9/BukkitChunk_1_9.java | 1 - .../fawe/bukkit/v1_9/BukkitQueue_1_9.java | 3 +- .../fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java | 3 +- bukkit/src/main/resources/plugin.yml | 3 + core/src/main/java/com/boydti/fawe/Fawe.java | 2 + .../java/com/boydti/fawe/command/Cancel.java | 62 ++++ .../main/java/com/boydti/fawe/config/BBC.java | 4 +- .../java/com/boydti/fawe/config/Settings.java | 5 +- .../com/boydti/fawe/object/FaweCommand.java | 10 +- .../clipboard/DiskOptimizedClipboard.java | 4 + .../fawe/object/clipboard/FaweClipboard.java | 92 ++++++ .../clipboard/MemoryOptimizedClipboard.java | 246 ++++++++++++++++ .../boydti/fawe/object/extent/FaweExtent.java | 1 + .../boydti/fawe/object/extent/NullExtent.java | 43 ++- .../fawe/object/extent/SafeExtentWrapper.java | 2 +- .../regions/general/PlotSquaredFeature.java | 4 +- .../java/com/boydti/fawe/util/FaweQueue.java | 20 +- .../com/boydti/fawe/util/ReflectionUtils.java | 12 +- .../java/com/boydti/fawe/util/SetQueue.java | 18 +- .../java/com/boydti/fawe/util/WEManager.java | 2 +- .../java/com/sk89q/worldedit/EditSession.java | 63 ++-- .../extent/clipboard/BlockArrayClipboard.java | 276 +----------------- .../boydti/fawe/forge/v0/ForgeChunk_All.java | 1 - .../boydti/fawe/forge/v0/ForgeQueue_All.java | 1 + .../boydti/fawe/forge/v0/ForgeChunk_All.java | 1 - .../boydti/fawe/forge/v0/ForgeQueue_All.java | 1 + .../com/boydti/fawe/v0/SpongeQueue_0.java | 1 + .../com/boydti/fawe/v1_8/SpongeChunk_1_8.java | 1 - 34 files changed, 558 insertions(+), 339 deletions(-) create mode 100644 core/src/main/java/com/boydti/fawe/command/Cancel.java create mode 100644 core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java create mode 100644 core/src/main/java/com/boydti/fawe/object/clipboard/FaweClipboard.java create mode 100644 core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java diff --git a/bukkit/build/resources/main/plugin.yml b/bukkit/build/resources/main/plugin.yml index ca4b079f..84de4843 100644 --- a/bukkit/build/resources/main/plugin.yml +++ b/bukkit/build/resources/main/plugin.yml @@ -27,6 +27,9 @@ commands: frb: description: (FAWE) Rollback an edit aliases: [fawerollback,fawerb,/uu,/rb,/frb,/fawerollback,/fawerb] + fcancel: + description: (FAWE) Cancel your edit + aliases: [fawecancel,/fcancel,/cancel,/fawecancel] permissions: fawe.bypass: default: false diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java index aeb35fb7..48899d61 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java @@ -206,7 +206,6 @@ public class FaweBukkit extends JavaPlugin implements IFawe, Listener { } catch (Throwable ignore) {} if (hasNMS) { try { - ReflectionUtils.init(); Field fieldDirtyCount = ReflectionUtils.getRefClass("{nms}.PlayerChunk").getField("dirtyCount").getRealField(); fieldDirtyCount.setAccessible(true); int mod = fieldDirtyCount.getModifiers(); diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_0.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_0.java index 866ff152..43b31c89 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_0.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_0.java @@ -165,6 +165,7 @@ public abstract class BukkitQueue_0 extends FaweQueue implements Listener { @Override public void clear() { this.blocks.clear(); + this.chunks.clear(); } @Override diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java index c77895d8..b52d8d75 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitQueue_All.java @@ -256,12 +256,6 @@ public class BukkitQueue_All extends BukkitQueue_0 { } else { return 0; } - long diff = System.currentTimeMillis() - start; - if (average == 0) { - average = diff; - } else { - average = ((average * 15) + diff) / 16; - } } lastChunk = getCachedChunk(cx, cz); lastSection = getCachedSection(lastChunk, cy); diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitChunk_1_8.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitChunk_1_8.java index ab8067dd..5c54349a 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitChunk_1_8.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitChunk_1_8.java @@ -204,7 +204,6 @@ public class BukkitChunk_1_8 extends FaweChunk { case 61: case 65: case 68: - case 50: if (data < 2) { data = 2; } diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue_1_8.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue_1_8.java index 0069981b..341a1f23 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue_1_8.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/BukkitQueue_1_8.java @@ -443,7 +443,8 @@ public class BukkitQueue_1_8 extends BukkitQueue_All { * - Unloads non visible chunks
*/ @Override - public void clear() { + public void saveMemory() { + super.saveMemory(); // Clear the queue super.clear(); ArrayDeque toUnload = new ArrayDeque<>(); diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitChunk_1_9.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitChunk_1_9.java index 0e037dc3..fb3c4a9d 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitChunk_1_9.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitChunk_1_9.java @@ -204,7 +204,6 @@ public class BukkitChunk_1_9 extends FaweChunk { case 61: case 65: case 68: - case 50: if (data < 2) { data = 2; } diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9.java index 4ab80c10..94b00257 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9.java @@ -413,7 +413,8 @@ public class BukkitQueue_1_9 extends BukkitQueue_All { * - Unloads non visible chunks
*/ @Override - public void clear() { + public void saveMemory() { + super.saveMemory(); // Clear the queue super.clear(); ArrayDeque toUnload = new ArrayDeque<>(); diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java index ad7364a8..9d78b440 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_9/BukkitQueue_1_9_R1.java @@ -444,7 +444,8 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_All { * - Unloads non visible chunks
*/ @Override - public void clear() { + public void saveMemory() { + super.saveMemory(); // Clear the queue super.clear(); ArrayDeque toUnload = new ArrayDeque<>(); diff --git a/bukkit/src/main/resources/plugin.yml b/bukkit/src/main/resources/plugin.yml index ca4b079f..84de4843 100644 --- a/bukkit/src/main/resources/plugin.yml +++ b/bukkit/src/main/resources/plugin.yml @@ -27,6 +27,9 @@ commands: frb: description: (FAWE) Rollback an edit aliases: [fawerollback,fawerb,/uu,/rb,/frb,/fawerollback,/fawerb] + fcancel: + description: (FAWE) Cancel your edit + aliases: [fawecancel,/fcancel,/cancel,/fawecancel] permissions: fawe.bypass: default: false diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java index b23fa9df..44b70f8f 100644 --- a/core/src/main/java/com/boydti/fawe/Fawe.java +++ b/core/src/main/java/com/boydti/fawe/Fawe.java @@ -1,5 +1,6 @@ package com.boydti.fawe; +import com.boydti.fawe.command.Cancel; import com.boydti.fawe.command.FixLighting; import com.boydti.fawe.command.Reload; import com.boydti.fawe.command.Rollback; @@ -201,6 +202,7 @@ public class Fawe { this.IMP.setupCommand("wrg", new WorldEditRegion()); this.IMP.setupCommand("fawe", new Reload()); this.IMP.setupCommand("frb", new Rollback()); + this.IMP.setupCommand("fcancel", new Cancel()); } public void setupConfigs() { diff --git a/core/src/main/java/com/boydti/fawe/command/Cancel.java b/core/src/main/java/com/boydti/fawe/command/Cancel.java new file mode 100644 index 00000000..e845add6 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/command/Cancel.java @@ -0,0 +1,62 @@ +package com.boydti.fawe.command; + +import com.boydti.fawe.config.BBC; +import com.boydti.fawe.object.FaweCommand; +import com.boydti.fawe.object.FawePlayer; +import com.boydti.fawe.object.extent.FaweExtent; +import com.boydti.fawe.object.extent.NullExtent; +import com.boydti.fawe.util.FaweQueue; +import com.boydti.fawe.util.SetQueue; +import com.boydti.fawe.util.WEManager; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.world.World; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +public class Cancel extends FaweCommand { + + public Cancel() { + super("fawe.cancel", false); + } + + @Override + public boolean execute(final FawePlayer player, final String... args) { + if (player == null) { + return false; + } + UUID uuid = player.getUUID(); + List queues = SetQueue.IMP.getAllQueues(); + int cancelled = 0; + for (FaweQueue queue : queues) { + Set sessions = queue.getEditSessions(); + for (EditSession session : sessions) { + Actor actor = session.actor; + if (actor == null) { + continue; + } + if (uuid.equals(actor.getUniqueId())) { + // Cancel this + FaweExtent fe = session.getFaweExtent(); + if (fe != null) { + cancelled++; + try { + WEManager.IMP.cancelEdit(fe, BBC.WORLDEDIT_CANCEL_REASON_MANUAL); + } catch (Throwable ignore) {} + World world = session.getWorld(); + NullExtent nullExtent = new NullExtent(world, BBC.WORLDEDIT_CANCEL_REASON_MANUAL); + session.bypassHistory = nullExtent; + session.bypassNone = nullExtent; + session.bypassReorderHistory = nullExtent; + session.faweExtent = nullExtent; + queue.clear(); + } + } + } + } + BBC.WORLDEDIT_CANCEL_COUNT.send(player,cancelled); + return true; + } + +} diff --git a/core/src/main/java/com/boydti/fawe/config/BBC.java b/core/src/main/java/com/boydti/fawe/config/BBC.java index d9fc619e..48e4bce7 100644 --- a/core/src/main/java/com/boydti/fawe/config/BBC.java +++ b/core/src/main/java/com/boydti/fawe/config/BBC.java @@ -39,9 +39,9 @@ public enum BBC { WORLDEDIT_BYPASSED("&7Currently bypassing WorldEdit restriction.", "Info"), WORLDEDIT_UNMASKED("&6Your WorldEdit is now unrestricted.", "Info"), WORLDEDIT_RESTRICTED("&6Your WorldEdit is now restricted.", "Info"), - WORLDEDIT_OOM("&cYour WorldEdit action was cancelled due to low memory.", "Info"), - + WORLDEDIT_CANCEL_COUNT("&cCancelled %s0 edits.", "Cancel"), WORLDEDIT_CANCEL_REASON("&cYour WorldEdit action was cancelled:&7 %s0&c.", "Cancel"), + WORLDEDIT_CANCEL_REASON_MANUAL("Manual cancellation", "Cancel"), WORLDEDIT_CANCEL_REASON_LOW_MEMORY("Low memory", "Cancel"), WORLDEDIT_CANCEL_REASON_MAX_CHANGES("Too many blocks changed", "Cancel"), WORLDEDIT_CANCEL_REASON_MAX_CHECKS("Too many block checks", "Cancel"), diff --git a/core/src/main/java/com/boydti/fawe/config/Settings.java b/core/src/main/java/com/boydti/fawe/config/Settings.java index f7417cbb..84c660e6 100644 --- a/core/src/main/java/com/boydti/fawe/config/Settings.java +++ b/core/src/main/java/com/boydti/fawe/config/Settings.java @@ -32,6 +32,7 @@ public class Settings { public static int QUEUE_MAX_WAIT = 1000; public static int QUEUE_DISCARD_AFTER = 60000; public static List ALLOWED_3RDPARTY_EXTENTS; + public static boolean EXTENT_DEBUG = true; public static boolean FIX_ALL_LIGHTING = true; public static boolean ASYNC_LIGHTING = true; @@ -93,6 +94,7 @@ public class Settings { options.put("queue.max-wait-ms", QUEUE_MAX_WAIT); options.put("queue.discard-after-ms", QUEUE_DISCARD_AFTER); options.put("extent.allowed-plugins", new ArrayList()); + options.put("extent.debug", EXTENT_DEBUG); options.put("metrics", METRICS); // Default limit @@ -128,8 +130,9 @@ public class Settings { QUEUE_SIZE = config.getInt("queue.target-size"); QUEUE_MAX_WAIT = config.getInt("queue.max-wait-ms"); QUEUE_DISCARD_AFTER = config.getInt("queue.discard-after-ms"); - ALLOWED_3RDPARTY_EXTENTS = config.getStringList("extent.allowed-plugins"); + EXTENT_DEBUG = config.getBoolean("extent.debug"); + if (STORE_HISTORY_ON_DISK = config.getBoolean("history.use-disk")) { LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE; diff --git a/core/src/main/java/com/boydti/fawe/object/FaweCommand.java b/core/src/main/java/com/boydti/fawe/object/FaweCommand.java index 8eedc5cb..88b89edb 100644 --- a/core/src/main/java/com/boydti/fawe/object/FaweCommand.java +++ b/core/src/main/java/com/boydti/fawe/object/FaweCommand.java @@ -5,9 +5,15 @@ import com.boydti.fawe.util.TaskManager; public abstract class FaweCommand { public final String perm; + public final boolean safe; - public FaweCommand(final String perm) { + public FaweCommand(String perm) { + this(perm, true); + } + + public FaweCommand(final String perm, final boolean safe) { this.perm = perm; + this.safe = safe; } public String getPerm() { @@ -15,7 +21,7 @@ public abstract class FaweCommand { } public boolean executeSafe(final FawePlayer player, final String... args) { - if (player == null) { + if (player == null || !safe) { execute(player, args); return true; } else { diff --git a/core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java b/core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java new file mode 100644 index 00000000..fecfd8f5 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/clipboard/DiskOptimizedClipboard.java @@ -0,0 +1,4 @@ +package com.boydti.fawe.object.clipboard; + +public class DiskOptimizedClipboard { +} diff --git a/core/src/main/java/com/boydti/fawe/object/clipboard/FaweClipboard.java b/core/src/main/java/com/boydti/fawe/object/clipboard/FaweClipboard.java new file mode 100644 index 00000000..0a84fe00 --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/clipboard/FaweClipboard.java @@ -0,0 +1,92 @@ +package com.boydti.fawe.object.clipboard; + +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.util.Location; +import java.util.List; +import javax.annotation.Nullable; + + +import static com.google.common.base.Preconditions.checkNotNull; + +public abstract class FaweClipboard { + public final int length; + public final int height; + public final int width; + public final int area; + + public FaweClipboard(int width, int height, int length) { + this.width = width; + this.height = height; + this.length = length; + this.area = width * length; + } + + public abstract BaseBlock getBlock(int x, int y, int z); + + public abstract boolean setBlock(int x, int y, int z, BaseBlock block); + + public abstract Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity); + + public abstract List getEntities(); + + public abstract boolean remove(ClipboardEntity clipboardEntity); + + /** + * Stores entity data. + */ + public class ClipboardEntity implements Entity { + private final BaseEntity entity; + private final Extent world; + private final double x,y,z; + private final float yaw,pitch; + + public ClipboardEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) { + checkNotNull(entity); + this.world = world; + this.x = x; + this.y = y; + this.z = z; + this.yaw = yaw; + this.pitch = pitch; + this.entity = new BaseEntity(entity); + } + + @Override + public boolean remove() { + return FaweClipboard.this.remove(this); + } + + @Nullable + @Override + public T getFacet(Class cls) { + return null; + } + + /** + * Get the entity state. This is not a copy. + * + * @return the entity + */ + BaseEntity getEntity() { + return entity; + } + + @Override + public BaseEntity getState() { + return new BaseEntity(entity); + } + + @Override + public Location getLocation() { + return new Location(world, x, y, z, yaw, pitch); + } + + @Override + public Extent getExtent() { + return world; + } + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java b/core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java new file mode 100644 index 00000000..d618b3cd --- /dev/null +++ b/core/src/main/java/com/boydti/fawe/object/clipboard/MemoryOptimizedClipboard.java @@ -0,0 +1,246 @@ +package com.boydti.fawe.object.clipboard; + +import com.boydti.fawe.FaweCache; +import com.boydti.fawe.object.IntegerTrio; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.extent.Extent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; + +public class MemoryOptimizedClipboard extends FaweClipboard { + + // x,z,y+15>>4 | y&15 + private final byte[][] ids; + private byte[][] datas; + private final HashMap nbtMap; + private final HashSet entities; + + public MemoryOptimizedClipboard(int width, int height, int length) { + super(width, height, length); + ids = new byte[width * length * ((height + 15) >> 4)][]; + nbtMap = new HashMap<>(); + entities = new HashSet(); + } + + @Override + public BaseBlock getBlock(int x, int y, int z) { + int i = x + z * width + (y >> 4) * area; + byte[] idArray = ids[i]; + if (idArray == null) { + return FaweCache.CACHE_BLOCK[0]; + } + int y2 = y & 0xF; + int id = idArray[y2] & 0xFF; + BaseBlock block; + if (!FaweCache.hasData(id) || datas == null) { + block = FaweCache.CACHE_BLOCK[id << 4]; + } else { + byte[] dataArray = datas[i]; + if (dataArray == null) { + block = FaweCache.CACHE_BLOCK[id << 4]; + } else { + block = FaweCache.CACHE_BLOCK[(id << 4) + dataArray[y2]]; + } + } + if (FaweCache.hasNBT(id)) { + CompoundTag nbt = nbtMap.get(new IntegerTrio(x, y, z)); + if (nbt != null) { + block = new BaseBlock(block.getId(), block.getData()); + block.setNbtData(nbt); + } + } + return block; + } + + @Override + public boolean setBlock(int x, int y, int z, BaseBlock block) { + final int id = block.getId(); + switch (id) { + case 0: + return true; + case 54: + case 130: + case 142: + case 27: + case 137: + case 52: + case 154: + case 84: + case 25: + case 144: + case 138: + case 176: + case 177: + case 63: + case 119: + case 68: + case 323: + case 117: + case 116: + case 28: + case 66: + case 157: + case 61: + case 62: + case 140: + case 146: + case 149: + case 150: + case 158: + case 23: + case 123: + case 124: + case 29: + case 33: + case 151: + case 178: { + if (block.hasNbtData()) { + nbtMap.put(new IntegerTrio(x, y, z), block.getNbtData()); + } + int i = x + z * width + (y >> 4) * area; + int y2 = y & 0xF; + byte[] idArray = ids[i]; + if (idArray == null) { + idArray = new byte[16]; + ids[i] = idArray; + } + idArray[y2] = (byte) id; + if (FaweCache.hasData(id)) { + int data = block.getData(); + if (data == 0) { + return true; + } + if (datas == null) { + datas = new byte[area * ((height + 15) >> 4)][]; + } + byte[] dataArray = datas[i]; + if (dataArray == null) { + dataArray = datas[i] = new byte[16]; + } + dataArray[y2] = (byte) data; + } + return true; + } + case 2: + case 4: + case 13: + case 14: + case 15: + case 20: + case 21: + case 22: + case 30: + case 32: + case 37: + case 39: + case 40: + case 41: + case 42: + case 45: + case 46: + case 47: + case 48: + case 49: + case 51: + case 56: + case 57: + case 58: + case 60: + case 7: + case 8: + case 9: + case 10: + case 11: + case 73: + case 74: + case 78: + case 79: + case 80: + case 81: + case 82: + case 83: + case 85: + case 87: + case 88: + case 101: + case 102: + case 103: + case 110: + case 112: + case 113: + case 121: + case 122: + case 129: + case 133: + case 165: + case 166: + case 169: + case 170: + case 172: + case 173: + case 174: + case 181: + case 182: + case 188: + case 189: + case 190: + case 191: + case 192: { + int i = x + z * width + (y >> 4) * area; + int y2 = y & 0xF; + byte[] idArray = ids[i]; + if (idArray == null) { + idArray = new byte[16]; + ids[i] = idArray; + } + idArray[y2] = (byte) id; + return true; + } + default: { + int i = x + z * width + (y >> 4) * area; + int y2 = y & 0xF; + byte[] idArray = ids[i]; + if (idArray == null) { + idArray = new byte[16]; + ids[i] = idArray; + } + idArray[y2] = (byte) id; + int data = block.getData(); + if (data == 0) { + return true; + } + if (datas == null) { + datas = new byte[area * ((height + 15) >> 4)][]; + } + byte[] dataArray = datas[i]; + if (dataArray == null) { + dataArray = datas[i] = new byte[16]; + } + dataArray[y2] = (byte) data; + return true; + } + } + } + + @Override + public Entity createEntity(Extent world, double x, double y, double z, float yaw, float pitch, BaseEntity entity) { + FaweClipboard.ClipboardEntity ret = new ClipboardEntity(world, x, y, z, yaw, pitch, entity); + entities.add(ret); + return ret; + } + + @Override + public List getEntities() { + return new ArrayList<>(entities); + } + + @Override + public boolean remove(ClipboardEntity clipboardEntity) { + return entities.remove(clipboardEntity); + } +} diff --git a/core/src/main/java/com/boydti/fawe/object/extent/FaweExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/FaweExtent.java index 33040843..3a5f704a 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/FaweExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/FaweExtent.java @@ -4,6 +4,7 @@ import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.Extent; public abstract class FaweExtent extends AbstractDelegateExtent { + /** * Create a new instance. * diff --git a/core/src/main/java/com/boydti/fawe/object/extent/NullExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/NullExtent.java index 5013cfb2..5d4b9ea9 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/NullExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/NullExtent.java @@ -16,41 +16,48 @@ import com.sk89q.worldedit.world.biome.BaseBiome; import java.util.ArrayList; import java.util.List; -public class NullExtent implements Extent { +public class NullExtent extends FaweExtent { + + private final BBC reason; + + /** + * Create a new instance. + * + * @param extent the extent + */ + public NullExtent(Extent extent, BBC failReason) { + super(extent); + this.reason = failReason; + } @Override public BaseBiome getBiome(final Vector2D arg0) { - throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); + throw new FaweException(reason); } @Override public BaseBlock getBlock(final Vector arg0) { - throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); + throw new FaweException(reason); } @Override public BaseBlock getLazyBlock(final Vector arg0) { - throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); - } - - @Override - public Operation commit() { - return null; + throw new FaweException(reason); } @Override public boolean setBiome(final Vector2D arg0, final BaseBiome arg1) { - throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); + throw new FaweException(reason); } @Override public boolean setBlock(final Vector arg0, final BaseBlock arg1) throws WorldEditException { - throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); + throw new FaweException(reason); } @Override public Entity createEntity(final Location arg0, final BaseEntity arg1) { - throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); + throw new FaweException(reason); } @Override @@ -73,4 +80,16 @@ public class NullExtent implements Extent { return new Vector(0, 0, 0); } + @Override + public boolean contains(int x, int y, int z) { return false; } + + @Override + protected Operation commitBefore() { + return null; + } + + @Override + public Extent getExtent() { + return this; + } } diff --git a/core/src/main/java/com/boydti/fawe/object/extent/SafeExtentWrapper.java b/core/src/main/java/com/boydti/fawe/object/extent/SafeExtentWrapper.java index 86e74a66..3d120e50 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/SafeExtentWrapper.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/SafeExtentWrapper.java @@ -24,7 +24,7 @@ public class SafeExtentWrapper extends AbstractDelegateExtent { if (super.setBlock(location, block)) { if (MemUtil.isMemoryLimited()) { if (this.player != null) { - BBC.WORLDEDIT_OOM.send(this.player); + player.sendMessage(BBC.WORLDEDIT_CANCEL_REASON.format(BBC.WORLDEDIT_CANCEL_REASON_LOW_MEMORY.s())); if (Perm.hasPermission(this.player, "worldedit.fast")) { BBC.WORLDEDIT_OOM_ADMIN.send(this.player); } diff --git a/core/src/main/java/com/boydti/fawe/regions/general/PlotSquaredFeature.java b/core/src/main/java/com/boydti/fawe/regions/general/PlotSquaredFeature.java index e4025b7a..a4b694f1 100644 --- a/core/src/main/java/com/boydti/fawe/regions/general/PlotSquaredFeature.java +++ b/core/src/main/java/com/boydti/fawe/regions/general/PlotSquaredFeature.java @@ -41,10 +41,8 @@ public class PlotSquaredFeature extends FaweMaskManager { } if (plot != null) { final PlotId id = plot.getId(); - boolean hasPerm = false; if (plot.owner != null) { - hasPerm = plot.isOwner(pp.getUUID()) || plot.getTrusted().contains(pp.getUUID()) || (plot.getMembers().contains(pp.getUUID()) && pp.hasPermission("fawe.plotsquared.member")); - if (hasPerm) { + if (plot.isOwner(pp.getUUID()) || plot.getTrusted().contains(pp.getUUID()) || (plot.getMembers().contains(pp.getUUID()) && pp.hasPermission("fawe.plotsquared.member"))) { RegionWrapper region = plot.getLargestRegion(); HashSet regions = plot.getRegions(); diff --git a/core/src/main/java/com/boydti/fawe/util/FaweQueue.java b/core/src/main/java/com/boydti/fawe/util/FaweQueue.java index 270003d7..7c7f430b 100644 --- a/core/src/main/java/com/boydti/fawe/util/FaweQueue.java +++ b/core/src/main/java/com/boydti/fawe/util/FaweQueue.java @@ -6,15 +6,33 @@ import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.exception.FaweException; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.world.biome.BaseBiome; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.LinkedBlockingDeque; public abstract class FaweQueue { public final String world; + public LinkedBlockingDeque sessions; public FaweQueue(String world) { this.world = world; } + public void addEditSession(EditSession session) { + if (session == null) { + return; + } + if (this.sessions == null) { + sessions = new LinkedBlockingDeque<>(); + } + sessions.add(session); + } + + public Set getEditSessions() { + return sessions == null ? new HashSet() : new HashSet<>(sessions); + } + public abstract boolean setBlock(final int x, final int y, final int z, final short id, final byte data); public abstract boolean setBiome(final int x, final int z, final BaseBiome biome); @@ -51,7 +69,7 @@ public abstract class FaweQueue { /** * This method is called when the server is < 1% available memory */ - protected abstract void clear(); + public abstract void clear(); public abstract void addTask(int x, int z, Runnable runnable); diff --git a/core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java b/core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java index 03b18192..3fe1e193 100644 --- a/core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java +++ b/core/src/main/java/com/boydti/fawe/util/ReflectionUtils.java @@ -21,19 +21,17 @@ public class ReflectionUtils { /** * prefix of bukkit classes */ - private static String preClassB; + private static volatile String preClassB = null; /** * prefix of minecraft classes */ - private static String preClassM = null; + private static volatile String preClassM = null; /** * boolean value, TRUE if server uses forge or MCPC+ */ private static boolean forge = false; /** check server version and class names */ public static void init() { - preClassM = "net.minecraft.server"; - preClassB = "org.bukkit.craftbukkit"; if (Bukkit.getServer() != null) { if (Bukkit.getVersion().contains("MCPC") || Bukkit.getVersion().contains("Forge")) { forge = true; @@ -43,7 +41,7 @@ public class ReflectionUtils { String[] pas = bukkitServerClass.getName().split("\\."); if (pas.length == 5) { final String verB = pas[3]; - preClassB += "." + verB; + preClassB = "org.bukkit.craftbukkit." + verB; } try { final Method getHandle = bukkitServerClass.getDeclaredMethod("getHandle"); @@ -52,7 +50,7 @@ public class ReflectionUtils { pas = handleServerClass.getName().split("\\."); if (pas.length == 5) { final String verM = pas[3]; - preClassM += "." + verM; + preClassM = "net.minecraft.server." + verM; } } catch (final Exception ignored) { ignored.printStackTrace(); @@ -233,7 +231,7 @@ public class ReflectionUtils { return getRefClass(Class.forName(className)); } catch (final ClassNotFoundException ignored) {} } - throw new RuntimeException("no class found"); + throw new RuntimeException("no class found: " + classes[0].replace("{cb}", preClassB).replace("{nms}", preClassM).replace("{nm}", "net.minecraft")); } /** diff --git a/core/src/main/java/com/boydti/fawe/util/SetQueue.java b/core/src/main/java/com/boydti/fawe/util/SetQueue.java index 5ff56870..93327493 100644 --- a/core/src/main/java/com/boydti/fawe/util/SetQueue.java +++ b/core/src/main/java/com/boydti/fawe/util/SetQueue.java @@ -40,7 +40,7 @@ public class SetQueue { final int mem = MemUtil.calculateMemory(); if (mem != Integer.MAX_VALUE) { if ((mem <= 1) && Settings.ENABLE_HARD_LIMIT) { - for (FaweQueue queue : getQueues()) { + for (FaweQueue queue : getAllQueues()) { queue.saveMemory(); } return; @@ -71,10 +71,21 @@ public class SetQueue { activeQueues.add(queue); } - public List getQueues() { + public List getAllQueues() { + ArrayList list = new ArrayList(activeQueues.size() + inactiveQueues.size()); + list.addAll(inactiveQueues); + list.addAll(activeQueues); + return list; + } + + public List getActiveQueues() { return new ArrayList<>(activeQueues); } + public List getInactiveQueues() { + return new ArrayList<>(inactiveQueues); + } + public FaweQueue getNewQueue(String world, boolean autoqueue) { FaweQueue queue = Fawe.imp().getNewQueue(world); if (autoqueue) { @@ -96,6 +107,9 @@ public class SetQueue { ArrayList tmp = new ArrayList<>(inactiveQueues); if (Settings.QUEUE_MAX_WAIT != -1) { long now = System.currentTimeMillis(); + if (lastSuccess == 0) { + lastSuccess = now; + } long diff = now - lastSuccess; if (diff > Settings.QUEUE_MAX_WAIT) { for (FaweQueue queue : tmp) { diff --git a/core/src/main/java/com/boydti/fawe/util/WEManager.java b/core/src/main/java/com/boydti/fawe/util/WEManager.java index a8b4e762..6879c480 100644 --- a/core/src/main/java/com/boydti/fawe/util/WEManager.java +++ b/core/src/main/java/com/boydti/fawe/util/WEManager.java @@ -26,7 +26,7 @@ public class WEManager { try { final Field field = AbstractDelegateExtent.class.getDeclaredField("extent"); field.setAccessible(true); - field.set(parent, new NullExtent()); + field.set(parent, new NullExtent((Extent) field.get(parent), reason)); } catch (final Exception e) { e.printStackTrace(); } diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index 2ed6b255..f16cb1e6 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -160,20 +160,20 @@ public class EditSession implements Extent { BEFORE_HISTORY, BEFORE_REORDER, BEFORE_CHANGE } - private World world; - private Actor actor; - private FaweChangeSet changeSet; - private final EditSessionWrapper wrapper; - private FaweExtent faweExtent; - private MaskingExtent maskingExtent; - private final Extent bypassReorderHistory; - private final Extent bypassHistory; - private final Extent bypassNone; - private SurvivalModeExtent lazySurvivalExtent; - private boolean fastmode; - private Mask oldMask; - private FaweLimit limit = FaweLimit.MAX; - private FaweQueue queue; + public World world; + public Actor actor; + public FaweChangeSet changeSet; + public EditSessionWrapper wrapper; + public FaweExtent faweExtent; + public MaskingExtent maskingExtent; + public Extent bypassReorderHistory; + public Extent bypassHistory; + public Extent bypassNone; + public SurvivalModeExtent lazySurvivalExtent; + public boolean fastmode; + public Mask oldMask; + public FaweLimit limit = FaweLimit.MAX; + public FaweQueue queue; public static BaseBiome nullBiome = new BaseBiome(0); public static BaseBlock nullBlock = new BaseBlock(0); @@ -220,13 +220,13 @@ public class EditSession implements Extent { checkNotNull(eventBus); checkArgument(maxBlocks >= -1, "maxBlocks >= -1 required"); checkNotNull(event); - + this.actor = event.getActor(); // Wrap world this.blockBag = blockBag; this.maxBlocks = maxBlocks; // Invalid; return null extent if (world == null) { - final Extent extent = new NullExtent(); + FaweExtent extent = faweExtent = new NullExtent(world, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); this.bypassReorderHistory = extent; this.bypassHistory = extent; this.bypassNone = extent; @@ -234,8 +234,8 @@ public class EditSession implements Extent { this.wrapper = Fawe.imp().getEditSessionWrapper(this); return; } - this.actor = event.getActor(); this.queue = SetQueue.IMP.getNewQueue(Fawe.imp().getWorldName(world), true); + queue.addEditSession(this); // Set the world of the event to the actual world (workaround for CoreProtect) try { Class eventClass = event.getClass(); @@ -266,7 +266,7 @@ public class EditSession implements Extent { } this.changeSet = Settings.STORE_HISTORY_ON_DISK ? new DiskStorageHistory(world, actor.getUniqueId()) : new MemoryOptimizedHistory(actor); Extent extent; - final FawePlayer fp = FawePlayer.wrap(actor); + final FawePlayer fp = FawePlayer.wrap(actor); final LocalSession session = fp.getSession(); this.fastmode = session.hasFastMode(); if (fp.hasWorldEditBypass()) { @@ -287,7 +287,7 @@ public class EditSession implements Extent { final HashSet mask = WEManager.IMP.getMask(fp); if (mask.size() == 0) { // No allowed area; return null extent - extent = new NullExtent(); + extent = faweExtent = new NullExtent(world, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); this.bypassReorderHistory = extent; this.bypassHistory = extent; this.bypassNone = extent; @@ -310,12 +310,12 @@ public class EditSession implements Extent { return; } else { if (MemUtil.isMemoryLimited()) { - BBC.WORLDEDIT_OOM.send(fp); + fp.sendMessage(BBC.WORLDEDIT_CANCEL_REASON.format(BBC.WORLDEDIT_CANCEL_REASON_LOW_MEMORY.s())); if (Perm.hasPermission(fp, "worldedit.fast")) { BBC.WORLDEDIT_OOM_ADMIN.send(fp); } // Memory limit reached; return null extent - extent = new NullExtent(); + extent = faweExtent = new NullExtent(world, BBC.WORLDEDIT_CANCEL_REASON_MAX_FAILS); this.bypassReorderHistory = extent; this.bypassHistory = extent; this.bypassNone = extent; @@ -370,11 +370,14 @@ public class EditSession implements Extent { eventBus.post(event); final Extent toReturn = event.getExtent(); if (toReturn != extent) { - String className = toReturn.getClass().getName().toLowerCase(); + String className = toReturn.getClass().getSimpleName().toLowerCase(); if (className.contains("coreprotect")) { - Fawe.debug("&cUnsafe extent detected: " + toReturn.getClass().getCanonicalName() + " !"); - Fawe.debug("&8 - &7Use BlocksHub instead"); - Fawe.debug("&8 - &7Or use FAWE rollback"); + if (Settings.EXTENT_DEBUG) { + Fawe.debug("&cUnsafe extent detected: " + toReturn.getClass().getCanonicalName() + " !"); + Fawe.debug("&8 - &7Use BlocksHub instead"); + Fawe.debug("&8 - &7Or use FAWE rollback"); + Fawe.debug("&8 - &7Change `extent.debug: false` to hide this message"); + } return extent; } for (String allowed : Settings.ALLOWED_3RDPARTY_EXTENTS) { @@ -382,11 +385,13 @@ public class EditSession implements Extent { return toReturn; } } - Fawe.debug("&cPotentially inefficient WorldEdit extent: " + toReturn.getClass().getCanonicalName()); - Fawe.debug("&8 - &7For area restrictions, it is recommended to use the FaweAPI"); - Fawe.debug("&8 - &7Ignore this if not an area restriction"); + if (Settings.EXTENT_DEBUG) { + Fawe.debug("&cPotentially inefficient WorldEdit extent: " + toReturn.getClass().getSimpleName()); + Fawe.debug("&8 - &7For area restrictions, it is recommended to use the FaweAPI"); + Fawe.debug("&8 - &7To allow this plugin add it to the FAWE `allowed-plugins` list"); + } } - return toReturn; + return extent; } /** diff --git a/core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java b/core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java index d47da08a..3c18f839 100644 --- a/core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java +++ b/core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java @@ -19,9 +19,8 @@ package com.sk89q.worldedit.extent.clipboard; -import com.boydti.fawe.FaweCache; -import com.boydti.fawe.object.IntegerTrio; -import com.sk89q.jnbt.CompoundTag; +import com.boydti.fawe.object.clipboard.FaweClipboard; +import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; @@ -29,14 +28,12 @@ import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; -import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.operation.Operation; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.biome.BaseBiome; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.List; import javax.annotation.Nullable; @@ -51,13 +48,11 @@ public class BlockArrayClipboard implements Clipboard { private final Region region; - // x,z,y+15>>4 | y&15 - private final byte[][] ids; - private byte[][] datas; + public FaweClipboard IMP; + private final Vector size; - private final HashMap nbtMap; - private final List entities = new ArrayList(); + private int mx; private int my; private int mz; @@ -78,14 +73,13 @@ public class BlockArrayClipboard implements Clipboard { checkNotNull(region); this.region = region.clone(); this.size = getDimensions(); - this.dx = size.getBlockX(); - this.dxz = dx * size.getBlockZ(); - ids = new byte[dx * size.getBlockZ() * ((size.getBlockY() + 15) >> 4)][]; - nbtMap = new HashMap<>(); + this.IMP = new MemoryOptimizedClipboard(size.getBlockX(), size.getBlockY(), size.getBlockZ()); this.origin = region.getMinimumPoint(); this.mx = origin.getBlockX(); this.my = origin.getBlockY(); this.mz = origin.getBlockZ(); + + } @Override @@ -121,7 +115,7 @@ public class BlockArrayClipboard implements Clipboard { @Override public List getEntities(Region region) { List filtered = new ArrayList(); - for (Entity entity : entities) { + for (Entity entity : getEntities()) { if (region.contains(entity.getLocation().toVector())) { filtered.add(entity); } @@ -131,15 +125,13 @@ public class BlockArrayClipboard implements Clipboard { @Override public List getEntities() { - return Collections.unmodifiableList(entities); + return IMP.getEntities(); } @Nullable @Override public Entity createEntity(Location location, BaseEntity entity) { - ClipboardEntity ret = new ClipboardEntity(location, entity); - entities.add(ret); - return ret; + return IMP.createEntity(location.getExtent(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch(), entity); } @Override @@ -148,34 +140,8 @@ public class BlockArrayClipboard implements Clipboard { int x = position.getBlockX() - mx; int y = position.getBlockY() - my; int z = position.getBlockZ() - mz; - int i = x + z * dx + (y >> 4) * dxz; - byte[] idArray = ids[i]; - if (idArray == null) { - return FaweCache.CACHE_BLOCK[0]; - } - int y2 = y & 0xF; - int id = idArray[y2] & 0xFF; - BaseBlock block; - if (!FaweCache.hasData(id) || datas == null) { - block = FaweCache.CACHE_BLOCK[id << 4]; - } else { - byte[] dataArray = datas[i]; - if (dataArray == null) { - block = FaweCache.CACHE_BLOCK[id << 4]; - } else { - block = FaweCache.CACHE_BLOCK[(id << 4) + dataArray[y2]]; - } - } - if (FaweCache.hasNBT(id)) { - CompoundTag nbt = nbtMap.get(new IntegerTrio(x, y, z)); - if (nbt != null) { - block = new BaseBlock(block.getId(), block.getData()); - block.setNbtData(nbt); - } - } - return block; + return IMP.getBlock(x, y, z); } - return EditSession.nullBlock; } @@ -199,172 +165,7 @@ public class BlockArrayClipboard implements Clipboard { x -= mx; y -= my; z -= mz; - final int id = block.getId(); - switch (id) { - case 0: - return true; - case 54: - case 130: - case 142: - case 27: - case 137: - case 52: - case 154: - case 84: - case 25: - case 144: - case 138: - case 176: - case 177: - case 63: - case 119: - case 68: - case 323: - case 117: - case 116: - case 28: - case 66: - case 157: - case 61: - case 62: - case 140: - case 146: - case 149: - case 150: - case 158: - case 23: - case 123: - case 124: - case 29: - case 33: - case 151: - case 178: { - if (block.hasNbtData()) { - nbtMap.put(new IntegerTrio(x, y, z), block.getNbtData()); - } - int i = x + z * dx + (y >> 4) * dxz; - int y2 = y & 0xF; - byte[] idArray = ids[i]; - if (idArray == null) { - idArray = new byte[16]; - ids[i] = idArray; - } - idArray[y2] = (byte) id; - if (FaweCache.hasData(id)) { - int data = block.getData(); - if (data == 0) { - return true; - } - if (datas == null) { - datas = new byte[dx * size.getBlockZ() * ((size.getBlockY() + 15) >> 4)][]; - } - byte[] dataArray = datas[i]; - if (dataArray == null) { - dataArray = datas[i] = new byte[16]; - } - dataArray[y2] = (byte) data; - } - return true; - } - case 2: - case 4: - case 13: - case 14: - case 15: - case 20: - case 21: - case 22: - case 30: - case 32: - case 37: - case 39: - case 40: - case 41: - case 42: - case 45: - case 46: - case 47: - case 48: - case 49: - case 51: - case 56: - case 57: - case 58: - case 60: - case 7: - case 8: - case 9: - case 10: - case 11: - case 73: - case 74: - case 78: - case 79: - case 80: - case 81: - case 82: - case 83: - case 85: - case 87: - case 88: - case 101: - case 102: - case 103: - case 110: - case 112: - case 113: - case 121: - case 122: - case 129: - case 133: - case 165: - case 166: - case 169: - case 170: - case 172: - case 173: - case 174: - case 181: - case 182: - case 188: - case 189: - case 190: - case 191: - case 192: { - int i = x + z * dx + (y >> 4) * dxz; - int y2 = y & 0xF; - byte[] idArray = ids[i]; - if (idArray == null) { - idArray = new byte[16]; - ids[i] = idArray; - } - idArray[y2] = (byte) id; - return true; - } - default: { - int i = x + z * dx + (y >> 4) * dxz; - int y2 = y & 0xF; - byte[] idArray = ids[i]; - if (idArray == null) { - idArray = new byte[16]; - ids[i] = idArray; - } - idArray[y2] = (byte) id; - int data = block.getData(); - if (data == 0) { - return true; - } - if (datas == null) { - datas = new byte[dx * size.getBlockZ() * ((size.getBlockY() + 15) >> 4)][]; - } - byte[] dataArray = datas[i]; - if (dataArray == null) { - dataArray = datas[i] = new byte[16]; - } - dataArray[y2] = (byte) data; - return true; - } - } + return IMP.setBlock(x, y, z, block); } @Override @@ -383,57 +184,6 @@ public class BlockArrayClipboard implements Clipboard { return null; } - /** - * Stores entity data. - */ - private class ClipboardEntity implements Entity { - private final Location location; - private final BaseEntity entity; - - ClipboardEntity(Location location, BaseEntity entity) { - checkNotNull(location); - checkNotNull(entity); - this.location = location; - this.entity = new BaseEntity(entity); - } - - @Override - public boolean remove() { - return entities.remove(this); - } - - @Nullable - @Override - public T getFacet(Class cls) { - return null; - } - - /** - * Get the entity state. This is not a copy. - * - * @return the entity - */ - BaseEntity getEntity() { - return entity; - } - - @Override - public BaseEntity getState() { - return new BaseEntity(entity); - } - - @Override - public Location getLocation() { - return location; - } - - @Override - public Extent getExtent() { - return location.getExtent(); - } - - } - public static Class inject() { return BlockArrayClipboard.class; } diff --git a/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeChunk_All.java b/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeChunk_All.java index 1b4b4425..af1d9c55 100644 --- a/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeChunk_All.java +++ b/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeChunk_All.java @@ -202,7 +202,6 @@ public class ForgeChunk_All extends FaweChunk { case 61: case 65: case 68: - case 50: if (data < 2) { data = 2; } diff --git a/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java b/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java index 5ebcff02..e643eb07 100644 --- a/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java +++ b/forge1710/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java @@ -318,6 +318,7 @@ public class ForgeQueue_All extends FaweQueue { @Override public void clear() { this.blocks.clear(); + this.chunks.clear(); } @Override diff --git a/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeChunk_All.java b/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeChunk_All.java index 0ac64089..682699b0 100644 --- a/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeChunk_All.java +++ b/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeChunk_All.java @@ -194,7 +194,6 @@ public class ForgeChunk_All extends FaweChunk { case 61: case 65: case 68: - case 50: if (data < 2) { data = 2; } diff --git a/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java b/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java index fa8a4182..2300ffb0 100644 --- a/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java +++ b/forge189/src/main/java/com/boydti/fawe/forge/v0/ForgeQueue_All.java @@ -273,6 +273,7 @@ public class ForgeQueue_All extends FaweQueue { @Override public void clear() { this.blocks.clear(); + this.chunks.clear(); } @Override diff --git a/sponge/src/main/java/com/boydti/fawe/v0/SpongeQueue_0.java b/sponge/src/main/java/com/boydti/fawe/v0/SpongeQueue_0.java index 040f6c09..799cba40 100644 --- a/sponge/src/main/java/com/boydti/fawe/v0/SpongeQueue_0.java +++ b/sponge/src/main/java/com/boydti/fawe/v0/SpongeQueue_0.java @@ -142,6 +142,7 @@ public abstract class SpongeQueue_0 extends FaweQueue { @Override public void clear() { this.blocks.clear(); + this.chunks.clear(); } @Override diff --git a/sponge/src/main/java/com/boydti/fawe/v1_8/SpongeChunk_1_8.java b/sponge/src/main/java/com/boydti/fawe/v1_8/SpongeChunk_1_8.java index 2b86a2c9..34d5597a 100644 --- a/sponge/src/main/java/com/boydti/fawe/v1_8/SpongeChunk_1_8.java +++ b/sponge/src/main/java/com/boydti/fawe/v1_8/SpongeChunk_1_8.java @@ -195,7 +195,6 @@ public class SpongeChunk_1_8 extends FaweChunk { case 61: case 65: case 68: - case 50: if (data < 2) { data = 2; }