mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2025-06-25 02:04:44 +02:00
Fix schematic pasting to paste tile entities and blocks with BlockData (e.g. stairs) properly
This commit is contained in:
@ -50,9 +50,9 @@ public class Load extends SubCommand {
|
||||
MainUtil.sendMessage(player, C.LOAD_NULL);
|
||||
return false;
|
||||
}
|
||||
String schematic;
|
||||
String schem;
|
||||
try {
|
||||
schematic = schematics.get(Integer.parseInt(args[0]) - 1);
|
||||
schem = schematics.get(Integer.parseInt(args[0]) - 1);
|
||||
} catch (Exception ignored) {
|
||||
// use /plot load <index>
|
||||
MainUtil
|
||||
@ -61,7 +61,7 @@ public class Load extends SubCommand {
|
||||
}
|
||||
final URL url;
|
||||
try {
|
||||
url = new URL(Settings.Web.URL + "saves/" + player.getUUID() + '/' + schematic);
|
||||
url = new URL(Settings.Web.URL + "saves/" + player.getUUID() + '/' + schem);
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
MainUtil.sendMessage(player, C.LOAD_FAILED);
|
||||
@ -69,29 +69,27 @@ public class Load extends SubCommand {
|
||||
}
|
||||
plot.addRunning();
|
||||
MainUtil.sendMessage(player, C.GENERATING_COMPONENT);
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
Schematic schematic = SchematicHandler.manager.getSchematic(url);
|
||||
if (schematic == null) {
|
||||
plot.removeRunning();
|
||||
sendMessage(player, C.SCHEMATIC_INVALID,
|
||||
"non-existent or not in gzip format");
|
||||
return;
|
||||
}
|
||||
PlotArea area = plot.getArea();
|
||||
SchematicHandler.manager
|
||||
.paste(schematic, plot, 0, area.MIN_BUILD_HEIGHT, 0, false,
|
||||
new RunnableVal<Boolean>() {
|
||||
@Override public void run(Boolean value) {
|
||||
plot.removeRunning();
|
||||
if (value) {
|
||||
sendMessage(player, C.SCHEMATIC_PASTE_SUCCESS);
|
||||
} else {
|
||||
sendMessage(player, C.SCHEMATIC_PASTE_FAILED);
|
||||
}
|
||||
}
|
||||
});
|
||||
TaskManager.runTaskAsync(() -> {
|
||||
Schematic schematic = SchematicHandler.manager.getSchematic(url);
|
||||
if (schematic == null) {
|
||||
plot.removeRunning();
|
||||
sendMessage(player, C.SCHEMATIC_INVALID,
|
||||
"non-existent or not in gzip format");
|
||||
return;
|
||||
}
|
||||
PlotArea area = plot.getArea();
|
||||
SchematicHandler.manager
|
||||
.paste(schematic, plot, 0, area.MIN_BUILD_HEIGHT, 0, false,
|
||||
new RunnableVal<Boolean>() {
|
||||
@Override public void run(Boolean value) {
|
||||
plot.removeRunning();
|
||||
if (value) {
|
||||
sendMessage(player, C.SCHEMATIC_PASTE_SUCCESS);
|
||||
} else {
|
||||
sendMessage(player, C.SCHEMATIC_PASTE_FAILED);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
@ -55,47 +55,45 @@ public class SchematicCmd extends SubCommand {
|
||||
}
|
||||
final String location = args[1];
|
||||
this.running = true;
|
||||
TaskManager.runTaskAsync(new Runnable() {
|
||||
@Override public void run() {
|
||||
Schematic schematic = null;
|
||||
if (location.startsWith("url:")) {
|
||||
try {
|
||||
UUID uuid = UUID.fromString(location.substring(4));
|
||||
URL base = new URL(Settings.Web.URL);
|
||||
URL url = new URL(base, "uploads/" + uuid + ".schematic");
|
||||
schematic = SchematicHandler.manager.getSchematic(url);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
sendMessage(player, C.SCHEMATIC_INVALID,
|
||||
"non-existent url: " + location);
|
||||
SchematicCmd.this.running = false;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
schematic = SchematicHandler.manager.getSchematic(location);
|
||||
} catch (SchematicHandler.UnsupportedFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (schematic == null) {
|
||||
SchematicCmd.this.running = false;
|
||||
TaskManager.runTaskAsync(() -> {
|
||||
Schematic schematic = null;
|
||||
if (location.startsWith("url:")) {
|
||||
try {
|
||||
UUID uuid = UUID.fromString(location.substring(4));
|
||||
URL base = new URL(Settings.Web.URL);
|
||||
URL url = new URL(base, "uploads/" + uuid + ".schematic");
|
||||
schematic = SchematicHandler.manager.getSchematic(url);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
sendMessage(player, C.SCHEMATIC_INVALID,
|
||||
"non-existent or not in gzip format");
|
||||
"non-existent url: " + location);
|
||||
SchematicCmd.this.running = false;
|
||||
return;
|
||||
}
|
||||
SchematicHandler.manager
|
||||
.paste(schematic, plot, 0, 1, 0, false, new RunnableVal<Boolean>() {
|
||||
@Override public void run(Boolean value) {
|
||||
SchematicCmd.this.running = false;
|
||||
if (value) {
|
||||
sendMessage(player, C.SCHEMATIC_PASTE_SUCCESS);
|
||||
} else {
|
||||
sendMessage(player, C.SCHEMATIC_PASTE_FAILED);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
schematic = SchematicHandler.manager.getSchematic(location);
|
||||
} catch (SchematicHandler.UnsupportedFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (schematic == null) {
|
||||
SchematicCmd.this.running = false;
|
||||
sendMessage(player, C.SCHEMATIC_INVALID,
|
||||
"non-existent or not in gzip format");
|
||||
return;
|
||||
}
|
||||
SchematicHandler.manager
|
||||
.paste(schematic, plot, 0, 1, 0, false, new RunnableVal<Boolean>() {
|
||||
@Override public void run(Boolean value) {
|
||||
SchematicCmd.this.running = false;
|
||||
if (value) {
|
||||
sendMessage(player, C.SCHEMATIC_PASTE_SUCCESS);
|
||||
} else {
|
||||
sendMessage(player, C.SCHEMATIC_PASTE_FAILED);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -153,12 +151,8 @@ public class SchematicCmd extends SubCommand {
|
||||
.sendMessage(player, "&cInvalid world. Use &7/plot sch exportall <area>");
|
||||
return false;
|
||||
}
|
||||
boolean result =
|
||||
SchematicHandler.manager.exportAll(plots, null, null, new Runnable() {
|
||||
@Override public void run() {
|
||||
MainUtil.sendMessage(player, "&aFinished mass export");
|
||||
}
|
||||
});
|
||||
boolean result = SchematicHandler.manager.exportAll(plots, null, null,
|
||||
() -> MainUtil.sendMessage(player, "&aFinished mass export"));
|
||||
if (!result) {
|
||||
MainUtil.sendMessage(player, "&cTask is already running.");
|
||||
return false;
|
||||
@ -197,13 +191,10 @@ public class SchematicCmd extends SubCommand {
|
||||
location.getWorld();
|
||||
Collection<Plot> plots = new ArrayList<>();
|
||||
plots.add(plot);
|
||||
boolean result =
|
||||
SchematicHandler.manager.exportAll(plots, null, null, new Runnable() {
|
||||
@Override public void run() {
|
||||
MainUtil.sendMessage(player, "&aFinished export");
|
||||
SchematicCmd.this.running = false;
|
||||
}
|
||||
});
|
||||
boolean result = SchematicHandler.manager.exportAll(plots, null, null, () -> {
|
||||
MainUtil.sendMessage(player, "&aFinished export");
|
||||
SchematicCmd.this.running = false;
|
||||
});
|
||||
if (!result) {
|
||||
MainUtil.sendMessage(player, "&cTask is already running.");
|
||||
return false;
|
||||
|
@ -180,19 +180,10 @@ public abstract class SchematicHandler {
|
||||
final int bcz = p1z >> 4;
|
||||
final int tcx = p2x >> 4;
|
||||
final int tcz = p2z >> 4;
|
||||
/* final ArrayList<ChunkLoc> 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<int[]>() {
|
||||
@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;
|
||||
@ -218,47 +209,24 @@ public abstract class SchematicHandler {
|
||||
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;
|
||||
int xx = p1x + xOffset + rx;
|
||||
int zz = p1z + zOffset + rz;
|
||||
BaseBlock id = blockArrayClipboard
|
||||
.getFullBlock(BlockVector3.at(rx, ry, rz));
|
||||
queue.setBlock(xx, yy, zz, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
queue.enqueue();
|
||||
/* }
|
||||
if (!chunks.isEmpty()) {
|
||||
this.run();
|
||||
} else {
|
||||
queue.flush();
|
||||
HashMap<BlockLoc, CompoundTag> tiles = schematic.getClipboard().getTiles();
|
||||
if (!tiles.isEmpty()) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override public void run(Object value) {
|
||||
for (Map.Entry<BlockLoc, CompoundTag> 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();
|
||||
}
|
||||
}, () -> {
|
||||
if (whenDone != null) {
|
||||
whenDone.value = true;
|
||||
whenDone.run();
|
||||
}
|
||||
}, 10);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
TaskManager.runTask(whenDone);
|
||||
|
@ -6,7 +6,7 @@ import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.MathMan;
|
||||
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import lombok.NonNull;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
@ -14,12 +14,13 @@ import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
|
||||
|
||||
private final String world;
|
||||
private final ConcurrentHashMap<Long, LocalChunk> blocks = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<Long, LocalChunk> blockChunks = new ConcurrentHashMap<>();
|
||||
private final ConcurrentLinkedDeque<LocalChunk> chunks = new ConcurrentLinkedDeque<>();
|
||||
private long modified;
|
||||
private LocalChunk lastWrappedChunk;
|
||||
private int lastX = Integer.MIN_VALUE;
|
||||
private int lastZ = Integer.MIN_VALUE;
|
||||
@Getter private boolean baseBlocks = false;
|
||||
|
||||
public BasicLocalBlockQueue(String world) {
|
||||
super(world);
|
||||
@ -41,13 +42,13 @@ public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
|
||||
lastX = Integer.MIN_VALUE;
|
||||
lastZ = Integer.MIN_VALUE;
|
||||
try {
|
||||
if (this.blocks.size() == 0) {
|
||||
if (this.blockChunks.size() == 0) {
|
||||
return false;
|
||||
}
|
||||
synchronized (blocks) {
|
||||
synchronized (blockChunks) {
|
||||
LocalChunk chunk = chunks.poll();
|
||||
if (chunk != null) {
|
||||
blocks.remove(chunk.longHash());
|
||||
blockChunks.remove(chunk.longHash());
|
||||
this.execute(chunk);
|
||||
return true;
|
||||
}
|
||||
@ -90,22 +91,23 @@ public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
|
||||
if ((y > 255) || (y < 0)) {
|
||||
return false;
|
||||
}
|
||||
baseBlocks = true;
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
if (cx != lastX || cz != lastZ) {
|
||||
lastX = cx;
|
||||
lastZ = cz;
|
||||
long pair = (long) (cx) << 32 | (cz) & 0xFFFFFFFFL;
|
||||
lastWrappedChunk = this.blocks.get(pair);
|
||||
lastWrappedChunk = this.blockChunks.get(pair);
|
||||
if (lastWrappedChunk == null) {
|
||||
lastWrappedChunk = this.getLocalChunk(x >> 4, z >> 4);
|
||||
lastWrappedChunk.setBlock(x & 15, y, z & 15, id);
|
||||
LocalChunk previous = this.blocks.put(pair, lastWrappedChunk);
|
||||
LocalChunk previous = this.blockChunks.put(pair, lastWrappedChunk);
|
||||
if (previous == null) {
|
||||
chunks.add(lastWrappedChunk);
|
||||
return true;
|
||||
}
|
||||
this.blocks.put(pair, previous);
|
||||
this.blockChunks.put(pair, previous);
|
||||
lastWrappedChunk = previous;
|
||||
}
|
||||
}
|
||||
@ -123,16 +125,16 @@ public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
|
||||
lastX = cx;
|
||||
lastZ = cz;
|
||||
long pair = (long) (cx) << 32 | (cz) & 0xFFFFFFFFL;
|
||||
lastWrappedChunk = this.blocks.get(pair);
|
||||
lastWrappedChunk = this.blockChunks.get(pair);
|
||||
if (lastWrappedChunk == null) {
|
||||
lastWrappedChunk = this.getLocalChunk(x >> 4, z >> 4);
|
||||
lastWrappedChunk.setBlock(x & 15, y, z & 15, id);
|
||||
LocalChunk previous = this.blocks.put(pair, lastWrappedChunk);
|
||||
LocalChunk previous = this.blockChunks.put(pair, lastWrappedChunk);
|
||||
if (previous == null) {
|
||||
chunks.add(lastWrappedChunk);
|
||||
return true;
|
||||
}
|
||||
this.blocks.put(pair, previous);
|
||||
this.blockChunks.put(pair, previous);
|
||||
lastWrappedChunk = previous;
|
||||
}
|
||||
}
|
||||
@ -142,12 +144,12 @@ public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
|
||||
|
||||
@Override public final boolean setBiome(int x, int z, String biome) {
|
||||
long pair = (long) (x >> 4) << 32 | (z >> 4) & 0xFFFFFFFFL;
|
||||
LocalChunk result = this.blocks.get(pair);
|
||||
LocalChunk result = this.blockChunks.get(pair);
|
||||
if (result == null) {
|
||||
result = this.getLocalChunk(x >> 4, z >> 4);
|
||||
LocalChunk previous = this.blocks.put(pair, result);
|
||||
LocalChunk previous = this.blockChunks.put(pair, result);
|
||||
if (previous != null) {
|
||||
this.blocks.put(pair, previous);
|
||||
this.blockChunks.put(pair, previous);
|
||||
result = previous;
|
||||
} else {
|
||||
chunks.add(result);
|
||||
@ -158,7 +160,7 @@ public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
|
||||
}
|
||||
|
||||
public final void setChunk(LocalChunk<T> chunk) {
|
||||
LocalChunk previous = this.blocks.put(chunk.longHash(), chunk);
|
||||
LocalChunk previous = this.blockChunks.put(chunk.longHash(), chunk);
|
||||
if (previous != null) {
|
||||
chunks.remove(previous);
|
||||
}
|
||||
@ -182,6 +184,7 @@ public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
|
||||
public final int x;
|
||||
|
||||
public T[] blocks;
|
||||
public BaseBlock[][] baseblocks;
|
||||
public String[][] biomes;
|
||||
|
||||
public LocalChunk(BasicLocalBlockQueue<T> parent, int x, int z) {
|
||||
@ -209,7 +212,7 @@ public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
|
||||
|
||||
public abstract void setBlock(final int x, final int y, final int z, final PlotBlock block);
|
||||
|
||||
public abstract void setBlock(final int x, final int y, final int z, final BaseBlock id);
|
||||
public abstract void setBlock(final int x, final int y, final int z, final BaseBlock block);
|
||||
|
||||
public void setBiome(int x, int z, String biome) {
|
||||
if (this.biomes == null) {
|
||||
@ -236,27 +239,13 @@ public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
|
||||
public BasicLocalChunk(BasicLocalBlockQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
blocks = new PlotBlock[16][];
|
||||
baseblocks = new BaseBlock[16][];
|
||||
}
|
||||
|
||||
@Override public void setBlock(int x, int y, int z, PlotBlock block) {
|
||||
this.setInternal(x, y, z, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(final int x, final int y, final int z, @NonNull final BaseBlock id) {
|
||||
this.setInternal(x, y, z, id);
|
||||
}
|
||||
|
||||
private void setInternal(final int x, final int y, final int z, final BaseBlock bsh) {
|
||||
final int i = MainUtil.CACHE_I[y][x][z];
|
||||
final int j = MainUtil.CACHE_J[y][x][z];
|
||||
PlotBlock[] array = blocks[i];
|
||||
if (array == null) {
|
||||
array = (blocks[i] = new PlotBlock[4096]);
|
||||
}
|
||||
array[j] = PlotBlock.get(bsh);
|
||||
}
|
||||
|
||||
private void setInternal(final int x, final int y, final int z, final PlotBlock plotBlock) {
|
||||
final int i = MainUtil.CACHE_I[y][x][z];
|
||||
final int j = MainUtil.CACHE_J[y][x][z];
|
||||
@ -267,6 +256,20 @@ public abstract class BasicLocalBlockQueue<T> extends LocalBlockQueue {
|
||||
array[j] = plotBlock;
|
||||
}
|
||||
|
||||
@Override public void setBlock(int x, int y, int z, BaseBlock block) {
|
||||
this.setInternal(x, y, z, block);
|
||||
}
|
||||
|
||||
private void setInternal(final int x, final int y, final int z, final BaseBlock baseBlock) {
|
||||
final int i = MainUtil.CACHE_I[y][x][z];
|
||||
final int j = MainUtil.CACHE_J[y][x][z];
|
||||
BaseBlock[] array = baseblocks[i];
|
||||
if (array == null) {
|
||||
array = (baseblocks[i] = new BaseBlock[4096]);
|
||||
}
|
||||
array[j] = baseBlock;
|
||||
}
|
||||
|
||||
public void setBlock(final int x, final int y, final int z, final int id, final int data) {
|
||||
final PlotBlock block = PlotBlock.get(id, data);
|
||||
this.setInternal(x, y, z, block);
|
||||
|
Reference in New Issue
Block a user