From e97c945b2fc6ac1f66df551737c863174041cc98 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 24 Sep 2021 12:22:01 +0100 Subject: [PATCH] Big fix to clipboards when relogging/restarting server etc. - Refactor the way FAWE clipboards work slightly with regards to offsets (FAWE-added) and origin (upstream-present) - Better error messages when exceptions are thrown attempting to load DOC - No longer attempt to resolve old clipboard versions. Attempt to give informative error instead - Don't always delete clipboards held in memory on player logout unless configured to do so - Go back to fully closing the DOC on logout. We now attempt to lock the file which will hopefully help with debugging shared clipboard folders --- .../com/fastasyncworldedit/core/Fawe.java | 1 + .../core/configuration/Settings.java | 5 + .../clipboard/CPUOptimizedClipboard.java | 2 +- .../clipboard/DiskOptimizedClipboard.java | 82 +++++++------- .../extent/clipboard/LinearClipboard.java | 4 +- .../clipboard/MemoryOptimizedClipboard.java | 2 +- .../extent/clipboard/SimpleClipboard.java | 17 +-- ...FaweClipboardVersionMismatchException.java | 11 ++ .../internal/exception/FaweException.java | 1 + .../com/sk89q/worldedit/entity/Player.java | 33 +++--- .../extent/clipboard/BlockArrayClipboard.java | 100 +++++++++--------- .../src/main/resources/lang/strings.json | 4 + 12 files changed, 146 insertions(+), 116 deletions(-) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/exception/FaweClipboardVersionMismatchException.java diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/Fawe.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/Fawe.java index bcbb912d0..01b602e24 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/Fawe.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/Fawe.java @@ -209,6 +209,7 @@ public class Fawe { case MAX_ENTITIES: case MAX_ITERATIONS: case OUTSIDE_REGION: + case CLIPBOARD: if (!faweExceptionReasonsUsed[type.ordinal()]) { faweExceptionReasonsUsed[type.ordinal()] = true; throw e; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Settings.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Settings.java index 4babe7423..9c2b18b61 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Settings.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Settings.java @@ -510,6 +510,11 @@ public class Settings extends Config { public int COMPRESSION_LEVEL = 1; @Comment("Number of days to keep history on disk before deleting it") public int DELETE_AFTER_DAYS = 1; + @Comment({ + "If a players clipboard should be removed from memory upon player logout,", + " - Will not delete clipboards on disk" + }) + public boolean DELETE_ON_LOGOUT = false; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/CPUOptimizedClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/CPUOptimizedClipboard.java index 95d52b2be..5049741c9 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/CPUOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/CPUOptimizedClipboard.java @@ -34,7 +34,7 @@ public class CPUOptimizedClipboard extends LinearClipboard { public CPUOptimizedClipboard(Region region) { - super(region.getDimensions()); + super(region.getDimensions(), region.getMinimumPoint()); this.states = new char[getVolume()]; nbtMapLoc = new HashMap<>(); nbtMapIndex = new HashMap<>(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java index 2c447aea0..cf35dc011 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java @@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.extent.clipboard; import com.fastasyncworldedit.core.Fawe; import com.fastasyncworldedit.core.configuration.Settings; +import com.fastasyncworldedit.core.internal.exception.FaweClipboardVersionMismatchException; import com.fastasyncworldedit.core.jnbt.streamer.IntValueReader; import com.fastasyncworldedit.core.math.IntTriple; import com.fastasyncworldedit.core.util.MainUtil; @@ -55,11 +56,10 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable private static final Logger LOGGER = LogManagerCompat.getLogger(); private static final int VERSION = 1; + private static final int HEADER_SIZE = 22; private final HashMap nbtMap; private final File file; - private final int version; - private final int HEADER_SIZE; private RandomAccessFile braf; private MappedByteBuffer byteBuffer; @@ -77,6 +77,7 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable ) ); setOffset(region.getMinimumPoint()); + setOrigin(region.getMinimumPoint()); } public DiskOptimizedClipboard(BlockVector3 dimensions) { @@ -90,8 +91,7 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable } public DiskOptimizedClipboard(BlockVector3 dimensions, File file) { - super(dimensions); - HEADER_SIZE = 20; + super(dimensions, BlockVector3.ZERO); if (HEADER_SIZE + ((long) getVolume() << 1) >= Integer.MAX_VALUE) { throw new IllegalArgumentException( "Dimensions too large for this clipboard format. Use //lazycopy for large selections."); @@ -119,29 +119,27 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable braf.setLength(fileLength); init(); // write getLength() etc - byteBuffer.putChar(0, (char) (version = VERSION)); - byteBuffer.putChar(2, (char) getWidth()); - byteBuffer.putChar(4, (char) getHeight()); - byteBuffer.putChar(6, (char) getLength()); + byteBuffer.putChar(2, (char) (VERSION)); + byteBuffer.putChar(4, (char) getWidth()); + byteBuffer.putChar(6, (char) getHeight()); + byteBuffer.putChar(8, (char) getLength()); } catch (IOException e) { - e.printStackTrace(); throw new RuntimeException(e); } } public DiskOptimizedClipboard(File file) { - super(readSize(file)); + super(readSize(file), BlockVector3.ZERO); nbtMap = new HashMap<>(); try { this.file = file; this.braf = new RandomAccessFile(file, "rw"); braf.setLength(file.length()); init(); - version = byteBuffer.getChar(0); - HEADER_SIZE = (version > 0 ? 20 : 14); if (braf.length() - HEADER_SIZE == ((long) getVolume() << 1) + (long) ((getHeight() >> 2) + 1) * ((getLength() >> 2) + 1) * ((getWidth() >> 2) + 1)) { hasBiomes = true; } + getOffset(); } catch (IOException e) { throw new RuntimeException(e); } @@ -149,16 +147,11 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable private static BlockVector3 readSize(File file) { try (DataInputStream is = new DataInputStream(new FileInputStream(file))) { + is.skipBytes(2); int version = is.readChar(); - int x; - if (version != 1) { - x = version; - } else { - x = is.readChar(); + if (version != VERSION) { + throw new FaweClipboardVersionMismatchException(); } -// if (version > VERSION) { -// throw new UnsupportedOperationException("Unsupported clipboard-on-disk version: " + version); -// } return BlockVector3.at(is.readChar(), is.readChar(), is.readChar()); } catch (IOException e) { e.printStackTrace(); @@ -178,6 +171,7 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable private void init() throws IOException { if (this.fileChannel == null) { this.fileChannel = braf.getChannel(); + this.fileChannel.lock(); this.byteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, file.length()); } } @@ -257,7 +251,6 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable } } } catch (IOException e) { - e.printStackTrace(); throw new RuntimeException(e); } } @@ -278,17 +271,12 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable BlockVector3.at(0, 0, 0), BlockVector3.at(getWidth() - 1, getHeight() - 1, getLength() - 1) ); - int originX = byteBuffer.getShort(8); - int originY = byteBuffer.getShort(10); - int originZ = byteBuffer.getShort(12); - if (version == 1) { - int offsetX = byteBuffer.getShort(14); - int offsetY = byteBuffer.getShort(16); - int offsetZ = byteBuffer.getShort(18); - region.shift(BlockVector3.at(offsetX, offsetY, offsetZ)); - } + int offsetX = byteBuffer.getShort(16); + int offsetY = byteBuffer.getShort(18); + int offsetZ = byteBuffer.getShort(20); + region.shift(BlockVector3.at(offsetX, offsetY, offsetZ)); BlockArrayClipboard clipboard = new BlockArrayClipboard(region, this); - clipboard.setOrigin(BlockVector3.at(originX, originY, originZ)); + clipboard.setOrigin(getOrigin()); return clipboard; } catch (Throwable e) { e.printStackTrace(); @@ -298,9 +286,9 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable @Override public BlockVector3 getOrigin() { - int ox = byteBuffer.getShort(8); - int oy = byteBuffer.getShort(10); - int oz = byteBuffer.getShort(12); + int ox = byteBuffer.getShort(10); + int oy = byteBuffer.getShort(12); + int oz = byteBuffer.getShort(14); return BlockVector3.at(ox, oy, oz); } @@ -308,27 +296,33 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable public void setOrigin(BlockVector3 offset) { super.setOrigin(offset); try { - byteBuffer.putShort(8, (short) offset.getBlockX()); - byteBuffer.putShort(10, (short) offset.getBlockY()); - byteBuffer.putShort(12, (short) offset.getBlockZ()); + byteBuffer.putShort(10, (short) offset.getBlockX()); + byteBuffer.putShort(12, (short) offset.getBlockY()); + byteBuffer.putShort(14, (short) offset.getBlockZ()); } catch (Throwable e) { e.printStackTrace(); } } - private void setOffset(BlockVector3 offset) { - if (version == 0) { - return; - } + @Override + protected void setOffset(BlockVector3 offset) { + super.setOffset(offset); try { - byteBuffer.putShort(14, (short) offset.getBlockX()); - byteBuffer.putShort(16, (short) offset.getBlockY()); - byteBuffer.putShort(18, (short) offset.getBlockZ()); + byteBuffer.putShort(16, (short) offset.getBlockX()); + byteBuffer.putShort(18, (short) offset.getBlockY()); + byteBuffer.putShort(20, (short) offset.getBlockZ()); } catch (Throwable e) { e.printStackTrace(); } } + private void getOffset() { + int x = byteBuffer.getShort(16); + int y = byteBuffer.getShort(18); + int z = byteBuffer.getShort(20); + super.setOffset(BlockVector3.at(x, y, z)); + } + @Override public void flush() { byteBuffer.force(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/LinearClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/LinearClipboard.java index 0ca503393..6b0614d7e 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/LinearClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/LinearClipboard.java @@ -25,8 +25,8 @@ public abstract class LinearClipboard extends SimpleClipboard { protected final HashSet entities = new HashSet<>(); - public LinearClipboard(BlockVector3 dimensions) { - super(dimensions); + public LinearClipboard(BlockVector3 dimensions, BlockVector3 offset) { + super(dimensions, offset); } // We shouldn't expose methods that directly reference the index as people cannot be trusted to use it properly. diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/MemoryOptimizedClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/MemoryOptimizedClipboard.java index 98163d6bf..8854027eb 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/MemoryOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/MemoryOptimizedClipboard.java @@ -58,7 +58,7 @@ public class MemoryOptimizedClipboard extends LinearClipboard { } public MemoryOptimizedClipboard(Region region, int compressionLevel) { - super(region.getDimensions()); + super(region.getDimensions(), region.getMinimumPoint()); states = new byte[1 + (getVolume() >> BLOCK_SHIFT)][]; nbtMap = new HashMap<>(); this.compressionLevel = compressionLevel; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/SimpleClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/SimpleClipboard.java index 7ffc03cd7..56ed562f6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/SimpleClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/SimpleClipboard.java @@ -10,10 +10,11 @@ public abstract class SimpleClipboard implements Clipboard { private final BlockVector3 size; private final int area; private final int volume; + private BlockVector3 offset; private BlockVector3 origin; - - SimpleClipboard(BlockVector3 dimensions) { + SimpleClipboard(BlockVector3 dimensions, BlockVector3 offset) { this.size = dimensions; + this.offset = offset; long longVolume = (long) getWidth() * (long) getHeight() * (long) getLength(); if (longVolume >= Integer.MAX_VALUE) { throw new IllegalArgumentException("Dimensions are too large for this clipboard format."); @@ -24,12 +25,11 @@ public abstract class SimpleClipboard implements Clipboard { } SimpleClipboard(Region region) { - this(region.getDimensions()); + this(region.getDimensions(), region.getMinimumPoint()); } - @Override - public void setOrigin(BlockVector3 offset) { - this.origin = offset; + protected void setOffset(final BlockVector3 offset) { + this.offset = offset; } @Override @@ -37,6 +37,11 @@ public abstract class SimpleClipboard implements Clipboard { return origin; } + @Override + public void setOrigin(BlockVector3 origin) { + this.origin = origin.subtract(offset); + } + @Override public BlockVector3 getMinimumPoint() { return BlockVector3.ZERO; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/exception/FaweClipboardVersionMismatchException.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/exception/FaweClipboardVersionMismatchException.java new file mode 100644 index 000000000..616361ff2 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/exception/FaweClipboardVersionMismatchException.java @@ -0,0 +1,11 @@ +package com.fastasyncworldedit.core.internal.exception; + +import com.fastasyncworldedit.core.configuration.Caption; + +public class FaweClipboardVersionMismatchException extends FaweException { + + public FaweClipboardVersionMismatchException() { + super(Caption.of("fawe.error.clipboard.on.disk.version.mismatch"), Type.CLIPBOARD); + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/exception/FaweException.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/exception/FaweException.java index dc5ea8608..83504f6b8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/exception/FaweException.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/exception/FaweException.java @@ -90,6 +90,7 @@ public class FaweException extends RuntimeException { CHUNK, PLAYER_ONLY, ACTOR_REQUIRED, + CLIPBOARD, OTHER } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Player.java b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Player.java index 9ef866628..d72bed418 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Player.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Player.java @@ -23,6 +23,7 @@ import com.fastasyncworldedit.core.Fawe; import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.extent.clipboard.DiskOptimizedClipboard; +import com.fastasyncworldedit.core.internal.exception.FaweClipboardVersionMismatchException; import com.fastasyncworldedit.core.regions.FaweMaskManager; import com.fastasyncworldedit.core.util.MainUtil; import com.sk89q.worldedit.EmptyClipboardException; @@ -46,7 +47,6 @@ import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.HandSide; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; @@ -353,8 +353,6 @@ public interface Player extends Entity, Actor { Region getLargestRegion(); - void setSelection(Region region); - /** * Get the player's selection region. If the selection is defined in * a different world, the {@code IncompleteRegionException} @@ -367,6 +365,8 @@ public interface Player extends Entity, Actor { return getSession().getSelection(getWorld()); } + void setSelection(Region region); + /** * Set the player's WorldEdit selection. * @@ -391,7 +391,9 @@ public interface Player extends Entity, Actor { */ default void unregister() { cancel(true); - getSession().flushClipboard(); + if (Settings.IMP.CLIPBOARD.DELETE_ON_LOGOUT || Settings.IMP.CLIPBOARD.USE_DISK) { + getSession().setClipboard(null); + } if (Settings.IMP.HISTORY.DELETE_ON_LOGOUT) { getSession().clearHistory(); } @@ -421,18 +423,21 @@ public interface Player extends Entity, Actor { ClipboardHolder holder = new ClipboardHolder(clip); getSession().setClipboard(holder); } - } catch (Exception event) { - printError(TextComponent.of("====== INVALID CLIPBOARD ======")); - event.printStackTrace(); + } catch (FaweClipboardVersionMismatchException e) { + printError(Caption.of("fawe.error.clipboard.on.disk.version.mismatch")); + } catch (RuntimeException e) { + printError(Caption.of("fawe.error.clipboard.invalid")); + e.printStackTrace(); + print(Caption.of("fawe.error.stacktrace")); + print(Caption.of("fawe.error.clipboard.load.failure")); + print(Caption.of("fawe.error.clipboard.invalid.info", file.getName(), file.length())); + print(Caption.of("fawe.error.stacktrace")); + } catch (Exception e) { + printError(Caption.of("fawe.error.clipboard.invalid")); + e.printStackTrace(); print(Caption.of("fawe.error.stacktrace")); print(Caption.of("fawe.error.no-failure")); - print(Caption.of( - "File: ", - TextComponent.of(file.getName()), - TextComponent.of(" (len:"), - TextComponent.of(file.length()), - TextComponent.of(")") - )); + print(Caption.of("fawe.error.clipboard.invalid.info", file.getName(), file.length())); print(Caption.of("fawe.error.stacktrace")); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java index 5ccf84360..633686107 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java @@ -57,8 +57,9 @@ public class BlockArrayClipboard implements Clipboard { //FAWE start private final Region region; - private final BlockVector3 origin; private final Clipboard parent; + private final BlockVector3 offset; + private BlockVector3 origin; /** * Create a new instance. Creates a parent clipboard based on the clipboard settings in settings.yml, with a randomly @@ -93,7 +94,8 @@ public class BlockArrayClipboard implements Clipboard { Region shifted = parent.getRegion().clone(); shifted.shift(offset); this.region = shifted; - this.origin = shifted.getMinimumPoint(); + this.offset = shifted.getMinimumPoint(); + this.origin = parent.getOrigin(); } /** @@ -129,7 +131,8 @@ public class BlockArrayClipboard implements Clipboard { checkNotNull(region); this.parent = parent; this.region = region.clone(); - this.origin = region.getMinimumPoint(); + this.offset = region.getMinimumPoint(); + this.origin = parent.getOrigin(); } //FAWE end @@ -140,12 +143,13 @@ public class BlockArrayClipboard implements Clipboard { @Override public BlockVector3 getOrigin() { - return getParent().getOrigin().add(region.getMinimumPoint()); + return origin; } @Override public void setOrigin(BlockVector3 origin) { - getParent().setOrigin(origin.subtract(region.getMinimumPoint())); + this.origin = origin; + getParent().setOrigin(origin); } @Override @@ -161,9 +165,9 @@ public class BlockArrayClipboard implements Clipboard { @Override public BlockState getBlock(BlockVector3 position) { if (region.contains(position)) { - int x = position.getBlockX() - origin.getX(); - int y = position.getBlockY() - origin.getY(); - int z = position.getBlockZ() - origin.getZ(); + int x = position.getBlockX() - offset.getX(); + int y = position.getBlockY() - offset.getY(); + int z = position.getBlockZ() - offset.getZ(); return getParent().getBlock(x, y, z); } @@ -173,9 +177,9 @@ public class BlockArrayClipboard implements Clipboard { @Override public BaseBlock getFullBlock(BlockVector3 position) { if (region.contains(position)) { - int x = position.getBlockX() - origin.getX(); - int y = position.getBlockY() - origin.getY(); - int z = position.getBlockZ() - origin.getZ(); + int x = position.getBlockX() - offset.getX(); + int y = position.getBlockY() - offset.getY(); + int z = position.getBlockZ() - offset.getZ(); return getParent().getFullBlock(x, y, z); } return BlockTypes.AIR.getDefaultState().toBaseBlock(); @@ -197,9 +201,9 @@ public class BlockArrayClipboard implements Clipboard { //FAWE start @Override public boolean setTile(int x, int y, int z, CompoundTag tag) { - x -= origin.getX(); - y -= origin.getY(); - z -= origin.getZ(); + x -= offset.getX(); + y -= offset.getY(); + z -= offset.getZ(); return getParent().setTile(x, y, z, tag); } @@ -210,9 +214,9 @@ public class BlockArrayClipboard implements Clipboard { @Override public > boolean setBlock(int x, int y, int z, B block) throws WorldEditException { - x -= origin.getX(); - y -= origin.getY(); - z -= origin.getZ(); + x -= offset.getX(); + y -= offset.getY(); + z -= offset.getZ(); return parent.setBlock(x, y, z, block); } @@ -223,39 +227,39 @@ public class BlockArrayClipboard implements Clipboard { @Override public BiomeType getBiome(BlockVector3 position) { - BlockVector3 v = position.subtract(region.getMinimumPoint()); + BlockVector3 v = position.subtract(offset); return getParent().getBiomeType(v.getX(), v.getY(), v.getZ()); } @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { - int x = position.getBlockX() - origin.getX(); - int y = position.getBlockY() - origin.getY(); - int z = position.getBlockZ() - origin.getZ(); + int x = position.getBlockX() - offset.getX(); + int y = position.getBlockY() - offset.getY(); + int z = position.getBlockZ() - offset.getZ(); return getParent().setBiome(x, y, z, biome); } @Override public boolean setBiome(int x, int y, int z, BiomeType biome) { - x -= origin.getX(); - y -= origin.getY(); - z -= origin.getZ(); + x -= offset.getX(); + y -= offset.getY(); + z -= offset.getZ(); return getParent().setBiome(x, y, z, biome); } @Override public List getEntities(Region region) { region = region.clone(); - region.shift(BlockVector3.ZERO.subtract(origin)); + region.shift(BlockVector3.ZERO.subtract(offset)); return getParent().getEntities(region).stream().map(e -> { if (e instanceof ClipboardEntity) { ClipboardEntity ce = (ClipboardEntity) e; Location oldloc = ce.getLocation(); Location loc = new Location(oldloc.getExtent(), - oldloc.getX() + origin.getBlockX(), - oldloc.getY() + origin.getBlockY(), - oldloc.getZ() + origin.getBlockZ(), + oldloc.getX() + offset.getBlockX(), + oldloc.getY() + offset.getBlockY(), + oldloc.getZ() + offset.getBlockZ(), oldloc.getYaw(), oldloc.getPitch() ); return new ClipboardEntity(loc, ce.entity); @@ -272,9 +276,9 @@ public class BlockArrayClipboard implements Clipboard { ClipboardEntity ce = (ClipboardEntity) e; Location oldloc = ce.getLocation(); Location loc = new Location(oldloc.getExtent(), - oldloc.getX() + origin.getBlockX(), - oldloc.getY() + origin.getBlockY(), - oldloc.getZ() + origin.getBlockZ(), + oldloc.getX() + offset.getBlockX(), + oldloc.getY() + offset.getBlockY(), + oldloc.getZ() + offset.getBlockZ(), oldloc.getYaw(), oldloc.getPitch() ); return new ClipboardEntity(loc, ce.entity); @@ -287,9 +291,9 @@ public class BlockArrayClipboard implements Clipboard { @Nullable public Entity createEntity(Location location, BaseEntity entity) { Location l = new Location(location.getExtent(), - location.getX() - origin.getBlockX(), - location.getY() - origin.getBlockY(), - location.getZ() - origin.getBlockZ(), + location.getX() - offset.getBlockX(), + location.getY() - offset.getBlockY(), + location.getZ() - offset.getBlockZ(), location.getYaw(), location.getPitch() ); return getParent().createEntity(l, entity); @@ -297,39 +301,39 @@ public class BlockArrayClipboard implements Clipboard { @Override public void removeEntity(int x, int y, int z, UUID uuid) { - x -= origin.getX(); - y -= origin.getY(); - z -= origin.getZ(); + x -= offset.getX(); + y -= offset.getY(); + z -= offset.getZ(); getParent().removeEntity(x, y, z, uuid); } @Override public BlockState getBlock(int x, int y, int z) { - x -= origin.getX(); - y -= origin.getY(); - z -= origin.getZ(); + x -= offset.getX(); + y -= offset.getY(); + z -= offset.getZ(); return getParent().getBlock(x, y, z); } @Override public BaseBlock getFullBlock(int x, int y, int z) { - x -= origin.getX(); - y -= origin.getY(); - z -= origin.getZ(); + x -= offset.getX(); + y -= offset.getY(); + z -= offset.getZ(); return getParent().getFullBlock(x, y, z); } @Override public BiomeType getBiomeType(int x, int y, int z) { - x -= origin.getX(); - z -= origin.getZ(); + x -= offset.getX(); + z -= offset.getZ(); return getParent().getBiomeType(x, y, z); } @Nonnull @Override public Iterator iterator() { - OffsetBlockVector3 mutable = new OffsetBlockVector3(origin); + OffsetBlockVector3 mutable = new OffsetBlockVector3(offset); return Iterators.transform(getParent().iterator(), mutable::init); } @@ -337,12 +341,12 @@ public class BlockArrayClipboard implements Clipboard { public Iterator iterator2d() { MutableBlockVector2 mutable = new MutableBlockVector2(); return Iterators.transform(getParent().iterator2d(), input -> - mutable.setComponents(input.getX() + origin.getX(), input.getZ() + origin.getZ())); + mutable.setComponents(input.getX() + offset.getX(), input.getZ() + offset.getZ())); } @Override public Iterator iterator(Order order) { - OffsetBlockVector3 mutable = new OffsetBlockVector3(origin); + OffsetBlockVector3 mutable = new OffsetBlockVector3(offset); return Iterators.transform(getParent().iterator(order), mutable::init); } //FAWE end diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index 242fc9c39..5558afce7 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -144,6 +144,10 @@ "fawe.error.parse.unknown-transform": "Unknown transform: {0}, See: {1}", "fawe.error.parse.no-clipboard": "To use {0}, please first copy something to your clipboard", "fawe.error.parse.no-clipboard-source": "No clipboards found at given source: {0}", + "fawe.error.clipboard.invalid": "====== INVALID CLIPBOARD ======", + "fawe.error.clipboard.invalid.info": "File: {0} (len: {1})", + "fawe.error.clipboard.load.failure": "Could not load clipboard. Possible that the clipboard is still being written to from another server?!", + "fawe.error.clipboard.on.disk.version.mismatch": "Clipboard version mismatch. Please delete your clipboards folder and restart the server.", "fawe.cancel.worldedit.cancel.count": "Cancelled {0} edits.", "fawe.cancel.worldedit.cancel.reason.confirm": "Use //confirm to execute {0}",