Fix clipboards to allow proper heights by allowing extended CuboidRegion heights (#1624)

* Fix clipboards to allow proper heights by allowing extended CuboidRegion heights
Fixes #1534

* Add @since

* Fix javadoc comment

Co-authored-by: Alex <mc.cache@web.de>
This commit is contained in:
Jordan 2022-02-24 10:32:45 +01:00 committed by GitHub
parent 0a04b0b4cd
commit 28a0239437
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 98 additions and 47 deletions

View File

@ -83,7 +83,7 @@ public class FaweBukkit implements IFawe, Listener {
Bukkit.getServer().shutdown(); Bukkit.getServer().shutdown();
} }
MinecraftVersion version = new MinecraftVersion(); MinecraftVersion version = MinecraftVersion.getCurrent();
chunksStretched = version.isEqualOrHigherThan(MinecraftVersion.NETHER); chunksStretched = version.isEqualOrHigherThan(MinecraftVersion.NETHER);

View File

@ -13,6 +13,7 @@ public class MinecraftVersion implements Comparable<MinecraftVersion> {
public static final MinecraftVersion NETHER = new MinecraftVersion(1, 16); public static final MinecraftVersion NETHER = new MinecraftVersion(1, 16);
public static final MinecraftVersion CAVES_17 = new MinecraftVersion(1, 17); public static final MinecraftVersion CAVES_17 = new MinecraftVersion(1, 17);
public static final MinecraftVersion CAVES_18 = new MinecraftVersion(1, 18); public static final MinecraftVersion CAVES_18 = new MinecraftVersion(1, 18);
private static MinecraftVersion current = null;
private final int major; private final int major;
private final int minor; private final int minor;
@ -57,6 +58,29 @@ public class MinecraftVersion implements Comparable<MinecraftVersion> {
this.release = Integer.parseInt(versionParts[2].substring(1)); this.release = Integer.parseInt(versionParts[2].substring(1));
} }
/**
* Get the minecraft version that the server is currently running
*
* @since TODO
*/
public static MinecraftVersion getCurrent() {
if (current == null) {
return current = new MinecraftVersion();
}
return current;
}
/**
* Determines the server version based on the CraftBukkit package path, e.g. {@code org.bukkit.craftbukkit.v1_16_R3},
* where v1_16_R3 is the resolved version.
*
* @return The package version.
*/
private static String getPackageVersion() {
String fullPackagePath = Bukkit.getServer().getClass().getPackage().getName();
return fullPackagePath.substring(fullPackagePath.lastIndexOf('.') + 1);
}
/** /**
* @param other The other version to compare against. * @param other The other version to compare against.
* @return {@code true} if this version is equal to the other version. * @return {@code true} if this version is equal to the other version.
@ -145,15 +169,4 @@ public class MinecraftVersion implements Comparable<MinecraftVersion> {
return major + "." + minor + "." + release; return major + "." + minor + "." + release;
} }
/**
* Determines the server version based on the CraftBukkit package path, e.g. {@code org.bukkit.craftbukkit.v1_16_R3},
* where v1_16_R3 is the resolved version.
*
* @return The package version.
*/
private static String getPackageVersion() {
String fullPackagePath = Bukkit.getServer().getClass().getPackage().getName();
return fullPackagePath.substring(fullPackagePath.lastIndexOf('.') + 1);
}
} }

View File

@ -282,12 +282,12 @@ public class BukkitServerInterface extends AbstractPlatform implements MultiUser
@Override @Override
public int versionMinY() { public int versionMinY() {
return new MinecraftVersion().isEqualOrHigherThan(MinecraftVersion.CAVES_18) ? -64 : 0; return MinecraftVersion.getCurrent().isEqualOrHigherThan(MinecraftVersion.CAVES_18) ? -64 : 0;
} }
@Override @Override
public int versionMaxY() { public int versionMaxY() {
return new MinecraftVersion().isEqualOrHigherThan(MinecraftVersion.CAVES_18) ? 319 : 255; return MinecraftVersion.getCurrent().isEqualOrHigherThan(MinecraftVersion.CAVES_18) ? 319 : 255;
} }
//FAWE end //FAWE end
} }

View File

