diff --git a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitSchematicHandler.java b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitSchematicHandler.java index acf18de85..5ae07bfba 100644 --- a/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitSchematicHandler.java +++ b/Bukkit/src/main/java/com/github/intellectualsites/plotsquared/bukkit/util/BukkitSchematicHandler.java @@ -1,7 +1,6 @@ package com.github.intellectualsites.plotsquared.bukkit.util; import com.github.intellectualsites.plotsquared.bukkit.object.schematic.StateWrapper; -import com.github.intellectualsites.plotsquared.plot.object.ChunkLoc; import com.github.intellectualsites.plotsquared.plot.object.Location; import com.github.intellectualsites.plotsquared.plot.object.RegionWrapper; import com.github.intellectualsites.plotsquared.plot.object.RunnableVal; @@ -13,12 +12,10 @@ import com.sk89q.jnbt.*; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.block.BaseBlock; -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.World; import java.io.ByteArrayOutputStream; import java.util.*; +import java.util.stream.IntStream; /** * Schematic Handler. @@ -39,9 +36,9 @@ public class BukkitSchematicHandler extends SchematicHandler { new CuboidRegion(BukkitUtil.IMP.getWeWorld(world), bot.getBlockVector3(), top.getBlockVector3()); - final int width = top.getX() - bot.getX() + 1; - int height = top.getY() - bot.getY() + 1; - final int length = top.getZ() - bot.getZ() + 1; + final int width = cuboidRegion.getWidth(); + int height = cuboidRegion.getHeight(); + final int length = cuboidRegion.getLength(); Map schematic = new HashMap<>(); schematic.put("Version", new IntTag(1)); @@ -89,109 +86,106 @@ public class BukkitSchematicHandler extends SchematicHandler { RegionWrapper region = queue.poll(); Location pos1 = new Location(world, region.minX, region.minY, region.minZ); Location pos2 = new Location(world, region.maxX, region.maxY, region.maxZ); - final int bx = bot.getX(); - final int bz = bot.getZ(); final int p1x = pos1.getX(); final int p1z = pos1.getZ(); final int p2x = pos2.getX(); final int p2z = pos2.getZ(); - final int bcx = p1x >> 4; - final int bcz = p1z >> 4; - final int tcx = p2x >> 4; - final int tcz = p2z >> 4; final int sy = pos1.getY(); final int ey = pos2.getY(); - // Generate list of chunks - final ArrayList chunks = new ArrayList<>(); - for (int x = bcx; x <= tcx; x++) { - for (int z = bcz; z <= tcz; z++) { - chunks.add(new ChunkLoc(x, z)); - } - } - final World worldObj = Bukkit.getWorld(world); - // Main thread + Iterator yiter = IntStream.range(sy, ey).iterator(); TaskManager.runTask(new Runnable() { @Override public void run() { - long start = System.currentTimeMillis(); - while (!chunks.isEmpty() - && System.currentTimeMillis() - start < 20) { - // save schematics - ChunkLoc chunk = chunks.remove(0); - Chunk bc = worldObj.getChunkAt(chunk.x, chunk.z); - if (!bc.load(false)) { - continue; - } - int X = chunk.x; - int Z = chunk.z; - int xxb = X << 4; - int zzb = Z << 4; - int xxt = xxb + 15; - int zzt = zzb + 15; + final Runnable yTask = this; + long ystart = System.currentTimeMillis(); + while (yiter.hasNext() + && System.currentTimeMillis() - ystart < 20) { + final int fy = yiter.next(); + Iterator ziter = IntStream.range(p1z, p2z).iterator(); + TaskManager.runTask(new Runnable() { + @Override public void run() { + final Runnable zTask = this; + long zstart = System.currentTimeMillis(); + Iterator xiter = + IntStream.range(p1x, p2x).iterator(); + while (ziter.hasNext() + && System.currentTimeMillis() - zstart < 20) { + final int fz = ziter.next(); + TaskManager.runTask(new Runnable() { + @Override public void run() { + long xstart = System.currentTimeMillis(); + while (xiter.hasNext() + && System.currentTimeMillis() - xstart + < 20) { + final int x = xiter.next(); + int rx = x - p1x; + int ry = fy - sy; + int rz = fz - p1z; + BlockVector3 point = + BlockVector3.at(x, fy, fz); + BaseBlock block = + cuboidRegion.getWorld() + .getFullBlock(point); + if (block.getNbtData() != null) { + Map values = + new HashMap<>(); + for (Map.Entry entry : block + .getNbtData().getValue() + .entrySet()) { + values.put(entry.getKey(), + entry.getValue()); + } + // Remove 'id' if it exists. We want 'Id' + values.remove("id"); - if (X == bcx) { - xxb = p1x; - } - if (X == tcx) { - xxt = p2x; - } - if (Z == bcz) { - zzb = p1z; - } - if (Z == tcz) { - zzt = p2z; - } - for (int y = sy; y <= Math.min(255, ey); y++) { - int ry = y - sy; - for (int z = zzb; z <= zzt; z++) { - int rz = z - bz; - for (int x = xxb; x <= xxt; x++) { - int rx = x - bx; - BlockVector3 point = BlockVector3.at(x, y, z); - BaseBlock block = - cuboidRegion.getWorld().getFullBlock(point); - if (block.getNbtData() != null) { - Map values = new HashMap<>(); - for (Map.Entry entry : block - .getNbtData().getValue().entrySet()) { - values - .put(entry.getKey(), entry.getValue()); + // Positions are kept in NBT, we don't want that. + values.remove("x"); + values.remove("y"); + values.remove("z"); + + values.put("Id", new StringTag( + block.getNbtId())); + values.put("Pos", new IntArrayTag( + new int[] {rx, ry, rz})); + + tileEntities + .add(new CompoundTag(values)); + } + String blockKey = + block.toImmutableState() + .getAsString(); + int blockId; + if (palette.containsKey(blockKey)) { + blockId = palette.get(blockKey); + } else { + blockId = palette.size(); + palette + .put(blockKey, palette.size()); + } + + while ((blockId & -128) != 0) { + buffer.write(blockId & 127 | 128); + blockId >>>= 7; + } + buffer.write(blockId); + } + if (xiter.hasNext()) { + TaskManager.runTaskLater(this, 1); + } else { + zTask.run(); + } } - // Remove 'id' if it exists. We want 'Id' - values.remove("id"); - - // Positions are kept in NBT, we don't want that. - values.remove("x"); - values.remove("y"); - values.remove("z"); - - values - .put("Id", new StringTag(block.getNbtId())); - values.put("Pos", - new IntArrayTag(new int[] {rx, ry, rz})); - - tileEntities.add(new CompoundTag(values)); - } - String blockKey = - block.toImmutableState().getAsString(); - int blockId; - if (palette.containsKey(blockKey)) { - blockId = palette.get(blockKey); - } else { - blockId = palette.size(); - palette.put(blockKey, palette.size()); - } - - while ((blockId & -128) != 0) { - buffer.write(blockId & 127 | 128); - blockId >>>= 7; - } - buffer.write(blockId); + }); + } + if (ziter.hasNext()) { + TaskManager.runTaskLater(zTask, 1); + } else { + yTask.run(); } } - } + }); } - if (!chunks.isEmpty()) { - TaskManager.runTaskLater(this, 1); + if (yiter.hasNext()) { + TaskManager.runTaskLater(yTask, 1); } else { regionTask.run(); } diff --git a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/SchematicHandler.java b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/SchematicHandler.java index c0081e14b..a49fb8ae7 100644 --- a/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/SchematicHandler.java +++ b/Core/src/main/java/com/github/intellectualsites/plotsquared/plot/util/SchematicHandler.java @@ -77,24 +77,17 @@ public abstract class SchematicHandler { if (value == null) { MainUtil.sendMessage(null, "&7 - Skipped plot &c" + plot.getId()); } else { - TaskManager.runTaskAsync(new Runnable() { - @Override public void run() { - MainUtil.sendMessage(null, "&6ID: " + plot.getId()); - boolean result = SchematicHandler.manager.save(value, - directory + File.separator + name + ".schematic"); - if (!result) { - MainUtil.sendMessage(null, - "&7 - Failed to save &c" + plot.getId()); - } else { - MainUtil - .sendMessage(null, "&7 - &a success: " + plot.getId()); - } - TaskManager.runTask(new Runnable() { - @Override public void run() { - THIS.run(); - } - }); + TaskManager.runTaskAsync(() -> { + MainUtil.sendMessage(null, "&6ID: " + plot.getId()); + boolean result = SchematicHandler.manager + .save(value, directory + File.separator + name + ".schematic"); + if (!result) { + MainUtil + .sendMessage(null, "&7 - Failed to save &c" + plot.getId()); + } else { + MainUtil.sendMessage(null, "&7 - &a success: " + plot.getId()); } + TaskManager.runTask(() -> THIS.run()); }); } } @@ -117,158 +110,156 @@ public abstract class SchematicHandler { final int yOffset, final int zOffset, final boolean autoHeight, final RunnableVal whenDone) { - TaskManager.runTask(new Runnable() { - @Override public void run() { - if (whenDone != null) { - whenDone.value = false; + TaskManager.runTask(() -> { + if (whenDone != null) { + whenDone.value = false; + } + if (schematic == null) { + PlotSquared.debug("Schematic == null :|"); + TaskManager.runTask(whenDone); + return; + } + try { + // Set flags + if (plot.hasOwner()) { + Map flags = schematic.getFlags(); + if (!flags.isEmpty()) { + for (Map.Entry entry : flags.entrySet()) { + plot.setFlag(Flags.getFlag(entry.getKey()), + StringTag.class.cast(entry.getValue()).getValue()); + } + + } } - if (schematic == null) { - PlotSquared.debug("Schematic == null :|"); + final LocalBlockQueue queue = plot.getArea().getQueue(false); + BlockVector3 dimension = schematic.getClipboard().getDimensions(); + final int WIDTH = dimension.getX(); + final int LENGTH = dimension.getZ(); + final int HEIGHT = dimension.getY(); + // Validate dimensions + RegionWrapper region = plot.getLargestRegion(); + if (((region.maxX - region.minX + xOffset + 1) < WIDTH) || ( + (region.maxZ - region.minZ + zOffset + 1) < LENGTH) || (HEIGHT > 256)) { + PlotSquared.debug("Schematic is too large"); + PlotSquared.debug( + "(" + WIDTH + ',' + LENGTH + ',' + HEIGHT + ") is bigger than (" + ( + region.maxX - region.minX) + ',' + (region.maxZ - region.minZ) + + ",256)"); TaskManager.runTask(whenDone); return; } - try { - // Set flags - if (plot.hasOwner()) { - Map flags = schematic.getFlags(); - if (!flags.isEmpty()) { - for (Map.Entry entry : flags.entrySet()) { - plot.setFlag(Flags.getFlag(entry.getKey()), - StringTag.class.cast(entry.getValue()).getValue()); - } - - } - } - final LocalBlockQueue queue = plot.getArea().getQueue(false); - BlockVector3 dimension = schematic.getClipboard().getDimensions(); - final int WIDTH = dimension.getX(); - final int LENGTH = dimension.getZ(); - final int HEIGHT = dimension.getY(); - // Validate dimensions - RegionWrapper region = plot.getLargestRegion(); - if (((region.maxX - region.minX + xOffset + 1) < WIDTH) || ( - (region.maxZ - region.minZ + zOffset + 1) < LENGTH) || (HEIGHT > 256)) { - PlotSquared.debug("Schematic is too large"); - PlotSquared.debug( - "(" + WIDTH + ',' + LENGTH + ',' + HEIGHT + ") is bigger than (" + ( - region.maxX - region.minX) + ',' + (region.maxZ - region.minZ) - + ",256)"); - TaskManager.runTask(whenDone); - return; - } - // block type and data arrays - final BlockArrayClipboard blockArrayClipboard = schematic.getClipboard(); - // Calculate the optimal height to paste the schematic at - final int y_offset_actual; - if (autoHeight) { - if (HEIGHT >= 256) { - y_offset_actual = yOffset; - } else { - PlotArea pw = plot.getArea(); - if (pw instanceof ClassicPlotWorld) { - y_offset_actual = yOffset + ((ClassicPlotWorld) pw).PLOT_HEIGHT; - } else { - y_offset_actual = yOffset + 1 + MainUtil - .getHeighestBlock(plot.getWorldName(), region.minX + 1, - region.minZ + 1); - } - } - } else { + // block type and data arrays + final BlockArrayClipboard blockArrayClipboard = schematic.getClipboard(); + // Calculate the optimal height to paste the schematic at + final int y_offset_actual; + if (autoHeight) { + if (HEIGHT >= 256) { y_offset_actual = yOffset; - } - Location pos1 = - new Location(plot.getWorldName(), region.minX + xOffset, y_offset_actual, - region.minZ + zOffset); - Location pos2 = pos1.clone().add(WIDTH - 1, HEIGHT - 1, LENGTH - 1); - final int p1x = pos1.getX(); - final int p1z = pos1.getZ(); - final int p2x = pos2.getX(); - final int p2z = pos2.getZ(); - final int bcx = p1x >> 4; - final int bcz = p1z >> 4; - final int tcx = p2x >> 4; - final int tcz = p2z >> 4; -/* final ArrayList chunks = new ArrayList<>(); - for (int x = bcx; x <= tcx; x++) { - for (int z = bcz; z <= tcz; z++) { - chunks.add(new ChunkLoc(x, z)); + } else { + PlotArea pw = plot.getArea(); + if (pw instanceof ClassicPlotWorld) { + y_offset_actual = yOffset + ((ClassicPlotWorld) pw).PLOT_HEIGHT; + } else { + y_offset_actual = yOffset + 1 + MainUtil + .getHeighestBlock(plot.getWorldName(), region.minX + 1, + region.minZ + 1); } - }*/ - ChunkManager.chunkTask(pos1, pos2, new RunnableVal() { - @Override public void run(int[] value) { - //int count = 0; - //while (!chunks.isEmpty() && count < 256) { - //count++; - ChunkLoc chunk = new ChunkLoc(value[0], value[1]); - PlotSquared.log(chunk.toString()); - int x = chunk.x; - int z = chunk.z; - int xxb = x << 4; - int zzb = z << 4; - int xxt = xxb + 15; - int zzt = zzb + 15; - if (x == bcx) { - xxb = p1x; - } - if (x == tcx) { - xxt = p2x; - } - if (z == bcz) { - zzb = p1z; - } - if (z == tcz) { - zzt = p2z; - } - // Paste schematic here - - for (int ry = 0; ry < Math.min(256, HEIGHT); ry++) { - int yy = y_offset_actual + ry; - if (yy > 255) { - continue; - } - int i1 = ry * WIDTH * LENGTH; - for (int rz = zzb - p1z; rz <= (zzt - p1z); rz++) { - int i2 = (rz * WIDTH) + i1; - for (int rx = xxb - p1x; rx <= (xxt - p1x); rx++) { - int i = i2 + rx; - int xx = p1x + rx; - int zz = p1z + rz; - BaseBlock id = blockArrayClipboard - .getFullBlock(BlockVector3.at(rx, ry, rz)); - queue.setBlock(xx, yy, zz, id); - } - } - } -/* } - if (!chunks.isEmpty()) { - this.run(); - } else { - queue.flush(); - HashMap tiles = schematic.getClipboard().getTiles(); - if (!tiles.isEmpty()) { - TaskManager.IMP.sync(new RunnableVal() { - @Override public void run(Object value) { - for (Map.Entry entry : schematic - .getTiles().entrySet()) { - BlockLoc loc = entry.getKey(); - restoreTile(queue, entry.getValue(), - p1x + xOffset + loc.x, loc.y + y_offset_actual, - p1z + zOffset + loc.z); - } - } - }); - } - }*/ - } - }, null, 10); - if (whenDone != null) { - whenDone.value = true; - whenDone.run(); } - } catch (Exception e) { - e.printStackTrace(); - TaskManager.runTask(whenDone); + } else { + y_offset_actual = yOffset; } + Location pos1 = + new Location(plot.getWorldName(), region.minX + xOffset, y_offset_actual, + region.minZ + zOffset); + Location pos2 = pos1.clone().add(WIDTH - 1, HEIGHT - 1, LENGTH - 1); + final int p1x = pos1.getX(); + final int p1z = pos1.getZ(); + final int p2x = pos2.getX(); + final int p2z = pos2.getZ(); + final int bcx = p1x >> 4; + final int bcz = p1z >> 4; + final int tcx = p2x >> 4; + final int tcz = p2z >> 4; +/* final ArrayList chunks = new ArrayList<>(); + for (int x = bcx; x <= tcx; x++) { + for (int z = bcz; z <= tcz; z++) { + chunks.add(new ChunkLoc(x, z)); + } + }*/ + ChunkManager.chunkTask(pos1, pos2, new RunnableVal() { + @Override public void run(int[] value) { + //int count = 0; + //while (!chunks.isEmpty() && count < 256) { + //count++; + ChunkLoc chunk = new ChunkLoc(value[0], value[1]); + PlotSquared.log(chunk.toString()); + int x = chunk.x; + int z = chunk.z; + int xxb = x << 4; + int zzb = z << 4; + int xxt = xxb + 15; + int zzt = zzb + 15; + if (x == bcx) { + xxb = p1x; + } + if (x == tcx) { + xxt = p2x; + } + if (z == bcz) { + zzb = p1z; + } + if (z == tcz) { + zzt = p2z; + } + // Paste schematic here + + for (int ry = 0; ry < Math.min(256, HEIGHT); ry++) { + int yy = y_offset_actual + ry; + if (yy > 255) { + continue; + } + int i1 = ry * WIDTH * LENGTH; + for (int rz = zzb - p1z; rz <= (zzt - p1z); rz++) { + int i2 = (rz * WIDTH) + i1; + for (int rx = xxb - p1x; rx <= (xxt - p1x); rx++) { + int i = i2 + rx; + int xx = p1x + rx; + int zz = p1z + rz; + BaseBlock id = blockArrayClipboard + .getFullBlock(BlockVector3.at(rx, ry, rz)); + queue.setBlock(xx, yy, zz, id); + } + } + } +/* } + if (!chunks.isEmpty()) { + this.run(); + } else { + queue.flush(); + HashMap tiles = schematic.getClipboard().getTiles(); + if (!tiles.isEmpty()) { + TaskManager.IMP.sync(new RunnableVal() { + @Override public void run(Object value) { + for (Map.Entry entry : schematic + .getTiles().entrySet()) { + BlockLoc loc = entry.getKey(); + restoreTile(queue, entry.getValue(), + p1x + xOffset + loc.x, loc.y + y_offset_actual, + p1z + zOffset + loc.z); + } + } + }); + } + }*/ + } + }, null, 10); + if (whenDone != null) { + whenDone.value = true; + whenDone.run(); + } + } catch (Exception e) { + e.printStackTrace(); + TaskManager.runTask(whenDone); } }); }