mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-12 08:08:34 +00:00
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
This commit is contained in:
@ -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<>();
|
||||
|
@ -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<IntTriple, CompoundTag> 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();
|
||||
|
@ -25,8 +25,8 @@ public abstract class LinearClipboard extends SimpleClipboard {
|
||||
|
||||
protected final HashSet<ClipboardEntity> 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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user