From fb15a425a75a11f7d2c69191ca2cc844bd24fcf4 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Mon, 4 Apr 2016 04:03:35 +1000 Subject: [PATCH] Queue, editsession and history optimizations Streamlined the queue so now the queue doesn't need to be fetched on each block Removed block reording from editsession as it alone takes half a second/million blocks Replaced block fetch from history extent with optimized algorithm. --- .../com/boydti/fawe/bukkit/BukkitCommand.java | 1 - .../com/boydti/fawe/bukkit/FaweBukkit.java | 6 +- .../boydti/fawe/bukkit/v0/BukkitQueue_0.java | 184 ++----- .../fawe/bukkit/v1_8/BukkitChunk_1_8.java | 21 +- .../fawe/bukkit/v1_8/BukkitQueue_1_8.java | 59 ++- .../fawe/bukkit/v1_8/FaweGenerator_1_8.java | 459 ------------------ .../fawe/bukkit/v1_9/BukkitChunk_1_9.java | 21 +- .../fawe/bukkit/v1_9/BukkitQueue_1_9.java | 56 ++- core/src/main/java/com/boydti/fawe/Fawe.java | 4 +- .../main/java/com/boydti/fawe/FaweAPI.java | 148 +++--- core/src/main/java/com/boydti/fawe/IFawe.java | 2 +- .../com/boydti/fawe/command/FixLighting.java | 6 +- .../java/com/boydti/fawe/object/ChunkLoc.java | 56 --- .../fawe/object/EditSessionWrapper.java | 2 +- .../com/boydti/fawe/object/FaweChunk.java | 59 ++- .../com/boydti/fawe/object/HistoryExtent.java | 43 +- .../com/boydti/fawe/object/NullChangeSet.java | 6 + .../com/boydti/fawe/object/SendChunk.java | 10 - .../object/changeset/DiskStorageHistory.java | 62 ++- .../fawe/object/changeset/FaweChangeSet.java | 4 + .../changeset/MemoryOptimizedHistory.java | 63 +-- .../object/extent/FastWorldEditExtent.java | 19 +- .../fawe/object/extent/ProcessedWEExtent.java | 28 +- .../java/com/boydti/fawe/util/FaweQueue.java | 21 +- .../java/com/boydti/fawe/util/SetQueue.java | 75 ++- .../java/com/sk89q/worldedit/EditSession.java | 3 +- forge/.gradle/gradle.log | 54 +-- .../com/boydti/fawe/forge/FaweSponge.java | 4 +- .../boydti/fawe/forge/v0/SpongeQueue_0.java | 63 ++- .../fawe/forge/v1_8/SpongeChunk_1_8.java | 18 +- .../fawe/forge/v1_8/SpongeQueue_1_8.java | 50 +- 31 files changed, 569 insertions(+), 1038 deletions(-) delete mode 100644 bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/FaweGenerator_1_8.java delete mode 100644 core/src/main/java/com/boydti/fawe/object/ChunkLoc.java delete mode 100644 core/src/main/java/com/boydti/fawe/object/SendChunk.java diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/BukkitCommand.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/BukkitCommand.java index 026e1318..64dd85da 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/BukkitCommand.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/BukkitCommand.java @@ -27,5 +27,4 @@ public class BukkitCommand implements CommandExecutor { this.cmd.execute(plr, args); return true; } - } 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 a9aabe42..fd20bfd2 100644 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java +++ b/bukkit/src/main/java/com/boydti/fawe/bukkit/FaweBukkit.java @@ -184,15 +184,15 @@ public class FaweBukkit extends JavaPlugin implements IFawe, Listener { * - When a block change is requested, the SetQueue will first check if the chunk exists in the queue, or it will create and add it
*/ @Override - public FaweQueue getQueue() { + public FaweQueue getNewQueue(String world) { if (FaweAPI.checkVersion(this.getServerVersion(), 1, 9, 0)) { try { - return new BukkitQueue_1_9(); + return new BukkitQueue_1_9(world); } catch (final Throwable e) { e.printStackTrace(); } } - return new BukkitQueue_1_8(); + return new BukkitQueue_1_8(world); } private int[] version; 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 376deb0e..c82c6455 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 @@ -1,181 +1,103 @@ package com.boydti.fawe.bukkit.v0; -import java.util.ArrayDeque; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map.Entry; -import java.util.concurrent.ConcurrentHashMap; - -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.World; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.Listener; -import org.bukkit.event.world.ChunkLoadEvent; -import org.bukkit.event.world.ChunkUnloadEvent; -import org.bukkit.event.world.WorldLoadEvent; -import org.bukkit.event.world.WorldUnloadEvent; -import org.bukkit.plugin.Plugin; - import com.boydti.fawe.Fawe; -import com.boydti.fawe.config.Settings; -import com.boydti.fawe.object.ChunkLoc; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.util.FaweQueue; import com.boydti.fawe.util.SetQueue; import com.boydti.fawe.util.TaskManager; import com.sk89q.worldedit.world.biome.BaseBiome; +import java.util.ArrayDeque; +import java.util.Collection; +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.event.Listener; +import org.bukkit.plugin.Plugin; /** * The base object for */ public abstract class BukkitQueue_0 extends FaweQueue implements Listener { - /** - * Map of loaded chunks for quicker checking - */ - private final HashMap> loaded = new HashMap<>(); - /** * Map of chunks in the queue */ - private final ConcurrentHashMap> blocks = new ConcurrentHashMap<>(); + private ConcurrentHashMap> blocks = new ConcurrentHashMap<>(); - public BukkitQueue_0() { + public BukkitQueue_0(String world) { + super(world); TaskManager.IMP.task(new Runnable() { @Override public void run() { Bukkit.getPluginManager().registerEvents(BukkitQueue_0.this, (Plugin) Fawe.imp()); } }); - for (final World world : Bukkit.getWorlds()) { - for (final Chunk chunk : world.getLoadedChunks()) { - this.addLoaded(chunk); - } - } - } - - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) - public void onWorldLoad(final WorldLoadEvent event) { - final World world = event.getWorld(); - for (final Chunk chunk : world.getLoadedChunks()) { - this.addLoaded(chunk); - } - } - - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) - public void onWorldUnload(final WorldUnloadEvent event) { - this.loaded.remove(event.getWorld().getName()); - } - - public void addLoaded(final Chunk chunk) { - final String world = chunk.getWorld().getName(); - final long x = chunk.getX(); - final long z = chunk.getZ(); - final long id = (x << 32) | (z & 0xFFFFFFFFL); - HashSet map = this.loaded.get(world); - if (map != null) { - map.add(id); - } else { - map = new HashSet<>(Arrays.asList(id)); - this.loaded.put(world, map); - } - } - - public void removeLoaded(final Chunk chunk) { - final String world = chunk.getWorld().getName(); - final long x = chunk.getX(); - final long z = chunk.getZ(); - final long id = (x << 32) | (z & 0xFFFFFFFFL); - final HashSet map = this.loaded.get(world); - if (map != null) { - map.remove(id); - } } @Override - public boolean isChunkLoaded(final String world, final int x, final int z) { - final long id = ((long) x << 32) | (z & 0xFFFFFFFFL); - final HashSet map = this.loaded.get(world); - if (map != null) { - return map.contains(id); - } - return false; + public boolean isChunkLoaded(int x, int z) { + return Bukkit.getWorld(world).isChunkLoaded(x, z); +// long id = ((long) x << 32) | (z & 0xFFFFFFFFL); +// HashSet map = this.loaded.get(world); +// if (map != null) { +// return map.contains(id); +// } +// return false; }; - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) - public void onChunkLoad(final ChunkLoadEvent event) { - final Chunk chunk = event.getChunk(); - this.addLoaded(chunk); - if (Settings.FIX_ALL_LIGHTING) { - this.fixLighting(this.getChunk(new ChunkLoc(chunk.getWorld().getName(), chunk.getX(), chunk.getZ())), false); - } - } - - @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) - public void onChunkUnload(final ChunkUnloadEvent event) { - this.removeLoaded(event.getChunk()); - } - @Override - public void addTask(String world, int x, int y, int z, Runnable runnable) { - final ChunkLoc wrap = new ChunkLoc(world, x >> 4, z >> 4); - FaweChunk result = this.blocks.get(wrap); + public void addTask(int x, int z, Runnable runnable) { + long pair = (long) (x) << 32 | (z) & 0xFFFFFFFFL; + FaweChunk result = this.blocks.get(pair); if (result == null) { - result = this.getChunk(wrap); + result = this.getChunk(x, z); result.addTask(runnable); - final FaweChunk previous = this.blocks.put(wrap, result); + FaweChunk previous = this.blocks.put(pair, result); if (previous == null) { return; } - this.blocks.put(wrap, previous); + this.blocks.put(pair, previous); result = previous; } result.addTask(runnable); } @Override - public boolean setBlock(final String world, int x, final int y, int z, final short id, final byte data) { + public boolean setBlock(int x, int y, int z, short id, byte data) { if ((y > 255) || (y < 0)) { return false; } - final ChunkLoc wrap = new ChunkLoc(world, x >> 4, z >> 4); - x = x & 15; - z = z & 15; - FaweChunk result = this.blocks.get(wrap); + long pair = (long) (x >> 4) << 32 | (z >> 4) & 0xFFFFFFFFL; + FaweChunk result = this.blocks.get(pair); if (result == null) { - result = this.getChunk(wrap); - result.setBlock(x, y, z, id, data); - final FaweChunk previous = this.blocks.put(wrap, result); + result = this.getChunk(x >> 4, z >> 4); + result.setBlock(x & 15, y, z & 15, id, data); + FaweChunk previous = this.blocks.put(pair, result); if (previous == null) { return true; } - this.blocks.put(wrap, previous); + this.blocks.put(pair, previous); result = previous; } - result.setBlock(x, y, z, id, data); + result.setBlock(x & 15, y, z & 15, id, data); return true; } @Override - public boolean setBiome(final String world, int x, int z, final BaseBiome biome) { - final ChunkLoc wrap = new ChunkLoc(world, x >> 4, z >> 4); - x = x & 15; - z = z & 15; - FaweChunk result = this.blocks.get(wrap); + public boolean setBiome(int x, int z, BaseBiome biome) { + long pair = (long) (x >> 4) << 32 | (z >> 4) & 0xFFFFFFFFL; + FaweChunk result = this.blocks.get(pair); if (result == null) { - result = this.getChunk(wrap); - final FaweChunk previous = this.blocks.put(wrap, result); + result = this.getChunk(x >> 4, z >> 4); + FaweChunk previous = this.blocks.put(pair, result); if (previous != null) { - this.blocks.put(wrap, previous); + this.blocks.put(pair, previous); result = previous; } } - result.setBiome(x, z, biome); + result.setBiome(x & 15, z & 15, biome); return true; } @@ -185,28 +107,28 @@ public abstract class BukkitQueue_0 extends FaweQueue implements Listener { if (this.blocks.size() == 0) { return null; } - final Iterator>> iter = this.blocks.entrySet().iterator(); - final FaweChunk toReturn = iter.next().getValue(); + Iterator>> iter = this.blocks.entrySet().iterator(); + FaweChunk toReturn = iter.next().getValue(); if (SetQueue.IMP.isWaiting()) { return null; } iter.remove(); this.execute(toReturn); return toReturn; - } catch (final Throwable e) { + } catch (Throwable e) { e.printStackTrace(); return null; } } - private final ArrayDeque> toUpdate = new ArrayDeque<>(); + private ArrayDeque> toUpdate = new ArrayDeque<>(); - public boolean execute(final FaweChunk fc) { + public boolean execute(FaweChunk fc) { if (fc == null) { return false; } // Load chunk - final Chunk chunk = fc.getChunk(); + Chunk chunk = fc.getChunk(); chunk.load(true); // Set blocks / entities / biome if (!this.setComponents(fc)) { @@ -222,17 +144,17 @@ public abstract class BukkitQueue_0 extends FaweQueue implements Listener { } @Override - public void setChunk(final FaweChunk chunk) { - this.blocks.put(chunk.getChunkLoc(), (FaweChunk) chunk); + public void setChunk(FaweChunk chunk) { + this.blocks.put(chunk.longHash(), (FaweChunk) chunk); } - public abstract Collection> sendChunk(final Collection> fcs); + public abstract Collection> sendChunk(Collection> fcs); - public abstract boolean setComponents(final FaweChunk fc); + public abstract boolean setComponents(FaweChunk fc); @Override - public abstract FaweChunk getChunk(final ChunkLoc wrap); + public abstract FaweChunk getChunk(int x, int z); @Override - public abstract boolean fixLighting(final FaweChunk fc, final boolean fixAll); + public abstract boolean fixLighting(FaweChunk fc, boolean fixAll); } 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 686bff61..9c0cded1 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 @@ -1,15 +1,13 @@ package com.boydti.fawe.bukkit.v1_8; +import com.boydti.fawe.FaweCache; +import com.boydti.fawe.object.FaweChunk; +import com.boydti.fawe.util.FaweQueue; +import com.sk89q.worldedit.world.biome.BaseBiome; import java.util.Arrays; - import org.bukkit.Bukkit; import org.bukkit.Chunk; -import com.boydti.fawe.FaweCache; -import com.boydti.fawe.object.ChunkLoc; -import com.boydti.fawe.object.FaweChunk; -import com.sk89q.worldedit.world.biome.BaseBiome; - public class BukkitChunk_1_8 extends FaweChunk { private char[][] ids; @@ -24,8 +22,8 @@ public class BukkitChunk_1_8 extends FaweChunk { /** * A FaweSections object represents a chunk and the blocks that you wish to change in it. */ - protected BukkitChunk_1_8(final ChunkLoc chunk) { - super(chunk); + protected BukkitChunk_1_8(FaweQueue parent, int x, int z) { + super(parent, x, z); this.ids = new char[16][]; this.count = new short[16]; this.air = new short[16]; @@ -35,15 +33,14 @@ public class BukkitChunk_1_8 extends FaweChunk { @Override public Chunk getChunk() { if (this.chunk == null) { - final ChunkLoc cl = this.getChunkLoc(); - this.chunk = Bukkit.getWorld(cl.world).getChunkAt(cl.x, cl.z); + this.chunk = Bukkit.getWorld(getParent().world).getChunkAt(getX(), getZ()); } return this.chunk; } @Override - public void setChunkLoc(final ChunkLoc loc) { - super.setChunkLoc(loc); + public void setLoc(final FaweQueue parent, int x, int z) { + super.setLoc(parent, x, z); this.chunk = null; } 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 f2252712..874c45c5 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 @@ -4,7 +4,6 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.bukkit.v0.BukkitQueue_0; import com.boydti.fawe.config.Settings; -import com.boydti.fawe.object.ChunkLoc; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.IntegerPair; @@ -75,9 +74,8 @@ public class BukkitQueue_1_8 extends BukkitQueue_0 { private RefMethod methodGetWorld; private RefField tileEntityListTick; - private final HashMap worldMap = new HashMap<>(); - - public BukkitQueue_1_8() { + public BukkitQueue_1_8(String world) { + super(world); try { this.methodGetHandlePlayer = this.classCraftPlayer.getMethod("getHandle"); this.methodGetHandleChunk = this.classCraftChunk.getMethod("getHandle"); @@ -99,20 +97,6 @@ public class BukkitQueue_1_8 extends BukkitQueue_0 { } } - public FaweGenerator_1_8 getFaweGenerator(final World world) { - final ChunkGenerator gen = world.getGenerator(); - if ((gen != null) && (gen instanceof FaweGenerator_1_8)) { - return (FaweGenerator_1_8) gen; - } - FaweGenerator_1_8 faweGen = this.worldMap.get(world.getName()); - if (faweGen != null) { - return faweGen; - } - faweGen = new FaweGenerator_1_8(this, world); - this.worldMap.put(world.getName(), faweGen); - return faweGen; - } - @Override public Collection> sendChunk(final Collection> fcs) { for (final FaweChunk fc : fcs) { @@ -264,6 +248,37 @@ public class BukkitQueue_1_8 extends BukkitQueue_0 { return array[j] >> 4; } + private int lcx = Integer.MIN_VALUE; + private int lcz = Integer.MIN_VALUE; + private int lcy = Integer.MIN_VALUE; + private Object lc; + private char[] ls; + private World bukkitWorld; + + @Override + public int getCombinedId4Data(int x, int y, int z) { + int cx = x >> 4; + int cz = z >> 4; + int cy = y >> 4; + if (cx != lcx || cz != lcz) { + if (bukkitWorld == null) { + bukkitWorld = Bukkit.getServer().getWorld(world); + } + lcx = cx; + lcz = cz; + lc = methodGetHandleChunk.of(bukkitWorld.getChunkAt(cx, cz)).call(); + } else if (cy == lcy) { + return ls != null ? ls[FaweCache.CACHE_J[y][x & 15][z & 15]] : 0; + } + Object storage = ((Object[]) fieldSections.of(lc).get())[cy]; + if (storage == null) { + ls = null; + return 0; + } + ls = getIdArray(storage); + return ls[FaweCache.CACHE_J[y][x & 15][z & 15]]; + } + @Override public boolean setComponents(final FaweChunk fc) { try { @@ -373,8 +388,8 @@ public class BukkitQueue_1_8 extends BukkitQueue_0 { final int[][] biomes = fs.getBiomeArray(); if (biomes != null) { final LocalWorld lw = BukkitUtil.getLocalWorld(world); - final int X = fs.getChunkLoc().x << 4; - final int Z = fs.getChunkLoc().z << 4; + final int X = fs.getX() << 4; + final int Z = fs.getZ() << 4; final BaseBiome bb = new BaseBiome(0); int last = 0; for (int x = 0; x < 16; x++) { @@ -529,8 +544,8 @@ public class BukkitQueue_1_8 extends BukkitQueue_0 { } @Override - public FaweChunk getChunk(final ChunkLoc wrap) { - return new BukkitChunk_1_8(wrap); + public FaweChunk getChunk(int x, int z) { + return new BukkitChunk_1_8(this, x, z); } public boolean unloadChunk(final String world, final Chunk chunk) { diff --git a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/FaweGenerator_1_8.java b/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/FaweGenerator_1_8.java deleted file mode 100644 index f05027e3..00000000 --- a/bukkit/src/main/java/com/boydti/fawe/bukkit/v1_8/FaweGenerator_1_8.java +++ /dev/null @@ -1,459 +0,0 @@ -package com.boydti.fawe.bukkit.v1_8; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Random; -import java.util.Set; - -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.block.Biome; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.world.ChunkPopulateEvent; -import org.bukkit.generator.BlockPopulator; -import org.bukkit.generator.ChunkGenerator; - -import com.boydti.fawe.Fawe; -import com.boydti.fawe.FaweCache; -import com.boydti.fawe.bukkit.FaweBukkit; -import com.boydti.fawe.config.Settings; -import com.boydti.fawe.object.ChunkLoc; - -/** - * Please ignore - */ -@Deprecated -public class FaweGenerator_1_8 extends ChunkGenerator implements Listener { - private boolean events; - - private final ChunkGenerator parent; - private final List pops; - private final Object provider; - - private short[][] ids; - private byte[][] data; - private Map tiles; - private List[] entities; - private Biome[][] biomes; - - private final World world; - - private final BukkitQueue_1_8 queue; - - private void registerEvents() { - if (this.events) { - return; - } - Bukkit.getPluginManager().registerEvents(this, Fawe. imp()); - } - - @EventHandler - private void onPopulate(final ChunkPopulateEvent event) { - final World world = event.getWorld(); - final ChunkGenerator gen = world.getGenerator(); - if (gen instanceof FaweGenerator_1_8) { - final FaweGenerator_1_8 fawe = (FaweGenerator_1_8) gen; - if (fawe.data == null) { - return; - } - fawe.populate(event.getChunk()); - this.decouple((FaweGenerator_1_8) gen, world); - } - } - - public void setBlock(final short[][] result, final int x, final int y, final int z, final short blkid) { - if (result[FaweCache.CACHE_I[y][x][z]] == null) { - result[FaweCache.CACHE_I[y][x][z]] = new short[4096]; - } - result[FaweCache.CACHE_I[y][x][z]][FaweCache.CACHE_J[y][x][z]] = blkid; - } - - public void setBlock(final short[][] result, final int x, final int y, final int z, final short[] blkid) { - if (blkid.length == 1) { - this.setBlock(result, x, y, z, blkid[0]); - } - final short id = blkid[FaweCache.RANDOM.random(blkid.length)]; - if (result[FaweCache.CACHE_I[y][x][z]] == null) { - result[FaweCache.CACHE_I[y][x][z]] = new short[4096]; - } - result[FaweCache.CACHE_I[y][x][z]][FaweCache.CACHE_J[y][x][z]] = id; - } - - public void setBlocks(final short[][] ids, final byte[][] data, final int x, final int z) { - this.ids = ids; - this.data = data == null ? new byte[16][] : data; - if (this.parent == null) { - this.inject(this, this.world); - } - this.world.regenerateChunk(x, z); - } - - /** - * Regenerate chunk with the provided id / data / block count
- * - You can provide null for datas / count but it will be marginally slower - * @param ids - * @param datas - * @param count - * @param chunk - */ - @Deprecated - public void regenerateBlocks(final short[][] ids, byte[][] datas, short[] count, final Chunk chunk) { - if (datas == null) { - datas = new byte[16][]; - } - if (count == null) { - count = new short[16]; - } - final int x = chunk.getX(); - final int z = chunk.getZ(); - - boolean skip = true; - for (int i = 0; i < 16; i++) { - if (count[i] < 4096) { - skip = false; - break; - } - } - - if (!skip) { - try { - chunk.load(true); - this.biomes = new Biome[16][16]; - final int X = x << 4; - final int Z = z << 4; - for (int xx = 0; xx < 16; xx++) { - final int xxx = X + x; - for (int zz = 0; zz < 16; zz++) { - final int zzz = Z + zz; - this.biomes[xx][zz] = this.world.getBiome(xxx, zzz); - } - } - final Method getHandele = chunk.getClass().getDeclaredMethod("getHandle"); - final Object c = getHandele.invoke(chunk); - final Class clazz = c.getClass(); - final Field sf = clazz.getDeclaredField("sections"); - sf.setAccessible(true); - final Field tf = clazz.getDeclaredField("tileEntities"); - final Field ef = clazz.getDeclaredField("entitySlices"); - - final Object[] sections = (Object[]) sf.get(c); - final HashMap tiles = (HashMap) tf.get(c); - final List[] entities = (List[]) ef.get(c); - - Method xm = null; - Method ym = null; - Method zm = null; - - // Copy entities / blockstates - final Set> entryset = (Set>) (Set) tiles.entrySet(); - final Iterator> iter = entryset.iterator(); - while (iter.hasNext()) { - final Entry tile = iter.next(); - final Object loc = tile.getKey(); - if (xm == null) { - final Class clazz2 = loc.getClass().getSuperclass(); - xm = clazz2.getDeclaredMethod("getX"); - ym = clazz2.getDeclaredMethod("getY"); - zm = clazz2.getDeclaredMethod("getZ"); - } - final int lx = (int) xm.invoke(loc) & 15; - final int ly = (int) ym.invoke(loc); - final int lz = (int) zm.invoke(loc) & 15; - final int j = FaweCache.CACHE_I[ly][lx][lz]; - final int k = FaweCache.CACHE_J[ly][lx][lz]; - if (ids[j] == null) { - continue; - } - if (ids[j][k] != 0) { - iter.remove(); - } - } - - this.tiles = tiles; - // Trim entities - for (int i = 0; i < 16; i++) { - if ((entities[i] != null) && (count[i] >= 4096)) { - entities[i].clear(); - } - } - this.entities = entities; - - // Efficiently merge sections - Method getIdArray = null; - for (int j = 0; j < sections.length; j++) { - if (count[j] >= 4096) { - continue; - } - final Object section = sections[j]; - if (section == null) { - continue; - } - if (getIdArray == null) { - final Class clazz2 = section.getClass(); - getIdArray = clazz2.getDeclaredMethod("getIdArray"); - } - final char[] array = (char[]) getIdArray.invoke(section); - for (int k = 0; k < array.length; k++) { - final int i = array[k]; - if (i < 16) { - continue; - } - short[] va = ids[j]; - if (va == null) { - va = new short[4096]; - ids[j] = va; - } - final short v = va[k]; - if (v != 0) { - continue; - } - final short id = FaweCache.CACHE_ID[i]; - va[k] = id; - switch (id) { - case 0: - 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: - continue; - case 53: - case 67: - case 108: - case 109: - case 114: - case 128: - case 134: - case 135: - case 136: - case 156: - case 163: - case 164: - case 180: - byte db = FaweCache.CACHE_DATA[i]; - if (db == 0) { - db = -1; - } - if (datas[j] == null) { - datas[j] = new byte[4096]; - } - datas[j][k] = db; - continue; - } - final byte db = FaweCache.CACHE_DATA[i]; - if (db == 0) { - continue; - } - if (datas[j] == null) { - datas[j] = new byte[4096]; - } - datas[j][k] = db; - } - } - - } catch (final Throwable e) { - e.printStackTrace(); - return; - } - } - // Execute - this.ids = ids; - this.data = datas; - if (this.parent == null) { - this.inject(this, this.world); - } - this.world.regenerateChunk(x, z); - } - - public void inject(final FaweGenerator_1_8 gen, final World world) { - this.queue.setGenerator(world, gen); - this.queue.setPopulator(world, new ArrayList()); - this.queue.setProvider(world, null); - } - - public void decouple(final FaweGenerator_1_8 gen, final World world) { - gen.data = null; - gen.ids = null; - gen.tiles = null; - gen.entities = null; - gen.biomes = null; - if (gen.parent == null) { - this.queue.setGenerator(world, gen.parent); - this.queue.setPopulator(world, gen.pops); - if (gen.provider != null) { - this.queue.setProvider(world, gen.provider); - } - } - } - - public FaweGenerator_1_8(final BukkitQueue_1_8 queue, final World world) { - this.queue = queue; - this.world = world; - this.parent = world.getGenerator(); - this.pops = world.getPopulators(); - if (this.parent == null) { - this.provider = queue.getProvider(world); - } else { - this.provider = null; - } - this.registerEvents(); - } - - @Override - public short[][] generateExtBlockSections(final World world, final Random random, final int x, final int z, final BiomeGrid biomes) { - short[][] result; - if (this.ids != null) { - result = this.ids; - if ((biomes != null) && (this.biomes != null)) { - for (int i = 0; i < 16; i++) { - for (int j = 0; j < 16; j++) { - biomes.setBiome(i, j, this.biomes[i][j]); - } - } - } - } else if (this.parent != null) { - result = this.parent.generateExtBlockSections(world, random, x, z, biomes); - } else { - result = null; - } - return result; - } - - public void populate(final Chunk chunk) { - for (int i = 0; i < this.data.length; i++) { - final byte[] section = this.data[i]; - if (section == null) { - continue; - } - for (int j = 0; j < section.length; j++) { - final byte v = section[j]; - if (v == 0) { - continue; - } - final int x = FaweCache.CACHE_X[i][j]; - final int y = FaweCache.CACHE_Y[i][j]; - final int z = FaweCache.CACHE_Z[i][j]; - chunk.getBlock(x, y, z).setData(v != -1 ? v : 0, false); - } - } - if ((this.tiles != null) || (this.entities != null)) { - this.queue.setEntitiesAndTiles(chunk, this.entities, this.tiles); - } - final BukkitChunk_1_8 fc = new BukkitChunk_1_8(new ChunkLoc(chunk.getWorld().getName(), chunk.getX(), chunk.getZ())); - fc.chunk = chunk; - this.queue.fixLighting(fc, Settings.FIX_ALL_LIGHTING); - } - - @Override - public byte[] generate(final World world, final Random random, final int x, final int z) { - if (this.ids == null) { - try { - this.parent.generate(world, random, x, z); - } catch (final Throwable e) { - return null; - } - } - return null; - } - - @Override - public byte[][] generateBlockSections(final World world, final Random random, final int x, final int z, final BiomeGrid biomes) { - if ((this.ids == null) && (this.parent != null)) { - return this.parent.generateBlockSections(world, random, x, z, biomes); - } - return null; - } - - @Override - public boolean canSpawn(final World world, final int x, final int z) { - if (this.parent != null) { - return this.parent.canSpawn(world, x, z); - } - return true; - } - - @Override - public List getDefaultPopulators(final World world) { - if ((this.ids == null) && (this.parent != null)) { - return this.parent.getDefaultPopulators(world); - } - return null; - } - - @Override - public Location getFixedSpawnLocation(final World world, final Random random) { - if ((this.ids == null) && (this.parent != null)) { - return this.parent.getFixedSpawnLocation(world, random); - } - return null; - } -} 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 60759e04..f2eed18f 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 @@ -1,15 +1,13 @@ package com.boydti.fawe.bukkit.v1_9; +import com.boydti.fawe.FaweCache; +import com.boydti.fawe.object.FaweChunk; +import com.boydti.fawe.util.FaweQueue; +import com.sk89q.worldedit.world.biome.BaseBiome; import java.util.Arrays; - import org.bukkit.Bukkit; import org.bukkit.Chunk; -import com.boydti.fawe.FaweCache; -import com.boydti.fawe.object.ChunkLoc; -import com.boydti.fawe.object.FaweChunk; -import com.sk89q.worldedit.world.biome.BaseBiome; - public class BukkitChunk_1_9 extends FaweChunk { private int[][] ids; @@ -24,8 +22,8 @@ public class BukkitChunk_1_9 extends FaweChunk { /** * A FaweSections object represents a chunk and the blocks that you wish to change in it. */ - protected BukkitChunk_1_9(final ChunkLoc chunk) { - super(chunk); + protected BukkitChunk_1_9(FaweQueue parent, int x, int z) { + super(parent, x, z); this.ids = new int[16][]; this.count = new short[16]; this.air = new short[16]; @@ -35,15 +33,14 @@ public class BukkitChunk_1_9 extends FaweChunk { @Override public Chunk getChunk() { if (this.chunk == null) { - final ChunkLoc cl = this.getChunkLoc(); - this.chunk = Bukkit.getWorld(cl.world).getChunkAt(cl.x, cl.z); + this.chunk = Bukkit.getWorld(getParent().world).getChunkAt(getX(), getZ()); } return this.chunk; } @Override - public void setChunkLoc(final ChunkLoc loc) { - super.setChunkLoc(loc); + public void setLoc(final FaweQueue parent, int x, int z) { + super.setLoc(parent, x, z); this.chunk = null; } 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 0c8755b5..32d0d836 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 @@ -4,7 +4,6 @@ import com.boydti.fawe.Fawe; import com.boydti.fawe.FaweCache; import com.boydti.fawe.bukkit.v0.BukkitQueue_0; import com.boydti.fawe.config.Settings; -import com.boydti.fawe.object.ChunkLoc; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.IntegerPair; @@ -64,12 +63,15 @@ public class BukkitQueue_1_9 extends BukkitQueue_0 { private final RefField fieldWorld; private final RefMethod methodGetBlocks; private final RefMethod methodSetType; + private final RefMethod methodGetType; private final RefMethod methodGetByCombinedId; + private final RefMethod methodGetCombinedId; private final Object air; private final RefMethod methodGetWorld; private final RefField tileEntityListTick; - public BukkitQueue_1_9() throws NoSuchMethodException, RuntimeException { + public BukkitQueue_1_9(String world) throws NoSuchMethodException, RuntimeException { + super(world); this.methodGetHandleChunk = this.classCraftChunk.getMethod("getHandle"); this.methodInitLighting = this.classChunk.getMethod("initLighting"); this.classBlockPositionConstructor = this.classBlockPosition.getConstructor(int.class, int.class, int.class); @@ -79,10 +81,12 @@ public class BukkitQueue_1_9 extends BukkitQueue_0 { this.methodGetByCombinedId = this.classBlock.getMethod("getByCombinedId", int.class); this.methodGetBlocks = this.classChunkSection.getMethod("getBlocks"); this.methodSetType = this.classChunkSection.getMethod("setType", int.class, int.class, int.class, this.classIBlockData.getRealClass()); + this.methodGetType = this.classChunk.getMethod("a", int.class, int.class, int.class); this.classChunkSectionConstructor = this.classChunkSection.getConstructor(int.class, boolean.class, char[].class); this.air = this.methodGetByCombinedId.call(0); this.tileEntityListTick = this.classWorld.getField("tileEntityListTick"); this.methodGetWorld = this.classChunk.getMethod("getWorld"); + this.methodGetCombinedId = classBlock.getMethod("getCombinedId", classIBlockData.getRealClass()); } @Override @@ -92,12 +96,11 @@ public class BukkitQueue_1_9 extends BukkitQueue_0 { } return new ArrayList<>(); } - + public void sendChunk(FaweChunk fc) { fixLighting(fc, Settings.FIX_ALL_LIGHTING); final Chunk chunk = fc.getChunk(); - final ChunkLoc loc = fc.getChunkLoc(); - chunk.getWorld().refreshChunk(loc.x, loc.z); + chunk.getWorld().refreshChunk(fc.getX(), fc.getZ()); } @Override @@ -187,10 +190,10 @@ public class BukkitQueue_1_9 extends BukkitQueue_0 { public boolean isSurrounded(final int[][] sections, final int x, final int y, final int z) { return this.isSolid(this.getId(sections, x, y + 1, z)) - && this.isSolid(this.getId(sections, x + 1, y - 1, z)) - && this.isSolid(this.getId(sections, x - 1, y, z)) - && this.isSolid(this.getId(sections, x, y, z + 1)) - && this.isSolid(this.getId(sections, x, y, z - 1)); + && this.isSolid(this.getId(sections, x + 1, y - 1, z)) + && this.isSolid(this.getId(sections, x - 1, y, z)) + && this.isSolid(this.getId(sections, x, y, z + 1)) + && this.isSolid(this.getId(sections, x, y, z - 1)); } public boolean isSolid(final int i) { @@ -221,6 +224,35 @@ public class BukkitQueue_1_9 extends BukkitQueue_0 { return this.methodGetBlocks.of(obj).call(); } + private int lcx = Integer.MIN_VALUE; + private int lcz = Integer.MIN_VALUE; + private int lcy = Integer.MIN_VALUE; + private RefExecutor lc; + private World bukkitWorld; + + @Override + public int getCombinedId4Data(int x, int y, int z) { + try { + int cx = x >> 4; + int cz = z >> 4; + int cy = y >> 4; + if (cx != lcx || cz != lcz) { + if (bukkitWorld == null) { + bukkitWorld = Bukkit.getServer().getWorld(world); + } + lcx = cx; + lcz = cz; + lc = methodGetType.of(methodGetHandleChunk.of(bukkitWorld.getChunkAt(cx, cz)).call()); + } + int combined = (int) methodGetCombinedId.call(lc.call(x & 15, y, z & 15)); + return ((combined & 4095) << 4) + (combined >> 12); + } + catch (Throwable e) { + e.printStackTrace(); + } + return 0; + } + @Override public boolean setComponents(final FaweChunk pc) { final BukkitChunk_1_9 fs = (BukkitChunk_1_9) pc; @@ -302,7 +334,7 @@ public class BukkitQueue_1_9 extends BukkitQueue_0 { final int combined = newArray[i]; final int id = combined & 4095; final int data = combined >> 12; - array[i] = (char) ((id << 4) + data); + array[i] = (char) ((id << 4) + data); } section = sections[j] = this.newChunkSection(j << 4, flag, array); continue; @@ -481,8 +513,8 @@ public class BukkitQueue_1_9 extends BukkitQueue_0 { } @Override - public FaweChunk getChunk(final ChunkLoc wrap) { - return new BukkitChunk_1_9(wrap); + public FaweChunk getChunk(int x, int z) { + return new BukkitChunk_1_9(this, x, z); } public boolean unloadChunk(final String world, final Chunk chunk) { diff --git a/core/src/main/java/com/boydti/fawe/Fawe.java b/core/src/main/java/com/boydti/fawe/Fawe.java index 2147929e..e72fa648 100644 --- a/core/src/main/java/com/boydti/fawe/Fawe.java +++ b/core/src/main/java/com/boydti/fawe/Fawe.java @@ -11,7 +11,6 @@ import com.boydti.fawe.regions.general.PlotSquaredFeature; import com.boydti.fawe.util.Lag; import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MemUtil; -import com.boydti.fawe.util.SetQueue; import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.WEManager; import com.boydti.fawe.util.WESubscriber; @@ -153,8 +152,7 @@ public class Fawe { if (Settings.METRICS) { this.IMP.startMetrics(); } - SetQueue.IMP.queue = this.IMP.getQueue(); - + // Delete old history MainUtil.deleteDirectory(new File(IMP.getDirectory(), "history")); diff --git a/core/src/main/java/com/boydti/fawe/FaweAPI.java b/core/src/main/java/com/boydti/fawe/FaweAPI.java index 6e170dda..9bb325dc 100644 --- a/core/src/main/java/com/boydti/fawe/FaweAPI.java +++ b/core/src/main/java/com/boydti/fawe/FaweAPI.java @@ -1,5 +1,14 @@ package com.boydti.fawe; +import com.boydti.fawe.object.FaweLocation; +import com.boydti.fawe.util.FaweQueue; +import com.boydti.fawe.util.SetQueue; +import com.boydti.fawe.util.TaskManager; +import com.sk89q.jnbt.ByteArrayTag; +import com.sk89q.jnbt.IntTag; +import com.sk89q.jnbt.NBTInputStream; +import com.sk89q.jnbt.ShortTag; +import com.sk89q.jnbt.Tag; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -9,23 +18,10 @@ import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.util.Map; import java.util.zip.GZIPInputStream; - import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.Material; -import com.boydti.fawe.object.ChunkLoc; -import com.boydti.fawe.object.FaweChunk; -import com.boydti.fawe.object.FaweLocation; -import com.boydti.fawe.util.SetQueue; -import com.boydti.fawe.util.TaskManager; -import com.sk89q.jnbt.ByteArrayTag; -import com.sk89q.jnbt.IntTag; -import com.sk89q.jnbt.NBTInputStream; -import com.sk89q.jnbt.ShortTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.world.biome.BaseBiome; - /** * The FaweAPI class offers a few useful functions.
* - This class is not intended to replace the WorldEdit API
@@ -68,77 +64,69 @@ public class FaweAPI { SetQueue.IMP.setBlock(world, x, y, z, id, data); } - /** - * Set a biome at a location asynchronously - * @param world - * @param x - * @param z - * @param id - * @param data - */ - public static void setBiomeAsync(final String world, final int x, final int z, final BaseBiome biome) { - SetQueue.IMP.setBiome(world, x, z, biome); +// /** +// * Set a biome at a location asynchronously +// * @param world +// * @param x +// * @param z +// * @param id +// * @param data +// */ +// public static void setBiomeAsync(final String world, final int x, final int z, final BaseBiome biome) { +// SetQueue.IMP.setBiome(world, x, z, biome); +// } +// +// /** +// * Set a biome at a location asynchronously +// * @param loc +// * @param biome +// */ +// public static void setBiomeAsync(final Location loc, final BaseBiome biome) { +// SetQueue.IMP.setBiome(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockZ(), biome); +// } +// +// /** +// * This will return a FaweChunk object that can be modified.
+// * - The FaweChunk object can be reused if you want identical changes across chunks
+// * - This is additive modification.
+// * - First use {@link FaweChunk#fill(int, byte)} (e.g. with air) for absolute modification
+// * When ready, use {@link #setChunk(FaweChunk, ChunkLoc)} +// * @return +// */ +// public static FaweChunk createChunk() { +// return SetQueue.IMP.queue.getChunk(new ChunkLoc(null, 0, 0)); +// } +// +// /** +// * @see #createChunk() +// * @param data +// * @param location +// */ +// public static void setChunkAsync(final FaweChunk data, final ChunkLoc location) { +// data.setChunkLoc(location); +// data.addToQueue(); +// } +// +// /** +// * @see #createChunk() +// * @param data +// * @param chunk +// */ +// public static void setChunkAsync(final FaweChunk data, final Chunk chunk) { +// final ChunkLoc loc = new ChunkLoc(chunk.getWorld().getName(), chunk.getX(), chunk.getZ()); +// data.setChunkLoc(loc); +// data.addToQueue(); +// } +// + public static void fixLighting(String world, int x, int z, final boolean fixAll) { + FaweQueue queue = SetQueue.IMP.getQueue(world); + queue.fixLighting(queue.getChunk(x, z), fixAll); } - /** - * Set a biome at a location asynchronously - * @param loc - * @param biome - */ - public static void setBiomeAsync(final Location loc, final BaseBiome biome) { - SetQueue.IMP.setBiome(loc.getWorld().getName(), loc.getBlockX(), loc.getBlockZ(), biome); - } - /** - * This will return a FaweChunk object that can be modified.
- * - The FaweChunk object can be reused if you want identical changes across chunks
- * - This is additive modification.
- * - First use {@link FaweChunk#fill(int, byte)} (e.g. with air) for absolute modification
- * When ready, use {@link #setChunk(FaweChunk, ChunkLoc)} - * @return - */ - public static FaweChunk createChunk() { - return SetQueue.IMP.queue.getChunk(new ChunkLoc(null, 0, 0)); - } - - /** - * @see #createChunk() - * @param data - * @param location - */ - public static void setChunkAsync(final FaweChunk data, final ChunkLoc location) { - data.setChunkLoc(location); - data.addToQueue(); - } - - /** - * @see #createChunk() - * @param data - * @param chunk - */ - public static void setChunkAsync(final FaweChunk data, final Chunk chunk) { - final ChunkLoc loc = new ChunkLoc(chunk.getWorld().getName(), chunk.getX(), chunk.getZ()); - data.setChunkLoc(loc); - data.addToQueue(); - } - - /** - * Fix the lighting at a chunk location.
- * - The fixAll parameter determines if extensive relighting should occur (slow) - * @param loc - */ - public static void fixLighting(final ChunkLoc loc, final boolean fixAll) { - SetQueue.IMP.queue.fixLighting(SetQueue.IMP.queue.getChunk(loc), fixAll); - } - - /** - * Fix the lighting at a chunk.
- * - The fixAll parameter determines if extensive relighting should occur (slow) - * @param chunk - */ public static void fixLighting(final Chunk chunk, final boolean fixAll) { - final ChunkLoc loc = new ChunkLoc(chunk.getWorld().getName(), chunk.getX(), chunk.getZ()); - SetQueue.IMP.queue.fixLighting(SetQueue.IMP.queue.getChunk(loc), fixAll); + FaweQueue queue = SetQueue.IMP.getQueue(chunk.getWorld().getName()); + queue.fixLighting(queue.getChunk(chunk.getX(), chunk.getZ()), fixAll); } /** diff --git a/core/src/main/java/com/boydti/fawe/IFawe.java b/core/src/main/java/com/boydti/fawe/IFawe.java index 36e32386..18043c68 100644 --- a/core/src/main/java/com/boydti/fawe/IFawe.java +++ b/core/src/main/java/com/boydti/fawe/IFawe.java @@ -28,7 +28,7 @@ public interface IFawe { public int[] getVersion(); - public FaweQueue getQueue(); + public FaweQueue getNewQueue(String world); public EditSessionWrapper getEditSessionWrapper(final EditSession session); diff --git a/core/src/main/java/com/boydti/fawe/command/FixLighting.java b/core/src/main/java/com/boydti/fawe/command/FixLighting.java index 998383b4..952add9e 100644 --- a/core/src/main/java/com/boydti/fawe/command/FixLighting.java +++ b/core/src/main/java/com/boydti/fawe/command/FixLighting.java @@ -3,7 +3,6 @@ package com.boydti.fawe.command; import com.boydti.fawe.FaweAPI; import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.Settings; -import com.boydti.fawe.object.ChunkLoc; import com.boydti.fawe.object.FaweCommand; import com.boydti.fawe.object.FaweLocation; import com.boydti.fawe.object.FawePlayer; @@ -24,7 +23,7 @@ public class FixLighting extends FaweCommand { final FaweLocation loc = player.getLocation(); final Region selection = player.getSelection(); if (selection == null) { - FaweAPI.fixLighting(new ChunkLoc(loc.world, loc.x >> 4, loc.z >> 4), Settings.FIX_ALL_LIGHTING); + FaweAPI.fixLighting(loc.world, loc.x >> 4, loc.z >> 4, Settings.FIX_ALL_LIGHTING); BBC.FIX_LIGHTING_CHUNK.send(player); return true; } @@ -42,8 +41,7 @@ public class FixLighting extends FaweCommand { int count = 0; for (int x = minX; x <= maxX; x++) { for (int z = minZ; z <= maxZ; z++) { - final ChunkLoc cl = new ChunkLoc(loc.world, x, z); - FaweAPI.fixLighting(cl, Settings.FIX_ALL_LIGHTING); + FaweAPI.fixLighting(loc.world, x, z, Settings.FIX_ALL_LIGHTING); count++; } } diff --git a/core/src/main/java/com/boydti/fawe/object/ChunkLoc.java b/core/src/main/java/com/boydti/fawe/object/ChunkLoc.java deleted file mode 100644 index 5e323a4b..00000000 --- a/core/src/main/java/com/boydti/fawe/object/ChunkLoc.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.boydti.fawe.object; - -public class ChunkLoc { - public final int x; - public final int z; - public final String world; - - public ChunkLoc(final String world, final int x, final int z) { - this.world = world; - this.x = x; - this.z = z; - } - - @Override - public int hashCode() { - int result; - if (this.x >= 0) { - if (this.z >= 0) { - result = (this.x * this.x) + (3 * this.x) + (2 * this.x * this.z) + this.z + (this.z * this.z); - } else { - final int y1 = -this.z; - result = (this.x * this.x) + (3 * this.x) + (2 * this.x * y1) + y1 + (y1 * y1) + 1; - } - } else { - final int x1 = -this.x; - if (this.z >= 0) { - result = -((x1 * x1) + (3 * x1) + (2 * x1 * this.z) + this.z + (this.z * this.z)); - } else { - final int y1 = -this.z; - result = -((x1 * x1) + (3 * x1) + (2 * x1 * y1) + y1 + (y1 * y1) + 1); - } - } - result = (result * 31) + this.world.hashCode(); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (this.getClass() != obj.getClass()) { - return false; - } - final ChunkLoc other = (ChunkLoc) obj; - return ((this.x == other.x) && (this.z == other.z) && (this.world.equals(other.world))); - } - - @Override - public String toString() { - return this.world + ":" + this.x + "," + this.z; - } -} diff --git a/core/src/main/java/com/boydti/fawe/object/EditSessionWrapper.java b/core/src/main/java/com/boydti/fawe/object/EditSessionWrapper.java index 319c7877..40037af7 100644 --- a/core/src/main/java/com/boydti/fawe/object/EditSessionWrapper.java +++ b/core/src/main/java/com/boydti/fawe/object/EditSessionWrapper.java @@ -27,6 +27,6 @@ public class EditSessionWrapper { } public Extent getHistoryExtent(final Extent parent, FaweChangeSet set, final FawePlayer player) { - return new HistoryExtent(parent, set); + return new HistoryExtent(player.getLocation().world, parent, set); } } diff --git a/core/src/main/java/com/boydti/fawe/object/FaweChunk.java b/core/src/main/java/com/boydti/fawe/object/FaweChunk.java index 80fa5381..6df8f0e5 100644 --- a/core/src/main/java/com/boydti/fawe/object/FaweChunk.java +++ b/core/src/main/java/com/boydti/fawe/object/FaweChunk.java @@ -1,41 +1,59 @@ package com.boydti.fawe.object; -import java.util.ArrayDeque; - import com.boydti.fawe.config.Settings; -import com.boydti.fawe.util.SetQueue; +import com.boydti.fawe.util.FaweQueue; import com.sk89q.worldedit.world.biome.BaseBiome; +import java.util.ArrayDeque; public abstract class FaweChunk { - private ChunkLoc chunk; + private FaweQueue parent; + private int x,z; private final ArrayDeque tasks = new ArrayDeque(); /** * A FaweSections object represents a chunk and the blocks that you wish to change in it. */ - public FaweChunk(final ChunkLoc chunk) { - this.chunk = chunk; + public FaweChunk(FaweQueue parent, int x, int z) { + this.parent = parent; + this.x = x; + this.z = z; } - public void setChunkLoc(final ChunkLoc loc) { - this.chunk = loc; + public void setLoc(FaweQueue parent, int x, int z) { + this.parent = parent; + this.x = x; + this.z = z; } - public ChunkLoc getChunkLoc() { - return this.chunk; + public FaweQueue getParent() { + return parent; } - public void addToQueue() { - if (this.chunk == null) { - throw new IllegalArgumentException("Chunk location cannot be null!"); - } - SetQueue.IMP.queue.setChunk(this); + public int getX() { + return x; + } + + public int getZ() { + return z; + } + + public long longHash() { + return (long) x << 32 | z & 0xFFFFFFFFL; + } + + @Override + public int hashCode() { + return x << 16 | z & 0xFFFF; + } + + public void addToQueue(String world) { + parent.setChunk(this); } public void fixLighting() { - SetQueue.IMP.queue.fixLighting(this, Settings.FIX_ALL_LIGHTING); + parent.fixLighting(this, Settings.FIX_ALL_LIGHTING); } public void fill(final int id, final byte data) { @@ -67,16 +85,11 @@ public abstract class FaweChunk { public abstract void setBiome(final int x, final int z, final BaseBiome biome); - @Override - public int hashCode() { - return this.chunk.hashCode(); - } - @Override public boolean equals(final Object obj) { - if ((obj == null) || !(obj instanceof FaweChunk)) { + if ((obj == null) || obj.hashCode() != hashCode() || !(obj instanceof FaweChunk)) { return false; } - return this.chunk.equals(((FaweChunk) obj).chunk); + return longHash() != ((FaweChunk) obj).longHash(); } } diff --git a/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java b/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java index a4e68a1c..83f3265f 100644 --- a/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/HistoryExtent.java @@ -2,6 +2,8 @@ package com.boydti.fawe.object; import com.boydti.fawe.FaweCache; import com.boydti.fawe.object.changeset.FaweChangeSet; +import com.boydti.fawe.util.FaweQueue; +import com.boydti.fawe.util.SetQueue; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; @@ -27,6 +29,7 @@ import static com.google.common.base.Preconditions.checkNotNull; public class HistoryExtent extends AbstractDelegateExtent { private final com.boydti.fawe.object.changeset.FaweChangeSet changeSet; + private final FaweQueue queue; /** * Create a new instance. @@ -34,33 +37,39 @@ public class HistoryExtent extends AbstractDelegateExtent { * @param extent the extent * @param changeSet the change set */ - public HistoryExtent(final Extent extent, final FaweChangeSet changeSet) { + public HistoryExtent(final String world, final Extent extent, final FaweChangeSet changeSet) { super(extent); + this.queue = SetQueue.IMP.getQueue(world); checkNotNull(changeSet); this.changeSet = changeSet; } @Override - public synchronized boolean setBlock(final Vector location, final BaseBlock block) throws WorldEditException { + public boolean setBlock(final Vector location, final BaseBlock block) throws WorldEditException { if (super.setBlock(location, block)) { - BaseBlock previous; - try { - previous = this.getBlock(location); - } catch (final Exception e) { - previous = this.getBlock(location); - } - final int id_p = previous.getId(); - final int id_b = block.getId(); - if (id_p == id_b) { - if (FaweCache.hasData(id_p)) { - if (previous.getData() == block.getData()) { - return false; - } - } else { + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + int combined = queue.getCombinedId4Data(x, y, z); + int id = (combined >> 4); + if (id == block.getId()) { + if (!FaweCache.hasData(id)) { + return false; + } + int data = id & 0xF; + if (data == block.getData()) { return false; } } - this.changeSet.add(location, previous, block); + if (!FaweCache.hasNBT(id)) { + if (FaweCache.hasNBT(block.getId())) { + this.changeSet.add(x, y, z, combined, block); + } else { + this.changeSet.add(x, y, z, combined, (block.getId() << 4) + block.getData()); + } + } else { + this.changeSet.add(location, getBlock(location), block); + } return true; } return false; diff --git a/core/src/main/java/com/boydti/fawe/object/NullChangeSet.java b/core/src/main/java/com/boydti/fawe/object/NullChangeSet.java index 27647609..906157d7 100644 --- a/core/src/main/java/com/boydti/fawe/object/NullChangeSet.java +++ b/core/src/main/java/com/boydti/fawe/object/NullChangeSet.java @@ -32,4 +32,10 @@ public class NullChangeSet implements FaweChangeSet { @Override public void add(Vector location, BaseBlock from, BaseBlock to) {} + + @Override + public void add(int x, int y, int z, int combinedId4DataFrom, BaseBlock to) {} + + @Override + public void add(int x, int y, int z, int combinedId4DataFrom, int combinedId4DataTo) {} } diff --git a/core/src/main/java/com/boydti/fawe/object/SendChunk.java b/core/src/main/java/com/boydti/fawe/object/SendChunk.java deleted file mode 100644 index 1d8ff7b6..00000000 --- a/core/src/main/java/com/boydti/fawe/object/SendChunk.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.boydti.fawe.object; - -import java.util.Collection; - -public abstract class SendChunk { - - public abstract void fixLighting(final Collection locs); - - public abstract void update(final Collection locs); -} diff --git a/core/src/main/java/com/boydti/fawe/object/changeset/DiskStorageHistory.java b/core/src/main/java/com/boydti/fawe/object/changeset/DiskStorageHistory.java index 010ecd69..7cdbddca 100644 --- a/core/src/main/java/com/boydti/fawe/object/changeset/DiskStorageHistory.java +++ b/core/src/main/java/com/boydti/fawe/object/changeset/DiskStorageHistory.java @@ -138,19 +138,8 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet { } @Override - public void add(Vector location, BaseBlock from, BaseBlock to) { - add(location.getBlockX(), location.getBlockY(), location.getBlockZ(), from, to); - } - - public void add(int x, int y, int z, BaseBlock from, BaseBlock to) { + public void add(int x, int y, int z, int combinedFrom, int combinedTo) { try { - int idfrom = from.getId(); - int combinedFrom = (FaweCache.hasData(idfrom) ? ((idfrom << 4) + from.getData()) : (idfrom << 4)); - CompoundTag nbtFrom = FaweCache.hasNBT(idfrom) ? from.getNbtData() : null; - - int idTo = to.getId(); - int combinedTo = (FaweCache.hasData(idTo) ? ((idTo << 4) + to.getData()) : (idTo << 4)); - CompoundTag nbtTo = FaweCache.hasNBT(idTo) ? to.getNbtData() : null; OutputStream stream = getBAOS(x, y, z); //x stream.write((x - ox) & 0xff); @@ -166,6 +155,41 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet { //to stream.write((combinedTo) & 0xff); stream.write(((combinedTo) >> 8) & 0xff); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + @Override + public void add(int x, int y, int z, int combinedId4DataFrom, BaseBlock to) { + int idTo = to.getId(); + int combinedTo = (FaweCache.hasData(idTo) ? ((idTo << 4) + to.getData()) : (idTo << 4)); + CompoundTag nbtTo = FaweCache.hasNBT(idTo) ? to.getNbtData() : null; + add(x, y, z, combinedId4DataFrom, combinedTo); + if (nbtTo != null && MainUtil.isValidTag(nbtTo)) { + try { + Map value = ReflectionUtils.getMap(nbtTo.getValue()); + value.put("x", new IntTag(x)); + value.put("y", new IntTag(y)); + value.put("z", new IntTag(z)); + NBTOutputStream nbtos = getNBTTOS(x, y, z); + nbtos.writeNamedTag(osNBTTI.getAndIncrement() + "", nbtTo); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + @Override + public void add(Vector loc, BaseBlock from, BaseBlock to) { + int x = loc.getBlockX(); + int y = loc.getBlockY(); + int z = loc.getBlockZ(); + try { + int idfrom = from.getId(); + int combinedFrom = (FaweCache.hasData(idfrom) ? ((idfrom << 4) + from.getData()) : (idfrom << 4)); + CompoundTag nbtFrom = FaweCache.hasNBT(idfrom) ? from.getNbtData() : null; if (nbtFrom != null && MainUtil.isValidTag(nbtFrom)) { Map value = ReflectionUtils.getMap(nbtFrom.getValue()); @@ -175,15 +199,8 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet { NBTOutputStream nbtos = getNBTFOS(x, y, z); nbtos.writeNamedTag(osNBTFI.getAndIncrement() + "", nbtFrom); } + add(x, y, z, combinedFrom, to); - if (nbtTo != null && MainUtil.isValidTag(nbtTo)) { - Map value = ReflectionUtils.getMap(nbtTo.getValue()); - value.put("x", new IntTag(x)); - value.put("y", new IntTag(y)); - value.put("z", new IntTag(z)); - NBTOutputStream nbtos = getNBTTOS(x, y, z); - nbtos.writeNamedTag(osNBTTI.getAndIncrement() + "", nbtTo); - } } catch (Exception e) { e.printStackTrace(); } @@ -200,12 +217,9 @@ public class DiskStorageHistory implements ChangeSet, FaweChangeSet { public void add(BlockChange change) { try { BlockVector loc = change.getPosition(); - int x = loc.getBlockX(); - int y = loc.getBlockY(); - int z = loc.getBlockZ(); BaseBlock from = change.getPrevious(); BaseBlock to = change.getCurrent(); - add(x, y, z, from, to); + add(loc, from, to); } catch (Exception e) { e.printStackTrace(); } diff --git a/core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java b/core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java index 315afda8..ab36eae8 100644 --- a/core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java +++ b/core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java @@ -8,4 +8,8 @@ public interface FaweChangeSet extends ChangeSet { void flush(); void add(Vector location, BaseBlock from, BaseBlock to); + + void add(int x, int y, int z, int combinedId4DataFrom, BaseBlock to); + + void add(int x, int y, int z, int combinedId4DataFrom, int combinedId4DataTo); } diff --git a/core/src/main/java/com/boydti/fawe/object/changeset/MemoryOptimizedHistory.java b/core/src/main/java/com/boydti/fawe/object/changeset/MemoryOptimizedHistory.java index 19732264..db6676f0 100644 --- a/core/src/main/java/com/boydti/fawe/object/changeset/MemoryOptimizedHistory.java +++ b/core/src/main/java/com/boydti/fawe/object/changeset/MemoryOptimizedHistory.java @@ -54,20 +54,10 @@ public class MemoryOptimizedHistory implements ChangeSet, FaweChangeSet { size = new AtomicInteger(); } + @Override - public void add(Vector location, BaseBlock from, BaseBlock to) { - add(location.getBlockX(), location.getBlockY(), location.getBlockZ(), from, to); - } - - public void add(int x, int y, int z, BaseBlock from, BaseBlock to) { + public void add(int x, int y, int z, int combinedFrom, int combinedTo) { try { - int idfrom = from.getId(); - int combinedFrom = (FaweCache.hasData(idfrom) ? ((idfrom << 4) + from.getData()) : (idfrom << 4)); - CompoundTag nbtFrom = FaweCache.hasNBT(idfrom) ? from.getNbtData() : null; - - int idTo = to.getId(); - int combinedTo = (FaweCache.hasData(idTo) ? ((idTo << 4) + to.getData()) : (idTo << 4)); - CompoundTag nbtTo = FaweCache.hasNBT(idTo) ? to.getNbtData() : null; OutputStream stream = getBAOS(x, y, z); //x stream.write((x - ox) & 0xff); @@ -83,7 +73,39 @@ public class MemoryOptimizedHistory implements ChangeSet, FaweChangeSet { //to stream.write((combinedTo) & 0xff); stream.write(((combinedTo) >> 8) & 0xff); + } catch (IOException e) { + e.printStackTrace(); + } + } + @Override + public void add(int x, int y, int z, int combinedId4DataFrom, BaseBlock to) { + int idTo = to.getId(); + int combinedTo = (FaweCache.hasData(idTo) ? ((idTo << 4) + to.getData()) : (idTo << 4)); + CompoundTag nbtTo = FaweCache.hasNBT(idTo) ? to.getNbtData() : null; + add(x, y, z, combinedId4DataFrom, combinedTo); + if (nbtTo != null && MainUtil.isValidTag(nbtTo)) { + Map value = ReflectionUtils.getMap(nbtTo.getValue()); + value.put("x", new IntTag(x)); + value.put("y", new IntTag(y)); + value.put("z", new IntTag(z)); + if (toTags == null) { + toTags = new ArrayDeque<>(); + } + toTags.add(nbtTo); + } + } + + @Override + public void add(Vector loc, BaseBlock from, BaseBlock to) { + try { + int x = loc.getBlockX(); + int y = loc.getBlockY(); + int z = loc.getBlockZ(); + + int idfrom = from.getId(); + int combinedFrom = (FaweCache.hasData(idfrom) ? ((idfrom << 4) + from.getData()) : (idfrom << 4)); + CompoundTag nbtFrom = FaweCache.hasNBT(idfrom) ? from.getNbtData() : null; if (nbtFrom != null && MainUtil.isValidTag(nbtFrom)) { Map value = ReflectionUtils.getMap(nbtFrom.getValue()); value.put("x", new IntTag(x)); @@ -94,17 +116,7 @@ public class MemoryOptimizedHistory implements ChangeSet, FaweChangeSet { } fromTags.add(nbtFrom); } - - if (nbtTo != null && MainUtil.isValidTag(nbtTo)) { - Map value = ReflectionUtils.getMap(nbtTo.getValue()); - value.put("x", new IntTag(x)); - value.put("y", new IntTag(y)); - value.put("z", new IntTag(z)); - if (toTags == null) { - toTags = new ArrayDeque<>(); - } - toTags.add(nbtTo); - } + add(x, y, z, combinedFrom, to); } catch (Exception e) { e.printStackTrace(); } @@ -116,12 +128,9 @@ public class MemoryOptimizedHistory implements ChangeSet, FaweChangeSet { if ((arg instanceof BlockChange)) { BlockChange change = (BlockChange) arg; BlockVector loc = change.getPosition(); - int x = loc.getBlockX(); - int y = loc.getBlockY(); - int z = loc.getBlockZ(); BaseBlock from = change.getPrevious(); BaseBlock to = change.getCurrent(); - add(x, y, z, from, to); + add(loc, from, to); } else { if (entities == null) { entities = new ArrayDeque<>(); diff --git a/core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java index 5394fdad..3aec4f54 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java @@ -1,6 +1,7 @@ package com.boydti.fawe.object.extent; import com.boydti.fawe.FaweCache; +import com.boydti.fawe.util.FaweQueue; import com.boydti.fawe.util.SetQueue; import com.boydti.fawe.util.TaskManager; import com.sk89q.worldedit.BlockVector; @@ -20,13 +21,13 @@ import java.util.List; public class FastWorldEditExtent extends AbstractDelegateExtent { - private final String world; private final Thread thread; + private final FaweQueue queue; public FastWorldEditExtent(final World world, final Thread thread) { super(world); this.thread = thread; - this.world = world.getName(); + this.queue = SetQueue.IMP.getQueue(world.getName()); } @Override @@ -42,7 +43,7 @@ public class FastWorldEditExtent extends AbstractDelegateExtent { @Override public BaseBiome getBiome(final Vector2D position) { - if (!SetQueue.IMP.isChunkLoaded(this.world, position.getBlockX() >> 4, position.getBlockZ() >> 4)) { + if (!queue.isChunkLoaded(position.getBlockX() >> 4, position.getBlockZ() >> 4)) { return EditSession.nullBiome; } synchronized (this.thread) { @@ -58,7 +59,7 @@ public class FastWorldEditExtent extends AbstractDelegateExtent { if ((this.lastBlock != null) && this.lastVector.equals(position.toBlockVector())) { return this.lastBlock; } - if (!SetQueue.IMP.isChunkLoaded(this.world, position.getBlockX() >> 4, position.getBlockZ() >> 4)) { + if (!queue.isChunkLoaded(position.getBlockX() >> 4, position.getBlockZ() >> 4)) { try { this.lastVector = position.toBlockVector(); return this.lastBlock = super.getBlock(position); @@ -93,7 +94,7 @@ public class FastWorldEditExtent extends AbstractDelegateExtent { @Override public boolean setBiome(final Vector2D position, final BaseBiome biome) { - SetQueue.IMP.setBiome(this.world, position.getBlockX(), position.getBlockZ(), biome); + queue.setBiome(position.getBlockX(), position.getBlockZ(), biome); return true; } @@ -141,7 +142,7 @@ public class FastWorldEditExtent extends AbstractDelegateExtent { case 151: case 178: { if (block.hasNbtData()) { - SetQueue.IMP.addTask(this.world, x, y, z, new Runnable() { + queue.addTask(x >> 4, z >> 4, new Runnable() { @Override public void run() { try { @@ -153,7 +154,7 @@ public class FastWorldEditExtent extends AbstractDelegateExtent { }); return true; } - SetQueue.IMP.setBlock(this.world, x, y, z, id, FaweCache.hasData(id) ? (byte) block.getData() : 0); + queue.setBlock(x, y, z, id, FaweCache.hasData(id) ? (byte) block.getData() : 0); return true; } case 0: @@ -222,11 +223,11 @@ public class FastWorldEditExtent extends AbstractDelegateExtent { case 190: case 191: case 192: { - SetQueue.IMP.setBlock(this.world, x, y, z, id); + queue.setBlock(x, y, z, id, (byte) 0); return true; } default: { - SetQueue.IMP.setBlock(this.world, x, y, z, id, (byte) block.getData()); + queue.setBlock(x, y, z, id, (byte) block.getData()); return true; } } diff --git a/core/src/main/java/com/boydti/fawe/object/extent/ProcessedWEExtent.java b/core/src/main/java/com/boydti/fawe/object/extent/ProcessedWEExtent.java index 1f833e0b..7c3d0786 100644 --- a/core/src/main/java/com/boydti/fawe/object/extent/ProcessedWEExtent.java +++ b/core/src/main/java/com/boydti/fawe/object/extent/ProcessedWEExtent.java @@ -1,13 +1,11 @@ package com.boydti.fawe.object.extent; import com.boydti.fawe.FaweCache; -import java.util.HashSet; -import java.util.List; - import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.RegionWrapper; +import com.boydti.fawe.util.FaweQueue; import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.SetQueue; import com.boydti.fawe.util.TaskManager; @@ -26,8 +24,11 @@ import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.biome.BaseBiome; +import java.util.HashSet; +import java.util.List; public class ProcessedWEExtent extends AbstractDelegateExtent { + private final FaweQueue queue; private Extent parent; private boolean BSblocked = false; @@ -38,14 +39,13 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { private int max; private final FawePlayer user; - private final String world; private final HashSet mask; private final Thread thread; public ProcessedWEExtent(final World world, final Thread thread, final FawePlayer player, final HashSet mask, final int max) { super(world); this.user = player; - this.world = world.getName(); + this.queue = SetQueue.IMP.getQueue(world.getName()); this.max = max != -1 ? max : Integer.MAX_VALUE; this.mask = mask; this.thread = thread; @@ -67,7 +67,7 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { this.Ecount++; if (this.Ecount > Settings.MAX_ENTITIES) { this.Eblocked = true; - MainUtil.sendAdmin(BBC.WORLDEDIT_DANGEROUS_WORLDEDIT.format(this.world + ": " + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ(), this.user)); + MainUtil.sendAdmin(BBC.WORLDEDIT_DANGEROUS_WORLDEDIT.format(queue.world + ": " + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ(), this.user)); } if (WEManager.IMP.maskContains(this.mask, location.getBlockX(), location.getBlockZ())) { TaskManager.IMP.task(new Runnable() { @@ -82,7 +82,7 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { @Override public BaseBiome getBiome(final Vector2D position) { - if (!SetQueue.IMP.isChunkLoaded(this.world, position.getBlockX() >> 4, position.getBlockZ() >> 4)) { + if (!queue.isChunkLoaded(position.getBlockX() >> 4, position.getBlockZ() >> 4)) { return EditSession.nullBiome; } synchronized (this.thread) { @@ -98,7 +98,7 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { if ((this.lastBlock != null) && this.lastVector.equals(position.toBlockVector())) { return this.lastBlock; } - if (!SetQueue.IMP.isChunkLoaded(this.world, position.getBlockX() >> 4, position.getBlockZ() >> 4)) { + if (!queue.isChunkLoaded(position.getBlockX() >> 4, position.getBlockZ() >> 4)) { try { this.lastVector = position.toBlockVector(); return this.lastBlock = super.getBlock(position); @@ -177,7 +177,7 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { this.BScount++; if (this.BScount > Settings.MAX_BLOCKSTATES) { this.BSblocked = true; - MainUtil.sendAdmin(BBC.WORLDEDIT_DANGEROUS_WORLDEDIT.format(this.world + ": " + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ(), this.user)); + MainUtil.sendAdmin(BBC.WORLDEDIT_DANGEROUS_WORLDEDIT.format(queue.world + ": " + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ(), this.user)); } final int x = location.getBlockX(); final int z = location.getBlockZ(); @@ -190,7 +190,7 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { return false; } if (block.hasNbtData()) { - SetQueue.IMP.addTask(this.world, x, location.getBlockY(), z, new Runnable() { + queue.addTask(x >> 4, z >> 4, new Runnable() { @Override public void run() { try { @@ -202,7 +202,7 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { }); return true; } - SetQueue.IMP.setBlock(this.world, x, location.getBlockY(), z, id, FaweCache.hasData(id) ? (byte) block.getData() : 0); + queue.setBlock(x, location.getBlockY(), z, id, FaweCache.hasData(id) ? (byte) block.getData() : 0); return true; } return false; @@ -298,11 +298,11 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { case 190: case 191: case 192: { - SetQueue.IMP.setBlock(this.world, x, y, z, id); + queue.setBlock(x, y, z, id, (byte) 0); return true; } default: { - SetQueue.IMP.setBlock(this.world, x, y, z, id, (byte) block.getData()); + queue.setBlock(x, y, z, id, (byte) block.getData()); return true; } } @@ -315,7 +315,7 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { @Override public boolean setBiome(final Vector2D position, final BaseBiome biome) { if (WEManager.IMP.maskContains(this.mask, position.getBlockX(), position.getBlockZ())) { - SetQueue.IMP.setBiome(this.world, position.getBlockX(), position.getBlockZ(), biome); + queue.setBiome(position.getBlockX(), position.getBlockZ(), biome); } return false; } 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 78b6a65e..831c98c7 100644 --- a/core/src/main/java/com/boydti/fawe/util/FaweQueue.java +++ b/core/src/main/java/com/boydti/fawe/util/FaweQueue.java @@ -2,23 +2,28 @@ package com.boydti.fawe.util; import com.boydti.fawe.Fawe; import com.boydti.fawe.config.BBC; -import com.boydti.fawe.object.ChunkLoc; import com.boydti.fawe.object.FaweChunk; import com.sk89q.worldedit.world.biome.BaseBiome; public abstract class FaweQueue { - public abstract boolean setBlock(final String world, final int x, final int y, final int z, final short id, final byte data); + public final String world; - public abstract boolean setBiome(final String world, final int x, final int z, final BaseBiome biome); + public FaweQueue(String world) { + this.world = world; + } - public abstract FaweChunk getChunk(final ChunkLoc wrap); + 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); + + public abstract FaweChunk getChunk(int x, int z); public abstract void setChunk(final FaweChunk chunk); public abstract boolean fixLighting(final FaweChunk chunk, final boolean fixAll); - public abstract boolean isChunkLoaded(final String world, final int x, final int z); + public abstract boolean isChunkLoaded(final int x, final int z); /** * Gets the FaweChunk and sets the requested blocks @@ -31,7 +36,7 @@ public abstract class FaweQueue { // Set memory limited MemUtil.memoryLimitedTask(); // Clear block placement - SetQueue.IMP.queue.clear(); + clear(); Fawe.get().getWorldEdit().clearSessions(); // GC System.gc(); @@ -44,5 +49,7 @@ public abstract class FaweQueue { */ protected abstract void clear(); - public abstract void addTask(String world, int x, int y, int z, Runnable runnable); + public abstract void addTask(int x, int z, Runnable runnable); + + public abstract int getCombinedId4Data(int x, int y, int z); } 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 d8cd7baf..8c1c9509 100644 --- a/core/src/main/java/com/boydti/fawe/util/SetQueue.java +++ b/core/src/main/java/com/boydti/fawe/util/SetQueue.java @@ -1,11 +1,15 @@ package com.boydti.fawe.util; -import java.util.ArrayDeque; -import java.util.concurrent.atomic.AtomicInteger; - +import com.boydti.fawe.Fawe; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.FaweChunk; import com.sk89q.worldedit.world.biome.BaseBiome; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; public class SetQueue { @@ -14,7 +18,7 @@ public class SetQueue { */ public static final SetQueue IMP = new SetQueue(); - public FaweQueue queue; + public final Map queues; /** * Track the time in ticks @@ -35,6 +39,7 @@ public class SetQueue { public SetQueue() { + queues = new ConcurrentHashMap<>(); TaskManager.IMP.repeat(new Runnable() { @Override public void run() { @@ -42,7 +47,9 @@ public class SetQueue { final int mem = MemUtil.calculateMemory(); if (mem != Integer.MAX_VALUE) { if ((mem <= 1) && Settings.ENABLE_HARD_LIMIT) { - SetQueue.this.queue.saveMemory(); + for (FaweQueue queue : getQueues()) { + queue.saveMemory(); + } return; } if (SetQueue.this.forceChunkSet()) { @@ -60,7 +67,7 @@ public class SetQueue { if (SetQueue.this.isWaiting()) { return; } - final FaweChunk current = SetQueue.this.queue.next(); + final FaweChunk current = next(); if (current == null) { SetQueue.this.time_waiting.set(Math.max(SetQueue.this.time_waiting.get(), SetQueue.this.time_current.get() - 2)); SetQueue.this.tasks(); @@ -72,9 +79,42 @@ public class SetQueue { }, 1); } + public List getQueues() { + List list = new ArrayList<>(queues.size()); + try { + for (Map.Entry entry : queues.entrySet()) { + list.add(entry.getValue()); + } + } + catch (Exception e) { + e.printStackTrace(); + } + return list; + } + + public FaweQueue getQueue(String world) { + FaweQueue queue = queues.get(world); + if (queue != null) { + return queue; + } + queue = Fawe.imp().getNewQueue(world); + queues.put(world, queue); + return queue; + } + + public FaweChunk next() { + for (Map.Entry entry : queues.entrySet()) { + FaweQueue queue = entry.getValue(); + final FaweChunk set = queue.next(); + if (set != null ) { + return set; + } + } + return null; + } + public boolean forceChunkSet() { - final FaweChunk set = this.queue.next(); - return set != null; + return next() != null; } public boolean isWaiting() { @@ -125,9 +165,10 @@ public class SetQueue { * @param data * @return */ + @Deprecated public boolean setBlock(final String world, final int x, final int y, final int z, final short id, final byte data) { SetQueue.IMP.setWaiting(); - return this.queue.setBlock(world, x, y, z, id, data); + return getQueue(world).setBlock(x, y, z, id, data); } /** @@ -138,27 +179,28 @@ public class SetQueue { * @param id * @return */ + @Deprecated public boolean setBlock(final String world, final int x, final int y, final int z, final short id) { SetQueue.IMP.setWaiting(); - return this.queue.setBlock(world, x, y, z, id, (byte) 0); + return getQueue(world).setBlock(x, y, z, id, (byte) 0); } /** * @param world * @param x - * @param y * @param z - * @param id - * @param data + * @param biome * @return */ + @Deprecated public boolean setBiome(final String world, final int x, final int z, final BaseBiome biome) { SetQueue.IMP.setWaiting(); - return this.queue.setBiome(world, x, z, biome); + return getQueue(world).setBiome(x, z, biome); } + @Deprecated public boolean isChunkLoaded(final String world, final int x, final int z) { - return this.queue.isChunkLoaded(world, x, z); + return getQueue(world).isChunkLoaded(x, z); } /** @@ -170,7 +212,8 @@ public class SetQueue { * @param z * @param runnable */ + @Deprecated public void addTask(String world, int x, int y, int z, Runnable runnable) { - this.queue.addTask(world, x, y, z, runnable); + getQueue(world).addTask(x >> 4, z >> 4, runnable); } } diff --git a/core/src/main/java/com/sk89q/worldedit/EditSession.java b/core/src/main/java/com/sk89q/worldedit/EditSession.java index 54ad9906..8380d514 100644 --- a/core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -314,7 +314,6 @@ public class EditSession implements Extent { // Include history, masking and memory checking. Extent wrapped; extent = wrapped = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_CHANGE); - extent = this.reorderExtent = new MultiStageReorder(extent, false); extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_REORDER); extent = this.changeSetExtent = this.wrapper.getHistoryExtent(extent, this.changeSet, fp); final Player skp = (Player) actor; @@ -335,7 +334,7 @@ public class EditSession implements Extent { extent = this.wrapExtent(extent, eventBus, event, Stage.BEFORE_HISTORY); extent = new SafeExtentWrapper(fp, extent); this.bypassReorderHistory = wrapped; - this.bypassHistory = this.reorderExtent; + this.bypassHistory = wrapped; this.bypassNone = extent; return; } diff --git a/forge/.gradle/gradle.log b/forge/.gradle/gradle.log index 8620bf50..8fbb2e8b 100644 --- a/forge/.gradle/gradle.log +++ b/forge/.gradle/gradle.log @@ -9,62 +9,28 @@ ################################################# Version string 'unspecified' does not match SemVer specification You should try SemVer : http://semver.org/ -Cookie rejected [JSESSIONID="26E6D52C45F2EEB46889F1A779E2FC24", version:0, domain:maven.sk89q.com, path:/artifactory/, expiry:null] Illegal 'path' attribute "/artifactory/". Path of origin: "/repo/org/spongepowered/spongeapi/" -Download http://repo.spongepowered.org/maven/org/spongepowered/spongeapi/4.1.0-SNAPSHOT/spongeapi-4.1.0-20160402.223304-15.jar :core:compileJava -:bukkit:processResources :forge:deobfCompileDummyTask :forge:deobfProvidedDummyTask :forge:extractDependencyATs SKIPPED :forge:extractMcpData -:bukkit:processTestResources UP-TO-DATE -warning: [options] bootstrap class path not set in conjunction with -source 1.7 +:core:compileJava UP-TO-DATE +:core:processResources UP-TO-DATE +:core:classes UP-TO-DATE +:core:jar UP-TO-DATE :forge:extractMcpData SKIPPED :forge:extractMcpMappings SKIPPED :forge:genSrgs SKIPPED :forge:getVersionJson :forge:downloadServer SKIPPED -:forge:splitServerJarNote: Some input files use or override a deprecated API. -Note: Recompile with -Xlint:deprecation for details. -Note: Some input files use unchecked or unsafe operations. -Note: Recompile with -Xlint:unchecked for details. -1 warning - -:core:processResources UP-TO-DATE -:core:classes -:core:jar -:bukkit:compileJava -:core:assemble -:core:compileTestJava UP-TO-DATE -:core:processTestResources UP-TO-DATE -:core:testClasses UP-TO-DATE -:core:test UP-TO-DATE -:core:check UP-TO-DATE -:core:build -warning: [options] bootstrap class path not set in conjunction with -source 1.7 :forge:splitServerJar SKIPPED :forge:deobfMcMCP SKIPPED :forge:sourceApiJava UP-TO-DATE :forge:compileApiJava UP-TO-DATE :forge:processApiResources UP-TO-DATE :forge:apiClasses UP-TO-DATE -:forge:sourceMainJava -:forge:compileJavaNote: Some input files use or override a deprecated API. -Note: Recompile with -Xlint:deprecation for details. -Note: Some input files use unchecked or unsafe operations. -Note: Recompile with -Xlint:unchecked for details. -1 warning - -:bukkit:classes -:bukkit:jar SKIPPED -:bukkit:assemble UP-TO-DATE -:bukkit:compileTestJava UP-TO-DATE -:bukkit:testClasses UP-TO-DATE -:bukkit:test UP-TO-DATE -:bukkit:check UP-TO-DATE -:bukkit:shadowJar -:bukkit:build -C:\Users\Jesse\.gradle\caches\modules-2\files-2.1\com.sk89q.worldedit\worldedit-forge-mc1.8.9\6.1.1\dffd7e1882eba256eb2132fe315682c1d26522b1\worldedit-forge-mc1.8.9-6.1.1.jar(com/sk89q/worldedit/forge/ForgeWorldEdit.class): warning: Cannot find annotation method 'modid()' in type 'Mod': class file for net.minecraftforge.fml.common.Mod not found +:forge:sourceMainJava UP-TO-DATE +:forge:compileJavaC:\Users\Jesse\.gradle\caches\modules-2\files-2.1\com.sk89q.worldedit\worldedit-forge-mc1.8.9\6.1.1\dffd7e1882eba256eb2132fe315682c1d26522b1\worldedit-forge-mc1.8.9-6.1.1.jar(com/sk89q/worldedit/forge/ForgeWorldEdit.class): warning: Cannot find annotation method 'modid()' in type 'Mod': class file for net.minecraftforge.fml.common.Mod not found C:\Users\Jesse\.gradle\caches\modules-2\files-2.1\com.sk89q.worldedit\worldedit-forge-mc1.8.9\6.1.1\dffd7e1882eba256eb2132fe315682c1d26522b1\worldedit-forge-mc1.8.9-6.1.1.jar(com/sk89q/worldedit/forge/ForgeWorldEdit.class): warning: Cannot find annotation method 'name()' in type 'Mod' C:\Users\Jesse\.gradle\caches\modules-2\files-2.1\com.sk89q.worldedit\worldedit-forge-mc1.8.9\6.1.1\dffd7e1882eba256eb2132fe315682c1d26522b1\worldedit-forge-mc1.8.9-6.1.1.jar(com/sk89q/worldedit/forge/ForgeWorldEdit.class): warning: Cannot find annotation method 'version()' in type 'Mod' C:\Users\Jesse\.gradle\caches\modules-2\files-2.1\com.sk89q.worldedit\worldedit-forge-mc1.8.9\6.1.1\dffd7e1882eba256eb2132fe315682c1d26522b1\worldedit-forge-mc1.8.9-6.1.1.jar(com/sk89q/worldedit/forge/ForgeWorldEdit.class): warning: Cannot find annotation method 'acceptableRemoteVersions()' in type 'Mod' @@ -97,6 +63,7 @@ Note: Recompile with -Xlint:deprecation for details. Note: Some input files use unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 27 warnings + :forge:processResources UP-TO-DATE :forge:classes :forge:jar @@ -110,13 +77,12 @@ Note: Recompile with -Xlint:unchecked for details. :forge:reobfShadowJar :forge:extractRangemapReplacedMain C:\Users\Jesse\Desktop\OTHER\GitHub\FastAsyncWorldEdit\forge\build\sources\main\java -:forge:retromapReplacedMain -remapping source... -:forge:sourceJar +:forge:retromapReplacedMain UP-TO-DATE +:forge:sourceJar UP-TO-DATE :forge:assemble :forge:check UP-TO-DATE :forge:build BUILD SUCCESSFUL -Total time: 1 mins 21.422 secs +Total time: 36.184 secs diff --git a/forge/src/main/java/com/boydti/fawe/forge/FaweSponge.java b/forge/src/main/java/com/boydti/fawe/forge/FaweSponge.java index 84d49546..805f052c 100644 --- a/forge/src/main/java/com/boydti/fawe/forge/FaweSponge.java +++ b/forge/src/main/java/com/boydti/fawe/forge/FaweSponge.java @@ -112,8 +112,8 @@ public class FaweSponge implements IFawe { } @Override - public FaweQueue getQueue() { - return new SpongeQueue_1_8(); + public FaweQueue getNewQueue(String world) { + return new SpongeQueue_1_8(world); } @Override diff --git a/forge/src/main/java/com/boydti/fawe/forge/v0/SpongeQueue_0.java b/forge/src/main/java/com/boydti/fawe/forge/v0/SpongeQueue_0.java index 31cf4114..1271f9c5 100644 --- a/forge/src/main/java/com/boydti/fawe/forge/v0/SpongeQueue_0.java +++ b/forge/src/main/java/com/boydti/fawe/forge/v0/SpongeQueue_0.java @@ -1,6 +1,5 @@ package com.boydti.fawe.forge.v0; -import com.boydti.fawe.object.ChunkLoc; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.util.FaweQueue; import com.boydti.fawe.util.SetQueue; @@ -22,70 +21,70 @@ public abstract class SpongeQueue_0 extends FaweQueue { /** * Map of chunks in the queue */ - private final ConcurrentHashMap> blocks = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> blocks = new ConcurrentHashMap<>(); + + public SpongeQueue_0(String world) { + super(world); + } @Override - public boolean isChunkLoaded(String worldName, int x, int z) { - World world = Sponge.getServer().getWorld(worldName).get(); + public boolean isChunkLoaded(int x, int z) { + World world = Sponge.getServer().getWorld(this.world).get(); Chunk chunk = world.getChunk(x << 4, 0, z << 4).orElse(null); return chunk != null && chunk.isLoaded(); } @Override - public void addTask(String world, int x, int y, int z, Runnable runnable) { - final ChunkLoc wrap = new ChunkLoc(world, x >> 4, z >> 4); - FaweChunk result = this.blocks.get(wrap); + public void addTask(int x, int z, Runnable runnable) { + long pair = (long) (x) << 32 | (z) & 0xFFFFFFFFL; + FaweChunk result = this.blocks.get(pair); if (result == null) { - result = this.getChunk(wrap); + result = this.getChunk(x, z); result.addTask(runnable); - final FaweChunk previous = this.blocks.put(wrap, result); + final FaweChunk previous = this.blocks.put(pair, result); if (previous == null) { return; } - this.blocks.put(wrap, previous); + this.blocks.put(pair, previous); result = previous; } result.addTask(runnable); } @Override - public boolean setBlock(final String world, int x, final int y, int z, final short id, final byte data) { + public boolean setBlock(int x, final int y, int z, final short id, final byte data) { if ((y > 255) || (y < 0)) { return false; } - final ChunkLoc wrap = new ChunkLoc(world, x >> 4, z >> 4); - x = x & 15; - z = z & 15; - FaweChunk result = this.blocks.get(wrap); + long pair = (long) (x >> 4) << 32 | (z >> 4) & 0xFFFFFFFFL; + FaweChunk result = this.blocks.get(pair); if (result == null) { - result = this.getChunk(wrap); - result.setBlock(x, y, z, id, data); - final FaweChunk previous = this.blocks.put(wrap, result); + result = this.getChunk(x >> 4, z >> 4); + result.setBlock(x & 15, y, z & 15, id, data); + final FaweChunk previous = this.blocks.put(pair, result); if (previous == null) { return true; } - this.blocks.put(wrap, previous); + this.blocks.put(pair, previous); result = previous; } - result.setBlock(x, y, z, id, data); + result.setBlock(x & 15, y, z & 15, id, data); return true; } @Override - public boolean setBiome(final String world, int x, int z, final BaseBiome biome) { - final ChunkLoc wrap = new ChunkLoc(world, x >> 4, z >> 4); - x = x & 15; - z = z & 15; - FaweChunk result = this.blocks.get(wrap); + public boolean setBiome(int x, int z, final BaseBiome biome) { + long pair = (long) (x >> 4) << 32 | (z >> 4) & 0xFFFFFFFFL; + FaweChunk result = this.blocks.get(pair); if (result == null) { - result = this.getChunk(wrap); - final FaweChunk previous = this.blocks.put(wrap, result); + result = this.getChunk(x >> 4, z >> 4); + final FaweChunk previous = this.blocks.put(pair, result); if (previous != null) { - this.blocks.put(wrap, previous); + this.blocks.put(pair, previous); result = previous; } } - result.setBiome(x, z, biome); + result.setBiome(x & 15, z & 15, biome); return true; } @@ -95,7 +94,7 @@ public abstract class SpongeQueue_0 extends FaweQueue { if (this.blocks.size() == 0) { return null; } - final Iterator>> iter = this.blocks.entrySet().iterator(); + final Iterator>> iter = this.blocks.entrySet().iterator(); final FaweChunk toReturn = iter.next().getValue(); if (SetQueue.IMP.isWaiting()) { return null; @@ -133,7 +132,7 @@ public abstract class SpongeQueue_0 extends FaweQueue { @Override public void setChunk(final FaweChunk chunk) { - this.blocks.put(chunk.getChunkLoc(), (FaweChunk) chunk); + this.blocks.put(chunk.longHash(), (FaweChunk) chunk); } public abstract Collection> sendChunk(final Collection> fcs); @@ -141,7 +140,7 @@ public abstract class SpongeQueue_0 extends FaweQueue { public abstract boolean setComponents(final FaweChunk fc); @Override - public abstract FaweChunk getChunk(final ChunkLoc wrap); + public abstract FaweChunk getChunk(int x, int z); @Override public abstract boolean fixLighting(final FaweChunk fc, final boolean fixAll); diff --git a/forge/src/main/java/com/boydti/fawe/forge/v1_8/SpongeChunk_1_8.java b/forge/src/main/java/com/boydti/fawe/forge/v1_8/SpongeChunk_1_8.java index e09e5f13..47032911 100644 --- a/forge/src/main/java/com/boydti/fawe/forge/v1_8/SpongeChunk_1_8.java +++ b/forge/src/main/java/com/boydti/fawe/forge/v1_8/SpongeChunk_1_8.java @@ -1,8 +1,8 @@ package com.boydti.fawe.forge.v1_8; import com.boydti.fawe.FaweCache; -import com.boydti.fawe.object.ChunkLoc; import com.boydti.fawe.object.FaweChunk; +import com.boydti.fawe.util.FaweQueue; import com.sk89q.worldedit.world.biome.BaseBiome; import java.util.Arrays; import org.spongepowered.api.Sponge; @@ -17,23 +17,29 @@ public class SpongeChunk_1_8 extends FaweChunk { public int[][] biomes; public Chunk chunk; - public SpongeChunk_1_8(ChunkLoc chunk) { - super(chunk); + public SpongeChunk_1_8(FaweQueue parent, int x, int z) { + super(parent, x, z); this.ids = new char[16][]; this.count = new short[16]; this.air = new short[16]; this.relight = new short[16]; } + @Override public Chunk getChunk() { if (this.chunk == null) { - ChunkLoc cl = getChunkLoc(); - this.chunk = Sponge.getServer().getWorld(cl.world).get().getChunk(cl.x, 0, cl.z).get(); + this.chunk = Sponge.getServer().getWorld(getParent().world).get().getChunk(getX(), 0, getZ()).get(); } return this.chunk; } + @Override + public void setLoc(final FaweQueue parent, int x, int z) { + super.setLoc(parent, x, z); + this.chunk = null; + } + /** * Get the number of block changes in a specified section. * @param i @@ -211,7 +217,7 @@ public class SpongeChunk_1_8 extends FaweChunk { @Override public FaweChunk clone() { - SpongeChunk_1_8 toReturn = new SpongeChunk_1_8(getChunkLoc()); + SpongeChunk_1_8 toReturn = new SpongeChunk_1_8(getParent(), getX(), getZ()); toReturn.air = this.air.clone(); toReturn.count = this.count.clone(); toReturn.relight = this.relight.clone(); diff --git a/forge/src/main/java/com/boydti/fawe/forge/v1_8/SpongeQueue_1_8.java b/forge/src/main/java/com/boydti/fawe/forge/v1_8/SpongeQueue_1_8.java index c6b85d73..577baa28 100644 --- a/forge/src/main/java/com/boydti/fawe/forge/v1_8/SpongeQueue_1_8.java +++ b/forge/src/main/java/com/boydti/fawe/forge/v1_8/SpongeQueue_1_8.java @@ -4,7 +4,6 @@ import com.boydti.fawe.FaweCache; import com.boydti.fawe.config.Settings; import com.boydti.fawe.forge.SpongeUtil; import com.boydti.fawe.forge.v0.SpongeQueue_0; -import com.boydti.fawe.object.ChunkLoc; import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.PseudoRandom; import com.boydti.fawe.util.TaskManager; @@ -31,6 +30,12 @@ import org.spongepowered.api.world.World; public class SpongeQueue_1_8 extends SpongeQueue_0 { + public World spongeWorld; + + public SpongeQueue_1_8(String world) { + super(world); + } + @Override public Collection> sendChunk(Collection> fcs) { if (fcs.isEmpty()) { @@ -75,12 +80,41 @@ public class SpongeQueue_1_8 extends SpongeQueue_0 { } } + private int lcx = Integer.MIN_VALUE; + private int lcz = Integer.MIN_VALUE; + private int lcy = Integer.MIN_VALUE; + private net.minecraft.world.chunk.Chunk lc; + private char[] ls; + + @Override + public int getCombinedId4Data(int x, int y, int z) { + int cx = x >> 4; + int cz = z >> 4; + int cy = y >> 4; + if (cx != lcx || cz != lcz) { + if (spongeWorld == null) { + spongeWorld = Sponge.getServer().getWorld(world).get(); + } + lcx = cx; + lcz = cz; + lc = (net.minecraft.world.chunk.Chunk) spongeWorld.getChunk(cx, 0, cz).get(); + } else if (cy == lcy) { + return ls != null ? ls[FaweCache.CACHE_J[y][x & 15][z & 15]] : 0; + } + ExtendedBlockStorage storage = lc.getBlockStorageArray()[cy]; + if (storage == null) { + ls = null; + return 0; + } + ls = storage.getData(); + return ls[FaweCache.CACHE_J[y][x & 15][z & 15]]; + } + @Override public boolean setComponents(FaweChunk fc) { SpongeChunk_1_8 fs = (SpongeChunk_1_8) fc; Chunk spongeChunk = fc.getChunk(); net.minecraft.world.World nmsWorld = (net.minecraft.world.World) spongeChunk.getWorld(); - ChunkLoc wrapper = fc.getChunkLoc(); try { boolean flag = !nmsWorld.provider.getHasNoSky(); // Sections @@ -181,11 +215,12 @@ public class SpongeQueue_1_8 extends SpongeQueue_0 { /** * This should be overridden by any specialized queues. - * @param wrap + * @param x + * @param z */ @Override - public SpongeChunk_1_8 getChunk(ChunkLoc wrap) { - return new SpongeChunk_1_8(wrap); + public SpongeChunk_1_8 getChunk(int x, int z) { + return new SpongeChunk_1_8(this, x, z); } @Override @@ -208,10 +243,9 @@ public class SpongeQueue_1_8 extends SpongeQueue_0 { } ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray(); net.minecraft.world.World nmsWorld = nmsChunk.getWorld(); - ChunkLoc loc = pc.getChunkLoc(); - int X = loc.x << 4; - int Z = loc.z << 4; + int X = pc.getX() << 4; + int Z = pc.getZ() << 4; for (int j = 0; j < sections.length; j++) {