mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-22 13:16:45 +01:00
Merge branch 'v5' into features/v5/uuid
# Conflicts: # Bukkit/pom.xml # Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java
This commit is contained in:
commit
f82a111518
1
.gitignore
vendored
1
.gitignore
vendored
@ -142,3 +142,4 @@ p2error.txt
|
|||||||
*.bat
|
*.bat
|
||||||
Nukkit/build/resources/main/plugin.yml
|
Nukkit/build/resources/main/plugin.yml
|
||||||
docs/
|
docs/
|
||||||
|
build/
|
||||||
|
@ -31,6 +31,7 @@ import com.plotsquared.core.PlotSquared;
|
|||||||
import com.plotsquared.core.queue.BasicLocalBlockQueue;
|
import com.plotsquared.core.queue.BasicLocalBlockQueue;
|
||||||
import com.plotsquared.core.util.BlockUtil;
|
import com.plotsquared.core.util.BlockUtil;
|
||||||
import com.plotsquared.core.util.MainUtil;
|
import com.plotsquared.core.util.MainUtil;
|
||||||
|
import com.plotsquared.core.util.task.TaskManager;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.EditSession;
|
import com.sk89q.worldedit.EditSession;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
@ -50,7 +51,6 @@ import org.bukkit.block.Biome;
|
|||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.Container;
|
import org.bukkit.block.Container;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.inventory.BlockInventoryHolder;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@ -117,9 +117,6 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue {
|
|||||||
@Override public final void setComponents(LocalChunk lc)
|
@Override public final void setComponents(LocalChunk lc)
|
||||||
throws ExecutionException, InterruptedException {
|
throws ExecutionException, InterruptedException {
|
||||||
setBaseBlocks(lc);
|
setBaseBlocks(lc);
|
||||||
if (setBiome() && lc.biomes != null) {
|
|
||||||
setBiomes(lc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBaseBlocks(LocalChunk localChunk) {
|
public void setBaseBlocks(LocalChunk localChunk) {
|
||||||
@ -165,6 +162,22 @@ public class BukkitLocalQueue extends BasicLocalBlockQueue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (setBiome() && localChunk.biomes != null) {
|
||||||
|
for (int x = 0; x < localChunk.biomes.length; x++) {
|
||||||
|
BiomeType[] biomeZ = localChunk.biomes[x];
|
||||||
|
if (biomeZ != null) {
|
||||||
|
for (int z = 0; z < biomeZ.length; z++) {
|
||||||
|
if (biomeZ[z] != null) {
|
||||||
|
BiomeType biomeType = biomeZ[z];
|
||||||
|
|
||||||
|
Biome biome = BukkitAdapter.adapt(biomeType);
|
||||||
|
worldObj.setBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z,
|
||||||
|
biome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
if (isForceSync()) {
|
if (isForceSync()) {
|
||||||
chunkConsumer.accept(getChunk(worldObj, localChunk));
|
chunkConsumer.accept(getChunk(worldObj, localChunk));
|
||||||
|
@ -25,258 +25,15 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.bukkit.schematic;
|
package com.plotsquared.bukkit.schematic;
|
||||||
|
|
||||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
|
||||||
import com.plotsquared.core.location.Location;
|
|
||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.LocalBlockQueue;
|
||||||
import com.plotsquared.core.util.MainUtil;
|
|
||||||
import com.plotsquared.core.util.SchematicHandler;
|
import com.plotsquared.core.util.SchematicHandler;
|
||||||
import com.plotsquared.core.util.task.RunnableVal;
|
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
|
||||||
import com.sk89q.jnbt.ByteArrayTag;
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.jnbt.IntArrayTag;
|
|
||||||
import com.sk89q.jnbt.IntTag;
|
|
||||||
import com.sk89q.jnbt.ListTag;
|
|
||||||
import com.sk89q.jnbt.ShortTag;
|
|
||||||
import com.sk89q.jnbt.StringTag;
|
|
||||||
import com.sk89q.jnbt.Tag;
|
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
|
||||||
import com.sk89q.worldedit.extension.platform.Capability;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.util.ArrayDeque;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.IntStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schematic Handler.
|
* Schematic Handler.
|
||||||
*/
|
*/
|
||||||
public class BukkitSchematicHandler extends SchematicHandler {
|
public class BukkitSchematicHandler extends SchematicHandler {
|
||||||
|
|
||||||
@Override
|
|
||||||
public void getCompoundTag(final String world, final Set<CuboidRegion> regions,
|
|
||||||
final RunnableVal<CompoundTag> whenDone) {
|
|
||||||
// async
|
|
||||||
TaskManager.runTaskAsync(new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
// Main positions
|
|
||||||
Location[] corners = MainUtil.getCorners(world, regions);
|
|
||||||
final Location bot = corners[0];
|
|
||||||
final Location top = corners[1];
|
|
||||||
|
|
||||||
CuboidRegion cuboidRegion =
|
|
||||||
new CuboidRegion(BukkitUtil.IMP.getWeWorld(world), bot.getBlockVector3(),
|
|
||||||
top.getBlockVector3());
|
|
||||||
|
|
||||||
final int width = cuboidRegion.getWidth();
|
|
||||||
int height = cuboidRegion.getHeight();
|
|
||||||
final int length = cuboidRegion.getLength();
|
|
||||||
Map<String, Tag> schematic = new HashMap<>();
|
|
||||||
schematic.put("Version", new IntTag(2));
|
|
||||||
schematic.put("DataVersion", new IntTag(WorldEdit.getInstance().getPlatformManager()
|
|
||||||
.queryCapability(Capability.WORLD_EDITING).getDataVersion()));
|
|
||||||
|
|
||||||
Map<String, Tag> metadata = new HashMap<>();
|
|
||||||
metadata.put("WEOffsetX", new IntTag(0));
|
|
||||||
metadata.put("WEOffsetY", new IntTag(0));
|
|
||||||
metadata.put("WEOffsetZ", new IntTag(0));
|
|
||||||
|
|
||||||
schematic.put("Metadata", new CompoundTag(metadata));
|
|
||||||
|
|
||||||
schematic.put("Width", new ShortTag((short) width));
|
|
||||||
schematic.put("Height", new ShortTag((short) height));
|
|
||||||
schematic.put("Length", new ShortTag((short) length));
|
|
||||||
|
|
||||||
// The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
|
|
||||||
schematic.put("Offset", new IntArrayTag(new int[] {0, 0, 0,}));
|
|
||||||
|
|
||||||
Map<String, Integer> palette = new HashMap<>();
|
|
||||||
Map<String, Integer> biomePalette = new HashMap<>();
|
|
||||||
|
|
||||||
List<CompoundTag> tileEntities = new ArrayList<>();
|
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length);
|
|
||||||
ByteArrayOutputStream biomeBuffer = new ByteArrayOutputStream(width * length);
|
|
||||||
// Queue
|
|
||||||
final ArrayDeque<CuboidRegion> queue = new ArrayDeque<>(regions);
|
|
||||||
TaskManager.runTask(new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
if (queue.isEmpty()) {
|
|
||||||
TaskManager.runTaskAsync(() -> {
|
|
||||||
schematic.put("PaletteMax", new IntTag(palette.size()));
|
|
||||||
|
|
||||||
Map<String, Tag> paletteTag = new HashMap<>();
|
|
||||||
palette.forEach(
|
|
||||||
(key, value) -> paletteTag.put(key, new IntTag(value)));
|
|
||||||
|
|
||||||
schematic.put("Palette", new CompoundTag(paletteTag));
|
|
||||||
schematic.put("BlockData", new ByteArrayTag(buffer.toByteArray()));
|
|
||||||
schematic.put("TileEntities",
|
|
||||||
new ListTag(CompoundTag.class, tileEntities));
|
|
||||||
|
|
||||||
schematic.put("BiomePaletteMax", new IntTag(biomePalette.size()));
|
|
||||||
|
|
||||||
Map<String, Tag> biomePaletteTag = new HashMap<>();
|
|
||||||
biomePalette.forEach(
|
|
||||||
(key, value) -> biomePaletteTag.put(key, new IntTag(value)));
|
|
||||||
|
|
||||||
schematic.put("BiomePalette", new CompoundTag(biomePaletteTag));
|
|
||||||
schematic
|
|
||||||
.put("BiomeData", new ByteArrayTag(biomeBuffer.toByteArray()));
|
|
||||||
whenDone.value = new CompoundTag(schematic);
|
|
||||||
TaskManager.runTask(whenDone);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final Runnable regionTask = this;
|
|
||||||
CuboidRegion region = queue.poll();
|
|
||||||
Location pos1 = new Location(world, region.getMinimumPoint().getX(),
|
|
||||||
region.getMinimumPoint().getY(), region.getMinimumPoint().getZ());
|
|
||||||
Location pos2 = new Location(world, region.getMaximumPoint().getX(),
|
|
||||||
region.getMaximumPoint().getY(), region.getMaximumPoint().getZ());
|
|
||||||
final int p1x = pos1.getX();
|
|
||||||
final int sy = pos1.getY();
|
|
||||||
final int p1z = pos1.getZ();
|
|
||||||
final int p2x = pos2.getX();
|
|
||||||
final int p2z = pos2.getZ();
|
|
||||||
final int ey = pos2.getY();
|
|
||||||
Iterator<Integer> yiter = IntStream.range(sy, ey + 1).iterator();
|
|
||||||
final Runnable yTask = new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
long ystart = System.currentTimeMillis();
|
|
||||||
while (yiter.hasNext()
|
|
||||||
&& System.currentTimeMillis() - ystart < 20) {
|
|
||||||
final int y = yiter.next();
|
|
||||||
Iterator<Integer> ziter =
|
|
||||||
IntStream.range(p1z, p2z + 1).iterator();
|
|
||||||
final Runnable zTask = new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
long zstart = System.currentTimeMillis();
|
|
||||||
while (ziter.hasNext()
|
|
||||||
&& System.currentTimeMillis() - zstart < 20) {
|
|
||||||
final int z = ziter.next();
|
|
||||||
Iterator<Integer> xiter =
|
|
||||||
IntStream.range(p1x, p2x + 1).iterator();
|
|
||||||
final Runnable xTask = new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
long xstart = System.currentTimeMillis();
|
|
||||||
final int ry = y - sy;
|
|
||||||
final int rz = z - p1z;
|
|
||||||
while (xiter.hasNext()
|
|
||||||
&& System.currentTimeMillis() - xstart
|
|
||||||
< 20) {
|
|
||||||
final int x = xiter.next();
|
|
||||||
final int rx = x - p1x;
|
|
||||||
BlockVector3 point =
|
|
||||||
BlockVector3.at(x, y, z);
|
|
||||||
BaseBlock block =
|
|
||||||
cuboidRegion.getWorld()
|
|
||||||
.getFullBlock(point);
|
|
||||||
if (block.getNbtData() != null) {
|
|
||||||
Map<String, Tag> values =
|
|
||||||
new HashMap<>();
|
|
||||||
for (Map.Entry<String, Tag> entry : block
|
|
||||||
.getNbtData().getValue()
|
|
||||||
.entrySet()) {
|
|
||||||
values.put(entry.getKey(),
|
|
||||||
entry.getValue());
|
|
||||||
}
|
|
||||||
// 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 (ry == sy) {
|
|
||||||
BlockVector2 pt =
|
|
||||||
BlockVector2.at(x, z);
|
|
||||||
BiomeType biome =
|
|
||||||
cuboidRegion.getWorld()
|
|
||||||
.getBiome(pt);
|
|
||||||
String biomeStr = biome.getId();
|
|
||||||
int biomeId;
|
|
||||||
if (biomePalette
|
|
||||||
.containsKey(biomeStr)) {
|
|
||||||
biomeId =
|
|
||||||
biomePalette.get(biomeStr);
|
|
||||||
} else {
|
|
||||||
biomeId = biomePalette.size();
|
|
||||||
biomePalette
|
|
||||||
.put(biomeStr, biomeId);
|
|
||||||
}
|
|
||||||
while ((biomeId & -128) != 0) {
|
|
||||||
biomeBuffer
|
|
||||||
.write(biomeId & 127 | 128);
|
|
||||||
biomeId >>>= 7;
|
|
||||||
}
|
|
||||||
biomeBuffer.write(biomeId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (xiter.hasNext()) {
|
|
||||||
this.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xTask.run();
|
|
||||||
}
|
|
||||||
if (ziter.hasNext()) {
|
|
||||||
this.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
zTask.run();
|
|
||||||
}
|
|
||||||
if (yiter.hasNext()) {
|
|
||||||
TaskManager.runTaskLater(this, 1);
|
|
||||||
} else {
|
|
||||||
regionTask.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
yTask.run();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean restoreTile(LocalBlockQueue queue, CompoundTag ct, int x, int y, int z) {
|
public boolean restoreTile(LocalBlockQueue queue, CompoundTag ct, int x, int y, int z) {
|
||||||
return new StateWrapper(ct).restoreTag(queue.getWorld(), x, y, z);
|
return new StateWrapper(ct).restoreTag(queue.getWorld(), x, y, z);
|
||||||
|
@ -267,7 +267,7 @@ public class PlotSquared {
|
|||||||
// create setup util class
|
// create setup util class
|
||||||
SetupUtils.manager = this.IMP.initSetupUtils();
|
SetupUtils.manager = this.IMP.initSetupUtils();
|
||||||
// Set block
|
// Set block
|
||||||
GlobalBlockQueue.IMP = new GlobalBlockQueue(IMP.initBlockQueue(), 1);
|
GlobalBlockQueue.IMP = new GlobalBlockQueue(IMP.initBlockQueue(), 1, Settings.QUEUE.TARGET_TIME);
|
||||||
GlobalBlockQueue.IMP.runTask();
|
GlobalBlockQueue.IMP.runTask();
|
||||||
// Set chunk
|
// Set chunk
|
||||||
ChunkManager.manager = this.IMP.initChunkManager();
|
ChunkManager.manager = this.IMP.initChunkManager();
|
||||||
|
@ -499,6 +499,13 @@ public class Settings extends Config {
|
|||||||
public static boolean TILE_ENTITY_CHECK = true;
|
public static boolean TILE_ENTITY_CHECK = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Comment("Settings relating to PlotSquared's GlobalBlockQueue")
|
||||||
|
public static final class QUEUE {
|
||||||
|
@Comment({"Average time per tick spent completing chunk tasks in ms. Target average TPS = 20 * 50 / TARGET_TIME.",
|
||||||
|
"Waits (chunk task time / target_time) ticks before completely the next task."})
|
||||||
|
public static int TARGET_TIME = 65;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Comment({"Enable or disable parts of the plugin",
|
@Comment({"Enable or disable parts of the plugin",
|
||||||
"Note: A cache will use some memory if enabled"})
|
"Note: A cache will use some memory if enabled"})
|
||||||
|
@ -36,6 +36,7 @@ import com.plotsquared.core.queue.GlobalBlockQueue;
|
|||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.LocalBlockQueue;
|
||||||
import com.plotsquared.core.util.BlockUtil;
|
import com.plotsquared.core.util.BlockUtil;
|
||||||
import com.plotsquared.core.util.MathMan;
|
import com.plotsquared.core.util.MathMan;
|
||||||
|
import com.plotsquared.core.util.RegionManager;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
@ -92,76 +93,39 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
|
|
||||||
public boolean setFloor(PlotId plotId, Pattern blocks) {
|
public boolean setFloor(PlotId plotId, Pattern blocks) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
if (plot.isBasePlot()) {
|
if (plot.isBasePlot()) {
|
||||||
for (CuboidRegion region : plot.getRegions()) {
|
return RegionManager.manager.setCuboids(classicPlotWorld, plot.getRegions(), blocks,
|
||||||
Location pos1 =
|
classicPlotWorld.PLOT_HEIGHT, classicPlotWorld.PLOT_HEIGHT);
|
||||||
new Location(classicPlotWorld.getWorldName(), region.getMinimumPoint().getX(),
|
|
||||||
classicPlotWorld.PLOT_HEIGHT, region.getMinimumPoint().getZ());
|
|
||||||
Location pos2 =
|
|
||||||
new Location(classicPlotWorld.getWorldName(), region.getMaximumPoint().getX(),
|
|
||||||
classicPlotWorld.PLOT_HEIGHT, region.getMaximumPoint().getZ());
|
|
||||||
queue.setCuboid(pos1, pos2, blocks);
|
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
return queue.enqueue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setAll(PlotId plotId, Pattern blocks) {
|
public boolean setAll(PlotId plotId, Pattern blocks) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
if (!plot.isBasePlot()) {
|
if (plot.isBasePlot()) {
|
||||||
|
return RegionManager.manager
|
||||||
|
.setCuboids(classicPlotWorld, plot.getRegions(), blocks, 1, getWorldHeight());
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
int maxY = getWorldHeight();
|
|
||||||
for (CuboidRegion region : plot.getRegions()) {
|
|
||||||
Location pos1 =
|
|
||||||
new Location(classicPlotWorld.getWorldName(), region.getMinimumPoint().getX(), 1,
|
|
||||||
region.getMinimumPoint().getZ());
|
|
||||||
Location pos2 =
|
|
||||||
new Location(classicPlotWorld.getWorldName(), region.getMaximumPoint().getX(), maxY,
|
|
||||||
region.getMaximumPoint().getZ());
|
|
||||||
queue.setCuboid(pos1, pos2, blocks);
|
|
||||||
}
|
|
||||||
return queue.enqueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean setAir(PlotId plotId, Pattern blocks) {
|
public boolean setAir(PlotId plotId, Pattern blocks) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
if (!plot.isBasePlot()) {
|
if (plot.isBasePlot()) {
|
||||||
|
return RegionManager.manager.setCuboids(classicPlotWorld, plot.getRegions(), blocks,
|
||||||
|
classicPlotWorld.PLOT_HEIGHT + 1, getWorldHeight());
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
int maxY = getWorldHeight();
|
|
||||||
for (CuboidRegion region : plot.getRegions()) {
|
|
||||||
Location pos1 =
|
|
||||||
new Location(classicPlotWorld.getWorldName(), region.getMinimumPoint().getX(),
|
|
||||||
classicPlotWorld.PLOT_HEIGHT + 1, region.getMinimumPoint().getZ());
|
|
||||||
Location pos2 =
|
|
||||||
new Location(classicPlotWorld.getWorldName(), region.getMaximumPoint().getX(), maxY,
|
|
||||||
region.getMaximumPoint().getZ());
|
|
||||||
queue.setCuboid(pos1, pos2, blocks);
|
|
||||||
}
|
|
||||||
return queue.enqueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean setMain(PlotId plotId, Pattern blocks) {
|
public boolean setMain(PlotId plotId, Pattern blocks) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
if (!plot.isBasePlot()) {
|
if (plot.isBasePlot()) {
|
||||||
|
return RegionManager.manager.setCuboids(classicPlotWorld, plot.getRegions(), blocks, 1,
|
||||||
|
classicPlotWorld.PLOT_HEIGHT - 1);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
LocalBlockQueue queue = classicPlotWorld.getQueue(false);
|
|
||||||
for (CuboidRegion region : plot.getRegions()) {
|
|
||||||
Location pos1 =
|
|
||||||
new Location(classicPlotWorld.getWorldName(), region.getMinimumPoint().getX(), 1,
|
|
||||||
region.getMinimumPoint().getZ());
|
|
||||||
Location pos2 =
|
|
||||||
new Location(classicPlotWorld.getWorldName(), region.getMaximumPoint().getX(),
|
|
||||||
classicPlotWorld.PLOT_HEIGHT - 1, region.getMaximumPoint().getZ());
|
|
||||||
queue.setCuboid(pos1, pos2, blocks);
|
|
||||||
}
|
|
||||||
return queue.enqueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean setMiddle(PlotId plotId, Pattern blocks) {
|
public boolean setMiddle(PlotId plotId, Pattern blocks) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
|
@ -44,8 +44,8 @@ public class GlobalBlockQueue {
|
|||||||
private final ConcurrentLinkedDeque<LocalBlockQueue> inactiveQueues;
|
private final ConcurrentLinkedDeque<LocalBlockQueue> inactiveQueues;
|
||||||
private final ConcurrentLinkedDeque<Runnable> runnables;
|
private final ConcurrentLinkedDeque<Runnable> runnables;
|
||||||
private final AtomicBoolean running;
|
private final AtomicBoolean running;
|
||||||
|
private final int targetTime;
|
||||||
private QueueProvider provider;
|
private QueueProvider provider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to calculate elapsed time in milliseconds and ensure block placement doesn't lag the
|
* Used to calculate elapsed time in milliseconds and ensure block placement doesn't lag the
|
||||||
* server
|
* server
|
||||||
@ -53,6 +53,7 @@ public class GlobalBlockQueue {
|
|||||||
private long last;
|
private long last;
|
||||||
private long secondLast;
|
private long secondLast;
|
||||||
private long lastSuccess;
|
private long lastSuccess;
|
||||||
|
private double lastPeriod = 0;
|
||||||
private final RunnableVal2<Long, LocalBlockQueue> SET_TASK =
|
private final RunnableVal2<Long, LocalBlockQueue> SET_TASK =
|
||||||
new RunnableVal2<Long, LocalBlockQueue>() {
|
new RunnableVal2<Long, LocalBlockQueue>() {
|
||||||
@Override public void run(Long free, LocalBlockQueue queue) {
|
@Override public void run(Long free, LocalBlockQueue queue) {
|
||||||
@ -65,17 +66,19 @@ public class GlobalBlockQueue {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} while (((GlobalBlockQueue.this.secondLast = System.currentTimeMillis())
|
} while ((lastPeriod =
|
||||||
- GlobalBlockQueue.this.last) < free);
|
((GlobalBlockQueue.this.secondLast = System.currentTimeMillis())
|
||||||
|
- GlobalBlockQueue.this.last)) < free);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public GlobalBlockQueue(QueueProvider provider, int threads) {
|
public GlobalBlockQueue(QueueProvider provider, int threads, int targetTime) {
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
this.activeQueues = new ConcurrentLinkedDeque<>();
|
this.activeQueues = new ConcurrentLinkedDeque<>();
|
||||||
this.inactiveQueues = new ConcurrentLinkedDeque<>();
|
this.inactiveQueues = new ConcurrentLinkedDeque<>();
|
||||||
this.runnables = new ConcurrentLinkedDeque<>();
|
this.runnables = new ConcurrentLinkedDeque<>();
|
||||||
this.running = new AtomicBoolean();
|
this.running = new AtomicBoolean();
|
||||||
|
this.targetTime = targetTime;
|
||||||
this.PARALLEL_THREADS = threads;
|
this.PARALLEL_THREADS = threads;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,9 +115,15 @@ public class GlobalBlockQueue {
|
|||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
if (inactiveQueues.isEmpty() && activeQueues.isEmpty()) {
|
if (inactiveQueues.isEmpty() && activeQueues.isEmpty()) {
|
||||||
lastSuccess = System.currentTimeMillis();
|
lastSuccess = System.currentTimeMillis();
|
||||||
|
lastPeriod = 0;
|
||||||
GlobalBlockQueue.this.runEmptyTasks();
|
GlobalBlockQueue.this.runEmptyTasks();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Server laggy? Skip.
|
||||||
|
if (lastPeriod > targetTime) {
|
||||||
|
lastPeriod -= targetTime;
|
||||||
|
return;
|
||||||
|
}
|
||||||
SET_TASK.value1 = 50 + Math.min(
|
SET_TASK.value1 = 50 + Math.min(
|
||||||
(50 + GlobalBlockQueue.this.last) - (GlobalBlockQueue.this.last =
|
(50 + GlobalBlockQueue.this.last) - (GlobalBlockQueue.this.last =
|
||||||
System.currentTimeMillis()),
|
System.currentTimeMillis()),
|
||||||
|
@ -28,8 +28,11 @@ package com.plotsquared.core.util;
|
|||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
|
import com.plotsquared.core.queue.LocalBlockQueue;
|
||||||
import com.plotsquared.core.util.task.RunnableVal;
|
import com.plotsquared.core.util.task.RunnableVal;
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
import com.plotsquared.core.util.task.TaskManager;
|
||||||
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
@ -147,6 +150,19 @@ public abstract class RegionManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean setCuboids(final PlotArea area, final Set<CuboidRegion> regions,
|
||||||
|
final Pattern blocks, int minY, int maxY) {
|
||||||
|
LocalBlockQueue queue = area.getQueue(false);
|
||||||
|
for (CuboidRegion region : regions) {
|
||||||
|
Location pos1 = new Location(area.getWorldName(), region.getMinimumPoint().getX(), minY,
|
||||||
|
region.getMinimumPoint().getZ());
|
||||||
|
Location pos2 = new Location(area.getWorldName(), region.getMaximumPoint().getX(), maxY,
|
||||||
|
region.getMaximumPoint().getZ());
|
||||||
|
queue.setCuboid(pos1, pos2, blocks);
|
||||||
|
}
|
||||||
|
return queue.enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy a region to a new location (in the same world)
|
* Copy a region to a new location (in the same world)
|
||||||
*/
|
*/
|
||||||
|
@ -35,9 +35,18 @@ import com.plotsquared.core.plot.schematic.Schematic;
|
|||||||
import com.plotsquared.core.queue.LocalBlockQueue;
|
import com.plotsquared.core.queue.LocalBlockQueue;
|
||||||
import com.plotsquared.core.util.task.RunnableVal;
|
import com.plotsquared.core.util.task.RunnableVal;
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
import com.plotsquared.core.util.task.TaskManager;
|
||||||
|
import com.sk89q.jnbt.ByteArrayTag;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import com.sk89q.jnbt.IntArrayTag;
|
||||||
|
import com.sk89q.jnbt.IntTag;
|
||||||
|
import com.sk89q.jnbt.ListTag;
|
||||||
import com.sk89q.jnbt.NBTInputStream;
|
import com.sk89q.jnbt.NBTInputStream;
|
||||||
import com.sk89q.jnbt.NBTOutputStream;
|
import com.sk89q.jnbt.NBTOutputStream;
|
||||||
|
import com.sk89q.jnbt.ShortTag;
|
||||||
|
import com.sk89q.jnbt.StringTag;
|
||||||
|
import com.sk89q.jnbt.Tag;
|
||||||
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
|
||||||
@ -54,6 +63,7 @@ import org.json.JSONArray;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@ -66,15 +76,19 @@ import java.net.URL;
|
|||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.nio.channels.Channels;
|
import java.nio.channels.Channels;
|
||||||
import java.nio.channels.ReadableByteChannel;
|
import java.nio.channels.ReadableByteChannel;
|
||||||
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
@ -104,10 +118,6 @@ public abstract class SchematicHandler {
|
|||||||
final Plot plot = i.next();
|
final Plot plot = i.next();
|
||||||
i.remove();
|
i.remove();
|
||||||
|
|
||||||
PlotSquared.get().getImpromptuUUIDPipeline().getSingle(plot.getOwnerAbs(), (username, throwable) -> {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
final String owner;
|
final String owner;
|
||||||
if (plot.hasOwner()) {
|
if (plot.hasOwner()) {
|
||||||
owner = plot.getOwnerAbs().toString();
|
owner = plot.getOwnerAbs().toString();
|
||||||
@ -126,12 +136,14 @@ public abstract class SchematicHandler {
|
|||||||
.replaceAll("%idy%", plot.getId().y + "")
|
.replaceAll("%idy%", plot.getId().y + "")
|
||||||
.replaceAll("%world%", plot.getArea().toString());
|
.replaceAll("%world%", plot.getArea().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
final String directory;
|
final String directory;
|
||||||
if (outputDir == null) {
|
if (outputDir == null) {
|
||||||
directory = Settings.Paths.SCHEMATICS;
|
directory = Settings.Paths.SCHEMATICS;
|
||||||
} else {
|
} else {
|
||||||
directory = outputDir.getAbsolutePath();
|
directory = outputDir.getAbsolutePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
final Runnable THIS = this;
|
final Runnable THIS = this;
|
||||||
SchematicHandler.manager.getCompoundTag(plot, new RunnableVal<CompoundTag>() {
|
SchematicHandler.manager.getCompoundTag(plot, new RunnableVal<CompoundTag>() {
|
||||||
@Override public void run(final CompoundTag value) {
|
@Override public void run(final CompoundTag value) {
|
||||||
@ -471,8 +483,190 @@ public abstract class SchematicHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void getCompoundTag(String world, Set<CuboidRegion> regions,
|
public void getCompoundTag(final String world, final Set<CuboidRegion> regions,
|
||||||
RunnableVal<CompoundTag> whenDone);
|
final RunnableVal<CompoundTag> whenDone) {
|
||||||
|
// async
|
||||||
|
TaskManager.runTaskAsync(() -> {
|
||||||
|
// Main positions
|
||||||
|
Location[] corners = MainUtil.getCorners(world, regions);
|
||||||
|
final Location bot = corners[0];
|
||||||
|
final Location top = corners[1];
|
||||||
|
|
||||||
|
CuboidRegion cuboidRegion =
|
||||||
|
new CuboidRegion(WorldUtil.IMP.getWeWorld(world), bot.getBlockVector3(),
|
||||||
|
top.getBlockVector3());
|
||||||
|
|
||||||
|
final int width = cuboidRegion.getWidth();
|
||||||
|
int height = cuboidRegion.getHeight();
|
||||||
|
final int length = cuboidRegion.getLength();
|
||||||
|
Map<String, Tag> schematic = new HashMap<>();
|
||||||
|
schematic.put("Version", new IntTag(2));
|
||||||
|
schematic.put("DataVersion", new IntTag(WorldEdit.getInstance().getPlatformManager()
|
||||||
|
.queryCapability(Capability.WORLD_EDITING).getDataVersion()));
|
||||||
|
|
||||||
|
Map<String, Tag> metadata = new HashMap<>();
|
||||||
|
metadata.put("WEOffsetX", new IntTag(0));
|
||||||
|
metadata.put("WEOffsetY", new IntTag(0));
|
||||||
|
metadata.put("WEOffsetZ", new IntTag(0));
|
||||||
|
|
||||||
|
schematic.put("Metadata", new CompoundTag(metadata));
|
||||||
|
|
||||||
|
schematic.put("Width", new ShortTag((short) width));
|
||||||
|
schematic.put("Height", new ShortTag((short) height));
|
||||||
|
schematic.put("Length", new ShortTag((short) length));
|
||||||
|
|
||||||
|
// The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin'
|
||||||
|
schematic.put("Offset", new IntArrayTag(new int[] {0, 0, 0,}));
|
||||||
|
|
||||||
|
Map<String, Integer> palette = new HashMap<>();
|
||||||
|
Map<String, Integer> biomePalette = new HashMap<>();
|
||||||
|
|
||||||
|
List<CompoundTag> tileEntities = new ArrayList<>();
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length);
|
||||||
|
ByteArrayOutputStream biomeBuffer = new ByteArrayOutputStream(width * length);
|
||||||
|
// Queue
|
||||||
|
final ArrayDeque<CuboidRegion> queue = new ArrayDeque<>(regions);
|
||||||
|
TaskManager.runTask(new Runnable() {
|
||||||
|
@Override public void run() {
|
||||||
|
if (queue.isEmpty()) {
|
||||||
|
TaskManager.runTaskAsync(() -> {
|
||||||
|
schematic.put("PaletteMax", new IntTag(palette.size()));
|
||||||
|
|
||||||
|
Map<String, Tag> paletteTag = new HashMap<>();
|
||||||
|
palette.forEach((key, value) -> paletteTag.put(key, new IntTag(value)));
|
||||||
|
|
||||||
|
schematic.put("Palette", new CompoundTag(paletteTag));
|
||||||
|
schematic.put("BlockData", new ByteArrayTag(buffer.toByteArray()));
|
||||||
|
schematic
|
||||||
|
.put("TileEntities", new ListTag(CompoundTag.class, tileEntities));
|
||||||
|
|
||||||
|
schematic.put("BiomePaletteMax", new IntTag(biomePalette.size()));
|
||||||
|
|
||||||
|
Map<String, Tag> biomePaletteTag = new HashMap<>();
|
||||||
|
biomePalette.forEach(
|
||||||
|
(key, value) -> biomePaletteTag.put(key, new IntTag(value)));
|
||||||
|
|
||||||
|
schematic.put("BiomePalette", new CompoundTag(biomePaletteTag));
|
||||||
|
schematic.put("BiomeData", new ByteArrayTag(biomeBuffer.toByteArray()));
|
||||||
|
whenDone.value = new CompoundTag(schematic);
|
||||||
|
TaskManager.runTask(whenDone);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Runnable regionTask = this;
|
||||||
|
CuboidRegion region = queue.poll();
|
||||||
|
Location pos1 = new Location(world, region.getMinimumPoint().getX(),
|
||||||
|
region.getMinimumPoint().getY(), region.getMinimumPoint().getZ());
|
||||||
|
Location pos2 = new Location(world, region.getMaximumPoint().getX(),
|
||||||
|
region.getMaximumPoint().getY(), region.getMaximumPoint().getZ());
|
||||||
|
final int p1x = pos1.getX();
|
||||||
|
final int sy = pos1.getY();
|
||||||
|
final int p1z = pos1.getZ();
|
||||||
|
final int p2x = pos2.getX();
|
||||||
|
final int p2z = pos2.getZ();
|
||||||
|
final int ey = pos2.getY();
|
||||||
|
Iterator<Integer> yiter = IntStream.range(sy, ey + 1).iterator();
|
||||||
|
final Runnable yTask = () -> {
|
||||||
|
long ystart = System.currentTimeMillis();
|
||||||
|
while (yiter.hasNext() && System.currentTimeMillis() - ystart < 20) {
|
||||||
|
final int y = yiter.next();
|
||||||
|
Iterator<Integer> ziter = IntStream.range(p1z, p2z + 1).iterator();
|
||||||
|
final Runnable zTask = () -> {
|
||||||
|
long zstart = System.currentTimeMillis();
|
||||||
|
while (ziter.hasNext()
|
||||||
|
&& System.currentTimeMillis() - zstart < 20) {
|
||||||
|
final int z = ziter.next();
|
||||||
|
Iterator<Integer> xiter =
|
||||||
|
IntStream.range(p1x, p2x + 1).iterator();
|
||||||
|
final Runnable xTask = () -> {
|
||||||
|
long xstart = System.currentTimeMillis();
|
||||||
|
final int ry = y - sy;
|
||||||
|
final int rz = z - p1z;
|
||||||
|
while (xiter.hasNext()
|
||||||
|
&& System.currentTimeMillis() - xstart < 20) {
|
||||||
|
final int x = xiter.next();
|
||||||
|
final int rx = x - p1x;
|
||||||
|
BlockVector3 point = BlockVector3.at(x, y, z);
|
||||||
|
BaseBlock block =
|
||||||
|
cuboidRegion.getWorld().getFullBlock(point);
|
||||||
|
if (block.getNbtData() != null) {
|
||||||
|
Map<String, Tag> values = new HashMap<>();
|
||||||
|
for (Map.Entry<String, Tag> entry : block
|
||||||
|
.getNbtData().getValue().entrySet()) {
|
||||||
|
values.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
// 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 (ry > 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
BlockVector2 pt = BlockVector2.at(x, z);
|
||||||
|
BiomeType biome = cuboidRegion.getWorld().getBiome(pt);
|
||||||
|
String biomeStr = biome.getId();
|
||||||
|
int biomeId;
|
||||||
|
if (biomePalette.containsKey(biomeStr)) {
|
||||||
|
biomeId = biomePalette.get(biomeStr);
|
||||||
|
} else {
|
||||||
|
biomeId = biomePalette.size();
|
||||||
|
biomePalette.put(biomeStr, biomeId);
|
||||||
|
}
|
||||||
|
while ((biomeId & -128) != 0) {
|
||||||
|
biomeBuffer.write(biomeId & 127 | 128);
|
||||||
|
biomeId >>>= 7;
|
||||||
|
}
|
||||||
|
biomeBuffer.write(biomeId);
|
||||||
|
}
|
||||||
|
if (xiter.hasNext()) {
|
||||||
|
this.run();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xTask.run();
|
||||||
|
}
|
||||||
|
if (ziter.hasNext()) {
|
||||||
|
this.run();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
zTask.run();
|
||||||
|
}
|
||||||
|
if (yiter.hasNext()) {
|
||||||
|
TaskManager.runTaskLater(this, 1);
|
||||||
|
} else {
|
||||||
|
regionTask.run();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
yTask.run();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void getCompoundTag(final Plot plot, final RunnableVal<CompoundTag> whenDone) {
|
public void getCompoundTag(final Plot plot, final RunnableVal<CompoundTag> whenDone) {
|
||||||
getCompoundTag(plot.getWorldName(), plot.getRegions(), new RunnableVal<CompoundTag>() {
|
getCompoundTag(plot.getWorldName(), plot.getRegions(), new RunnableVal<CompoundTag>() {
|
||||||
@ -502,7 +696,6 @@ public abstract class SchematicHandler {
|
|||||||
public UnsupportedFormatException(String message, Throwable cause) {
|
public UnsupportedFormatException(String message, Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user