@ -40,7 +40,7 @@ public class BukkitImplLoader {
private static final Logger LOGGER = LogManagerCompat.getLogger(); private static final Logger LOGGER = LogManagerCompat.getLogger();
private final List<String> adapterCandidates = new ArrayList<>(); private final List<String> adapterCandidates = new ArrayList<>();
private final String minorMCVersion = String.valueOf(new MinecraftVersion().getMinor()); private final String minorMCVersion = String.valueOf(MinecraftVersion.getCurrent().getMinor());
private int zeroth = 0; private int zeroth = 0;
private String customCandidate; private String customCandidate;

View File

@ -27,7 +27,6 @@ import com.sk89q.worldedit.world.block.BlockTypes;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.io.Closeable;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -51,7 +50,7 @@ import java.util.stream.Collectors;
* - Uses an auto closable RandomAccessFile for getting / setting id / data * - Uses an auto closable RandomAccessFile for getting / setting id / data
* - I don't know how to reduce nbt / entities to O(2) complexity, so it is stored in memory. * - I don't know how to reduce nbt / entities to O(2) complexity, so it is stored in memory.
*/ */
public class DiskOptimizedClipboard extends LinearClipboard implements Closeable { public class DiskOptimizedClipboard extends LinearClipboard {
private static final Logger LOGGER = LogManagerCompat.getLogger(); private static final Logger LOGGER = LogManagerCompat.getLogger();
@ -139,7 +138,7 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable
if (braf.length() - HEADER_SIZE == ((long) getVolume() << 1) + (long) ((getHeight() >> 2) + 1) * ((getLength() >> 2) + 1) * ((getWidth() >> 2) + 1)) { if (braf.length() - HEADER_SIZE == ((long) getVolume() << 1) + (long) ((getHeight() >> 2) + 1) * ((getLength() >> 2) + 1) * ((getWidth() >> 2) + 1)) {
hasBiomes = true; hasBiomes = true;
} }
getOffset(); getAndSetOffsetAndOrigin();
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -267,14 +266,8 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable
public BlockArrayClipboard toClipboard() { public BlockArrayClipboard toClipboard() {
try { try {
CuboidRegion region = new CuboidRegion( Region region = getRegion();
BlockVector3.at(0, 0, 0), region.shift(offset);
BlockVector3.at(getWidth() - 1, getHeight() - 1, getLength() - 1)
);
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); BlockArrayClipboard clipboard = new BlockArrayClipboard(region, this);
clipboard.setOrigin(getOrigin().add(offset)); clipboard.setOrigin(getOrigin().add(offset));
return clipboard; return clipboard;
@ -285,20 +278,13 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable
} }
@Override @Override
public BlockVector3 getOrigin() { public void setOrigin(BlockVector3 origin) {
int ox = byteBuffer.getShort(10); super.setOrigin(origin);
int oy = byteBuffer.getShort(12); origin = origin.subtract(offset);
int oz = byteBuffer.getShort(14);
return BlockVector3.at(ox, oy, oz).subtract(offset);
}
@Override
public void setOrigin(BlockVector3 offset) {
super.setOrigin(offset);
try { try {
byteBuffer.putShort(10, (short) offset.getBlockX()); byteBuffer.putShort(10, (short) origin.getBlockX());
byteBuffer.putShort(12, (short) offset.getBlockY()); byteBuffer.putShort(12, (short) origin.getBlockY());
byteBuffer.putShort(14, (short) offset.getBlockZ()); byteBuffer.putShort(14, (short) origin.getBlockZ());
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -316,11 +302,15 @@ public class DiskOptimizedClipboard extends LinearClipboard implements Closeable
} }
} }
private void getOffset() { private void getAndSetOffsetAndOrigin() {
int x = byteBuffer.getShort(16); int x = byteBuffer.getShort(16);
int y = byteBuffer.getShort(18); int y = byteBuffer.getShort(18);
int z = byteBuffer.getShort(20); int z = byteBuffer.getShort(20);
super.setOffset(BlockVector3.at(x, y, z)); super.setOffset(BlockVector3.at(x, y, z));
int ox = byteBuffer.getShort(10);
int oy = byteBuffer.getShort(12);
int oz = byteBuffer.getShort(14);
super.setOrigin(BlockVector3.at(ox, oy, oz).add(offset));
} }
@Override @Override

View File

@ -55,7 +55,12 @@ public abstract class SimpleClipboard implements Clipboard {
@Override @Override
public Region getRegion() { public Region getRegion() {
return new CuboidRegion(BlockVector3.ZERO, BlockVector3.at(getWidth() - 1, getHeight() - 1, getLength() - 1)); return new CuboidRegion(
null,
BlockVector3.ZERO,
BlockVector3.at(getWidth() - 1, getHeight() - 1, getLength() - 1),
false
);
} }
@Override @Override

View File

@ -61,6 +61,7 @@ import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.AbstractDelegateExtent;
import com.sk89q.worldedit.extent.ChangeSetExtent; import com.sk89q.worldedit.extent.ChangeSetExtent;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
@ -263,8 +264,10 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
this.limit = builder.getLimit().copy(); this.limit = builder.getLimit().copy();
this.actor = builder.getActor(); this.actor = builder.getActor();
this.changeSet = builder.getChangeTask(); this.changeSet = builder.getChangeTask();
this.minY = world.getMinY(); this.minY = world != null ? world.getMinY() :
this.maxY = world.getMaxY(); WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).versionMinY();
this.maxY = world != null ? world.getMaxY() :
WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).versionMaxY();
this.blockBag = builder.getBlockBag(); this.blockBag = builder.getBlockBag();
this.history = changeSet != null; this.history = changeSet != null;
this.relighter = builder.getRelighter(); this.relighter = builder.getRelighter();

View File

@ -340,8 +340,7 @@ public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable, Fl
copy.setTransform(transform); copy.setTransform(transform);
} }
copy.setCopyingBiomes(this.hasBiomes()); copy.setCopyingBiomes(this.hasBiomes());
if (extent instanceof EditSession) { if (extent instanceof EditSession editSession) {
EditSession editSession = (EditSession) extent;
Mask sourceMask = editSession.getSourceMask(); Mask sourceMask = editSession.getSourceMask();
if (sourceMask != null) { if (sourceMask != null) {
new MaskTraverser(sourceMask).reset(extent); new MaskTraverser(sourceMask).reset(extent);
@ -393,7 +392,7 @@ public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable, Fl
continue; continue;
} }
if (pos.getY() < extent.getMinY()) { if (pos.getY() < extent.getMinY()) {
throw new RuntimeException("Y-Position cannot be less than 0!"); throw new RuntimeException("Y-Position cannot be less than the extent's minimum Y!");
} }
extent.setBlock(xx, yy, zz, block); extent.setBlock(xx, yy, zz, block);
} }

View File

@ -85,6 +85,30 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
recalculate(); recalculate();
} }
//FAWE start - allow region to be created without clamping Y
/**
* Construct a new instance of this cuboid using two corners of the cuboid.
*
* @param world the world
* @param pos1 the first position
* @param pos2 the second position
* @param clampY if the min/max Y of the region should be clamped to the world
* @since TODO
*/
public CuboidRegion(World world, BlockVector3 pos1, BlockVector3 pos2, boolean clampY) {
super(world);
checkNotNull(pos1);
checkNotNull(pos2);
this.pos1 = pos1;
this.pos2 = pos2;
if (clampY) {
recalculate();
} else {
recalculateNoClamp();
}
}
//FAWE end
/** /**
* Get the first cuboid-defining corner. * Get the first cuboid-defining corner.
* *
@ -128,7 +152,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
} }
/** /**
* Clamps the cuboid according to boundaries of the world. * Sets the cached min and max x/y/z and clamps Y to world y min/max
*/ */
protected void recalculate() { protected void recalculate() {
if (pos1 == null || pos2 == null) { if (pos1 == null || pos2 == null) {
@ -144,6 +168,23 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
maxZ = Math.max(pos1.getZ(), pos2.getZ()); maxZ = Math.max(pos1.getZ(), pos2.getZ());
} }
//FAWE start - allow region to be created without clamping Y
/**
* Sets the cached min and max x/y/z
*/
protected void recalculateNoClamp() {
if (pos1 == null || pos2 == null) {
return;
}
minX = Math.min(pos1.getX(), pos2.getX());
minY = Math.min(pos1.getY(), pos2.getY());
minZ = Math.min(pos1.getZ(), pos2.getZ());
maxX = Math.max(pos1.getX(), pos2.getX());
maxY = Math.max(pos1.getY(), pos2.getY());
maxZ = Math.max(pos1.getZ(), pos2.getZ());
}
//FAWE end
/** /**
* Get a region that contains the faces of this cuboid. * Get a region that contains the faces of this cuboid.
* *