From 763a497cdcf63bc73983529835f21497d111d259 Mon Sep 17 00:00:00 2001 From: Zeranny Date: Sun, 28 Jan 2024 12:10:48 +0000 Subject: [PATCH 001/220] Fix out of bounds error for erode and pull brushes (#2554) - Fixes #2380 --- .../core/command/tool/brush/ErodeBrush.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ErodeBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ErodeBrush.java index 13490dc2f..21879751c 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ErodeBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ErodeBrush.java @@ -67,11 +67,11 @@ public class ErodeBrush implements Brush { final int by = target.getBlockY(); final int bz = target.getBlockZ(); - for (int x = -brushSize, relx = 0; x <= brushSize; x++, relx++) { + for (int x = -brushSize, relx = 0; x <= brushSize && relx < buffer1.getWidth(); x++, relx++) { int x0 = x + bx; - for (int y = -brushSize, rely = 0; y <= brushSize; y++, rely++) { + for (int y = -brushSize, rely = 0; y <= brushSize && rely < buffer1.getHeight(); y++, rely++) { int y0 = y + by; - for (int z = -brushSize, relz = 0; z <= brushSize; z++, relz++) { + for (int z = -brushSize, relz = 0; z <= brushSize && relz < buffer1.getLength(); z++, relz++) { int z0 = z + bz; BlockState state = es.getBlock(x0, y0, z0); buffer1.setBlock(relx, rely, relz, state); @@ -115,11 +115,11 @@ public class ErodeBrush implements Brush { Clipboard current, Clipboard target ) { int[] frequency = null; - for (int x = -brushSize, relx = 0; x <= brushSize; x++, relx++) { + for (int x = -brushSize, relx = 0; x <= brushSize && relx < target.getWidth(); x++, relx++) { int x2 = x * x; - for (int z = -brushSize, relz = 0; z <= brushSize; z++, relz++) { + for (int z = -brushSize, relz = 0; z <= brushSize && relz < target.getLength(); z++, relz++) { int x2y2 = x2 + z * z; - for (int y = -brushSize, rely = 0; y <= brushSize; y++, rely++) { + for (int y = -brushSize, rely = 0; y <= brushSize && rely < target.getHeight(); y++, rely++) { int cube = x2y2 + y * y; target.setBlock(relx, rely, relz, current.getBlock(relx, rely, relz)); if (cube >= brushSizeSquared) { @@ -166,11 +166,11 @@ public class ErodeBrush implements Brush { Clipboard current, Clipboard target ) { int[] frequency = null; - for (int x = -brushSize, relx = 0; x <= brushSize; x++, relx++) { + for (int x = -brushSize, relx = 0; x <= brushSize && relx < target.getWidth(); x++, relx++) { int x2 = x * x; - for (int z = -brushSize, relz = 0; z <= brushSize; z++, relz++) { + for (int z = -brushSize, relz = 0; z <= brushSize && relz < target.getLength(); z++, relz++) { int x2y2 = x2 + z * z; - for (int y = -brushSize, rely = 0; y <= brushSize; y++, rely++) { + for (int y = -brushSize, rely = 0; y <= brushSize && rely < target.getHeight(); y++, rely++) { int cube = x2y2 + y * y; target.setBlock(relx, rely, relz, current.getBlock(relx, rely, relz)); if (cube >= brushSizeSquared) { From 9ffe76dce3fe5bb46fe02897b1fb3721a6eab3eb Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sun, 28 Jan 2024 13:32:25 +0100 Subject: [PATCH 002/220] fix: add missing methods top TestOfflinePermissible --- .../java/com/sk89q/wepif/TestOfflinePermissible.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/worldedit-bukkit/src/test/java/com/sk89q/wepif/TestOfflinePermissible.java b/worldedit-bukkit/src/test/java/com/sk89q/wepif/TestOfflinePermissible.java index 052c772d5..507da7e01 100644 --- a/worldedit-bukkit/src/test/java/com/sk89q/wepif/TestOfflinePermissible.java +++ b/worldedit-bukkit/src/test/java/com/sk89q/wepif/TestOfflinePermissible.java @@ -245,6 +245,11 @@ public class TestOfflinePermissible implements OfflinePlayer, Permissible { throw new UnsupportedOperationException("Not supported yet."); } + @Override + public @Nullable Location getRespawnLocation() { + return null; + } + @Override public void incrementStatistic(@Nonnull Statistic statistic) throws IllegalArgumentException { @@ -365,4 +370,9 @@ public class TestOfflinePermissible implements OfflinePlayer, Permissible { return null; } + @Override + public @Nullable Location getLocation() { + return null; + } + } From 033b8e35d235205c6f72f09156b0b4a3d393a4da Mon Sep 17 00:00:00 2001 From: Jordan Date: Fri, 2 Feb 2024 18:06:57 +0100 Subject: [PATCH 003/220] fix: always set createCopy status on chunk get as chunks are cached (#2567) - fixes #2539 --- .../adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java | 1 + .../bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks.java | 1 + .../bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java | 1 + .../bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java | 1 + .../bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java | 1 + .../bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java | 1 + .../core/queue/implementation/chunk/ChunkHolder.java | 2 +- 7 files changed, 7 insertions(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java index a93437c1a..214a39bc6 100644 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java @@ -148,6 +148,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); } this.createCopy = createCopy; + // Increment regardless of whether copy will be created or not to return null from getCopy() return ++this.copyKey; } diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks.java index 81580910c..7291c0f69 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks.java @@ -153,6 +153,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); } this.createCopy = createCopy; + // Increment regardless of whether copy will be created or not to return null from getCopy() return ++this.copyKey; } diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java index 60695c1e8..63bdb5997 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java @@ -156,6 +156,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); } this.createCopy = createCopy; + // Increment regardless of whether copy will be created or not to return null from getCopy() return ++this.copyKey; } diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java index 67bcd6902..5f74d1073 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java @@ -156,6 +156,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); } this.createCopy = createCopy; + // Increment regardless of whether copy will be created or not to return null from getCopy() return ++this.copyKey; } diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java index d51d31500..1531358fb 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java @@ -135,6 +135,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); } this.createCopy = createCopy; + // Increment regardless of whether copy will be created or not to return null from getCopy() return ++this.copyKey; } diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java index 8139adc87..42333f9e5 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java @@ -135,6 +135,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); } this.createCopy = createCopy; + // Increment regardless of whether copy will be created or not to return null from getCopy() return ++this.copyKey; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java index e4a18ef69..9458aa1b0 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java @@ -1031,10 +1031,10 @@ public class ChunkHolder> implements IQueueChunk { try { get.lockCall(); boolean postProcess = !(getExtent().getPostProcessor() instanceof EmptyBatchProcessor); + final int copyKey = get.setCreateCopy(postProcess); final IChunkSet iChunkSet = getExtent().processSet(this, get, set); Runnable finalizer; if (postProcess) { - int copyKey = get.setCreateCopy(true); finalizer = () -> { getExtent().postProcess(this, get.getCopy(copyKey), iChunkSet); finalize.run(); From a502287906da63cc689d53eeba855ef7df9efea9 Mon Sep 17 00:00:00 2001 From: Jordan Date: Fri, 2 Feb 2024 18:07:13 +0100 Subject: [PATCH 004/220] refactor: minor adjustments to error handling (ignoring) and blocking queue (#2566) --- .../fastasyncworldedit/core/FaweCache.java | 36 ++++++++++++++++--- .../queue/implementation/QueueHandler.java | 3 +- .../SingleThreadQueueExtent.java | 1 + .../implementation/chunk/ChunkHolder.java | 3 +- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java index 0655e4214..f5cc88284 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java @@ -612,12 +612,38 @@ public enum FaweCache implements Trimable { /* Thread stuff */ + + /** + * Create a new blocking executor with default name and FaweCache logger + * + * @return new blocking executor + */ public ThreadPoolExecutor newBlockingExecutor() { + return newBlockingExecutor("FAWE Blocking Executor - %d"); + } + + /** + * Create a new blocking executor with specified name and FaweCache logger + * + * @return new blocking executor + * @since TODO + */ + public ThreadPoolExecutor newBlockingExecutor(String name) { + return newBlockingExecutor(name, LOGGER); + } + + /** + * Create a new blocking executor with specified name and logger + * + * @return new blocking executor + * @since TODO + */ + public ThreadPoolExecutor newBlockingExecutor(String name, Logger logger) { int nThreads = Settings.settings().QUEUE.PARALLEL_THREADS; ArrayBlockingQueue queue = new ArrayBlockingQueue<>(nThreads, true); return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, queue, - new ThreadFactoryBuilder().setNameFormat("FAWE Blocking Executor - %d").build(), + new ThreadFactoryBuilder().setNameFormat(name).build(), new ThreadPoolExecutor.CallerRunsPolicy() ) { @@ -652,10 +678,10 @@ public enum FaweCache implements Trimable { int hash = throwable.getMessage() != null ? throwable.getMessage().hashCode() : 0; if (hash != lastException) { lastException = hash; - LOGGER.catching(throwable); + logger.catching(throwable); count = 0; } else if (count < Settings.settings().QUEUE.PARALLEL_THREADS) { - LOGGER.warn(throwable.getMessage()); + logger.warn(throwable.getMessage()); count++; } } @@ -665,10 +691,10 @@ public enum FaweCache implements Trimable { private void handleFaweException(FaweException e) { FaweException.Type type = e.getType(); if (e.getType() == FaweException.Type.OTHER) { - LOGGER.catching(e); + logger.catching(e); } else if (!faweExceptionReasonsUsed[type.ordinal()]) { faweExceptionReasonsUsed[type.ordinal()] = true; - LOGGER.warn("FaweException: " + e.getMessage()); + logger.warn("FaweException: " + e.getMessage()); } } }; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/QueueHandler.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/QueueHandler.java index 014b94fce..956c33fb2 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/QueueHandler.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/QueueHandler.java @@ -68,7 +68,8 @@ public abstract class QueueHandler implements Trimable, Runnable { * Main "work-horse" queue for FAWE. Handles chunk submission (and chunk submission alone). Blocking in order to forcibly * prevent overworking/over-submission of chunk process tasks. */ - private final ThreadPoolExecutor blockingExecutor = FaweCache.INSTANCE.newBlockingExecutor(); + private final ThreadPoolExecutor blockingExecutor = FaweCache.INSTANCE.newBlockingExecutor( + "FAWE QueueHandler Blocking Executor - %d"); /** * Queue for tasks to be completed on the main thread. These take priority of tasks submitted to syncWhenFree queue */ diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java index 34dd5191e..132229d1d 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java @@ -158,6 +158,7 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen this.setProcessor(EmptyBatchProcessor.getInstance()); this.setPostProcessor(EmptyBatchProcessor.getInstance()); this.world = null; + this.faweExceptionReasonsUsed = new boolean[FaweException.Type.values().length]; } /** diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java index 9458aa1b0..6103a1649 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java @@ -12,6 +12,7 @@ import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueChunk; import com.fastasyncworldedit.core.queue.IQueueExtent; import com.fastasyncworldedit.core.queue.Pool; +import com.fastasyncworldedit.core.util.MemUtil; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; @@ -959,7 +960,7 @@ public class ChunkHolder> implements IQueueChunk { public final IChunkGet getOrCreateGet() { if (chunkExisting == null) { chunkExisting = newWrappedGet(); - chunkExisting.trim(false); + chunkExisting.trim(MemUtil.isMemoryLimited()); } return chunkExisting; } From d1e1d5105e04dcce486aed1ae18e6866ae0881e3 Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 5 Feb 2024 22:44:45 +0100 Subject: [PATCH 005/220] fix: invalidate cached allowed regions if WG region deleted (#2572) --- .../bukkit/regions/WorldGuardFeature.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java index ade2d8258..1043d9a3e 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java @@ -163,13 +163,22 @@ public class WorldGuardFeature extends BukkitMaskManager implements Listener { final Location location = player.getLocation(); final Set regions = this.getRegions(localplayer, location, isWhitelist); if (!regions.isEmpty()) { + RegionManager manager = WorldGuard + .getInstance() + .getPlatform() + .getRegionContainer() + .get(BukkitAdapter.adapt(location.getWorld())); + if (manager == null) { + return null; + } Set result = new HashSet<>(); for (ProtectedRegion myRegion : regions) { if (myRegion.getId().equals("__global__")) { return new FaweMask(RegionWrapper.GLOBAL()) { @Override public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) { - return isAllowed(worldguard.wrapPlayer(BukkitAdapter.adapt(player)), myRegion); + return manager.hasRegion(myRegion.getId()) + && isAllowed(worldguard.wrapPlayer(BukkitAdapter.adapt(player)), myRegion); } }; } else { @@ -185,7 +194,7 @@ public class WorldGuardFeature extends BukkitMaskManager implements Listener { public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) { final LocalPlayer localplayer = worldguard.wrapPlayer(BukkitAdapter.adapt(player)); for (ProtectedRegion myRegion : regions) { - if (!isAllowed(localplayer, myRegion)) { + if (!manager.hasRegion(myRegion.getId()) || !isAllowed(localplayer, myRegion)) { return false; } } From 36ce7afcfffa26eeaf88026a372b952f82ab68b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 22:45:15 +0100 Subject: [PATCH 006/220] Update gradle/wrapper-validation-action action to v2 (#2565) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build-pr.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/upload-release-assets.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 394cb9f56..de239164e 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -11,7 +11,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v1 + uses: gradle/wrapper-validation-action@v2 - name: Setup Java uses: actions/setup-java@v4 with: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 571658fb4..675f0cc1c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v1 + uses: gradle/wrapper-validation-action@v2 - name: Setup Java uses: actions/setup-java@v4 with: diff --git a/.github/workflows/upload-release-assets.yml b/.github/workflows/upload-release-assets.yml index 7315f1d6c..a621e9d13 100644 --- a/.github/workflows/upload-release-assets.yml +++ b/.github/workflows/upload-release-assets.yml @@ -9,7 +9,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v1 + uses: gradle/wrapper-validation-action@v2 - name: Setup Java uses: actions/setup-java@v4 with: From 9beda23f4a66e2680f750c7e27b8e90b573ce01a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 22:45:23 +0100 Subject: [PATCH 007/220] Update dependency org.mockito:mockito-core to v5.10.0 (#2564) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- worldedit-sponge/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9d255510e..5e715d3e3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -46,7 +46,7 @@ text = "3.0.4" piston = "0.5.7" # Tests -mockito = "5.9.0" +mockito = "5.10.0" # Gradle plugins pluginyml = "0.6.0" diff --git a/worldedit-sponge/build.gradle.kts b/worldedit-sponge/build.gradle.kts index 272ea46ec..c37fe591e 100644 --- a/worldedit-sponge/build.gradle.kts +++ b/worldedit-sponge/build.gradle.kts @@ -28,7 +28,7 @@ dependencies { }) api("org.apache.logging.log4j:log4j-api") api("org.bstats:bstats-sponge:1.7") - testImplementation("org.mockito:mockito-core:5.9.0") + testImplementation("org.mockito:mockito-core:5.10.0") } <<<<<<< HEAD From f6c82eaa8234a554b541e6458fa8de4bc8772553 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 22:45:32 +0100 Subject: [PATCH 008/220] Update plotsquared to v7.3.2 (#2563) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5e715d3e3..bd29cd455 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" towny = "0.100.1.5" -plotsquared = "7.3.1" +plotsquared = "7.3.2" # Third party bstats = "3.0.2" From 40f0c7ca9f8fe497ebb81834469f28f02c6c84ee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:12:08 +0100 Subject: [PATCH 009/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.1.10 (#2573) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bd29cd455..5d9cede7c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.1.5" +towny = "0.100.1.10" plotsquared = "7.3.2" # Third party From 000b41331637c0a92b15d7234b3e93c9d231533b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:12:17 +0100 Subject: [PATCH 010/220] Update dependency gradle to v8.6 (#2577) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew.bat | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e0930..a80b22ce5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew.bat b/gradlew.bat index 6689b85be..7101f8e46 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail From a52924e03f8a45aba8a28817db214c2f3316c486 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:14:06 +0100 Subject: [PATCH 011/220] Update plugin xyz.jpenilla.run-paper to v2.2.3 (#2576) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index ad62a28c1..20c957a9d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ import xyz.jpenilla.runpaper.task.RunServer plugins { id("io.github.gradle-nexus.publish-plugin") version "1.3.0" - id("xyz.jpenilla.run-paper") version "2.2.2" + id("xyz.jpenilla.run-paper") version "2.2.3" } if (!File("$rootDir/.git").exists()) { From 63689d8cd87462684ef70b05fa863988aa9ba0f8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:15:03 +0100 Subject: [PATCH 012/220] Update piston to v0.5.8 (#2574) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5d9cede7c..4280b03ff 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -43,7 +43,7 @@ serverlib = "2.3.4" ## Internal text-adapter = "3.0.6" text = "3.0.4" -piston = "0.5.7" +piston = "0.5.8" # Tests mockito = "5.10.0" From e13ef63c6533ad054b19aa99b983626903009f0c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:28:54 +0100 Subject: [PATCH 013/220] Update plotsquared to v7.3.3 (#2575) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4280b03ff..ced8af919 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" towny = "0.100.1.10" -plotsquared = "7.3.2" +plotsquared = "7.3.3" # Third party bstats = "3.0.2" From 4ef4b874984e5bb5bd9622d3060292864b4e2865 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 15:29:22 +0100 Subject: [PATCH 014/220] Update release-drafter/release-drafter action to v6 (#2578) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/release-drafter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 90248b436..131fb810e 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -12,6 +12,6 @@ jobs: if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }} runs-on: ubuntu-latest steps: - - uses: release-drafter/release-drafter@v5 + - uses: release-drafter/release-drafter@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 974078c2cd0ed65e19ecef80a3f81d0dd0cff72a Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Tue, 6 Feb 2024 21:45:25 +0100 Subject: [PATCH 015/220] Release 2.9.2 Signed-off-by: Alexander Brandes --- build.gradle.kts | 4 ++-- .../src/main/java/com/fastasyncworldedit/core/FaweCache.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 20c957a9d..fb3256d36 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,7 +34,7 @@ logger.lifecycle(""" ******************************************* """) -var rootVersion by extra("2.8.5") +var rootVersion by extra("2.9.0") var snapshot by extra("SNAPSHOT") var revision: String by extra("") var buildNumber by extra("") @@ -52,7 +52,7 @@ ext { } } -version = String.format("%s-%s", rootVersion, buildNumber) +version = String.format("%s", rootVersion) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java index f5cc88284..46a3a1574 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java @@ -626,7 +626,7 @@ public enum FaweCache implements Trimable { * Create a new blocking executor with specified name and FaweCache logger * * @return new blocking executor - * @since TODO + * @since 2.9.0 */ public ThreadPoolExecutor newBlockingExecutor(String name) { return newBlockingExecutor(name, LOGGER); @@ -636,7 +636,7 @@ public enum FaweCache implements Trimable { * Create a new blocking executor with specified name and logger * * @return new blocking executor - * @since TODO + * @since 2.9.0 */ public ThreadPoolExecutor newBlockingExecutor(String name, Logger logger) { int nThreads = Settings.settings().QUEUE.PARALLEL_THREADS; From c93ec878fa1f4c04f7e3a783a425171c587a958a Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Tue, 6 Feb 2024 23:09:06 +0100 Subject: [PATCH 016/220] Back to snapshot for development Signed-off-by: Alexander Brandes --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index fb3256d36..84685390e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,7 +34,7 @@ logger.lifecycle(""" ******************************************* """) -var rootVersion by extra("2.9.0") +var rootVersion by extra("2.9.1") var snapshot by extra("SNAPSHOT") var revision: String by extra("") var buildNumber by extra("") @@ -52,7 +52,7 @@ ext { } } -version = String.format("%s", rootVersion) +version = String.format("%s-%s", rootVersion, buildNumber) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") From f94b96d5b2dbc9863bc183bb3764b8158601add2 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Sun, 18 Feb 2024 09:55:06 +0100 Subject: [PATCH 017/220] Use actual radius for inverse and adjust inside region check (#2582) --- .../java/com/sk89q/worldedit/regions/CylinderRegion.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java index 03b38a55c..6439d6079 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java @@ -141,7 +141,7 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { */ public void setRadius(Vector2 radius) { this.radius = radius.add(0.5, 0.5); - this.radiusInverse = Vector2.ONE.divide(radius); + this.radiusInverse = Vector2.ONE.divide(this.radius); } /** @@ -413,11 +413,12 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { final IChunk chunk, final Filter filter, final ChunkFilterBlock block, final IChunkGet get, final IChunkSet set, boolean full ) { - int bcx = chunk.getX() >> 4; - int bcz = chunk.getZ() >> 4; + int bcx = chunk.getX() << 4; + int bcz = chunk.getZ() << 4; int tcx = bcx + 15; int tcz = bcz + 15; - if (contains(bcx, bcz) && contains(tcx, tcz)) { + // must contain all 4 corners for fast path + if (contains(bcx, bcz) && contains(tcx, tcz) && contains(bcx, tcz) && contains(tcx, bcz)) { filter(chunk, filter, block, get, set, minY, maxY, full); return; } From 5a749b3b2ce531baa9a95622811600f1dde8afa3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Mar 2024 12:00:21 +0100 Subject: [PATCH 018/220] Update dependency org.mockito:mockito-core to v5.11.0 (#2601) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- worldedit-sponge/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ced8af919..513d46a23 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -46,7 +46,7 @@ text = "3.0.4" piston = "0.5.8" # Tests -mockito = "5.10.0" +mockito = "5.11.0" # Gradle plugins pluginyml = "0.6.0" diff --git a/worldedit-sponge/build.gradle.kts b/worldedit-sponge/build.gradle.kts index c37fe591e..6498cca7e 100644 --- a/worldedit-sponge/build.gradle.kts +++ b/worldedit-sponge/build.gradle.kts @@ -28,7 +28,7 @@ dependencies { }) api("org.apache.logging.log4j:log4j-api") api("org.bstats:bstats-sponge:1.7") - testImplementation("org.mockito:mockito-core:5.10.0") + testImplementation("org.mockito:mockito-core:5.11.0") } <<<<<<< HEAD From c74486f1403b74b174f59015018d78bc8e54ea3d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Mar 2024 12:00:40 +0100 Subject: [PATCH 019/220] Update dependency net.kyori:adventure-nbt to v4.16.0 (#2600) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- worldedit-bukkit/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index 5a9273371..1a922b7af 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -178,7 +178,7 @@ tasks.named("shadowJar") { include(dependency("org.lz4:lz4-java:1.8.0")) } relocate("net.kyori", "com.fastasyncworldedit.core.adventure") { - include(dependency("net.kyori:adventure-nbt:4.15.0")) + include(dependency("net.kyori:adventure-nbt:4.16.0")) } relocate("com.zaxxer", "com.fastasyncworldedit.core.math") { include(dependency("com.zaxxer:SparseBitSet:1.3")) From dbc84a4565311d8f68b98d3846e99f8cb3d8c046 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Mar 2024 12:01:09 +0100 Subject: [PATCH 020/220] Update adventure to v4.16.0 (#2599) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 513d46a23..48443e60e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,7 +21,7 @@ plotsquared = "7.3.3" bstats = "3.0.2" sparsebitset = "1.3" parallelgzip = "1.0.5" -adventure = "4.15.0" +adventure = "4.16.0" adventure-bukkit = "4.3.2" checkerqual = "3.42.0" truezip = "6.8.4" From d62e631ce3e0789679a9349c3076ec321f3891b6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Mar 2024 12:01:49 +0100 Subject: [PATCH 021/220] Update plotsquared to v7.3.5 (#2598) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 48443e60e..264ff5a59 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" towny = "0.100.1.10" -plotsquared = "7.3.3" +plotsquared = "7.3.5" # Third party bstats = "3.0.2" From 7af7c28a9ae5ef7ffe57dd31d680a2d2c9c7a0fa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Mar 2024 12:02:08 +0100 Subject: [PATCH 022/220] Update dependency org.ajoberstar.grgit:grgit-gradle to v5.2.2 (#2596) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index fdb47a435..e4227d576 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -22,7 +22,7 @@ val properties = Properties().also { props -> dependencies { implementation(gradleApi()) - implementation("org.ajoberstar.grgit:grgit-gradle:5.2.1") + implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2") implementation("com.github.johnrengelman:shadow:8.1.1") implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.11") } From 3a9bbb72932ef9740111830364cb942165b8bf8e Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Sat, 2 Mar 2024 12:31:25 +0100 Subject: [PATCH 023/220] Update renovate.json --- .github/renovate.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/renovate.json b/.github/renovate.json index 740d991fb..3d0f91b5a 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -33,9 +33,6 @@ "Renovate" ], "rebaseWhen" : "conflicted", - "schedule" : [ - "on the first day of the month" - ], "customManagers" : [ { "customType" : "regex", From f5dfe3ae168c8225ef57e44ad4cd1b2b20f49880 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Sat, 2 Mar 2024 13:43:38 +0100 Subject: [PATCH 024/220] fix rollback database query (#2591) --- .../core/database/RollbackDatabase.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java index 603e8061a..1677521fe 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java @@ -159,18 +159,23 @@ public class RollbackDatabase extends AsyncNotifyQueue { Future future = call(() -> { try { int count = 0; - String stmtStr; + String stmtStr = """ + SELECT * FROM `%sedits` + WHERE `time` > ? + AND `x2` >= ? + AND `x1` <= ? + AND `z2` >= ? + AND `z1` <= ? + AND `y2` >= ? + AND `y1` <= ? + """; + if (uuid != null) { + stmtStr += "\n AND `player`= ?"; + } if (ascending) { - if (uuid == null) { - stmtStr = "SELECT * FROM`%sedits` WHERE `time`>? AND `x2`>=? AND `x1`<=? AND `z2`>=? AND `z1`<=? AND " + - "`y2`>=? AND `y1`<=? ORDER BY `time` , `id`"; - } else { - stmtStr = "SELECT * FROM`%sedits` WHERE `time`>? AND `x2`>=? AND `x1`<=? AND `z2`>=? AND `z1`<=? AND " + - "`y2`>=? AND `y1`<=? AND `player`=? ORDER BY `time` ASC, `id` ASC"; - } + stmtStr += "\n ORDER BY `time` ASC, `id` ASC"; } else { - stmtStr = "SELECT * FROM`%sedits` WHERE `time`>? AND `x2`>=? AND `x1`<=? AND `z2`>=? AND `z1`<=? AND " + - "`y2`>=? AND `y1`<=? AND `player`=? ORDER BY `time` DESC, `id` DESC"; + stmtStr += "\n ORDER BY `time` DESC, `id` DESC"; } try (PreparedStatement stmt = connection.prepareStatement(stmtStr.formatted(this.prefix))) { stmt.setInt(1, (int) (minTime / 1000)); From b6d691d12b1ff5910705c301f0f818e9fb271e25 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 2 Mar 2024 11:02:35 +0000 Subject: [PATCH 025/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.1.17 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 264ff5a59..0119179f7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.1.10" +towny = "0.100.1.17" plotsquared = "7.3.5" # Third party From 164271374b46957775f52aedf7a39bebd3ff3df3 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Mon, 4 Mar 2024 07:31:56 +0100 Subject: [PATCH 026/220] Decrease lock contention in SingleThreadQueueExtent (#2594) * thread local extent * avoid race conditions due to ChunkHolder pooling * clean up JFR events, javadoc * remove ThreadLocalPassthroughExtent --- .../implementation/ParallelQueueExtent.java | 33 +++++++++++++- .../queue/implementation/QueueHandler.java | 2 +- .../SingleThreadQueueExtent.java | 16 +++---- .../implementation/chunk/ChunkHolder.java | 43 +++++++++++-------- .../com/sk89q/worldedit/LocalSession.java | 5 +++ 5 files changed, 67 insertions(+), 32 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java index 2d2b45aae..52e6cf2c6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java @@ -18,6 +18,7 @@ import com.fastasyncworldedit.core.queue.Filter; import com.fastasyncworldedit.core.queue.IQueueChunk; import com.fastasyncworldedit.core.queue.IQueueExtent; import com.sk89q.worldedit.MaxChangedBlocksException; +import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.function.mask.BlockMask; import com.sk89q.worldedit.function.mask.ExistingBlockMask; @@ -45,6 +46,7 @@ import java.util.stream.IntStream; public class ParallelQueueExtent extends PassthroughExtent { private static final Logger LOGGER = LogManagerCompat.getLogger(); + private static final ThreadLocal extents = new ThreadLocal<>(); private final World world; private final QueueHandler handler; @@ -73,10 +75,36 @@ public class ParallelQueueExtent extends PassthroughExtent { this.fastmode = fastmode; } + /** + * Removes the extent currently associated with the calling thread. + */ + public static void clearCurrentExtent() { + extents.remove(); + } + + /** + * Sets the extent associated with the calling thread. + */ + public static void setCurrentExtent(Extent extent) { + extents.set(extent); + } + + private void enter(Extent extent) { + setCurrentExtent(extent); + } + + private void exit() { + clearCurrentExtent(); + } + @Override @SuppressWarnings({"unchecked", "rawtypes"}) public IQueueExtent getExtent() { - return (IQueueExtent) super.getExtent(); + Extent extent = extents.get(); + if (extent == null) { + extent = super.getExtent(); + } + return (IQueueExtent) extent; } @Override @@ -114,6 +142,7 @@ public class ParallelQueueExtent extends PassthroughExtent { final SingleThreadQueueExtent queue = (SingleThreadQueueExtent) getNewQueue(); queue.setFastMode(fastmode); queue.setFaweExceptionArray(faweExceptionReasonsUsed); + enter(queue); synchronized (queue) { try { ChunkFilterBlock block = null; @@ -154,6 +183,8 @@ public class ParallelQueueExtent extends PassthroughExtent { exceptionCount++; LOGGER.warn(message); } + } finally { + exit(); } })).toArray(ForkJoinTask[]::new); // Join filters diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/QueueHandler.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/QueueHandler.java index 956c33fb2..7bdbf4645 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/QueueHandler.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/QueueHandler.java @@ -408,7 +408,7 @@ public abstract class QueueHandler implements Trimable, Runnable { * Sets the current thread's {@link IQueueExtent} instance in the queue pool to null. */ public void unCache() { - queuePool.set(null); + queuePool.remove(); } private IQueueExtent pool() { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java index 132229d1d..6e06ce348 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java @@ -9,7 +9,6 @@ import com.fastasyncworldedit.core.extent.processor.EmptyBatchProcessor; import com.fastasyncworldedit.core.extent.processor.ExtentBatchProcessorHolder; import com.fastasyncworldedit.core.extent.processor.ProcessorScope; import com.fastasyncworldedit.core.internal.exception.FaweException; -import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkCache; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; @@ -48,11 +47,9 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen private static final Logger LOGGER = LogManagerCompat.getLogger(); - // Pool discarded chunks for reuse (can safely be cleared by another thread) - // private static final ConcurrentLinkedQueue CHUNK_POOL = new ConcurrentLinkedQueue<>(); // Chunks currently being queued / worked on - private final Long2ObjectLinkedOpenHashMap chunks = new Long2ObjectLinkedOpenHashMap<>(); - private final ConcurrentLinkedQueue submissions = new ConcurrentLinkedQueue<>(); + private final Long2ObjectLinkedOpenHashMap> chunks = new Long2ObjectLinkedOpenHashMap<>(); + private final ConcurrentLinkedQueue> submissions = new ConcurrentLinkedQueue<>(); private final ReentrantLock getChunkLock = new ReentrantLock(); private World world = null; private int minY = 0; @@ -142,12 +139,10 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen if (!this.initialized) { return; } - if (!this.chunks.isEmpty()) { - getChunkLock.lock(); - for (IChunk chunk : this.chunks.values()) { - chunk.recycle(); - } + getChunkLock.lock(); + try { this.chunks.clear(); + } finally { getChunkLock.unlock(); } this.enabledQueue = true; @@ -234,7 +229,6 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen } } if (chunk.isEmpty()) { - chunk.recycle(); Future result = Futures.immediateFuture(null); return (V) result; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java index 6103a1649..a7417eddf 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java @@ -1,7 +1,5 @@ package com.fastasyncworldedit.core.queue.implementation.chunk; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock; import com.fastasyncworldedit.core.extent.processor.EmptyBatchProcessor; import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; @@ -11,36 +9,34 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueChunk; import com.fastasyncworldedit.core.queue.IQueueExtent; -import com.fastasyncworldedit.core.queue.Pool; +import com.fastasyncworldedit.core.queue.implementation.ParallelQueueExtent; import com.fastasyncworldedit.core.util.MemUtil; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; +import org.apache.logging.log4j.Logger; import javax.annotation.Nullable; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicBoolean; /** * An abstract {@link IChunk} class that implements basic get/set blocks. */ @SuppressWarnings("rawtypes") public class ChunkHolder> implements IQueueChunk { - - private static final Pool POOL = FaweCache.INSTANCE.registerPool( - ChunkHolder.class, - ChunkHolder::new, - Settings.settings().QUEUE.POOL - ); + private static final Logger LOGGER = LogManagerCompat.getLogger(); public static ChunkHolder newInstance() { - return POOL.poll(); + return new ChunkHolder(); } private volatile IChunkGet chunkExisting; // The existing chunk (e.g. a clipboard, or the world, before changes) @@ -63,16 +59,12 @@ public class ChunkHolder> implements IQueueChunk { this.delegate = delegate; } + private static final AtomicBoolean recycleWarning = new AtomicBoolean(false); @Override - public synchronized void recycle() { - delegate = NULL; - if (chunkSet != null) { - chunkSet.recycle(); - chunkSet = null; + public void recycle() { + if (!recycleWarning.getAndSet(true)) { + LOGGER.warn("ChunkHolder should not be recycled.", new Exception()); } - chunkExisting = null; - extent = null; - POOL.offer(this); } public long initAge() { @@ -1018,7 +1010,6 @@ public class ChunkHolder> implements IQueueChunk { // Do nothing }); } - recycle(); return null; } @@ -1031,6 +1022,7 @@ public class ChunkHolder> implements IQueueChunk { IChunkGet get = getOrCreateGet(); try { get.lockCall(); + trackExtent(); boolean postProcess = !(getExtent().getPostProcessor() instanceof EmptyBatchProcessor); final int copyKey = get.setCreateCopy(postProcess); final IChunkSet iChunkSet = getExtent().processSet(this, get, set); @@ -1046,11 +1038,24 @@ public class ChunkHolder> implements IQueueChunk { return get.call(set, finalizer); } finally { get.unlockCall(); + untrackExtent(); } } return null; } + // "call" can be called by QueueHandler#blockingExecutor. In such case, we still want the other thread + // to use this SingleThreadQueueExtent. Otherwise, many threads might end up locking on **one** STQE. + // This way, locking is spread across multiple STQEs, allowing for better performance + + private void trackExtent() { + ParallelQueueExtent.setCurrentExtent(extent); + } + + private void untrackExtent() { + ParallelQueueExtent.clearCurrentExtent(); + } + /** * Get the extent this chunk is in. */ diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index 67bbff7af..a00b26702 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -32,6 +32,7 @@ import com.fastasyncworldedit.core.internal.io.FaweOutputStream; import com.fastasyncworldedit.core.limit.FaweLimit; import com.fastasyncworldedit.core.util.BrushCache; import com.fastasyncworldedit.core.util.MainUtil; +import com.fastasyncworldedit.core.util.MaskTraverser; import com.fastasyncworldedit.core.util.StringMan; import com.fastasyncworldedit.core.util.TaskManager; import com.fastasyncworldedit.core.util.TextureHolder; @@ -53,6 +54,7 @@ import com.sk89q.worldedit.command.tool.Tool; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Locatable; +import com.sk89q.worldedit.extent.NullExtent; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.inventory.BlockBag; @@ -594,6 +596,9 @@ public class LocalSession implements TextureHolder { long size = MainUtil.getSize(item); historySize -= size; } + // free the mask from any remaining references to e.g. extents + // if used again + new MaskTraverser(mask).reset(NullExtent.INSTANCE); } finally { historyWriteLock.unlock(); } From 641297497abf26886f2f11f24d2978143fad5c33 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Mon, 4 Mar 2024 07:32:33 +0100 Subject: [PATCH 027/220] Maintain insertion order for RandomPattern sub-patterns (#2603) --- .../core/util/collection/RandomCollection.java | 2 +- .../com/sk89q/worldedit/function/pattern/RandomPattern.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/RandomCollection.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/RandomCollection.java index a157ebd7c..6214777e5 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/RandomCollection.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/RandomCollection.java @@ -33,7 +33,7 @@ public abstract class RandomCollection { public static RandomCollection of(Map weights, SimpleRandom random) { checkNotNull(random); return FastRandomCollection.create(weights, random) - .orElse(new SimpleRandomCollection<>(weights, random)); + .orElseGet(() -> new SimpleRandomCollection<>(weights, random)); } public void setRandom(SimpleRandom random) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java index 0568fd5b8..1d2df7223 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java @@ -27,7 +27,7 @@ import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; @@ -41,7 +41,7 @@ public class RandomPattern extends AbstractPattern { //FAWE start - SimpleRandom > Random, LHS

> List private final SimpleRandom random; - private Map weights = new HashMap<>(); + private Map weights = new LinkedHashMap<>(); private RandomCollection collection; private LinkedHashSet patterns = new LinkedHashSet<>(); //FAWE end From eca4dbdca1df8a02fc073f57f9bc84960207d9e6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 21:56:45 +0000 Subject: [PATCH 028/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.1.18 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0119179f7..c55c9169c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.1.17" +towny = "0.100.1.18" plotsquared = "7.3.5" # Third party From 9fa3385edccfeee1dc40a1e4d91aa657ea523bc5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 9 Mar 2024 13:02:30 +0000 Subject: [PATCH 029/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.1.19 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c55c9169c..414e204f5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.1.18" +towny = "0.100.1.19" plotsquared = "7.3.5" # Third party From e682917c437096885b84332cf421d62fc395bcf8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 10 Mar 2024 18:53:53 +0000 Subject: [PATCH 030/220] Update plotsquared to v7.3.6 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 414e204f5..19a0bd368 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" towny = "0.100.1.19" -plotsquared = "7.3.5" +plotsquared = "7.3.6" # Third party bstats = "3.0.2" From 1053d467a43c215083908679d16b5d4727cadf40 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 17:47:53 +0000 Subject: [PATCH 031/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.1.20 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 19a0bd368..a6acb6c2e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.1.19" +towny = "0.100.1.20" plotsquared = "7.3.6" # Third party From facd31ce31fc31b7a6e7fdbed5b81777231aaf13 Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 14 Mar 2024 17:56:08 +0100 Subject: [PATCH 032/220] fix: do not forcefully direct to x,y,z methods in AbstractDelegateExtent (#2614) - we probably shouldn't be doing this --- .../extent/AbstractDelegateExtent.java | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java index 768af09c1..f2d7dc884 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/AbstractDelegateExtent.java @@ -91,9 +91,7 @@ public class AbstractDelegateExtent implements Extent { @Override public BlockState getBlock(BlockVector3 position) { - //FAWE start - return coordinates - return extent.getBlock(position.getX(), position.getY(), position.getZ()); - //FAWE end + return extent.getBlock(position); } @Override @@ -103,9 +101,7 @@ public class AbstractDelegateExtent implements Extent { @Override public BaseBlock getFullBlock(BlockVector3 position) { - //FAWE start - return coordinates - return extent.getFullBlock(position.getX(), position.getY(), position.getZ()); - //FAWE end + return extent.getFullBlock(position); } //FAWE start @@ -117,9 +113,7 @@ public class AbstractDelegateExtent implements Extent { @Override public BaseBlock getFullBlock(int x, int y, int z) { - //FAWE start - return coordinates return extent.getFullBlock(x, y, z); - //FAWE end } @Override @@ -375,9 +369,7 @@ public class AbstractDelegateExtent implements Extent { @Override public BiomeType getBiome(BlockVector3 position) { - //FAWE start - switch top x,y,z - return extent.getBiomeType(position.getX(), position.getY(), position.getZ()); - //FAWE end + return extent.getBiome(position); } //FAWE start @@ -420,9 +412,7 @@ public class AbstractDelegateExtent implements Extent { @Override public > boolean setBlock(BlockVector3 position, T block) throws WorldEditException { - //FAWE start - switch to x,y,z - return extent.setBlock(position.getX(), position.getY(), position.getZ(), block); - //FAWE end + return extent.setBlock(position, block); } //FAWE start @@ -447,9 +437,7 @@ public class AbstractDelegateExtent implements Extent { @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { - //FAWE start - switch to x,y,z - return extent.setBiome(position.getX(), position.getY(), position.getZ(), biome); - //FAWE end + return extent.setBiome(position, biome); } //FAWE start From df9527b0b7c4a686b6496dae26661392356d74fa Mon Sep 17 00:00:00 2001 From: MineFact <66020920+MineFact@users.noreply.github.com> Date: Fri, 15 Mar 2024 11:27:25 +0100 Subject: [PATCH 033/220] fix: set and clone Expression Environment after Expression cloning (#2617) - Fixes #2616 --- .../sk89q/worldedit/internal/expression/Expression.java | 5 ++++- .../internal/expression/ExpressionEnvironment.java | 5 ++++- .../regions/shape/WorldEditExpressionEnvironment.java | 9 +++++++-- .../internal/expression/BaseExpressionTest.java | 5 +++++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java index b7ce1acf3..23ba96a88 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Expression.java @@ -24,6 +24,7 @@ import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.antlr.ExpressionLexer; import com.sk89q.worldedit.antlr.ExpressionParser; import com.sk89q.worldedit.internal.expression.invoke.ExpressionCompiler; +import com.sk89q.worldedit.regions.shape.WorldEditExpressionEnvironment; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; @@ -199,7 +200,9 @@ public class Expression implements Cloneable { //FAWE start public Expression clone() { - return new Expression(initialExpression, new HashSet<>(providedSlots)); + Expression expression = new Expression(initialExpression, new HashSet<>(providedSlots)); + expression.setEnvironment(getEnvironment().clone()); + return expression; } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/ExpressionEnvironment.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/ExpressionEnvironment.java index 061a520a9..5e44d9da1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/ExpressionEnvironment.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/ExpressionEnvironment.java @@ -22,7 +22,7 @@ package com.sk89q.worldedit.internal.expression; /** * Represents a way to access blocks in a world. Has to accept non-rounded coordinates. */ -public interface ExpressionEnvironment { +public interface ExpressionEnvironment extends Cloneable { int getBlockType(double x, double y, double z); @@ -36,4 +36,7 @@ public interface ExpressionEnvironment { int getBlockDataRel(double x, double y, double z); + // FAWE start + ExpressionEnvironment clone(); + // FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/WorldEditExpressionEnvironment.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/WorldEditExpressionEnvironment.java index 15e93c7db..4b87ebcc6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/WorldEditExpressionEnvironment.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/WorldEditExpressionEnvironment.java @@ -28,6 +28,8 @@ import com.sk89q.worldedit.math.Vector3; public class WorldEditExpressionEnvironment implements ExpressionEnvironment { + private static final Vector3 BLOCK_CENTER_OFFSET = Vector3.at(0.5, 0.5, 0.5); + private final Vector3 unit; private final Vector3 zero2; //FAWE start - MutableVector3 @@ -42,7 +44,7 @@ public class WorldEditExpressionEnvironment implements ExpressionEnvironment { public WorldEditExpressionEnvironment(Extent extent, Vector3 unit, Vector3 zero) { this.extent = extent; this.unit = unit; - this.zero2 = zero.add(0.5, 0.5, 0.5); + this.zero2 = zero.add(BLOCK_CENTER_OFFSET); } public BlockVector3 toWorld(double x, double y, double z) { @@ -94,10 +96,13 @@ public class WorldEditExpressionEnvironment implements ExpressionEnvironment { public Vector3 toWorldRel(double x, double y, double z) { return current.add(x, y, z); } + + public WorldEditExpressionEnvironment clone() { + return new WorldEditExpressionEnvironment(extent, unit, zero2.subtract(BLOCK_CENTER_OFFSET)); + } //FAWe end public void setCurrentBlock(Vector3 current) { this.current = current; } - } diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/BaseExpressionTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/BaseExpressionTest.java index 3491347a4..3c8ba65d6 100644 --- a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/BaseExpressionTest.java +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/BaseExpressionTest.java @@ -114,6 +114,11 @@ class BaseExpressionTest { public int getBlockDataRel(double x, double y, double z) { return (int) y * 100; } + + @Override + public ExpressionEnvironment clone() { + return this; + } }); return expression.evaluate(); From 8363badf8015b58475b500f2814ed05b290f6ac1 Mon Sep 17 00:00:00 2001 From: Jordan Date: Fri, 15 Mar 2024 18:39:35 +0100 Subject: [PATCH 034/220] fix: correctly (de)serialise ItemType (#2620) - InternalId changes depending on ~~magic~~ so we should not store this value - fixes #2589 --- .../sk89q/worldedit/util/gson/GsonUtil.java | 3 +++ .../worldedit/util/gson/ItemTypeAdapter.java | 26 +++++++++++++++++++ .../sk89q/worldedit/world/item/ItemType.java | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/ItemTypeAdapter.java diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java index 9b9a9a6e5..d31750e11 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java @@ -23,6 +23,8 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; +import com.sk89q.worldedit.world.item.ItemType; +import com.sk89q.worldedit.world.item.ItemTypes; /** * Utility methods for Google's GSON library. @@ -41,6 +43,7 @@ public final class GsonUtil { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(Vector3.class, new VectorAdapter()); gsonBuilder.registerTypeAdapter(BlockVector3.class, new BlockVectorAdapter()); + gsonBuilder.registerTypeAdapter(ItemType.class, new ItemTypeAdapter()); return gsonBuilder; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/ItemTypeAdapter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/ItemTypeAdapter.java new file mode 100644 index 000000000..5f8d6d9a2 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/ItemTypeAdapter.java @@ -0,0 +1,26 @@ +package com.sk89q.worldedit.util.gson; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.sk89q.worldedit.world.item.ItemType; +import com.sk89q.worldedit.world.item.ItemTypes; + +import java.lang.reflect.Type; + +public final class ItemTypeAdapter implements JsonDeserializer { + + @Override + public ItemType deserialize(JsonElement json, Type type, JsonDeserializationContext cont) throws JsonParseException { + JsonObject jsonObject = json.getAsJsonObject(); + String id = jsonObject.get("id").getAsString(); + ItemType itemType = ItemTypes.get(id); + if (itemType == null) { + throw new JsonParseException("Could not parse item type `" + id + "`"); + } + return itemType; + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java index 5a1e7653f..16a65c308 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java @@ -79,7 +79,7 @@ public class ItemType implements RegistryItem, Keyed { } //FAWE start - private int internalId; + private transient int internalId; @Override public void setInternalId(int internalId) { From 10dc64eeaf5693cf2d1e4064c045cd36262cf42a Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Fri, 15 Mar 2024 18:41:16 +0100 Subject: [PATCH 035/220] Make sure to process all chunks in PQE even if PARALLEL_THREADS = 1 (#2611) make sure to process all chunks in PQE even if PARALLEL_THREADS = 1 --- .../core/queue/implementation/ParallelQueueExtent.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java index 52e6cf2c6..e88a9ccd3 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java @@ -131,9 +131,12 @@ public class ParallelQueueExtent extends PassthroughExtent { // Get a pool, to operate on the chunks in parallel final int size = Math.min(chunks.size(), Settings.settings().QUEUE.PARALLEL_THREADS); - if (size <= 1 && chunksIter.hasNext()) { - BlockVector2 pos = chunksIter.next(); - getExtent().apply(null, filter, region, pos.getX(), pos.getZ(), full); + if (size <= 1) { + // if PQE is ever used with PARALLEL_THREADS = 1, or only one chunk is edited, just run sequentially + while (chunksIter.hasNext()) { + BlockVector2 pos = chunksIter.next(); + getExtent().apply(null, filter, region, pos.getX(), pos.getZ(), full); + } } else { final ForkJoinTask[] tasks = IntStream.range(0, size).mapToObj(i -> handler.submit(() -> { try { From 37d4e9bb6f431204ceccb59b836de9e5358c7acb Mon Sep 17 00:00:00 2001 From: Zeranny Date: Fri, 15 Mar 2024 17:41:53 +0000 Subject: [PATCH 036/220] Allow factory suggestions to have parser context (#2613) * Add context to rich parser * Description for getSuggestions with context * Tidy up imports * Swap which getSuggestions is primary * Revert "Swap which getSuggestions is primary" This reverts commit 5c257f60ea9ec002e407b2a4a8a7c6ede6bee5e7. * Revert default swap and add deprecation note --- .../extension/factory/parser/RichParser.java | 25 ++++++++++++++++--- .../factory/parser/mask/RichMaskParser.java | 8 +++--- .../command/argument/FactoryConverter.java | 14 ++++++++--- .../extension/factory/MaskFactory.java | 6 ++--- .../internal/registry/AbstractFactory.java | 7 +++++- .../internal/registry/InputParser.java | 13 ++++++++++ 6 files changed, 58 insertions(+), 15 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/RichParser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/RichParser.java index 617143495..30dad8f37 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/RichParser.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/RichParser.java @@ -53,7 +53,7 @@ public abstract class RichParser extends InputParser implements AliasedPar } @Nonnull - private Function> extractArguments(String input) { + private Function> extractArguments(String input, ParserContext context) { return prefix -> { if (input.length() > prefix.length() && input.startsWith(prefix + "[")) { // input already contains argument(s) -> extract them @@ -65,7 +65,7 @@ public abstract class RichParser extends InputParser implements AliasedPar } String previous = prefix + builder; // read the suggestions for the last argument - return getSuggestions(strings[strings.length - 1], strings.length - 1) + return getSuggestions(strings[strings.length - 1], strings.length - 1, context) .map(suggestion -> previous + "[" + suggestion); } else { return Stream.of(prefix); @@ -95,7 +95,7 @@ public abstract class RichParser extends InputParser implements AliasedPar public Stream getSuggestions(String input) { return Arrays.stream(this.prefixes) .filter(validPrefix(input)) - .flatMap(extractArguments(input)); + .flatMap(extractArguments(input, new ParserContext())); } @Override @@ -122,8 +122,25 @@ public abstract class RichParser extends InputParser implements AliasedPar * @param argumentInput the already provided input for the argument at the given index. * @param index the index of the argument to get suggestions for. * @return a stream of suggestions matching the given input for the argument at the given index. + * + * @deprecated Use the version that takes a {@link ParserContext}, {@link #getSuggestions(String, int, ParserContext)} */ - protected abstract Stream getSuggestions(String argumentInput, int index); + @Deprecated + protected Stream getSuggestions(String argumentInput, int index) { + return Stream.empty(); + } + + /** + * Returns a stream of suggestions for the argument at the given index. + * + * @param argumentInput the already provided input for the argument at the given index. + * @param index the index of the argument to get suggestions for. + * @param context the context which may optionally be provided by a parser. + * @return a stream of suggestions matching the given input for the argument at the given index. + */ + protected Stream getSuggestions(String argumentInput, int index, ParserContext context) { + return getSuggestions(argumentInput, index); + } /** * Parses the already split arguments. diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/RichMaskParser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/RichMaskParser.java index 4e0fbfa91..84437c19a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/RichMaskParser.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/RichMaskParser.java @@ -97,11 +97,11 @@ public class RichMaskParser extends FaweParser { )), () -> { if (full.length() == 1) { - return new ArrayList<>(worldEdit.getMaskFactory().getSuggestions("")); + return new ArrayList<>(worldEdit.getMaskFactory().getSuggestions("", context)); } return new ArrayList<>(worldEdit .getMaskFactory() - .getSuggestions(command.toLowerCase(Locale.ROOT))); + .getSuggestions(command.toLowerCase(Locale.ROOT), context)); } ); } @@ -164,11 +164,11 @@ public class RichMaskParser extends FaweParser { )), () -> { if (full.length() == 1) { - return new ArrayList<>(worldEdit.getMaskFactory().getSuggestions("")); + return new ArrayList<>(worldEdit.getMaskFactory().getSuggestions("", context)); } return new ArrayList<>(worldEdit .getMaskFactory() - .getSuggestions(command.toLowerCase(Locale.ROOT))); + .getSuggestions(command.toLowerCase(Locale.ROOT), context)); } ); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/FactoryConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/FactoryConverter.java index 1a382d43c..d82d25394 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/FactoryConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/FactoryConverter.java @@ -113,8 +113,7 @@ public class FactoryConverter implements ArgumentConverter { ); } - @Override - public ConversionResult convert(String argument, InjectedValueAccess context) { + private ParserContext createContext(InjectedValueAccess context) { Actor actor = context.injectedValue(Key.of(Actor.class)) .orElseThrow(() -> new IllegalStateException("No actor")); LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor); @@ -139,6 +138,13 @@ public class FactoryConverter implements ArgumentConverter { contextTweaker.accept(parserContext); } + return parserContext; + } + + @Override + public ConversionResult convert(String argument, InjectedValueAccess context) { + ParserContext parserContext = createContext(context); + try { return SuccessfulConversion.fromSingle( factoryExtractor.apply(worldEdit).parseFromInput(argument, parserContext) @@ -150,7 +156,9 @@ public class FactoryConverter implements ArgumentConverter { @Override public List getSuggestions(String input, InjectedValueAccess context) { - return factoryExtractor.apply(worldEdit).getSuggestions(input); + ParserContext parserContext = createContext(context); + + return factoryExtractor.apply(worldEdit).getSuggestions(input, parserContext); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java index 24c674f0b..5c8ff7d6f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java @@ -127,13 +127,13 @@ public final class MaskFactory extends AbstractFactory { } @Override - public List getSuggestions(String input) { + public List getSuggestions(String input, final ParserContext parserContext) { final String[] split = input.split(" "); if (split.length > 1) { String prev = input.substring(0, input.lastIndexOf(" ")) + " "; - return super.getSuggestions(split[split.length - 1]).stream().map(s -> prev + s).collect(Collectors.toList()); + return super.getSuggestions(split[split.length - 1], parserContext).stream().map(s -> prev + s).collect(Collectors.toList()); } - return super.getSuggestions(input); + return super.getSuggestions(input, parserContext); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java index ef4299b33..237dd1c4c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java @@ -96,9 +96,14 @@ public abstract class AbstractFactory { throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input))); } + @Deprecated public List getSuggestions(String input) { + return getSuggestions(input, new ParserContext()); + } + + public List getSuggestions(String input, ParserContext context) { return parsers.stream().flatMap( - p -> p.getSuggestions(input) + p -> p.getSuggestions(input, context) ).collect(Collectors.toList()); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/InputParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/InputParser.java index 87829a272..57ec3a247 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/InputParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/InputParser.java @@ -45,9 +45,22 @@ public abstract class InputParser { * Gets a stream of suggestions of input to this parser. * * @return a stream of suggestions + * @deprecated Use the version that takes a {@link ParserContext}, {@link #getSuggestions(String, ParserContext)} */ + @Deprecated public Stream getSuggestions(String input) { return Stream.empty(); } + /** + * Gets a stream of suggestions of input to this parser. + * + * @param input The string input + * @param context The parser context + * + * @return a stream of suggestions + */ + public Stream getSuggestions(String input, ParserContext context) { + return getSuggestions(input); + } } From 84f661d57f595d5b80ffb81e8cc26172634b420d Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Fri, 15 Mar 2024 23:37:02 +0100 Subject: [PATCH 037/220] Release 2.9.1 Signed-off-by: Alexander Brandes --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 84685390e..9d5734134 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -52,7 +52,7 @@ ext { } } -version = String.format("%s-%s", rootVersion, buildNumber) +version = String.format("%s", rootVersion) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") From bb9a0d27f26903f768ba72c729ee3d5f221e8775 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Fri, 15 Mar 2024 23:48:14 +0100 Subject: [PATCH 038/220] Back to snapshot for development Signed-off-by: Alexander Brandes --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9d5734134..c5c27082b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,7 +34,7 @@ logger.lifecycle(""" ******************************************* """) -var rootVersion by extra("2.9.1") +var rootVersion by extra("2.9.2") var snapshot by extra("SNAPSHOT") var revision: String by extra("") var buildNumber by extra("") @@ -52,7 +52,7 @@ ext { } } -version = String.format("%s", rootVersion) +version = String.format("%s-%s", rootVersion, buildNumber) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") From f60539f41ddd6d917b52f6119274c1985dcff2b4 Mon Sep 17 00:00:00 2001 From: Jordan Date: Sat, 16 Mar 2024 20:12:02 +0100 Subject: [PATCH 039/220] chore: deprecate transform extent for removal (#2623) --- .../com/fastasyncworldedit/core/extent/TransformExtent.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java index 91b99b025..64b940d97 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java @@ -12,6 +12,10 @@ import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; +/** + * @deprecated Unused internal, will be removed in v3 + */ +@Deprecated(forRemoval = true, since = "TODO") public class TransformExtent extends BlockTransformExtent { private final MutableVector3 mutable1 = new MutableVector3(); From 0db8154546af60ba7c35ea9da627d77051035d65 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Sun, 17 Mar 2024 08:37:03 +0100 Subject: [PATCH 040/220] Drop support for 1.17.1 (#2627) Signed-off-by: Alexander Brandes --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 - build.gradle.kts | 2 +- settings.gradle.kts | 2 +- .../adapters/adapter-1_17_1/build.gradle.kts | 27 - .../adapter/ext/fawe/PaperweightAdapter.java | 1013 ------ .../ext/fawe/PaperweightDataConverters.java | 2961 ----------------- .../ext/fawe/PaperweightFakePlayer.java | 103 - .../fawe/PaperweightWorldNativeAccess.java | 209 -- .../v1_17_R1_2/PaperweightBlockMaterial.java | 189 -- .../v1_17_R1_2/PaperweightFaweAdapter.java | 671 ---- .../PaperweightFaweWorldNativeAccess.java | 286 -- .../fawe/v1_17_R1_2/PaperweightGetBlocks.java | 1096 ------ .../v1_17_R1_2/PaperweightGetBlocks_Copy.java | 251 -- .../v1_17_R1_2/PaperweightMapChunkUtil.java | 32 - .../PaperweightPlatformAdapter.java | 526 --- .../v1_17_R1_2/PaperweightPostProcessor.java | 175 - .../PaperweightStarlightRelighter.java | 113 - .../PaperweightStarlightRelighterFactory.java | 26 - .../nbt/PaperweightLazyCompoundTag.java | 161 - .../v1_17_R1_2/regen/PaperweightRegen.java | 694 ---- worldedit-bukkit/build.gradle.kts | 2 +- .../bukkit/BukkitServerInterface.java | 3 - .../core/configuration/Settings.java | 8 +- 23 files changed, 4 insertions(+), 8547 deletions(-) delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/build.gradle.kts delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightDataConverters.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightFakePlayer.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightWorldNativeAccess.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightBlockMaterial.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweWorldNativeAccess.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks_Copy.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightMapChunkUtil.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPostProcessor.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightStarlightRelighter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightStarlightRelighterFactory.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/nbt/PaperweightLazyCompoundTag.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/regen/PaperweightRegen.java diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index b687075ad..bc78076bd 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -31,7 +31,6 @@ body: - '1.20' - '1.19.4' - '1.18.2' - - '1.17.1' validations: required: true diff --git a/build.gradle.kts b/build.gradle.kts index c5c27082b..15845439a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -83,7 +83,7 @@ allprojects { } applyCommonConfiguration() -val supportedVersions = listOf("1.17.1", "1.18.2", "1.19.4", "1.20", "1.20.4") +val supportedVersions = listOf("1.18.2", "1.19.4", "1.20", "1.20.4") tasks { supportedVersions.forEach { diff --git a/settings.gradle.kts b/settings.gradle.kts index 6f9b3e8e0..74cba1396 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,7 +2,7 @@ rootProject.name = "FastAsyncWorldEdit" include("worldedit-libs") -listOf("1_17_1", "1_18_2", "1_19_4", "1_20", "1_20_2", "1_20_4").forEach { +listOf("1_18_2", "1_19_4", "1_20", "1_20_2", "1_20_4").forEach { include("worldedit-bukkit:adapters:adapter-$it") } diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_17_1/build.gradle.kts deleted file mode 100644 index 9eb68ea36..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/build.gradle.kts +++ /dev/null @@ -1,27 +0,0 @@ -import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension - -applyPaperweightAdapterConfiguration() - -plugins { - java -} - -repositories { - mavenCentral() - gradlePluginPortal() -} - -java { - toolchain.languageVersion.set(JavaLanguageVersion.of(17)) -} - -configurations.all { - attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17) -} - - -dependencies { - // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.17.1-R0.1-SNAPSHOT - the().paperDevBundle("1.17.1-R0.1-20220414.034903-210") - compileOnly(libs.paperlib) -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightAdapter.java deleted file mode 100644 index 7d1fcc84e..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightAdapter.java +++ /dev/null @@ -1,1013 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit.adapter.ext.fawe; - -import com.google.common.base.Preconditions; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.common.util.concurrent.Futures; -import com.mojang.datafixers.util.Either; -import com.mojang.serialization.Lifecycle; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.blocks.BaseItem; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.PaperweightFaweAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.PaperweightPlatformAdapter; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.extension.platform.Watchdog; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.math.BlockVector2; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.registry.state.BooleanProperty; -import com.sk89q.worldedit.registry.state.DirectionalProperty; -import com.sk89q.worldedit.registry.state.EnumProperty; -import com.sk89q.worldedit.registry.state.IntegerProperty; -import com.sk89q.worldedit.registry.state.Property; -import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; -import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.ByteArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.ByteBinaryTag; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.DoubleBinaryTag; -import com.sk89q.worldedit.util.nbt.EndBinaryTag; -import com.sk89q.worldedit.util.nbt.FloatBinaryTag; -import com.sk89q.worldedit.util.nbt.IntArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.IntBinaryTag; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; -import com.sk89q.worldedit.util.nbt.LongArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.LongBinaryTag; -import com.sk89q.worldedit.util.nbt.ShortBinaryTag; -import com.sk89q.worldedit.util.nbt.StringBinaryTag; -import com.sk89q.worldedit.world.DataFixer; -import com.sk89q.worldedit.world.RegenOptions; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockStateHolder; -import com.sk89q.worldedit.world.block.BlockType; -import com.sk89q.worldedit.world.block.BlockTypes; -import com.sk89q.worldedit.world.item.ItemType; -import net.minecraft.Util; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Registry; -import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.util.StringRepresentable; -import net.minecraft.util.thread.BlockableEventLoop; -import net.minecraft.world.Clearable; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.UseOnContext; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.LevelSettings; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkBiomeContainer; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.dimension.LevelStem; -import net.minecraft.world.level.levelgen.WorldGenSettings; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraft.world.level.storage.PrimaryLevelData; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.Vec3; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World.Environment; -import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.v1_17_R1.CraftServer; -import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_17_R1.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_17_R1.util.CraftMagicNumbers; -import org.bukkit.entity.Player; -import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; -import org.bukkit.generator.ChunkGenerator; -import org.spigotmc.SpigotConfig; -import org.spigotmc.WatchdogThread; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.OptionalInt; -import java.util.OptionalLong; -import java.util.Set; -import java.util.TreeMap; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ForkJoinPool; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -public final class PaperweightAdapter implements BukkitImplAdapter { - - private final Logger LOGGER = Logger.getLogger(getClass().getCanonicalName()); - - private final Field worldsField; - private final Method getChunkFutureMainThreadMethod; - private final Field mainThreadProcessorField; - private final Watchdog watchdog; - - // ------------------------------------------------------------------------ - // Code that may break between versions of Minecraft - // ------------------------------------------------------------------------ - - public PaperweightAdapter() throws NoSuchFieldException, NoSuchMethodException { - // A simple test - CraftServer.class.cast(Bukkit.getServer()); - - int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion(); - if (dataVersion != 2730) { - throw new UnsupportedClassVersionError("Not 1.17.1!"); - } - - worldsField = CraftServer.class.getDeclaredField("worlds"); - worldsField.setAccessible(true); - - getChunkFutureMainThreadMethod = ServerChunkCache.class.getDeclaredMethod("getChunkFutureMainThread", - int.class, int.class, ChunkStatus.class, boolean.class - ); - getChunkFutureMainThreadMethod.setAccessible(true); - - mainThreadProcessorField = ServerChunkCache.class.getDeclaredField( - Refraction.pickName("mainThreadProcessor", "g") - ); - mainThreadProcessorField.setAccessible(true); - - new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this).build(ForkJoinPool.commonPool()); - - Watchdog watchdog; - try { - Class.forName("org.spigotmc.WatchdogThread"); - watchdog = new SpigotWatchdog(); - } catch (ClassNotFoundException | NoSuchFieldException e) { - try { - watchdog = new MojangWatchdog(((CraftServer) Bukkit.getServer()).getServer()); - } catch (NoSuchFieldException ex) { - watchdog = null; - } - } - this.watchdog = watchdog; - - try { - Class.forName("org.spigotmc.SpigotConfig"); - SpigotConfig.config.set("world-settings.faweregentempworld.verbose", false); - } catch (ClassNotFoundException ignored) { - } - } - - @Override - public DataFixer getDataFixer() { - return PaperweightDataConverters.INSTANCE; - } - - /** - * Read the given NBT data into the given tile entity. - * - * @param tileEntity the tile entity - * @param tag the tag - */ - static void readTagIntoTileEntity(net.minecraft.nbt.CompoundTag tag, BlockEntity tileEntity) { - tileEntity.load(tag); - tileEntity.setChanged(); - } - - /** - * Write the tile entity's NBT data to the given tag. - * - * @param tileEntity the tile entity - * @param tag the tag - */ - private static void readTileEntityIntoTag(BlockEntity tileEntity, net.minecraft.nbt.CompoundTag tag) { - tileEntity.save(tag); - } - - /** - * Get the ID string of the given entity. - * - * @param entity the entity - * @return the entity ID - */ - private static String getEntityId(Entity entity) { - return EntityType.getKey(entity.getType()).toString(); - } - - /** - * Create an entity using the given entity ID. - * - * @param id the entity ID - * @param world the world - * @return an entity or null - */ - @Nullable - private static Entity createEntityFromId(String id, net.minecraft.world.level.Level world) { - return EntityType.byString(id).map(t -> t.create(world)).orElse(null); - } - - /** - * Write the given NBT data into the given entity. - * - * @param entity the entity - * @param tag the tag - */ - private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) { - entity.load(tag); - } - - /** - * Write the entity's NBT data to the given tag. - * - * @param entity the entity - * @param tag the tag - */ - private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag tag) { - //FAWE start - avoid villager async catcher - PaperweightPlatformAdapter.readEntityIntoTag(entity, tag); - //FAWE end - } - - private static Block getBlockFromType(BlockType blockType) { - return Registry.BLOCK.get(ResourceLocation.tryParse(blockType.getId())); - } - - private static Item getItemFromType(ItemType itemType) { - return Registry.ITEM.get(ResourceLocation.tryParse(itemType.getId())); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockData data) { - net.minecraft.world.level.block.state.BlockState state = ((CraftBlockData) data).getState(); - int combinedId = Block.getId(state); - return combinedId == 0 && state.getBlock() != Blocks.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockState state) { - Block mcBlock = getBlockFromType(state.getBlockType()); - net.minecraft.world.level.block.state.BlockState newState = mcBlock.defaultBlockState(); - Map, Object> states = state.getStates(); - newState = applyProperties(mcBlock.getStateDefinition(), newState, states); - final int combinedId = Block.getId(newState); - return combinedId == 0 && state.getBlockType() != BlockTypes.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId); - } - - @Deprecated - @Override - public BlockState getBlock(Location location) { - Preconditions.checkNotNull(location); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - final CraftBlockData blockData = chunk.getBlockState(blockPos).createCraftBlockData(); - BlockState state = BukkitAdapter.adapt(blockData); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - - return state; - } - - @Override - public BaseBlock getFullBlock(Location location) { - BlockState state = getBlock(location); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - - // Read the NBT data - BlockEntity te = chunk.getBlockEntity(blockPos); - if (te != null) { - net.minecraft.nbt.CompoundTag tag = te.save(new net.minecraft.nbt.CompoundTag()); - //FAWE start - BinaryTag - return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag)); - //FAWE end - } - - return state.toBaseBlock(); - } - - @Override - public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { - return new PaperweightWorldNativeAccess( - this, - new WeakReference<>(((CraftWorld) world).getHandle()) - ); - } - - private static net.minecraft.core.Direction adapt(Direction face) { - switch (face) { - case NORTH: - return net.minecraft.core.Direction.NORTH; - case SOUTH: - return net.minecraft.core.Direction.SOUTH; - case WEST: - return net.minecraft.core.Direction.WEST; - case EAST: - return net.minecraft.core.Direction.EAST; - case DOWN: - return net.minecraft.core.Direction.DOWN; - case UP: - default: - return net.minecraft.core.Direction.UP; - } - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - private net.minecraft.world.level.block.state.BlockState applyProperties( - StateDefinition stateContainer, - net.minecraft.world.level.block.state.BlockState newState, - Map, Object> states - ) { - for (Map.Entry, Object> state : states.entrySet()) { - net.minecraft.world.level.block.state.properties.Property property = - stateContainer.getProperty(state.getKey().getName()); - Comparable value = (Comparable) state.getValue(); - // we may need to adapt this value, depending on the source prop - if (property instanceof DirectionProperty) { - Direction dir = (Direction) value; - value = adapt(dir); - } else if (property instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - String enumName = (String) value; - value = ((net.minecraft.world.level.block.state.properties.EnumProperty) property) - .getValue(enumName).orElseThrow(() -> - new IllegalStateException( - "Enum property " + property.getName() + " does not contain " + enumName - ) - ); - } - - newState = newState.setValue( - (net.minecraft.world.level.block.state.properties.Property) property, - (Comparable) value - ); - } - return newState; - } - - @Override - public BaseEntity getEntity(org.bukkit.entity.Entity entity) { - checkNotNull(entity); - - CraftEntity craftEntity = ((CraftEntity) entity); - Entity mcEntity = craftEntity.getHandle(); - - String id = getEntityId(mcEntity); - - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - readEntityIntoTag(mcEntity, tag); - //FAWE start - BinaryTag - return new BaseEntity( - com.sk89q.worldedit.world.entity.EntityTypes.get(id), - LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag)) - ); - //FAWE end - } - - @Nullable - @Override - public org.bukkit.entity.Entity createEntity(Location location, BaseEntity state) { - checkNotNull(location); - checkNotNull(state); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - ServerLevel worldServer = craftWorld.getHandle(); - - Entity createdEntity = createEntityFromId(state.getType().getId(), craftWorld.getHandle()); - - if (createdEntity != null) { - CompoundTag nativeTag = state.getNbtData(); - if (nativeTag != null) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNative(nativeTag); - for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - readTagIntoEntity(tag, createdEntity); - } - - createdEntity.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - - worldServer.addEntity(createdEntity, SpawnReason.CUSTOM); - return createdEntity.getBukkitEntity(); - } else { - return null; - } - } - - @Override - public Component getRichBlockName(BlockType blockType) { - return TranslatableComponent.of(getBlockFromType(blockType).getDescriptionId()); - } - - @Override - public Component getRichItemName(ItemType itemType) { - return TranslatableComponent.of(getItemFromType(itemType).getDescriptionId()); - } - - @Override - public Component getRichItemName(BaseItemStack itemStack) { - return TranslatableComponent.of(CraftItemStack.asNMSCopy(BukkitAdapter.adapt(itemStack)).getDescriptionId()); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private static final LoadingCache> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader>() { - @Override - public Property load(net.minecraft.world.level.block.state.properties.Property state) throws Exception { - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else if (state instanceof DirectionProperty) { - return new DirectionalProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).collect(Collectors.toList())); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - return new EnumProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).collect(Collectors.toList())); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else { - throw new IllegalArgumentException("FastAsyncWorldEdit needs an update to support " + state.getClass().getSimpleName()); - } - } - }); - - @SuppressWarnings({ "rawtypes" }) - @Override - public Map> getProperties(BlockType blockType) { - Map> properties = new TreeMap<>(); - Block block = getBlockFromType(blockType); - StateDefinition blockStateList = - block.getStateDefinition(); - for (net.minecraft.world.level.block.state.properties.Property state : blockStateList.getProperties()) { - Property property = PROPERTY_CACHE.getUnchecked(state); - properties.put(property.getName(), property); - } - return properties; - } - - @Override - public void sendFakeNBT(final Player player, final BlockVector3 pos, final CompoundBinaryTag nbtData) { - - } - - @Override - public void sendFakeOP(Player player) { - ((CraftPlayer) player).getHandle().networkManager.send(new ClientboundEntityEventPacket( - ((CraftPlayer) player).getHandle(), (byte) 28 - )); - } - - @Override - public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) { - ItemStack stack = new ItemStack(Registry.ITEM.get(ResourceLocation.tryParse(item.getType().getId())), item.getAmount()); - stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData()))); - return CraftItemStack.asCraftMirror(stack); - } - - @Override - public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { - final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); - weStack.setNbtData(((CompoundTag) toNative(nmsStack.getTag()))); - return weStack; - } - - private final LoadingCache fakePlayers - = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new)); - - @Override - public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) { - CraftWorld craftWorld = (CraftWorld) world; - ServerLevel worldServer = craftWorld.getHandle(); - ItemStack stack = CraftItemStack.asNMSCopy(BukkitAdapter.adapt(item instanceof BaseItemStack - ? ((BaseItemStack) item) : new BaseItemStack(item.getType(), item.getNbtData(), 1))); - stack.setTag((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData())); - - PaperweightFakePlayer fakePlayer; - try { - fakePlayer = fakePlayers.get(worldServer); - } catch (ExecutionException ignored) { - return false; - } - fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack); - fakePlayer.absMoveTo(position.getBlockX(), position.getBlockY(), position.getBlockZ(), - (float) face.toVector().toYaw(), (float) face.toVector().toPitch() - ); - - final BlockPos blockPos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()); - final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos); - final net.minecraft.core.Direction enumFacing = adapt(face); - BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false); - UseOnContext context = new UseOnContext(fakePlayer, InteractionHand.MAIN_HAND, rayTrace); - InteractionResult result = stack.placeItem(context, InteractionHand.MAIN_HAND); - if (result != InteractionResult.SUCCESS) { - if (worldServer - .getBlockState(blockPos) - .use(worldServer, fakePlayer, InteractionHand.MAIN_HAND, rayTrace) - .consumesAction()) { - result = InteractionResult.SUCCESS; - } else { - result = stack.getItem().use(worldServer, fakePlayer, InteractionHand.MAIN_HAND).getResult(); - } - } - - return result == InteractionResult.SUCCESS; - } - - @Override - public boolean canPlaceAt(org.bukkit.World world, BlockVector3 position, BlockState blockState) { - int internalId = BlockStateIdAccess.getBlockStateId(blockState); - net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId); - return blockData.canSurvive( - ((CraftWorld) world).getHandle(), - new BlockPos(position.getX(), position.getY(), position.getZ()) - ); - } - - @Override - public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent extent, RegenOptions options) { - try { - doRegen(bukkitWorld, region, extent, options); - } catch (Exception e) { - throw new IllegalStateException("Regen failed.", e); - } - - return true; - } - - private void doRegen(org.bukkit.World bukkitWorld, Region region, Extent extent, RegenOptions options) throws Exception { - Environment env = bukkitWorld.getEnvironment(); - ChunkGenerator gen = bukkitWorld.getGenerator(); - - Path tempDir = Files.createTempDirectory("FastAsyncWorldEditWorldGen"); - LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir); - ResourceKey worldDimKey = getWorldDimKey(env); - try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("faweregentempworld", worldDimKey)) { - ServerLevel originalWorld = ((CraftWorld) bukkitWorld).getHandle(); - PrimaryLevelData levelProperties = (PrimaryLevelData) originalWorld.getServer() - .getWorldData().overworldData(); - WorldGenSettings originalOpts = levelProperties.worldGenSettings(); - - long seed = options.getSeed().orElse(originalWorld.getSeed()); - WorldGenSettings newOpts = options.getSeed().isPresent() - ? originalOpts.withSeed(levelProperties.isHardcore(), OptionalLong.of(seed)) - : originalOpts; - - LevelSettings newWorldSettings = new LevelSettings( - "faweregentempworld", - levelProperties.settings.gameType(), - levelProperties.settings.hardcore(), - levelProperties.settings.difficulty(), - levelProperties.settings.allowCommands(), - levelProperties.settings.gameRules(), - levelProperties.settings.getDataPackConfig() - ); - PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, Lifecycle.stable()); - - ServerLevel freshWorld = new ServerLevel( - originalWorld.getServer(), - originalWorld.getServer().executor, - session, newWorldData, - originalWorld.dimension(), - originalWorld.dimensionType(), - new NoOpWorldLoadListener(), - newOpts.dimensions().get(worldDimKey).generator(), - originalWorld.isDebug(), - seed, - ImmutableList.of(), - false, - env, gen, - bukkitWorld.getBiomeProvider() - ); - try { - regenForWorld(region, extent, freshWorld, options); - } finally { - freshWorld.getChunkSource().close(false); - } - } finally { - try { - @SuppressWarnings("unchecked") - Map map = (Map) worldsField.get(Bukkit.getServer()); - map.remove("faweregentempworld"); - } catch (IllegalAccessException ignored) { - } - SafeFiles.tryHardToDeleteDir(tempDir); - } - } - - private BiomeType adapt(ServerLevel serverWorld, Biome origBiome) { - ResourceLocation key = serverWorld.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getKey(origBiome); - if (key == null) { - return null; - } - return BiomeTypes.get(key.toString()); - } - - @SuppressWarnings("unchecked") - private void regenForWorld(Region region, Extent extent, ServerLevel serverWorld, RegenOptions options) throws - WorldEditException { - List> chunkLoadings = submitChunkLoadTasks(region, serverWorld); - BlockableEventLoop executor; - try { - executor = (BlockableEventLoop) mainThreadProcessorField.get(serverWorld.getChunkSource()); - } catch (IllegalAccessException e) { - throw new IllegalStateException("Couldn't get executor for chunk loading.", e); - } - executor.managedBlock(() -> { - // bail out early if a future fails - if (chunkLoadings.stream().anyMatch(ftr -> - ftr.isDone() && Futures.getUnchecked(ftr) == null - )) { - return false; - } - return chunkLoadings.stream().allMatch(CompletableFuture::isDone); - }); - Map chunks = new HashMap<>(); - for (CompletableFuture future : chunkLoadings) { - @Nullable - ChunkAccess chunk = future.getNow(null); - checkState(chunk != null, "Failed to generate a chunk, regen failed."); - chunks.put(chunk.getPos(), chunk); - } - - for (BlockVector3 vec : region) { - BlockPos pos = new BlockPos(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ()); - ChunkAccess chunk = chunks.get(new ChunkPos(pos)); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos); - BlockStateHolder state = ((PaperweightFaweAdapter) WorldEditPlugin - .getInstance() - .getBukkitImplAdapter()).adapt(blockData); - Objects.requireNonNull(state); - BlockEntity blockEntity = chunk.getBlockEntity(pos); - if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - blockEntity.save(tag); - //FAWE start - BinaryTag - state = state.toBaseBlock(((CompoundBinaryTag) toNativeBinary(tag))); - //FAWE end - } - extent.setBlock(vec, state.toBaseBlock()); - if (options.shouldRegenBiomes()) { - ChunkBiomeContainer biomeIndex = chunk.getBiomes(); - if (biomeIndex != null) { - Biome origBiome = biomeIndex.getNoiseBiome(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ()); - BiomeType adaptedBiome = adapt(serverWorld, origBiome); - if (adaptedBiome != null) { - extent.setBiome(vec, adaptedBiome); - } - } - } - } - } - - @SuppressWarnings("unchecked") - private List> submitChunkLoadTasks(Region region, ServerLevel serverWorld) { - ServerChunkCache chunkManager = serverWorld.getChunkSource(); - List> chunkLoadings = new ArrayList<>(); - // Pre-gen all the chunks - for (BlockVector2 chunk : region.getChunks()) { - try { - chunkLoadings.add( - ((CompletableFuture>) - getChunkFutureMainThreadMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true)) - .thenApply(either -> either.left().orElse(null)) - ); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new IllegalStateException("Couldn't load chunk for regen.", e); - } - } - return chunkLoadings; - } - - private ResourceKey getWorldDimKey(Environment env) { - switch (env) { - case NETHER: - return LevelStem.NETHER; - case THE_END: - return LevelStem.END; - case NORMAL: - default: - return LevelStem.OVERWORLD; - } - } - - private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( - SideEffect.NEIGHBORS, - SideEffect.LIGHTING, - SideEffect.VALIDATION, - SideEffect.ENTITY_AI, - SideEffect.EVENTS, - SideEffect.UPDATE - ); - - @Override - public Set getSupportedSideEffects() { - return SUPPORTED_SIDE_EFFECTS; - } - - @Override - public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) { - ServerLevel originalWorld = ((CraftWorld) world).getHandle(); - - BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); - if (entity instanceof Clearable) { - ((Clearable) entity).clearContent(); - return true; - } - return false; - } - - // ------------------------------------------------------------------------ - // Code that is less likely to break - // ------------------------------------------------------------------------ - - /** - * Converts from a non-native NMS NBT structure to a native WorldEdit NBT - * structure. - * - * @param foreign non-native NMS NBT structure - * @return native WorldEdit NBT structure - */ - //FAWE start - BinaryTag - @Override - public BinaryTag toNativeBinary(net.minecraft.nbt.Tag foreign) { - if (foreign == null) { - return null; - } - if (foreign instanceof net.minecraft.nbt.CompoundTag) { - Map values = new HashMap<>(); - Set foreignKeys = ((net.minecraft.nbt.CompoundTag) foreign).getAllKeys(); - - for (String str : foreignKeys) { - net.minecraft.nbt.Tag base = ((net.minecraft.nbt.CompoundTag) foreign).get(str); - values.put(str, toNativeBinary(base)); - } - return CompoundBinaryTag.from(values); - } else if (foreign instanceof net.minecraft.nbt.ByteTag) { - return ByteBinaryTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); - } else if (foreign instanceof net.minecraft.nbt.ByteArrayTag) { - return ByteArrayBinaryTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); - } else if (foreign instanceof net.minecraft.nbt.DoubleTag) { - return DoubleBinaryTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); - } else if (foreign instanceof net.minecraft.nbt.FloatTag) { - return FloatBinaryTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); - } else if (foreign instanceof net.minecraft.nbt.IntTag) { - return IntBinaryTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); - } else if (foreign instanceof net.minecraft.nbt.IntArrayTag) { - return IntArrayBinaryTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); - } else if (foreign instanceof net.minecraft.nbt.LongArrayTag) { - return LongArrayBinaryTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); - } else if (foreign instanceof net.minecraft.nbt.ListTag) { - try { - return toNativeList((net.minecraft.nbt.ListTag) foreign); - } catch (Throwable e) { - LOGGER.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); - return ListBinaryTag.empty(); - } - } else if (foreign instanceof net.minecraft.nbt.LongTag) { - return LongBinaryTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); - } else if (foreign instanceof net.minecraft.nbt.ShortTag) { - return ShortBinaryTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); - } else if (foreign instanceof net.minecraft.nbt.StringTag) { - return StringBinaryTag.of(foreign.getAsString()); - } else if (foreign instanceof net.minecraft.nbt.EndTag) { - return EndBinaryTag.get(); - } else { - throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); - } - } - - /** - * Convert a foreign NBT list tag into a native WorldEdit one. - * - * @param foreign the foreign tag - * @return the converted tag - * @throws SecurityException on error - * @throws IllegalArgumentException on error - */ - private ListBinaryTag toNativeList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException { - ListBinaryTag.Builder values = ListBinaryTag.builder(); - - for (net.minecraft.nbt.Tag tag : foreign) { - values.add(toNativeBinary(tag)); - } - - return values.build(); - } - - /** - * Converts a WorldEdit-native NBT structure to a NMS structure. - * - * @param foreign structure to convert - * @return non-native structure - */ - @Override - public net.minecraft.nbt.Tag fromNativeBinary(BinaryTag foreign) { - if (foreign == null) { - return null; - } - if (foreign instanceof CompoundBinaryTag) { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - for (String key : ((CompoundBinaryTag) foreign).keySet()) { - tag.put(key, fromNativeBinary(((CompoundBinaryTag) foreign).get(key))); - } - return tag; - } else if (foreign instanceof ByteBinaryTag) { - return net.minecraft.nbt.ByteTag.valueOf(((ByteBinaryTag) foreign).value()); - } else if (foreign instanceof ByteArrayBinaryTag) { - return new net.minecraft.nbt.ByteArrayTag(((ByteArrayBinaryTag) foreign).value()); - } else if (foreign instanceof DoubleBinaryTag) { - return net.minecraft.nbt.DoubleTag.valueOf(((DoubleBinaryTag) foreign).value()); - } else if (foreign instanceof FloatBinaryTag) { - return net.minecraft.nbt.FloatTag.valueOf(((FloatBinaryTag) foreign).value()); - } else if (foreign instanceof IntBinaryTag) { - return net.minecraft.nbt.IntTag.valueOf(((IntBinaryTag) foreign).value()); - } else if (foreign instanceof IntArrayBinaryTag) { - return new net.minecraft.nbt.IntArrayTag(((IntArrayBinaryTag) foreign).value()); - } else if (foreign instanceof LongArrayBinaryTag) { - return new net.minecraft.nbt.LongArrayTag(((LongArrayBinaryTag) foreign).value()); - } else if (foreign instanceof ListBinaryTag foreignList) { - net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); - for (BinaryTag t : foreignList) { - tag.add(fromNativeBinary(t)); - } - return tag; - } else if (foreign instanceof LongBinaryTag) { - return net.minecraft.nbt.LongTag.valueOf(((LongBinaryTag) foreign).value()); - } else if (foreign instanceof ShortBinaryTag) { - return net.minecraft.nbt.ShortTag.valueOf(((ShortBinaryTag) foreign).value()); - } else if (foreign instanceof StringBinaryTag) { - return net.minecraft.nbt.StringTag.valueOf(((StringBinaryTag) foreign).value()); - } else if (foreign instanceof EndBinaryTag) { - return net.minecraft.nbt.EndTag.INSTANCE; - } else { - throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName()); - } - } - //FAWE end - - @Override - public boolean supportsWatchdog() { - return watchdog != null; - } - - @Override - public void tickWatchdog() { - watchdog.tick(); - } - - private class SpigotWatchdog implements Watchdog { - - private final Field instanceField; - private final Field lastTickField; - - SpigotWatchdog() throws NoSuchFieldException { - Field instanceField = WatchdogThread.class.getDeclaredField("instance"); - instanceField.setAccessible(true); - this.instanceField = instanceField; - - Field lastTickField = WatchdogThread.class.getDeclaredField("lastTick"); - lastTickField.setAccessible(true); - this.lastTickField = lastTickField; - } - - @Override - public void tick() { - try { - WatchdogThread instance = (WatchdogThread) this.instanceField.get(null); - if ((long) lastTickField.get(instance) != 0) { - WatchdogThread.tick(); - } - } catch (IllegalAccessException e) { - LOGGER.log(Level.WARNING, "Failed to tick watchdog", e); - } - } - - } - - private static class MojangWatchdog implements Watchdog { - - private final DedicatedServer server; - private final Field tickField; - - MojangWatchdog(DedicatedServer server) throws NoSuchFieldException { - this.server = server; - Field tickField = MinecraftServer.class.getDeclaredField( - Refraction.pickName("nextTickTime", "ao") - ); - tickField.setAccessible(true); - this.tickField = tickField; - } - - @Override - public void tick() { - try { - tickField.set(server, Util.getMillis()); - } catch (IllegalAccessException ignored) { - } - } - - } - - private static class NoOpWorldLoadListener implements ChunkProgressListener { - - @Override - public void updateSpawnPos(ChunkPos spawnPos) { - } - - @Override - public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) { - } - - @Override - public void start() { - } - - @Override - public void stop() { - } - - @Override - public void setChunkRadius(int radius) { - } - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightDataConverters.java deleted file mode 100644 index 6678bdc52..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightDataConverters.java +++ /dev/null @@ -1,2961 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit.adapter.ext.fawe; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.mojang.datafixers.DSL.TypeReference; -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.DataFixerBuilder; -import com.mojang.datafixers.schemas.Schema; -import com.mojang.serialization.Dynamic; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import net.minecraft.core.Direction; -import net.minecraft.nbt.NbtOps; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.GsonHelper; -import net.minecraft.util.StringUtil; -import net.minecraft.util.datafix.DataFixers; -import net.minecraft.util.datafix.fixes.References; -import net.minecraft.world.item.DyeColor; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import javax.annotation.Nullable; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; - -/** - * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2) - *

- * We register a DFU Fixer per Legacy Data Version and apply the fixes using legacy strategy - * which is safer, faster and cleaner code. - *

- * The pre DFU code did not fail when the Source version was unknown. - *

- * This class also provides util methods for converting compounds to wrap the update call to - * receive the source version in the compound - */ -@SuppressWarnings({"rawtypes", "unchecked"}) -class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.worldedit.world.DataFixer { - - //FAWE start - BinaryTag - @SuppressWarnings("unchecked") - @Override - public T fixUp(FixType type, T original, int srcVer) { - if (type == FixTypes.CHUNK) { - return (T) fixChunk((CompoundBinaryTag) original, srcVer); - } else if (type == FixTypes.BLOCK_ENTITY) { - return (T) fixBlockEntity((CompoundBinaryTag) original, srcVer); - } else if (type == FixTypes.ENTITY) { - return (T) fixEntity((CompoundBinaryTag) original, srcVer); - } else if (type == FixTypes.BLOCK_STATE) { - return (T) fixBlockState((String) original, srcVer); - } else if (type == FixTypes.ITEM_TYPE) { - return (T) fixItemType((String) original, srcVer); - } else if (type == FixTypes.BIOME) { - return (T) fixBiome((String) original, srcVer); - } - return original; - } - - private CompoundBinaryTag fixChunk(CompoundBinaryTag originalChunk, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(originalChunk); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.CHUNK, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); - } - - private CompoundBinaryTag fixBlockEntity(CompoundBinaryTag origTileEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origTileEnt); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.BLOCK_ENTITY, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); - } - - private CompoundBinaryTag fixEntity(CompoundBinaryTag origEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origEnt); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.ENTITY, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); - } - //FAWE end - - private String fixBlockState(String blockState, int srcVer) { - net.minecraft.nbt.CompoundTag stateNBT = stateToNBT(blockState); - Dynamic dynamic = new Dynamic<>(OPS_NBT, stateNBT); - net.minecraft.nbt.CompoundTag fixed = (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update( - References.BLOCK_STATE, - dynamic, - srcVer, - DATA_VERSION - ).getValue(); - return nbtToState(fixed); - } - - private String nbtToState(net.minecraft.nbt.CompoundTag tagCompound) { - StringBuilder sb = new StringBuilder(); - sb.append(tagCompound.getString("Name")); - if (tagCompound.contains("Properties", 10)) { - sb.append('['); - net.minecraft.nbt.CompoundTag props = tagCompound.getCompound("Properties"); - sb.append(props - .getAllKeys() - .stream() - .map(k -> k + "=" + props.getString(k).replace("\"", "")) - .collect(Collectors.joining(","))); - sb.append(']'); - } - return sb.toString(); - } - - private static net.minecraft.nbt.CompoundTag stateToNBT(String blockState) { - int propIdx = blockState.indexOf('['); - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - if (propIdx < 0) { - tag.putString("Name", blockState); - } else { - tag.putString("Name", blockState.substring(0, propIdx)); - net.minecraft.nbt.CompoundTag propTag = new net.minecraft.nbt.CompoundTag(); - String props = blockState.substring(propIdx + 1, blockState.length() - 1); - String[] propArr = props.split(","); - for (String pair : propArr) { - final String[] split = pair.split("="); - propTag.putString(split[0], split[1]); - } - tag.put("Properties", propTag); - } - return tag; - } - - private String fixBiome(String key, int srcVer) { - return fixName(key, srcVer, References.BIOME); - } - - private String fixItemType(String key, int srcVer) { - return fixName(key, srcVer, References.ITEM_NAME); - } - - private static String fixName(String key, int srcVer, TypeReference type) { - return INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, net.minecraft.nbt.StringTag.valueOf(key)), srcVer, DATA_VERSION) - .getValue().getAsString(); - } - - private final PaperweightAdapter adapter; - - private static final NbtOps OPS_NBT = NbtOps.INSTANCE; - private static final int LEGACY_VERSION = 1343; - private static int DATA_VERSION; - static PaperweightDataConverters INSTANCE; - - private final Map> converters = new EnumMap<>(LegacyType.class); - private final Map> inspectors = new EnumMap<>(LegacyType.class); - - // Set on build - private DataFixer fixer; - private static final Map DFU_TO_LEGACY = new HashMap<>(); - - public enum LegacyType { - LEVEL(References.LEVEL), - PLAYER(References.PLAYER), - CHUNK(References.CHUNK), - BLOCK_ENTITY(References.BLOCK_ENTITY), - ENTITY(References.ENTITY), - ITEM_INSTANCE(References.ITEM_STACK), - OPTIONS(References.OPTIONS), - STRUCTURE(References.STRUCTURE); - - private final TypeReference type; - - LegacyType(TypeReference type) { - this.type = type; - DFU_TO_LEGACY.put(type.typeName(), this); - } - - public TypeReference getDFUType() { - return type; - } - } - - PaperweightDataConverters(int dataVersion, PaperweightAdapter adapter) { - super(dataVersion); - DATA_VERSION = dataVersion; - INSTANCE = this; - this.adapter = adapter; - registerConverters(); - registerInspectors(); - } - - - // Called after fixers are built and ready for FIXING - @Override - public DataFixer build(final Executor executor) { - return this.fixer = new WrappedDataFixer(DataFixers.getDataFixer()); - } - - @SuppressWarnings("unchecked") - private class WrappedDataFixer implements DataFixer { - - private final DataFixer realFixer; - - WrappedDataFixer(DataFixer realFixer) { - this.realFixer = realFixer; - } - - @Override - public Dynamic update(TypeReference type, Dynamic dynamic, int sourceVer, int targetVer) { - LegacyType legacyType = DFU_TO_LEGACY.get(type.typeName()); - if (sourceVer < LEGACY_VERSION && legacyType != null) { - net.minecraft.nbt.CompoundTag cmp = (net.minecraft.nbt.CompoundTag) dynamic.getValue(); - int desiredVersion = Math.min(targetVer, LEGACY_VERSION); - - cmp = convert(legacyType, cmp, sourceVer, desiredVersion); - sourceVer = desiredVersion; - dynamic = new Dynamic(OPS_NBT, cmp); - } - return realFixer.update(type, dynamic, sourceVer, targetVer); - } - - private net.minecraft.nbt.CompoundTag convert( - LegacyType type, - net.minecraft.nbt.CompoundTag cmp, - int sourceVer, - int desiredVersion - ) { - List converters = PaperweightDataConverters.this.converters.get(type); - if (converters != null && !converters.isEmpty()) { - for (DataConverter converter : converters) { - int dataVersion = converter.getDataVersion(); - if (dataVersion > sourceVer && dataVersion <= desiredVersion) { - cmp = converter.convert(cmp); - } - } - } - - List inspectors = PaperweightDataConverters.this.inspectors.get(type); - if (inspectors != null && !inspectors.isEmpty()) { - for (DataInspector inspector : inspectors) { - cmp = inspector.inspect(cmp, sourceVer, desiredVersion); - } - } - - return cmp; - } - - @Override - public Schema getSchema(int i) { - return realFixer.getSchema(i); - } - - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp) { - return convert(type.getDFUType(), cmp); - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { - return convert(type.getDFUType(), cmp, sourceVer); - } - - public static net.minecraft.nbt.CompoundTag convert( - LegacyType type, - net.minecraft.nbt.CompoundTag cmp, - int sourceVer, - int targetVer - ) { - return convert(type.getDFUType(), cmp, sourceVer, targetVer); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp) { - int i = cmp.contains("DataVersion", 99) ? cmp.getInt("DataVersion") : -1; - return convert(type, cmp, i); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { - return convert(type, cmp, sourceVer, DATA_VERSION); - } - - public static net.minecraft.nbt.CompoundTag convert( - TypeReference type, - net.minecraft.nbt.CompoundTag cmp, - int sourceVer, - int targetVer - ) { - if (sourceVer >= targetVer) { - return cmp; - } - return (net.minecraft.nbt.CompoundTag) INSTANCE.fixer - .update(type, new Dynamic<>(OPS_NBT, cmp), sourceVer, targetVer) - .getValue(); - } - - - public interface DataInspector { - - net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer); - - } - - public interface DataConverter { - - int getDataVersion(); - - net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp); - - } - - - private void registerInspector(LegacyType type, DataInspector inspector) { - this.inspectors.computeIfAbsent(type, k -> new ArrayList<>()).add(inspector); - } - - private void registerConverter(LegacyType type, DataConverter converter) { - int version = converter.getDataVersion(); - - List list = this.converters.computeIfAbsent(type, k -> new ArrayList<>()); - if (!list.isEmpty() && list.get(list.size() - 1).getDataVersion() > version) { - for (int j = 0; j < list.size(); ++j) { - if (list.get(j).getDataVersion() > version) { - list.add(j, converter); - break; - } - } - } else { - list.add(converter); - } - } - - private void registerInspectors() { - registerEntityItemList("EntityHorseDonkey", "SaddleItem", "Items"); - registerEntityItemList("EntityHorseMule", "Items"); - registerEntityItemList("EntityMinecartChest", "Items"); - registerEntityItemList("EntityMinecartHopper", "Items"); - registerEntityItemList("EntityVillager", "Inventory"); - registerEntityItemListEquipment("EntityArmorStand"); - registerEntityItemListEquipment("EntityBat"); - registerEntityItemListEquipment("EntityBlaze"); - registerEntityItemListEquipment("EntityCaveSpider"); - registerEntityItemListEquipment("EntityChicken"); - registerEntityItemListEquipment("EntityCow"); - registerEntityItemListEquipment("EntityCreeper"); - registerEntityItemListEquipment("EntityEnderDragon"); - registerEntityItemListEquipment("EntityEnderman"); - registerEntityItemListEquipment("EntityEndermite"); - registerEntityItemListEquipment("EntityEvoker"); - registerEntityItemListEquipment("EntityGhast"); - registerEntityItemListEquipment("EntityGiantZombie"); - registerEntityItemListEquipment("EntityGuardian"); - registerEntityItemListEquipment("EntityGuardianElder"); - registerEntityItemListEquipment("EntityHorse"); - registerEntityItemListEquipment("EntityHorseDonkey"); - registerEntityItemListEquipment("EntityHorseMule"); - registerEntityItemListEquipment("EntityHorseSkeleton"); - registerEntityItemListEquipment("EntityHorseZombie"); - registerEntityItemListEquipment("EntityIronGolem"); - registerEntityItemListEquipment("EntityMagmaCube"); - registerEntityItemListEquipment("EntityMushroomCow"); - registerEntityItemListEquipment("EntityOcelot"); - registerEntityItemListEquipment("EntityPig"); - registerEntityItemListEquipment("EntityPigZombie"); - registerEntityItemListEquipment("EntityRabbit"); - registerEntityItemListEquipment("EntitySheep"); - registerEntityItemListEquipment("EntityShulker"); - registerEntityItemListEquipment("EntitySilverfish"); - registerEntityItemListEquipment("EntitySkeleton"); - registerEntityItemListEquipment("EntitySkeletonStray"); - registerEntityItemListEquipment("EntitySkeletonWither"); - registerEntityItemListEquipment("EntitySlime"); - registerEntityItemListEquipment("EntitySnowman"); - registerEntityItemListEquipment("EntitySpider"); - registerEntityItemListEquipment("EntitySquid"); - registerEntityItemListEquipment("EntityVex"); - registerEntityItemListEquipment("EntityVillager"); - registerEntityItemListEquipment("EntityVindicator"); - registerEntityItemListEquipment("EntityWitch"); - registerEntityItemListEquipment("EntityWither"); - registerEntityItemListEquipment("EntityWolf"); - registerEntityItemListEquipment("EntityZombie"); - registerEntityItemListEquipment("EntityZombieHusk"); - registerEntityItemListEquipment("EntityZombieVillager"); - registerEntityItemSingle("EntityFireworks", "FireworksItem"); - registerEntityItemSingle("EntityHorse", "ArmorItem"); - registerEntityItemSingle("EntityHorse", "SaddleItem"); - registerEntityItemSingle("EntityHorseMule", "SaddleItem"); - registerEntityItemSingle("EntityHorseSkeleton", "SaddleItem"); - registerEntityItemSingle("EntityHorseZombie", "SaddleItem"); - registerEntityItemSingle("EntityItem", "Item"); - registerEntityItemSingle("EntityItemFrame", "Item"); - registerEntityItemSingle("EntityPotion", "Potion"); - - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItem("TileEntityRecordPlayer", "RecordItem")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityBrewingStand", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityChest", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDispenser", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDropper", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityFurnace", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityHopper", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityShulkerBox", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorMobSpawnerMobs()); - registerInspector(LegacyType.CHUNK, new DataInspectorChunks()); - registerInspector(LegacyType.ENTITY, new DataInspectorCommandBlock()); - registerInspector(LegacyType.ENTITY, new DataInspectorEntityPassengers()); - registerInspector(LegacyType.ENTITY, new DataInspectorMobSpawnerMinecart()); - registerInspector(LegacyType.ENTITY, new DataInspectorVillagers()); - registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorBlockEntity()); - registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorEntity()); - registerInspector(LegacyType.LEVEL, new DataInspectorLevelPlayer()); - registerInspector(LegacyType.PLAYER, new DataInspectorPlayer()); - registerInspector(LegacyType.PLAYER, new DataInspectorPlayerVehicle()); - registerInspector(LegacyType.STRUCTURE, new DataInspectorStructure()); - } - - private void registerConverters() { - registerConverter(LegacyType.ENTITY, new DataConverterEquipment()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterSignText()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterMaterialId()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionId()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterSpawnEgg()); - registerConverter(LegacyType.ENTITY, new DataConverterMinecart()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterMobSpawner()); - registerConverter(LegacyType.ENTITY, new DataConverterUUID()); - registerConverter(LegacyType.ENTITY, new DataConverterHealth()); - registerConverter(LegacyType.ENTITY, new DataConverterSaddle()); - registerConverter(LegacyType.ENTITY, new DataConverterHanging()); - registerConverter(LegacyType.ENTITY, new DataConverterDropChances()); - registerConverter(LegacyType.ENTITY, new DataConverterRiding()); - registerConverter(LegacyType.ENTITY, new DataConverterArmorStand()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBook()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterCookedFish()); - registerConverter(LegacyType.ENTITY, new DataConverterZombie()); - registerConverter(LegacyType.OPTIONS, new DataConverterVBO()); - registerConverter(LegacyType.ENTITY, new DataConverterGuardian()); - registerConverter(LegacyType.ENTITY, new DataConverterSkeleton()); - registerConverter(LegacyType.ENTITY, new DataConverterZombieType()); - registerConverter(LegacyType.ENTITY, new DataConverterHorse()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterTileEntity()); - registerConverter(LegacyType.ENTITY, new DataConverterEntity()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBanner()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionWater()); - registerConverter(LegacyType.ENTITY, new DataConverterShulker()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterShulkerBoxItem()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterShulkerBoxBlock()); - registerConverter(LegacyType.OPTIONS, new DataConverterLang()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterTotem()); - registerConverter(LegacyType.CHUNK, new DataConverterBedBlock()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBedItem()); - } - - private void registerEntityItemList(String type, String... keys) { - registerInspector(LegacyType.ENTITY, new DataInspectorItemList(type, keys)); - } - - private void registerEntityItemSingle(String type, String key) { - registerInspector(LegacyType.ENTITY, new DataInspectorItem(type, key)); - } - - private void registerEntityItemListEquipment(String type) { - registerEntityItemList(type, "ArmorItems", "HandItems"); - } - - private static final Map OLD_ID_TO_KEY_MAP = new HashMap<>(); - - static { - final Map map = OLD_ID_TO_KEY_MAP; - map.put("EntityItem", new ResourceLocation("item")); - map.put("EntityExperienceOrb", new ResourceLocation("xp_orb")); - map.put("EntityAreaEffectCloud", new ResourceLocation("area_effect_cloud")); - map.put("EntityGuardianElder", new ResourceLocation("elder_guardian")); - map.put("EntitySkeletonWither", new ResourceLocation("wither_skeleton")); - map.put("EntitySkeletonStray", new ResourceLocation("stray")); - map.put("EntityEgg", new ResourceLocation("egg")); - map.put("EntityLeash", new ResourceLocation("leash_knot")); - map.put("EntityPainting", new ResourceLocation("painting")); - map.put("EntityTippedArrow", new ResourceLocation("arrow")); - map.put("EntitySnowball", new ResourceLocation("snowball")); - map.put("EntityLargeFireball", new ResourceLocation("fireball")); - map.put("EntitySmallFireball", new ResourceLocation("small_fireball")); - map.put("EntityEnderPearl", new ResourceLocation("ender_pearl")); - map.put("EntityEnderSignal", new ResourceLocation("eye_of_ender_signal")); - map.put("EntityPotion", new ResourceLocation("potion")); - map.put("EntityThrownExpBottle", new ResourceLocation("xp_bottle")); - map.put("EntityItemFrame", new ResourceLocation("item_frame")); - map.put("EntityWitherSkull", new ResourceLocation("wither_skull")); - map.put("EntityTNTPrimed", new ResourceLocation("tnt")); - map.put("EntityFallingBlock", new ResourceLocation("falling_block")); - map.put("EntityFireworks", new ResourceLocation("fireworks_rocket")); - map.put("EntityZombieHusk", new ResourceLocation("husk")); - map.put("EntitySpectralArrow", new ResourceLocation("spectral_arrow")); - map.put("EntityShulkerBullet", new ResourceLocation("shulker_bullet")); - map.put("EntityDragonFireball", new ResourceLocation("dragon_fireball")); - map.put("EntityZombieVillager", new ResourceLocation("zombie_villager")); - map.put("EntityHorseSkeleton", new ResourceLocation("skeleton_horse")); - map.put("EntityHorseZombie", new ResourceLocation("zombie_horse")); - map.put("EntityArmorStand", new ResourceLocation("armor_stand")); - map.put("EntityHorseDonkey", new ResourceLocation("donkey")); - map.put("EntityHorseMule", new ResourceLocation("mule")); - map.put("EntityEvokerFangs", new ResourceLocation("evocation_fangs")); - map.put("EntityEvoker", new ResourceLocation("evocation_illager")); - map.put("EntityVex", new ResourceLocation("vex")); - map.put("EntityVindicator", new ResourceLocation("vindication_illager")); - map.put("EntityIllagerIllusioner", new ResourceLocation("illusion_illager")); - map.put("EntityMinecartCommandBlock", new ResourceLocation("commandblock_minecart")); - map.put("EntityBoat", new ResourceLocation("boat")); - map.put("EntityMinecartRideable", new ResourceLocation("minecart")); - map.put("EntityMinecartChest", new ResourceLocation("chest_minecart")); - map.put("EntityMinecartFurnace", new ResourceLocation("furnace_minecart")); - map.put("EntityMinecartTNT", new ResourceLocation("tnt_minecart")); - map.put("EntityMinecartHopper", new ResourceLocation("hopper_minecart")); - map.put("EntityMinecartMobSpawner", new ResourceLocation("spawner_minecart")); - map.put("EntityCreeper", new ResourceLocation("creeper")); - map.put("EntitySkeleton", new ResourceLocation("skeleton")); - map.put("EntitySpider", new ResourceLocation("spider")); - map.put("EntityGiantZombie", new ResourceLocation("giant")); - map.put("EntityZombie", new ResourceLocation("zombie")); - map.put("EntitySlime", new ResourceLocation("slime")); - map.put("EntityGhast", new ResourceLocation("ghast")); - map.put("EntityPigZombie", new ResourceLocation("zombie_pigman")); - map.put("EntityEnderman", new ResourceLocation("enderman")); - map.put("EntityCaveSpider", new ResourceLocation("cave_spider")); - map.put("EntitySilverfish", new ResourceLocation("silverfish")); - map.put("EntityBlaze", new ResourceLocation("blaze")); - map.put("EntityMagmaCube", new ResourceLocation("magma_cube")); - map.put("EntityEnderDragon", new ResourceLocation("ender_dragon")); - map.put("EntityWither", new ResourceLocation("wither")); - map.put("EntityBat", new ResourceLocation("bat")); - map.put("EntityWitch", new ResourceLocation("witch")); - map.put("EntityEndermite", new ResourceLocation("endermite")); - map.put("EntityGuardian", new ResourceLocation("guardian")); - map.put("EntityShulker", new ResourceLocation("shulker")); - map.put("EntityPig", new ResourceLocation("pig")); - map.put("EntitySheep", new ResourceLocation("sheep")); - map.put("EntityCow", new ResourceLocation("cow")); - map.put("EntityChicken", new ResourceLocation("chicken")); - map.put("EntitySquid", new ResourceLocation("squid")); - map.put("EntityWolf", new ResourceLocation("wolf")); - map.put("EntityMushroomCow", new ResourceLocation("mooshroom")); - map.put("EntitySnowman", new ResourceLocation("snowman")); - map.put("EntityOcelot", new ResourceLocation("ocelot")); - map.put("EntityIronGolem", new ResourceLocation("villager_golem")); - map.put("EntityHorse", new ResourceLocation("horse")); - map.put("EntityRabbit", new ResourceLocation("rabbit")); - map.put("EntityPolarBear", new ResourceLocation("polar_bear")); - map.put("EntityLlama", new ResourceLocation("llama")); - map.put("EntityLlamaSpit", new ResourceLocation("llama_spit")); - map.put("EntityParrot", new ResourceLocation("parrot")); - map.put("EntityVillager", new ResourceLocation("villager")); - map.put("EntityEnderCrystal", new ResourceLocation("ender_crystal")); - map.put("TileEntityFurnace", new ResourceLocation("furnace")); - map.put("TileEntityChest", new ResourceLocation("chest")); - map.put("TileEntityEnderChest", new ResourceLocation("ender_chest")); - map.put("TileEntityRecordPlayer", new ResourceLocation("jukebox")); - map.put("TileEntityDispenser", new ResourceLocation("dispenser")); - map.put("TileEntityDropper", new ResourceLocation("dropper")); - map.put("TileEntitySign", new ResourceLocation("sign")); - map.put("TileEntityMobSpawner", new ResourceLocation("mob_spawner")); - map.put("TileEntityNote", new ResourceLocation("noteblock")); - map.put("TileEntityPiston", new ResourceLocation("piston")); - map.put("TileEntityBrewingStand", new ResourceLocation("brewing_stand")); - map.put("TileEntityEnchantTable", new ResourceLocation("enchanting_table")); - map.put("TileEntityEnderPortal", new ResourceLocation("end_portal")); - map.put("TileEntityBeacon", new ResourceLocation("beacon")); - map.put("TileEntitySkull", new ResourceLocation("skull")); - map.put("TileEntityLightDetector", new ResourceLocation("daylight_detector")); - map.put("TileEntityHopper", new ResourceLocation("hopper")); - map.put("TileEntityComparator", new ResourceLocation("comparator")); - map.put("TileEntityFlowerPot", new ResourceLocation("flower_pot")); - map.put("TileEntityBanner", new ResourceLocation("banner")); - map.put("TileEntityStructure", new ResourceLocation("structure_block")); - map.put("TileEntityEndGateway", new ResourceLocation("end_gateway")); - map.put("TileEntityCommand", new ResourceLocation("command_block")); - map.put("TileEntityShulkerBox", new ResourceLocation("shulker_box")); - map.put("TileEntityBed", new ResourceLocation("bed")); - } - - private static ResourceLocation getKey(String type) { - final ResourceLocation key = OLD_ID_TO_KEY_MAP.get(type); - if (key == null) { - throw new IllegalArgumentException("Unknown mapping for " + type); - } - return key; - } - - private static void convertCompound( - LegacyType type, - net.minecraft.nbt.CompoundTag cmp, - String key, - int sourceVer, - int targetVer - ) { - cmp.put(key, convert(type, cmp.getCompound(key), sourceVer, targetVer)); - } - - private static void convertItem(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { - if (nbttagcompound.contains(key, 10)) { - convertCompound(LegacyType.ITEM_INSTANCE, nbttagcompound, key, sourceVer, targetVer); - } - } - - private static void convertItems(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { - if (nbttagcompound.contains(key, 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound.getList(key, 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ITEM_INSTANCE, nbttaglist.getCompound(j), sourceVer, targetVer)); - } - } - - } - - private static class DataConverterEquipment implements DataConverter { - - DataConverterEquipment() { - } - - public int getDataVersion() { - return 100; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("Equipment", 10); - net.minecraft.nbt.ListTag nbttaglist1; - - if (!nbttaglist.isEmpty() && !cmp.contains("HandItems", 10)) { - nbttaglist1 = new net.minecraft.nbt.ListTag(); - nbttaglist1.add(nbttaglist.get(0)); - nbttaglist1.add(new net.minecraft.nbt.CompoundTag()); - cmp.put("HandItems", nbttaglist1); - } - - if (nbttaglist.size() > 1 && !cmp.contains("ArmorItem", 10)) { - nbttaglist1 = new net.minecraft.nbt.ListTag(); - nbttaglist1.add(nbttaglist.get(1)); - nbttaglist1.add(nbttaglist.get(2)); - nbttaglist1.add(nbttaglist.get(3)); - nbttaglist1.add(nbttaglist.get(4)); - cmp.put("ArmorItems", nbttaglist1); - } - - cmp.remove("Equipment"); - if (cmp.contains("DropChances", 9)) { - nbttaglist1 = cmp.getList("DropChances", 5); - net.minecraft.nbt.ListTag nbttaglist2; - - if (!cmp.contains("HandDropChances", 10)) { - nbttaglist2 = new net.minecraft.nbt.ListTag(); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(0))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(0.0F)); - cmp.put("HandDropChances", nbttaglist2); - } - - if (!cmp.contains("ArmorDropChances", 10)) { - nbttaglist2 = new net.minecraft.nbt.ListTag(); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(1))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(2))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(3))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(4))); - cmp.put("ArmorDropChances", nbttaglist2); - } - - cmp.remove("DropChances"); - } - - return cmp; - } - - } - - private static class DataInspectorBlockEntity implements DataInspector { - - private static final Map b = Maps.newHashMap(); - private static final Map c = Maps.newHashMap(); - - DataInspectorBlockEntity() { - } - - @Nullable - private static String convertEntityId(int i, String s) { - String key = new ResourceLocation(s).toString(); - if (i < 515 && DataInspectorBlockEntity.b.containsKey(key)) { - return DataInspectorBlockEntity.b.get(key); - } else { - return DataInspectorBlockEntity.c.get(key); - } - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (!cmp.contains("tag", 10)) { - return cmp; - } else { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - String s = cmp.getString("id"); - String s1 = convertEntityId(sourceVer, s); - boolean flag; - - if (s1 == null) { - // CraftBukkit - Remove unnecessary warning (occurs when deserializing a Shulker Box item) - // DataInspectorBlockEntity.a.warn("Unable to resolve BlockEntity for ItemInstance: {}", s); - flag = false; - } else { - flag = !nbttagcompound2.contains("id"); - nbttagcompound2.putString("id", s1); - } - - convert(LegacyType.BLOCK_ENTITY, nbttagcompound2, sourceVer, targetVer); - if (flag) { - nbttagcompound2.remove("id"); - } - } - - return cmp; - } - } - - static { - Map map = DataInspectorBlockEntity.b; - - map.put("minecraft:furnace", "Furnace"); - map.put("minecraft:lit_furnace", "Furnace"); - map.put("minecraft:chest", "Chest"); - map.put("minecraft:trapped_chest", "Chest"); - map.put("minecraft:ender_chest", "EnderChest"); - map.put("minecraft:jukebox", "RecordPlayer"); - map.put("minecraft:dispenser", "Trap"); - map.put("minecraft:dropper", "Dropper"); - map.put("minecraft:sign", "Sign"); - map.put("minecraft:mob_spawner", "MobSpawner"); - map.put("minecraft:noteblock", "Music"); - map.put("minecraft:brewing_stand", "Cauldron"); - map.put("minecraft:enhanting_table", "EnchantTable"); - map.put("minecraft:command_block", "CommandBlock"); - map.put("minecraft:beacon", "Beacon"); - map.put("minecraft:skull", "Skull"); - map.put("minecraft:daylight_detector", "DLDetector"); - map.put("minecraft:hopper", "Hopper"); - map.put("minecraft:banner", "Banner"); - map.put("minecraft:flower_pot", "FlowerPot"); - map.put("minecraft:repeating_command_block", "CommandBlock"); - map.put("minecraft:chain_command_block", "CommandBlock"); - map.put("minecraft:standing_sign", "Sign"); - map.put("minecraft:wall_sign", "Sign"); - map.put("minecraft:piston_head", "Piston"); - map.put("minecraft:daylight_detector_inverted", "DLDetector"); - map.put("minecraft:unpowered_comparator", "Comparator"); - map.put("minecraft:powered_comparator", "Comparator"); - map.put("minecraft:wall_banner", "Banner"); - map.put("minecraft:standing_banner", "Banner"); - map.put("minecraft:structure_block", "Structure"); - map.put("minecraft:end_portal", "Airportal"); - map.put("minecraft:end_gateway", "EndGateway"); - map.put("minecraft:shield", "Shield"); - map = DataInspectorBlockEntity.c; - map.put("minecraft:furnace", "minecraft:furnace"); - map.put("minecraft:lit_furnace", "minecraft:furnace"); - map.put("minecraft:chest", "minecraft:chest"); - map.put("minecraft:trapped_chest", "minecraft:chest"); - map.put("minecraft:ender_chest", "minecraft:enderchest"); - map.put("minecraft:jukebox", "minecraft:jukebox"); - map.put("minecraft:dispenser", "minecraft:dispenser"); - map.put("minecraft:dropper", "minecraft:dropper"); - map.put("minecraft:sign", "minecraft:sign"); - map.put("minecraft:mob_spawner", "minecraft:mob_spawner"); - map.put("minecraft:noteblock", "minecraft:noteblock"); - map.put("minecraft:brewing_stand", "minecraft:brewing_stand"); - map.put("minecraft:enhanting_table", "minecraft:enchanting_table"); - map.put("minecraft:command_block", "minecraft:command_block"); - map.put("minecraft:beacon", "minecraft:beacon"); - map.put("minecraft:skull", "minecraft:skull"); - map.put("minecraft:daylight_detector", "minecraft:daylight_detector"); - map.put("minecraft:hopper", "minecraft:hopper"); - map.put("minecraft:banner", "minecraft:banner"); - map.put("minecraft:flower_pot", "minecraft:flower_pot"); - map.put("minecraft:repeating_command_block", "minecraft:command_block"); - map.put("minecraft:chain_command_block", "minecraft:command_block"); - map.put("minecraft:shulker_box", "minecraft:shulker_box"); - map.put("minecraft:white_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:orange_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:magenta_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:light_blue_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:yellow_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:lime_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:pink_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:gray_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:silver_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:cyan_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:purple_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:blue_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:brown_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:green_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:red_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:black_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:bed", "minecraft:bed"); - map.put("minecraft:standing_sign", "minecraft:sign"); - map.put("minecraft:wall_sign", "minecraft:sign"); - map.put("minecraft:piston_head", "minecraft:piston"); - map.put("minecraft:daylight_detector_inverted", "minecraft:daylight_detector"); - map.put("minecraft:unpowered_comparator", "minecraft:comparator"); - map.put("minecraft:powered_comparator", "minecraft:comparator"); - map.put("minecraft:wall_banner", "minecraft:banner"); - map.put("minecraft:standing_banner", "minecraft:banner"); - map.put("minecraft:structure_block", "minecraft:structure_block"); - map.put("minecraft:end_portal", "minecraft:end_portal"); - map.put("minecraft:end_gateway", "minecraft:end_gateway"); - map.put("minecraft:shield", "minecraft:shield"); - } - } - - private static class DataInspectorEntity implements DataInspector { - - private static final Logger a = LogManager.getLogger(PaperweightDataConverters.class); - - DataInspectorEntity() { - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("EntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); - String s = cmp.getString("id"); - String s1; - - if ("minecraft:armor_stand".equals(s)) { - s1 = sourceVer < 515 ? "ArmorStand" : "minecraft:armor_stand"; - } else { - if (!"minecraft:spawn_egg".equals(s)) { - return cmp; - } - - s1 = nbttagcompound2.getString("id"); - } - - boolean flag; - - flag = !nbttagcompound2.contains("id", 8); - nbttagcompound2.putString("id", s1); - - convert(LegacyType.ENTITY, nbttagcompound2, sourceVer, targetVer); - if (flag) { - nbttagcompound2.remove("id"); - } - } - - return cmp; - } - - } - - - private abstract static class DataInspectorTagged implements DataInspector { - - private final ResourceLocation key; - - DataInspectorTagged(String type) { - this.key = getKey(type); - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (this.key.equals(new ResourceLocation(cmp.getString("id")))) { - cmp = this.inspectChecked(cmp, sourceVer, targetVer); - } - - return cmp; - } - - abstract net.minecraft.nbt.CompoundTag inspectChecked( - net.minecraft.nbt.CompoundTag nbttagcompound, - int sourceVer, - int targetVer - ); - - } - - private static class DataInspectorItemList extends DataInspectorTagged { - - private final String[] keys; - - DataInspectorItemList(String oclass, String... astring) { - super(oclass); - this.keys = astring; - } - - net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer) { - for (String s : this.keys) { - PaperweightDataConverters.convertItems(nbttagcompound, s, sourceVer, targetVer); - } - - return nbttagcompound; - } - - } - - private static class DataInspectorItem extends DataInspectorTagged { - - private final String[] keys; - - DataInspectorItem(String oclass, String... astring) { - super(oclass); - this.keys = astring; - } - - net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer) { - for (String key : this.keys) { - PaperweightDataConverters.convertItem(nbttagcompound, key, sourceVer, targetVer); - } - - return nbttagcompound; - } - - } - - private static class DataConverterMaterialId implements DataConverter { - - private static final String[] materials = new String[2268]; - - DataConverterMaterialId() { - } - - public int getDataVersion() { - return 102; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("id", 99)) { - short short0 = cmp.getShort("id"); - - if (short0 > 0 && short0 < materials.length && materials[short0] != null) { - cmp.putString("id", materials[short0]); - } - } - - return cmp; - } - - static { - materials[1] = "minecraft:stone"; - materials[2] = "minecraft:grass"; - materials[3] = "minecraft:dirt"; - materials[4] = "minecraft:cobblestone"; - materials[5] = "minecraft:planks"; - materials[6] = "minecraft:sapling"; - materials[7] = "minecraft:bedrock"; - materials[8] = "minecraft:flowing_water"; - materials[9] = "minecraft:water"; - materials[10] = "minecraft:flowing_lava"; - materials[11] = "minecraft:lava"; - materials[12] = "minecraft:sand"; - materials[13] = "minecraft:gravel"; - materials[14] = "minecraft:gold_ore"; - materials[15] = "minecraft:iron_ore"; - materials[16] = "minecraft:coal_ore"; - materials[17] = "minecraft:log"; - materials[18] = "minecraft:leaves"; - materials[19] = "minecraft:sponge"; - materials[20] = "minecraft:glass"; - materials[21] = "minecraft:lapis_ore"; - materials[22] = "minecraft:lapis_block"; - materials[23] = "minecraft:dispenser"; - materials[24] = "minecraft:sandstone"; - materials[25] = "minecraft:noteblock"; - materials[27] = "minecraft:golden_rail"; - materials[28] = "minecraft:detector_rail"; - materials[29] = "minecraft:sticky_piston"; - materials[30] = "minecraft:web"; - materials[31] = "minecraft:tallgrass"; - materials[32] = "minecraft:deadbush"; - materials[33] = "minecraft:piston"; - materials[35] = "minecraft:wool"; - materials[37] = "minecraft:yellow_flower"; - materials[38] = "minecraft:red_flower"; - materials[39] = "minecraft:brown_mushroom"; - materials[40] = "minecraft:red_mushroom"; - materials[41] = "minecraft:gold_block"; - materials[42] = "minecraft:iron_block"; - materials[43] = "minecraft:double_stone_slab"; - materials[44] = "minecraft:stone_slab"; - materials[45] = "minecraft:brick_block"; - materials[46] = "minecraft:tnt"; - materials[47] = "minecraft:bookshelf"; - materials[48] = "minecraft:mossy_cobblestone"; - materials[49] = "minecraft:obsidian"; - materials[50] = "minecraft:torch"; - materials[51] = "minecraft:fire"; - materials[52] = "minecraft:mob_spawner"; - materials[53] = "minecraft:oak_stairs"; - materials[54] = "minecraft:chest"; - materials[56] = "minecraft:diamond_ore"; - materials[57] = "minecraft:diamond_block"; - materials[58] = "minecraft:crafting_table"; - materials[60] = "minecraft:farmland"; - materials[61] = "minecraft:furnace"; - materials[62] = "minecraft:lit_furnace"; - materials[65] = "minecraft:ladder"; - materials[66] = "minecraft:rail"; - materials[67] = "minecraft:stone_stairs"; - materials[69] = "minecraft:lever"; - materials[70] = "minecraft:stone_pressure_plate"; - materials[72] = "minecraft:wooden_pressure_plate"; - materials[73] = "minecraft:redstone_ore"; - materials[76] = "minecraft:redstone_torch"; - materials[77] = "minecraft:stone_button"; - materials[78] = "minecraft:snow_layer"; - materials[79] = "minecraft:ice"; - materials[80] = "minecraft:snow"; - materials[81] = "minecraft:cactus"; - materials[82] = "minecraft:clay"; - materials[84] = "minecraft:jukebox"; - materials[85] = "minecraft:fence"; - materials[86] = "minecraft:pumpkin"; - materials[87] = "minecraft:netherrack"; - materials[88] = "minecraft:soul_sand"; - materials[89] = "minecraft:glowstone"; - materials[90] = "minecraft:portal"; - materials[91] = "minecraft:lit_pumpkin"; - materials[95] = "minecraft:stained_glass"; - materials[96] = "minecraft:trapdoor"; - materials[97] = "minecraft:monster_egg"; - materials[98] = "minecraft:stonebrick"; - materials[99] = "minecraft:brown_mushroom_block"; - materials[100] = "minecraft:red_mushroom_block"; - materials[101] = "minecraft:iron_bars"; - materials[102] = "minecraft:glass_pane"; - materials[103] = "minecraft:melon_block"; - materials[106] = "minecraft:vine"; - materials[107] = "minecraft:fence_gate"; - materials[108] = "minecraft:brick_stairs"; - materials[109] = "minecraft:stone_brick_stairs"; - materials[110] = "minecraft:mycelium"; - materials[111] = "minecraft:waterlily"; - materials[112] = "minecraft:nether_brick"; - materials[113] = "minecraft:nether_brick_fence"; - materials[114] = "minecraft:nether_brick_stairs"; - materials[116] = "minecraft:enchanting_table"; - materials[119] = "minecraft:end_portal"; - materials[120] = "minecraft:end_portal_frame"; - materials[121] = "minecraft:end_stone"; - materials[122] = "minecraft:dragon_egg"; - materials[123] = "minecraft:redstone_lamp"; - materials[125] = "minecraft:double_wooden_slab"; - materials[126] = "minecraft:wooden_slab"; - materials[127] = "minecraft:cocoa"; - materials[128] = "minecraft:sandstone_stairs"; - materials[129] = "minecraft:emerald_ore"; - materials[130] = "minecraft:ender_chest"; - materials[131] = "minecraft:tripwire_hook"; - materials[133] = "minecraft:emerald_block"; - materials[134] = "minecraft:spruce_stairs"; - materials[135] = "minecraft:birch_stairs"; - materials[136] = "minecraft:jungle_stairs"; - materials[137] = "minecraft:command_block"; - materials[138] = "minecraft:beacon"; - materials[139] = "minecraft:cobblestone_wall"; - materials[141] = "minecraft:carrots"; - materials[142] = "minecraft:potatoes"; - materials[143] = "minecraft:wooden_button"; - materials[145] = "minecraft:anvil"; - materials[146] = "minecraft:trapped_chest"; - materials[147] = "minecraft:light_weighted_pressure_plate"; - materials[148] = "minecraft:heavy_weighted_pressure_plate"; - materials[151] = "minecraft:daylight_detector"; - materials[152] = "minecraft:redstone_block"; - materials[153] = "minecraft:quartz_ore"; - materials[154] = "minecraft:hopper"; - materials[155] = "minecraft:quartz_block"; - materials[156] = "minecraft:quartz_stairs"; - materials[157] = "minecraft:activator_rail"; - materials[158] = "minecraft:dropper"; - materials[159] = "minecraft:stained_hardened_clay"; - materials[160] = "minecraft:stained_glass_pane"; - materials[161] = "minecraft:leaves2"; - materials[162] = "minecraft:log2"; - materials[163] = "minecraft:acacia_stairs"; - materials[164] = "minecraft:dark_oak_stairs"; - materials[170] = "minecraft:hay_block"; - materials[171] = "minecraft:carpet"; - materials[172] = "minecraft:hardened_clay"; - materials[173] = "minecraft:coal_block"; - materials[174] = "minecraft:packed_ice"; - materials[175] = "minecraft:double_plant"; - materials[256] = "minecraft:iron_shovel"; - materials[257] = "minecraft:iron_pickaxe"; - materials[258] = "minecraft:iron_axe"; - materials[259] = "minecraft:flint_and_steel"; - materials[260] = "minecraft:apple"; - materials[261] = "minecraft:bow"; - materials[262] = "minecraft:arrow"; - materials[263] = "minecraft:coal"; - materials[264] = "minecraft:diamond"; - materials[265] = "minecraft:iron_ingot"; - materials[266] = "minecraft:gold_ingot"; - materials[267] = "minecraft:iron_sword"; - materials[268] = "minecraft:wooden_sword"; - materials[269] = "minecraft:wooden_shovel"; - materials[270] = "minecraft:wooden_pickaxe"; - materials[271] = "minecraft:wooden_axe"; - materials[272] = "minecraft:stone_sword"; - materials[273] = "minecraft:stone_shovel"; - materials[274] = "minecraft:stone_pickaxe"; - materials[275] = "minecraft:stone_axe"; - materials[276] = "minecraft:diamond_sword"; - materials[277] = "minecraft:diamond_shovel"; - materials[278] = "minecraft:diamond_pickaxe"; - materials[279] = "minecraft:diamond_axe"; - materials[280] = "minecraft:stick"; - materials[281] = "minecraft:bowl"; - materials[282] = "minecraft:mushroom_stew"; - materials[283] = "minecraft:golden_sword"; - materials[284] = "minecraft:golden_shovel"; - materials[285] = "minecraft:golden_pickaxe"; - materials[286] = "minecraft:golden_axe"; - materials[287] = "minecraft:string"; - materials[288] = "minecraft:feather"; - materials[289] = "minecraft:gunpowder"; - materials[290] = "minecraft:wooden_hoe"; - materials[291] = "minecraft:stone_hoe"; - materials[292] = "minecraft:iron_hoe"; - materials[293] = "minecraft:diamond_hoe"; - materials[294] = "minecraft:golden_hoe"; - materials[295] = "minecraft:wheat_seeds"; - materials[296] = "minecraft:wheat"; - materials[297] = "minecraft:bread"; - materials[298] = "minecraft:leather_helmet"; - materials[299] = "minecraft:leather_chestplate"; - materials[300] = "minecraft:leather_leggings"; - materials[301] = "minecraft:leather_boots"; - materials[302] = "minecraft:chainmail_helmet"; - materials[303] = "minecraft:chainmail_chestplate"; - materials[304] = "minecraft:chainmail_leggings"; - materials[305] = "minecraft:chainmail_boots"; - materials[306] = "minecraft:iron_helmet"; - materials[307] = "minecraft:iron_chestplate"; - materials[308] = "minecraft:iron_leggings"; - materials[309] = "minecraft:iron_boots"; - materials[310] = "minecraft:diamond_helmet"; - materials[311] = "minecraft:diamond_chestplate"; - materials[312] = "minecraft:diamond_leggings"; - materials[313] = "minecraft:diamond_boots"; - materials[314] = "minecraft:golden_helmet"; - materials[315] = "minecraft:golden_chestplate"; - materials[316] = "minecraft:golden_leggings"; - materials[317] = "minecraft:golden_boots"; - materials[318] = "minecraft:flint"; - materials[319] = "minecraft:porkchop"; - materials[320] = "minecraft:cooked_porkchop"; - materials[321] = "minecraft:painting"; - materials[322] = "minecraft:golden_apple"; - materials[323] = "minecraft:sign"; - materials[324] = "minecraft:wooden_door"; - materials[325] = "minecraft:bucket"; - materials[326] = "minecraft:water_bucket"; - materials[327] = "minecraft:lava_bucket"; - materials[328] = "minecraft:minecart"; - materials[329] = "minecraft:saddle"; - materials[330] = "minecraft:iron_door"; - materials[331] = "minecraft:redstone"; - materials[332] = "minecraft:snowball"; - materials[333] = "minecraft:boat"; - materials[334] = "minecraft:leather"; - materials[335] = "minecraft:milk_bucket"; - materials[336] = "minecraft:brick"; - materials[337] = "minecraft:clay_ball"; - materials[338] = "minecraft:reeds"; - materials[339] = "minecraft:paper"; - materials[340] = "minecraft:book"; - materials[341] = "minecraft:slime_ball"; - materials[342] = "minecraft:chest_minecart"; - materials[343] = "minecraft:furnace_minecart"; - materials[344] = "minecraft:egg"; - materials[345] = "minecraft:compass"; - materials[346] = "minecraft:fishing_rod"; - materials[347] = "minecraft:clock"; - materials[348] = "minecraft:glowstone_dust"; - materials[349] = "minecraft:fish"; - materials[350] = "minecraft:cooked_fish"; // Paper - cooked_fished -> cooked_fish - materials[351] = "minecraft:dye"; - materials[352] = "minecraft:bone"; - materials[353] = "minecraft:sugar"; - materials[354] = "minecraft:cake"; - materials[355] = "minecraft:bed"; - materials[356] = "minecraft:repeater"; - materials[357] = "minecraft:cookie"; - materials[358] = "minecraft:filled_map"; - materials[359] = "minecraft:shears"; - materials[360] = "minecraft:melon"; - materials[361] = "minecraft:pumpkin_seeds"; - materials[362] = "minecraft:melon_seeds"; - materials[363] = "minecraft:beef"; - materials[364] = "minecraft:cooked_beef"; - materials[365] = "minecraft:chicken"; - materials[366] = "minecraft:cooked_chicken"; - materials[367] = "minecraft:rotten_flesh"; - materials[368] = "minecraft:ender_pearl"; - materials[369] = "minecraft:blaze_rod"; - materials[370] = "minecraft:ghast_tear"; - materials[371] = "minecraft:gold_nugget"; - materials[372] = "minecraft:nether_wart"; - materials[373] = "minecraft:potion"; - materials[374] = "minecraft:glass_bottle"; - materials[375] = "minecraft:spider_eye"; - materials[376] = "minecraft:fermented_spider_eye"; - materials[377] = "minecraft:blaze_powder"; - materials[378] = "minecraft:magma_cream"; - materials[379] = "minecraft:brewing_stand"; - materials[380] = "minecraft:cauldron"; - materials[381] = "minecraft:ender_eye"; - materials[382] = "minecraft:speckled_melon"; - materials[383] = "minecraft:spawn_egg"; - materials[384] = "minecraft:experience_bottle"; - materials[385] = "minecraft:fire_charge"; - materials[386] = "minecraft:writable_book"; - materials[387] = "minecraft:written_book"; - materials[388] = "minecraft:emerald"; - materials[389] = "minecraft:item_frame"; - materials[390] = "minecraft:flower_pot"; - materials[391] = "minecraft:carrot"; - materials[392] = "minecraft:potato"; - materials[393] = "minecraft:baked_potato"; - materials[394] = "minecraft:poisonous_potato"; - materials[395] = "minecraft:map"; - materials[396] = "minecraft:golden_carrot"; - materials[397] = "minecraft:skull"; - materials[398] = "minecraft:carrot_on_a_stick"; - materials[399] = "minecraft:nether_star"; - materials[400] = "minecraft:pumpkin_pie"; - materials[401] = "minecraft:fireworks"; - materials[402] = "minecraft:firework_charge"; - materials[403] = "minecraft:enchanted_book"; - materials[404] = "minecraft:comparator"; - materials[405] = "minecraft:netherbrick"; - materials[406] = "minecraft:quartz"; - materials[407] = "minecraft:tnt_minecart"; - materials[408] = "minecraft:hopper_minecart"; - materials[417] = "minecraft:iron_horse_armor"; - materials[418] = "minecraft:golden_horse_armor"; - materials[419] = "minecraft:diamond_horse_armor"; - materials[420] = "minecraft:lead"; - materials[421] = "minecraft:name_tag"; - materials[422] = "minecraft:command_block_minecart"; - materials[2256] = "minecraft:record_13"; - materials[2257] = "minecraft:record_cat"; - materials[2258] = "minecraft:record_blocks"; - materials[2259] = "minecraft:record_chirp"; - materials[2260] = "minecraft:record_far"; - materials[2261] = "minecraft:record_mall"; - materials[2262] = "minecraft:record_mellohi"; - materials[2263] = "minecraft:record_stal"; - materials[2264] = "minecraft:record_strad"; - materials[2265] = "minecraft:record_ward"; - materials[2266] = "minecraft:record_11"; - materials[2267] = "minecraft:record_wait"; - // Paper start - materials[409] = "minecraft:prismarine_shard"; - materials[410] = "minecraft:prismarine_crystals"; - materials[411] = "minecraft:rabbit"; - materials[412] = "minecraft:cooked_rabbit"; - materials[413] = "minecraft:rabbit_stew"; - materials[414] = "minecraft:rabbit_foot"; - materials[415] = "minecraft:rabbit_hide"; - materials[416] = "minecraft:armor_stand"; - materials[423] = "minecraft:mutton"; - materials[424] = "minecraft:cooked_mutton"; - materials[425] = "minecraft:banner"; - materials[426] = "minecraft:end_crystal"; - materials[427] = "minecraft:spruce_door"; - materials[428] = "minecraft:birch_door"; - materials[429] = "minecraft:jungle_door"; - materials[430] = "minecraft:acacia_door"; - materials[431] = "minecraft:dark_oak_door"; - materials[432] = "minecraft:chorus_fruit"; - materials[433] = "minecraft:chorus_fruit_popped"; - materials[434] = "minecraft:beetroot"; - materials[435] = "minecraft:beetroot_seeds"; - materials[436] = "minecraft:beetroot_soup"; - materials[437] = "minecraft:dragon_breath"; - materials[438] = "minecraft:splash_potion"; - materials[439] = "minecraft:spectral_arrow"; - materials[440] = "minecraft:tipped_arrow"; - materials[441] = "minecraft:lingering_potion"; - materials[442] = "minecraft:shield"; - materials[443] = "minecraft:elytra"; - materials[444] = "minecraft:spruce_boat"; - materials[445] = "minecraft:birch_boat"; - materials[446] = "minecraft:jungle_boat"; - materials[447] = "minecraft:acacia_boat"; - materials[448] = "minecraft:dark_oak_boat"; - materials[449] = "minecraft:totem_of_undying"; - materials[450] = "minecraft:shulker_shell"; - materials[452] = "minecraft:iron_nugget"; - materials[453] = "minecraft:knowledge_book"; - // Paper end - } - } - - private static class DataConverterArmorStand implements DataConverter { - - DataConverterArmorStand() { - } - - public int getDataVersion() { - return 147; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("ArmorStand".equals(cmp.getString("id")) && cmp.getBoolean("Silent") && !cmp.getBoolean("Marker")) { - cmp.remove("Silent"); - } - - return cmp; - } - - } - - private static class DataConverterBanner implements DataConverter { - - DataConverterBanner() { - } - - public int getDataVersion() { - return 804; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:banner".equals(cmp.getString("id")) && cmp.contains("tag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - - if (nbttagcompound2.contains("Base", 99)) { - cmp.putShort("Damage", (short) (nbttagcompound2.getShort("Base") & 15)); - if (nbttagcompound1.contains("display", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound3 = nbttagcompound1.getCompound("display"); - - if (nbttagcompound3.contains("Lore", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound3.getList("Lore", 8); - - if (nbttaglist.size() == 1 && "(+NBT)".equals(nbttaglist.getString(0))) { - return cmp; - } - } - } - - nbttagcompound2.remove("Base"); - if (nbttagcompound2.isEmpty()) { - nbttagcompound1.remove("BlockEntityTag"); - } - - if (nbttagcompound1.isEmpty()) { - cmp.remove("tag"); - } - } - } - } - - return cmp; - } - - } - - private static class DataConverterPotionId implements DataConverter { - - private static final String[] potions = new String[128]; - - DataConverterPotionId() { - } - - public int getDataVersion() { - return 102; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:potion".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - short short0 = cmp.getShort("Damage"); - - if (!nbttagcompound1.contains("Potion", 8)) { - String s = DataConverterPotionId.potions[short0 & 127]; - - nbttagcompound1.putString("Potion", s == null ? "minecraft:water" : s); - cmp.put("tag", nbttagcompound1); - if ((short0 & 16384) == 16384) { - cmp.putString("id", "minecraft:splash_potion"); - } - } - - if (short0 != 0) { - cmp.putShort("Damage", (short) 0); - } - } - - return cmp; - } - - static { - DataConverterPotionId.potions[0] = "minecraft:water"; - DataConverterPotionId.potions[1] = "minecraft:regeneration"; - DataConverterPotionId.potions[2] = "minecraft:swiftness"; - DataConverterPotionId.potions[3] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[4] = "minecraft:poison"; - DataConverterPotionId.potions[5] = "minecraft:healing"; - DataConverterPotionId.potions[6] = "minecraft:night_vision"; - DataConverterPotionId.potions[7] = null; - DataConverterPotionId.potions[8] = "minecraft:weakness"; - DataConverterPotionId.potions[9] = "minecraft:strength"; - DataConverterPotionId.potions[10] = "minecraft:slowness"; - DataConverterPotionId.potions[11] = "minecraft:leaping"; - DataConverterPotionId.potions[12] = "minecraft:harming"; - DataConverterPotionId.potions[13] = "minecraft:water_breathing"; - DataConverterPotionId.potions[14] = "minecraft:invisibility"; - DataConverterPotionId.potions[15] = null; - DataConverterPotionId.potions[16] = "minecraft:awkward"; - DataConverterPotionId.potions[17] = "minecraft:regeneration"; - DataConverterPotionId.potions[18] = "minecraft:swiftness"; - DataConverterPotionId.potions[19] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[20] = "minecraft:poison"; - DataConverterPotionId.potions[21] = "minecraft:healing"; - DataConverterPotionId.potions[22] = "minecraft:night_vision"; - DataConverterPotionId.potions[23] = null; - DataConverterPotionId.potions[24] = "minecraft:weakness"; - DataConverterPotionId.potions[25] = "minecraft:strength"; - DataConverterPotionId.potions[26] = "minecraft:slowness"; - DataConverterPotionId.potions[27] = "minecraft:leaping"; - DataConverterPotionId.potions[28] = "minecraft:harming"; - DataConverterPotionId.potions[29] = "minecraft:water_breathing"; - DataConverterPotionId.potions[30] = "minecraft:invisibility"; - DataConverterPotionId.potions[31] = null; - DataConverterPotionId.potions[32] = "minecraft:thick"; - DataConverterPotionId.potions[33] = "minecraft:strong_regeneration"; - DataConverterPotionId.potions[34] = "minecraft:strong_swiftness"; - DataConverterPotionId.potions[35] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[36] = "minecraft:strong_poison"; - DataConverterPotionId.potions[37] = "minecraft:strong_healing"; - DataConverterPotionId.potions[38] = "minecraft:night_vision"; - DataConverterPotionId.potions[39] = null; - DataConverterPotionId.potions[40] = "minecraft:weakness"; - DataConverterPotionId.potions[41] = "minecraft:strong_strength"; - DataConverterPotionId.potions[42] = "minecraft:slowness"; - DataConverterPotionId.potions[43] = "minecraft:strong_leaping"; - DataConverterPotionId.potions[44] = "minecraft:strong_harming"; - DataConverterPotionId.potions[45] = "minecraft:water_breathing"; - DataConverterPotionId.potions[46] = "minecraft:invisibility"; - DataConverterPotionId.potions[47] = null; - DataConverterPotionId.potions[48] = null; - DataConverterPotionId.potions[49] = "minecraft:strong_regeneration"; - DataConverterPotionId.potions[50] = "minecraft:strong_swiftness"; - DataConverterPotionId.potions[51] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[52] = "minecraft:strong_poison"; - DataConverterPotionId.potions[53] = "minecraft:strong_healing"; - DataConverterPotionId.potions[54] = "minecraft:night_vision"; - DataConverterPotionId.potions[55] = null; - DataConverterPotionId.potions[56] = "minecraft:weakness"; - DataConverterPotionId.potions[57] = "minecraft:strong_strength"; - DataConverterPotionId.potions[58] = "minecraft:slowness"; - DataConverterPotionId.potions[59] = "minecraft:strong_leaping"; - DataConverterPotionId.potions[60] = "minecraft:strong_harming"; - DataConverterPotionId.potions[61] = "minecraft:water_breathing"; - DataConverterPotionId.potions[62] = "minecraft:invisibility"; - DataConverterPotionId.potions[63] = null; - DataConverterPotionId.potions[64] = "minecraft:mundane"; - DataConverterPotionId.potions[65] = "minecraft:long_regeneration"; - DataConverterPotionId.potions[66] = "minecraft:long_swiftness"; - DataConverterPotionId.potions[67] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[68] = "minecraft:long_poison"; - DataConverterPotionId.potions[69] = "minecraft:healing"; - DataConverterPotionId.potions[70] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[71] = null; - DataConverterPotionId.potions[72] = "minecraft:long_weakness"; - DataConverterPotionId.potions[73] = "minecraft:long_strength"; - DataConverterPotionId.potions[74] = "minecraft:long_slowness"; - DataConverterPotionId.potions[75] = "minecraft:long_leaping"; - DataConverterPotionId.potions[76] = "minecraft:harming"; - DataConverterPotionId.potions[77] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[78] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[79] = null; - DataConverterPotionId.potions[80] = "minecraft:awkward"; - DataConverterPotionId.potions[81] = "minecraft:long_regeneration"; - DataConverterPotionId.potions[82] = "minecraft:long_swiftness"; - DataConverterPotionId.potions[83] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[84] = "minecraft:long_poison"; - DataConverterPotionId.potions[85] = "minecraft:healing"; - DataConverterPotionId.potions[86] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[87] = null; - DataConverterPotionId.potions[88] = "minecraft:long_weakness"; - DataConverterPotionId.potions[89] = "minecraft:long_strength"; - DataConverterPotionId.potions[90] = "minecraft:long_slowness"; - DataConverterPotionId.potions[91] = "minecraft:long_leaping"; - DataConverterPotionId.potions[92] = "minecraft:harming"; - DataConverterPotionId.potions[93] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[94] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[95] = null; - DataConverterPotionId.potions[96] = "minecraft:thick"; - DataConverterPotionId.potions[97] = "minecraft:regeneration"; - DataConverterPotionId.potions[98] = "minecraft:swiftness"; - DataConverterPotionId.potions[99] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[100] = "minecraft:poison"; - DataConverterPotionId.potions[101] = "minecraft:strong_healing"; - DataConverterPotionId.potions[102] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[103] = null; - DataConverterPotionId.potions[104] = "minecraft:long_weakness"; - DataConverterPotionId.potions[105] = "minecraft:strength"; - DataConverterPotionId.potions[106] = "minecraft:long_slowness"; - DataConverterPotionId.potions[107] = "minecraft:leaping"; - DataConverterPotionId.potions[108] = "minecraft:strong_harming"; - DataConverterPotionId.potions[109] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[110] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[111] = null; - DataConverterPotionId.potions[112] = null; - DataConverterPotionId.potions[113] = "minecraft:regeneration"; - DataConverterPotionId.potions[114] = "minecraft:swiftness"; - DataConverterPotionId.potions[115] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[116] = "minecraft:poison"; - DataConverterPotionId.potions[117] = "minecraft:strong_healing"; - DataConverterPotionId.potions[118] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[119] = null; - DataConverterPotionId.potions[120] = "minecraft:long_weakness"; - DataConverterPotionId.potions[121] = "minecraft:strength"; - DataConverterPotionId.potions[122] = "minecraft:long_slowness"; - DataConverterPotionId.potions[123] = "minecraft:leaping"; - DataConverterPotionId.potions[124] = "minecraft:strong_harming"; - DataConverterPotionId.potions[125] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[126] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[127] = null; - } - } - - private static class DataConverterSpawnEgg implements DataConverter { - - private static final String[] eggs = new String[256]; - - DataConverterSpawnEgg() { - } - - public int getDataVersion() { - return 105; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:spawn_egg".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); - short short0 = cmp.getShort("Damage"); - - if (!nbttagcompound2.contains("id", 8)) { - String s = DataConverterSpawnEgg.eggs[short0 & 255]; - - if (s != null) { - nbttagcompound2.putString("id", s); - nbttagcompound1.put("EntityTag", nbttagcompound2); - cmp.put("tag", nbttagcompound1); - } - } - - if (short0 != 0) { - cmp.putShort("Damage", (short) 0); - } - } - - return cmp; - } - - static { - - DataConverterSpawnEgg.eggs[1] = "Item"; - DataConverterSpawnEgg.eggs[2] = "XPOrb"; - DataConverterSpawnEgg.eggs[7] = "ThrownEgg"; - DataConverterSpawnEgg.eggs[8] = "LeashKnot"; - DataConverterSpawnEgg.eggs[9] = "Painting"; - DataConverterSpawnEgg.eggs[10] = "Arrow"; - DataConverterSpawnEgg.eggs[11] = "Snowball"; - DataConverterSpawnEgg.eggs[12] = "Fireball"; - DataConverterSpawnEgg.eggs[13] = "SmallFireball"; - DataConverterSpawnEgg.eggs[14] = "ThrownEnderpearl"; - DataConverterSpawnEgg.eggs[15] = "EyeOfEnderSignal"; - DataConverterSpawnEgg.eggs[16] = "ThrownPotion"; - DataConverterSpawnEgg.eggs[17] = "ThrownExpBottle"; - DataConverterSpawnEgg.eggs[18] = "ItemFrame"; - DataConverterSpawnEgg.eggs[19] = "WitherSkull"; - DataConverterSpawnEgg.eggs[20] = "PrimedTnt"; - DataConverterSpawnEgg.eggs[21] = "FallingSand"; - DataConverterSpawnEgg.eggs[22] = "FireworksRocketEntity"; - DataConverterSpawnEgg.eggs[23] = "TippedArrow"; - DataConverterSpawnEgg.eggs[24] = "SpectralArrow"; - DataConverterSpawnEgg.eggs[25] = "ShulkerBullet"; - DataConverterSpawnEgg.eggs[26] = "DragonFireball"; - DataConverterSpawnEgg.eggs[30] = "ArmorStand"; - DataConverterSpawnEgg.eggs[41] = "Boat"; - DataConverterSpawnEgg.eggs[42] = "MinecartRideable"; - DataConverterSpawnEgg.eggs[43] = "MinecartChest"; - DataConverterSpawnEgg.eggs[44] = "MinecartFurnace"; - DataConverterSpawnEgg.eggs[45] = "MinecartTNT"; - DataConverterSpawnEgg.eggs[46] = "MinecartHopper"; - DataConverterSpawnEgg.eggs[47] = "MinecartSpawner"; - DataConverterSpawnEgg.eggs[40] = "MinecartCommandBlock"; - DataConverterSpawnEgg.eggs[48] = "Mob"; - DataConverterSpawnEgg.eggs[49] = "Monster"; - DataConverterSpawnEgg.eggs[50] = "Creeper"; - DataConverterSpawnEgg.eggs[51] = "Skeleton"; - DataConverterSpawnEgg.eggs[52] = "Spider"; - DataConverterSpawnEgg.eggs[53] = "Giant"; - DataConverterSpawnEgg.eggs[54] = "Zombie"; - DataConverterSpawnEgg.eggs[55] = "Slime"; - DataConverterSpawnEgg.eggs[56] = "Ghast"; - DataConverterSpawnEgg.eggs[57] = "PigZombie"; - DataConverterSpawnEgg.eggs[58] = "Enderman"; - DataConverterSpawnEgg.eggs[59] = "CaveSpider"; - DataConverterSpawnEgg.eggs[60] = "Silverfish"; - DataConverterSpawnEgg.eggs[61] = "Blaze"; - DataConverterSpawnEgg.eggs[62] = "LavaSlime"; - DataConverterSpawnEgg.eggs[63] = "EnderDragon"; - DataConverterSpawnEgg.eggs[64] = "WitherBoss"; - DataConverterSpawnEgg.eggs[65] = "Bat"; - DataConverterSpawnEgg.eggs[66] = "Witch"; - DataConverterSpawnEgg.eggs[67] = "Endermite"; - DataConverterSpawnEgg.eggs[68] = "Guardian"; - DataConverterSpawnEgg.eggs[69] = "Shulker"; - DataConverterSpawnEgg.eggs[90] = "Pig"; - DataConverterSpawnEgg.eggs[91] = "Sheep"; - DataConverterSpawnEgg.eggs[92] = "Cow"; - DataConverterSpawnEgg.eggs[93] = "Chicken"; - DataConverterSpawnEgg.eggs[94] = "Squid"; - DataConverterSpawnEgg.eggs[95] = "Wolf"; - DataConverterSpawnEgg.eggs[96] = "MushroomCow"; - DataConverterSpawnEgg.eggs[97] = "SnowMan"; - DataConverterSpawnEgg.eggs[98] = "Ozelot"; - DataConverterSpawnEgg.eggs[99] = "VillagerGolem"; - DataConverterSpawnEgg.eggs[100] = "EntityHorse"; - DataConverterSpawnEgg.eggs[101] = "Rabbit"; - DataConverterSpawnEgg.eggs[120] = "Villager"; - DataConverterSpawnEgg.eggs[200] = "EnderCrystal"; - } - } - - private static class DataConverterMinecart implements DataConverter { - - private static final List a = Lists.newArrayList( - "MinecartRideable", - "MinecartChest", - "MinecartFurnace", - "MinecartTNT", - "MinecartSpawner", - "MinecartHopper", - "MinecartCommandBlock" - ); - - DataConverterMinecart() { - } - - public int getDataVersion() { - return 106; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Minecart".equals(cmp.getString("id"))) { - String s = "MinecartRideable"; - int i = cmp.getInt("Type"); - - if (i > 0 && i < DataConverterMinecart.a.size()) { - s = DataConverterMinecart.a.get(i); - } - - cmp.putString("id", s); - cmp.remove("Type"); - } - - return cmp; - } - - } - - private static class DataConverterMobSpawner implements DataConverter { - - DataConverterMobSpawner() { - } - - public int getDataVersion() { - return 107; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (!"MobSpawner".equals(cmp.getString("id"))) { - return cmp; - } else { - if (cmp.contains("EntityId", 8)) { - String s = cmp.getString("EntityId"); - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("SpawnData"); - - nbttagcompound1.putString("id", s.isEmpty() ? "Pig" : s); - cmp.put("SpawnData", nbttagcompound1); - cmp.remove("EntityId"); - } - - if (cmp.contains("SpawnPotentials", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("SpawnPotentials", 10); - - for (int i = 0; i < nbttaglist.size(); ++i) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompound(i); - - if (nbttagcompound2.contains("Type", 8)) { - net.minecraft.nbt.CompoundTag nbttagcompound3 = nbttagcompound2.getCompound("Properties"); - - nbttagcompound3.putString("id", nbttagcompound2.getString("Type")); - nbttagcompound2.put("Entity", nbttagcompound3); - nbttagcompound2.remove("Type"); - nbttagcompound2.remove("Properties"); - } - } - } - - return cmp; - } - } - - } - - private static class DataConverterUUID implements DataConverter { - - DataConverterUUID() { - } - - public int getDataVersion() { - return 108; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("UUID", 8)) { - cmp.putUUID("UUID", UUID.fromString(cmp.getString("UUID"))); - } - - return cmp; - } - - } - - private static class DataConverterHealth implements DataConverter { - - private static final Set a = Sets.newHashSet( - "ArmorStand", - "Bat", - "Blaze", - "CaveSpider", - "Chicken", - "Cow", - "Creeper", - "EnderDragon", - "Enderman", - "Endermite", - "EntityHorse", - "Ghast", - "Giant", - "Guardian", - "LavaSlime", - "MushroomCow", - "Ozelot", - "Pig", - "PigZombie", - "Rabbit", - "Sheep", - "Shulker", - "Silverfish", - "Skeleton", - "Slime", - "SnowMan", - "Spider", - "Squid", - "Villager", - "VillagerGolem", - "Witch", - "WitherBoss", - "Wolf", - "Zombie" - ); - - DataConverterHealth() { - } - - public int getDataVersion() { - return 109; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (DataConverterHealth.a.contains(cmp.getString("id"))) { - float f; - - if (cmp.contains("HealF", 99)) { - f = cmp.getFloat("HealF"); - cmp.remove("HealF"); - } else { - if (!cmp.contains("Health", 99)) { - return cmp; - } - - f = cmp.getFloat("Health"); - } - - cmp.putFloat("Health", f); - } - - return cmp; - } - - } - - private static class DataConverterSaddle implements DataConverter { - - DataConverterSaddle() { - } - - public int getDataVersion() { - return 110; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("EntityHorse".equals(cmp.getString("id")) && !cmp.contains("SaddleItem", 10) && cmp.getBoolean("Saddle")) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = new net.minecraft.nbt.CompoundTag(); - - nbttagcompound1.putString("id", "minecraft:saddle"); - nbttagcompound1.putByte("Count", (byte) 1); - nbttagcompound1.putShort("Damage", (short) 0); - cmp.put("SaddleItem", nbttagcompound1); - cmp.remove("Saddle"); - } - - return cmp; - } - - } - - private static class DataConverterHanging implements DataConverter { - - DataConverterHanging() { - } - - public int getDataVersion() { - return 111; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - boolean flag = "Painting".equals(s); - boolean flag1 = "ItemFrame".equals(s); - - if ((flag || flag1) && !cmp.contains("Facing", 99)) { - Direction enumdirection; - - if (cmp.contains("Direction", 99)) { - enumdirection = Direction.from2DDataValue(cmp.getByte("Direction")); - cmp.putInt("TileX", cmp.getInt("TileX") + enumdirection.getStepX()); - cmp.putInt("TileY", cmp.getInt("TileY") + enumdirection.getStepY()); - cmp.putInt("TileZ", cmp.getInt("TileZ") + enumdirection.getStepZ()); - cmp.remove("Direction"); - if (flag1 && cmp.contains("ItemRotation", 99)) { - cmp.putByte("ItemRotation", (byte) (cmp.getByte("ItemRotation") * 2)); - } - } else { - enumdirection = Direction.from2DDataValue(cmp.getByte("Dir")); - cmp.remove("Dir"); - } - - cmp.putByte("Facing", (byte) enumdirection.get2DDataValue()); - } - - return cmp; - } - - } - - private static class DataConverterDropChances implements DataConverter { - - DataConverterDropChances() { - } - - public int getDataVersion() { - return 113; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - net.minecraft.nbt.ListTag nbttaglist; - - if (cmp.contains("HandDropChances", 9)) { - nbttaglist = cmp.getList("HandDropChances", 5); - if (nbttaglist.size() == 2 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F) { - cmp.remove("HandDropChances"); - } - } - - if (cmp.contains("ArmorDropChances", 9)) { - nbttaglist = cmp.getList("ArmorDropChances", 5); - if (nbttaglist.size() == 4 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F && nbttaglist.getFloat( - 2) == 0.0F && nbttaglist.getFloat(3) == 0.0F) { - cmp.remove("ArmorDropChances"); - } - } - - return cmp; - } - - } - - private static class DataConverterRiding implements DataConverter { - - DataConverterRiding() { - } - - public int getDataVersion() { - return 135; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - while (cmp.contains("Riding", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = this.b(cmp); - - this.convert(cmp, nbttagcompound1); - cmp = nbttagcompound1; - } - - return cmp; - } - - protected void convert(net.minecraft.nbt.CompoundTag nbttagcompound, net.minecraft.nbt.CompoundTag nbttagcompound1) { - net.minecraft.nbt.ListTag nbttaglist = new net.minecraft.nbt.ListTag(); - - nbttaglist.add(nbttagcompound); - nbttagcompound1.put("Passengers", nbttaglist); - } - - protected net.minecraft.nbt.CompoundTag b(net.minecraft.nbt.CompoundTag nbttagcompound) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttagcompound.getCompound("Riding"); - - nbttagcompound.remove("Riding"); - return nbttagcompound1; - } - - } - - private static class DataConverterBook implements DataConverter { - - DataConverterBook() { - } - - public int getDataVersion() { - return 165; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:written_book".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("pages", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("pages", 8); - - for (int i = 0; i < nbttaglist.size(); ++i) { - String s = nbttaglist.getString(i); - Component object = null; - - if (!"null".equals(s) && !StringUtil.isNullOrEmpty(s)) { - if ((s.charAt(0) != 34 || s.charAt(s.length() - 1) != 34) && (s.charAt(0) != 123 || s.charAt(s.length() - 1) != 125)) { - object = new TextComponent(s); - } else { - try { - object = GsonHelper.fromJson(DataConverterSignText.a, s, Component.class, true); - if (object == null) { - object = new TextComponent(""); - } - } catch (JsonParseException jsonparseexception) { - ; - } - - if (object == null) { - try { - object = Component.Serializer.fromJson(s); - } catch (JsonParseException jsonparseexception1) { - ; - } - } - - if (object == null) { - try { - object = Component.Serializer.fromJsonLenient(s); - } catch (JsonParseException jsonparseexception2) { - ; - } - } - - if (object == null) { - object = new TextComponent(s); - } - } - } else { - object = new TextComponent(""); - } - - nbttaglist.set(i, net.minecraft.nbt.StringTag.valueOf(Component.Serializer.toJson(object))); - } - - nbttagcompound1.put("pages", nbttaglist); - } - } - - return cmp; - } - - } - - private static class DataConverterCookedFish implements DataConverter { - - private static final ResourceLocation a = new ResourceLocation("cooked_fished"); - - DataConverterCookedFish() { - } - - public int getDataVersion() { - return 502; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("id", 8) && DataConverterCookedFish.a.equals(new ResourceLocation(cmp.getString("id")))) { - cmp.putString("id", "minecraft:cooked_fish"); - } - - return cmp; - } - - } - - private static class DataConverterZombie implements DataConverter { - - private static final Random a = new Random(); - - DataConverterZombie() { - } - - public int getDataVersion() { - return 502; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Zombie".equals(cmp.getString("id")) && cmp.getBoolean("IsVillager")) { - if (!cmp.contains("ZombieType", 99)) { - int i = -1; - - if (cmp.contains("VillagerProfession", 99)) { - try { - i = this.convert(cmp.getInt("VillagerProfession")); - } catch (RuntimeException runtimeexception) { - ; - } - } - - if (i == -1) { - i = this.convert(DataConverterZombie.a.nextInt(6)); - } - - cmp.putInt("ZombieType", i); - } - - cmp.remove("IsVillager"); - } - - return cmp; - } - - private int convert(int i) { - return i >= 0 && i < 6 ? i : -1; - } - - } - - private static class DataConverterVBO implements DataConverter { - - DataConverterVBO() { - } - - public int getDataVersion() { - return 505; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - cmp.putString("useVbo", "true"); - return cmp; - } - - } - - private static class DataConverterGuardian implements DataConverter { - - DataConverterGuardian() { - } - - public int getDataVersion() { - return 700; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Guardian".equals(cmp.getString("id"))) { - if (cmp.getBoolean("Elder")) { - cmp.putString("id", "ElderGuardian"); - } - - cmp.remove("Elder"); - } - - return cmp; - } - - } - - private static class DataConverterSkeleton implements DataConverter { - - DataConverterSkeleton() { - } - - public int getDataVersion() { - return 701; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - - if ("Skeleton".equals(s)) { - int i = cmp.getInt("SkeletonType"); - - if (i == 1) { - cmp.putString("id", "WitherSkeleton"); - } else if (i == 2) { - cmp.putString("id", "Stray"); - } - - cmp.remove("SkeletonType"); - } - - return cmp; - } - - } - - private static class DataConverterZombieType implements DataConverter { - - DataConverterZombieType() { - } - - public int getDataVersion() { - return 702; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Zombie".equals(cmp.getString("id"))) { - int i = cmp.getInt("ZombieType"); - - switch (i) { - case 0: - default: - break; - - case 1: - case 2: - case 3: - case 4: - case 5: - cmp.putString("id", "ZombieVillager"); - cmp.putInt("Profession", i - 1); - break; - - case 6: - cmp.putString("id", "Husk"); - } - - cmp.remove("ZombieType"); - } - - return cmp; - } - - } - - private static class DataConverterHorse implements DataConverter { - - DataConverterHorse() { - } - - public int getDataVersion() { - return 703; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("EntityHorse".equals(cmp.getString("id"))) { - int i = cmp.getInt("Type"); - - switch (i) { - case 0: - default: - cmp.putString("id", "Horse"); - break; - - case 1: - cmp.putString("id", "Donkey"); - break; - - case 2: - cmp.putString("id", "Mule"); - break; - - case 3: - cmp.putString("id", "ZombieHorse"); - break; - - case 4: - cmp.putString("id", "SkeletonHorse"); - } - - cmp.remove("Type"); - } - - return cmp; - } - - } - - private static class DataConverterTileEntity implements DataConverter { - - private static final Map a = Maps.newHashMap(); - - DataConverterTileEntity() { - } - - public int getDataVersion() { - return 704; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = DataConverterTileEntity.a.get(cmp.getString("id")); - - if (s != null) { - cmp.putString("id", s); - } - - return cmp; - } - - static { - DataConverterTileEntity.a.put("Airportal", "minecraft:end_portal"); - DataConverterTileEntity.a.put("Banner", "minecraft:banner"); - DataConverterTileEntity.a.put("Beacon", "minecraft:beacon"); - DataConverterTileEntity.a.put("Cauldron", "minecraft:brewing_stand"); - DataConverterTileEntity.a.put("Chest", "minecraft:chest"); - DataConverterTileEntity.a.put("Comparator", "minecraft:comparator"); - DataConverterTileEntity.a.put("Control", "minecraft:command_block"); - DataConverterTileEntity.a.put("DLDetector", "minecraft:daylight_detector"); - DataConverterTileEntity.a.put("Dropper", "minecraft:dropper"); - DataConverterTileEntity.a.put("EnchantTable", "minecraft:enchanting_table"); - DataConverterTileEntity.a.put("EndGateway", "minecraft:end_gateway"); - DataConverterTileEntity.a.put("EnderChest", "minecraft:ender_chest"); - DataConverterTileEntity.a.put("FlowerPot", "minecraft:flower_pot"); - DataConverterTileEntity.a.put("Furnace", "minecraft:furnace"); - DataConverterTileEntity.a.put("Hopper", "minecraft:hopper"); - DataConverterTileEntity.a.put("MobSpawner", "minecraft:mob_spawner"); - DataConverterTileEntity.a.put("Music", "minecraft:noteblock"); - DataConverterTileEntity.a.put("Piston", "minecraft:piston"); - DataConverterTileEntity.a.put("RecordPlayer", "minecraft:jukebox"); - DataConverterTileEntity.a.put("Sign", "minecraft:sign"); - DataConverterTileEntity.a.put("Skull", "minecraft:skull"); - DataConverterTileEntity.a.put("Structure", "minecraft:structure_block"); - DataConverterTileEntity.a.put("Trap", "minecraft:dispenser"); - } - } - - private static class DataConverterEntity implements DataConverter { - - private static final Map a = Maps.newHashMap(); - - DataConverterEntity() { - } - - public int getDataVersion() { - return 704; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = DataConverterEntity.a.get(cmp.getString("id")); - - if (s != null) { - cmp.putString("id", s); - } - - return cmp; - } - - static { - DataConverterEntity.a.put("AreaEffectCloud", "minecraft:area_effect_cloud"); - DataConverterEntity.a.put("ArmorStand", "minecraft:armor_stand"); - DataConverterEntity.a.put("Arrow", "minecraft:arrow"); - DataConverterEntity.a.put("Bat", "minecraft:bat"); - DataConverterEntity.a.put("Blaze", "minecraft:blaze"); - DataConverterEntity.a.put("Boat", "minecraft:boat"); - DataConverterEntity.a.put("CaveSpider", "minecraft:cave_spider"); - DataConverterEntity.a.put("Chicken", "minecraft:chicken"); - DataConverterEntity.a.put("Cow", "minecraft:cow"); - DataConverterEntity.a.put("Creeper", "minecraft:creeper"); - DataConverterEntity.a.put("Donkey", "minecraft:donkey"); - DataConverterEntity.a.put("DragonFireball", "minecraft:dragon_fireball"); - DataConverterEntity.a.put("ElderGuardian", "minecraft:elder_guardian"); - DataConverterEntity.a.put("EnderCrystal", "minecraft:ender_crystal"); - DataConverterEntity.a.put("EnderDragon", "minecraft:ender_dragon"); - DataConverterEntity.a.put("Enderman", "minecraft:enderman"); - DataConverterEntity.a.put("Endermite", "minecraft:endermite"); - DataConverterEntity.a.put("EyeOfEnderSignal", "minecraft:eye_of_ender_signal"); - DataConverterEntity.a.put("FallingSand", "minecraft:falling_block"); - DataConverterEntity.a.put("Fireball", "minecraft:fireball"); - DataConverterEntity.a.put("FireworksRocketEntity", "minecraft:fireworks_rocket"); - DataConverterEntity.a.put("Ghast", "minecraft:ghast"); - DataConverterEntity.a.put("Giant", "minecraft:giant"); - DataConverterEntity.a.put("Guardian", "minecraft:guardian"); - DataConverterEntity.a.put("Horse", "minecraft:horse"); - DataConverterEntity.a.put("Husk", "minecraft:husk"); - DataConverterEntity.a.put("Item", "minecraft:item"); - DataConverterEntity.a.put("ItemFrame", "minecraft:item_frame"); - DataConverterEntity.a.put("LavaSlime", "minecraft:magma_cube"); - DataConverterEntity.a.put("LeashKnot", "minecraft:leash_knot"); - DataConverterEntity.a.put("MinecartChest", "minecraft:chest_minecart"); - DataConverterEntity.a.put("MinecartCommandBlock", "minecraft:commandblock_minecart"); - DataConverterEntity.a.put("MinecartFurnace", "minecraft:furnace_minecart"); - DataConverterEntity.a.put("MinecartHopper", "minecraft:hopper_minecart"); - DataConverterEntity.a.put("MinecartRideable", "minecraft:minecart"); - DataConverterEntity.a.put("MinecartSpawner", "minecraft:spawner_minecart"); - DataConverterEntity.a.put("MinecartTNT", "minecraft:tnt_minecart"); - DataConverterEntity.a.put("Mule", "minecraft:mule"); - DataConverterEntity.a.put("MushroomCow", "minecraft:mooshroom"); - DataConverterEntity.a.put("Ozelot", "minecraft:ocelot"); - DataConverterEntity.a.put("Painting", "minecraft:painting"); - DataConverterEntity.a.put("Pig", "minecraft:pig"); - DataConverterEntity.a.put("PigZombie", "minecraft:zombie_pigman"); - DataConverterEntity.a.put("PolarBear", "minecraft:polar_bear"); - DataConverterEntity.a.put("PrimedTnt", "minecraft:tnt"); - DataConverterEntity.a.put("Rabbit", "minecraft:rabbit"); - DataConverterEntity.a.put("Sheep", "minecraft:sheep"); - DataConverterEntity.a.put("Shulker", "minecraft:shulker"); - DataConverterEntity.a.put("ShulkerBullet", "minecraft:shulker_bullet"); - DataConverterEntity.a.put("Silverfish", "minecraft:silverfish"); - DataConverterEntity.a.put("Skeleton", "minecraft:skeleton"); - DataConverterEntity.a.put("SkeletonHorse", "minecraft:skeleton_horse"); - DataConverterEntity.a.put("Slime", "minecraft:slime"); - DataConverterEntity.a.put("SmallFireball", "minecraft:small_fireball"); - DataConverterEntity.a.put("SnowMan", "minecraft:snowman"); - DataConverterEntity.a.put("Snowball", "minecraft:snowball"); - DataConverterEntity.a.put("SpectralArrow", "minecraft:spectral_arrow"); - DataConverterEntity.a.put("Spider", "minecraft:spider"); - DataConverterEntity.a.put("Squid", "minecraft:squid"); - DataConverterEntity.a.put("Stray", "minecraft:stray"); - DataConverterEntity.a.put("ThrownEgg", "minecraft:egg"); - DataConverterEntity.a.put("ThrownEnderpearl", "minecraft:ender_pearl"); - DataConverterEntity.a.put("ThrownExpBottle", "minecraft:xp_bottle"); - DataConverterEntity.a.put("ThrownPotion", "minecraft:potion"); - DataConverterEntity.a.put("Villager", "minecraft:villager"); - DataConverterEntity.a.put("VillagerGolem", "minecraft:villager_golem"); - DataConverterEntity.a.put("Witch", "minecraft:witch"); - DataConverterEntity.a.put("WitherBoss", "minecraft:wither"); - DataConverterEntity.a.put("WitherSkeleton", "minecraft:wither_skeleton"); - DataConverterEntity.a.put("WitherSkull", "minecraft:wither_skull"); - DataConverterEntity.a.put("Wolf", "minecraft:wolf"); - DataConverterEntity.a.put("XPOrb", "minecraft:xp_orb"); - DataConverterEntity.a.put("Zombie", "minecraft:zombie"); - DataConverterEntity.a.put("ZombieHorse", "minecraft:zombie_horse"); - DataConverterEntity.a.put("ZombieVillager", "minecraft:zombie_villager"); - } - } - - private static class DataConverterPotionWater implements DataConverter { - - DataConverterPotionWater() { - } - - public int getDataVersion() { - return 806; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - - if ("minecraft:potion".equals(s) || "minecraft:splash_potion".equals(s) || "minecraft:lingering_potion".equals(s) || "minecraft:tipped_arrow".equals( - s)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (!nbttagcompound1.contains("Potion", 8)) { - nbttagcompound1.putString("Potion", "minecraft:water"); - } - - if (!cmp.contains("tag", 10)) { - cmp.put("tag", nbttagcompound1); - } - } - - return cmp; - } - - } - - private static class DataConverterShulker implements DataConverter { - - DataConverterShulker() { - } - - public int getDataVersion() { - return 808; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker".equals(cmp.getString("id")) && !cmp.contains("Color", 99)) { - cmp.putByte("Color", (byte) 10); - } - - return cmp; - } - - } - - private static class DataConverterShulkerBoxItem implements DataConverter { - - public static final String[] a = new String[]{"minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box"}; - - DataConverterShulkerBoxItem() { - } - - public int getDataVersion() { - return 813; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker_box".equals(cmp.getString("id")) && cmp.contains("tag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - - if (nbttagcompound2.getList("Items", 10).isEmpty()) { - nbttagcompound2.remove("Items"); - } - - int i = nbttagcompound2.getInt("Color"); - - nbttagcompound2.remove("Color"); - if (nbttagcompound2.isEmpty()) { - nbttagcompound1.remove("BlockEntityTag"); - } - - if (nbttagcompound1.isEmpty()) { - cmp.remove("tag"); - } - - cmp.putString("id", DataConverterShulkerBoxItem.a[i % 16]); - } - } - - return cmp; - } - - } - - private static class DataConverterShulkerBoxBlock implements DataConverter { - - DataConverterShulkerBoxBlock() { - } - - public int getDataVersion() { - return 813; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker".equals(cmp.getString("id"))) { - cmp.remove("Color"); - } - - return cmp; - } - - } - - private static class DataConverterLang implements DataConverter { - - DataConverterLang() { - } - - public int getDataVersion() { - return 816; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("lang", 8)) { - cmp.putString("lang", cmp.getString("lang").toLowerCase(Locale.ROOT)); - } - - return cmp; - } - - } - - private static class DataConverterTotem implements DataConverter { - - DataConverterTotem() { - } - - public int getDataVersion() { - return 820; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:totem".equals(cmp.getString("id"))) { - cmp.putString("id", "minecraft:totem_of_undying"); - } - - return cmp; - } - - } - - private static class DataConverterBedBlock implements DataConverter { - - private static final Logger a = LogManager.getLogger(PaperweightDataConverters.class); - - DataConverterBedBlock() { - } - - public int getDataVersion() { - return 1125; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - try { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Level"); - int i = nbttagcompound1.getInt("xPos"); - int j = nbttagcompound1.getInt("zPos"); - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("TileEntities", 10); - net.minecraft.nbt.ListTag nbttaglist1 = nbttagcompound1.getList("Sections", 10); - - for (int k = 0; k < nbttaglist1.size(); ++k) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist1.getCompound(k); - byte b0 = nbttagcompound2.getByte("Y"); - byte[] abyte = nbttagcompound2.getByteArray("Blocks"); - - for (int l = 0; l < abyte.length; ++l) { - if (416 == (abyte[l] & 255) << 4) { - int i1 = l & 15; - int j1 = l >> 8 & 15; - int k1 = l >> 4 & 15; - net.minecraft.nbt.CompoundTag nbttagcompound3 = new net.minecraft.nbt.CompoundTag(); - - nbttagcompound3.putString("id", "bed"); - nbttagcompound3.putInt("x", i1 + (i << 4)); - nbttagcompound3.putInt("y", j1 + (b0 << 4)); - nbttagcompound3.putInt("z", k1 + (j << 4)); - nbttaglist.add(nbttagcompound3); - } - } - } - } catch (Exception exception) { - DataConverterBedBlock.a.warn("Unable to datafix Bed blocks, level format may be missing tags."); - } - - return cmp; - } - - } - - private static class DataConverterBedItem implements DataConverter { - - DataConverterBedItem() { - } - - public int getDataVersion() { - return 1125; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:bed".equals(cmp.getString("id")) && cmp.getShort("Damage") == 0) { - cmp.putShort("Damage", (short) DyeColor.RED.getId()); - } - - return cmp; - } - - } - - private static class DataConverterSignText implements DataConverter { - - public static final Gson a = new GsonBuilder().registerTypeAdapter(Component.class, new JsonDeserializer() { - MutableComponent a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws - JsonParseException { - if (jsonelement.isJsonPrimitive()) { - return new TextComponent(jsonelement.getAsString()); - } else if (jsonelement.isJsonArray()) { - JsonArray jsonarray = jsonelement.getAsJsonArray(); - MutableComponent ichatbasecomponent = null; - Iterator iterator = jsonarray.iterator(); - - while (iterator.hasNext()) { - JsonElement jsonelement1 = (JsonElement) iterator.next(); - MutableComponent ichatbasecomponent1 = this.a( - jsonelement1, - jsonelement1.getClass(), - jsondeserializationcontext - ); - - if (ichatbasecomponent == null) { - ichatbasecomponent = ichatbasecomponent1; - } else { - ichatbasecomponent.append(ichatbasecomponent1); - } - } - - return ichatbasecomponent; - } else { - throw new JsonParseException("Don't know how to turn " + jsonelement + " into a Component"); - } - } - - public Object deserialize( - JsonElement jsonelement, - Type type, - JsonDeserializationContext jsondeserializationcontext - ) throws JsonParseException { - return this.a(jsonelement, type, jsondeserializationcontext); - } - }).create(); - - DataConverterSignText() { - } - - public int getDataVersion() { - return 101; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Sign".equals(cmp.getString("id"))) { - this.convert(cmp, "Text1"); - this.convert(cmp, "Text2"); - this.convert(cmp, "Text3"); - this.convert(cmp, "Text4"); - } - - return cmp; - } - - private void convert(net.minecraft.nbt.CompoundTag nbttagcompound, String s) { - String s1 = nbttagcompound.getString(s); - Component object = null; - - if (!"null".equals(s1) && !StringUtil.isNullOrEmpty(s1)) { - if ((s1.charAt(0) != 34 || s1.charAt(s1.length() - 1) != 34) && (s1.charAt(0) != 123 || s1.charAt(s1.length() - 1) != 125)) { - object = new TextComponent(s1); - } else { - try { - object = GsonHelper.fromJson(DataConverterSignText.a, s1, Component.class, true); - if (object == null) { - object = new TextComponent(""); - } - } catch (JsonParseException jsonparseexception) { - ; - } - - if (object == null) { - try { - object = Component.Serializer.fromJson(s1); - } catch (JsonParseException jsonparseexception1) { - ; - } - } - - if (object == null) { - try { - object = Component.Serializer.fromJsonLenient(s1); - } catch (JsonParseException jsonparseexception2) { - ; - } - } - - if (object == null) { - object = new TextComponent(s1); - } - } - } else { - object = new TextComponent(""); - } - - nbttagcompound.putString(s, Component.Serializer.toJson(object)); - } - - } - - private static class DataInspectorPlayerVehicle implements DataInspector { - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("RootVehicle", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("RootVehicle"); - - if (nbttagcompound1.contains("Entity", 10)) { - convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer); - } - } - - return cmp; - } - - } - - private static class DataInspectorLevelPlayer implements DataInspector { - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Player", 10)) { - convertCompound(LegacyType.PLAYER, cmp, "Player", sourceVer, targetVer); - } - - return cmp; - } - - } - - private static class DataInspectorStructure implements DataInspector { - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - net.minecraft.nbt.ListTag nbttaglist; - int j; - net.minecraft.nbt.CompoundTag nbttagcompound1; - - if (cmp.contains("entities", 9)) { - nbttaglist = cmp.getList("entities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j); - if (nbttagcompound1.contains("nbt", 10)) { - convertCompound(LegacyType.ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer); - } - } - } - - if (cmp.contains("blocks", 9)) { - nbttaglist = cmp.getList("blocks", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j); - if (nbttagcompound1.contains("nbt", 10)) { - convertCompound(LegacyType.BLOCK_ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer); - } - } - } - - return cmp; - } - - } - - private static class DataInspectorChunks implements DataInspector { - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Level", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Level"); - net.minecraft.nbt.ListTag nbttaglist; - int j; - - if (nbttagcompound1.contains("Entities", 9)) { - nbttaglist = nbttagcompound1.getList("Entities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set( - j, - convert( - LegacyType.ENTITY, - (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), - sourceVer, - targetVer - ) - ); - } - } - - if (nbttagcompound1.contains("TileEntities", 9)) { - nbttaglist = nbttagcompound1.getList("TileEntities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set( - j, - convert( - LegacyType.BLOCK_ENTITY, - (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), - sourceVer, - targetVer - ) - ); - } - } - } - - return cmp; - } - - } - - private static class DataInspectorEntityPassengers implements DataInspector { - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Passengers", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("Passengers", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ENTITY, nbttaglist.getCompound(j), sourceVer, targetVer)); - } - } - - return cmp; - } - - } - - private static class DataInspectorPlayer implements DataInspector { - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - convertItems(cmp, "Inventory", sourceVer, targetVer); - convertItems(cmp, "EnderItems", sourceVer, targetVer); - if (cmp.contains("ShoulderEntityLeft", 10)) { - convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityLeft", sourceVer, targetVer); - } - - if (cmp.contains("ShoulderEntityRight", 10)) { - convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityRight", sourceVer, targetVer); - } - - return cmp; - } - - } - - private static class DataInspectorVillagers implements DataInspector { - - ResourceLocation entityVillager = getKey("EntityVillager"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (entityVillager.equals(new ResourceLocation(cmp.getString("id"))) && cmp.contains("Offers", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Offers"); - - if (nbttagcompound1.contains("Recipes", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("Recipes", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompound(j); - - convertItem(nbttagcompound2, "buy", sourceVer, targetVer); - convertItem(nbttagcompound2, "buyB", sourceVer, targetVer); - convertItem(nbttagcompound2, "sell", sourceVer, targetVer); - nbttaglist.set(j, nbttagcompound2); - } - } - } - - return cmp; - } - - } - - private static class DataInspectorMobSpawnerMinecart implements DataInspector { - - ResourceLocation entityMinecartMobSpawner = getKey("EntityMinecartMobSpawner"); - ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - String s = cmp.getString("id"); - if (entityMinecartMobSpawner.equals(new ResourceLocation(s))) { - cmp.putString("id", tileEntityMobSpawner.toString()); - convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer); - cmp.putString("id", s); - } - - return cmp; - } - - } - - private static class DataInspectorMobSpawnerMobs implements DataInspector { - - ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (tileEntityMobSpawner.equals(new ResourceLocation(cmp.getString("id")))) { - if (cmp.contains("SpawnPotentials", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("SpawnPotentials", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttaglist.getCompound(j); - - convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer); - } - } - - convertCompound(LegacyType.ENTITY, cmp, "SpawnData", sourceVer, targetVer); - } - - return cmp; - } - - } - - private static class DataInspectorCommandBlock implements DataInspector { - - ResourceLocation tileEntityCommand = getKey("TileEntityCommand"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (tileEntityCommand.equals(new ResourceLocation(cmp.getString("id")))) { - cmp.putString("id", "Control"); - convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer); - cmp.putString("id", "MinecartCommandBlock"); - } - - return cmp; - } - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightFakePlayer.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightFakePlayer.java deleted file mode 100644 index 9f081b05e..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightFakePlayer.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit.adapter.ext.fawe; - -import com.mojang.authlib.GameProfile; -import net.minecraft.network.chat.ChatType; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ServerboundClientInformationPacket; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.stats.Stat; -import net.minecraft.world.MenuProvider; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.block.entity.SignBlockEntity; -import net.minecraft.world.phys.Vec3; -import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; - -import java.util.OptionalInt; -import java.util.UUID; - -class PaperweightFakePlayer extends ServerPlayer { - - private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile( - UUID.nameUUIDFromBytes("worldedit".getBytes()), - "[WorldEdit]" - ); - private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D); - - PaperweightFakePlayer(ServerLevel world) { - super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE); - } - - @Override - public Vec3 position() { - return ORIGIN; - } - - @Override - public void tick() { - } - - @Override - public void die(DamageSource damagesource) { - } - - @Override - public Entity changeDimension(ServerLevel worldserver, TeleportCause cause) { - return this; - } - - @Override - public OptionalInt openMenu(MenuProvider factory) { - return OptionalInt.empty(); - } - - @Override - public void updateOptions(ServerboundClientInformationPacket packet) { - } - - @Override - public void displayClientMessage(Component message, boolean actionBar) { - } - - @Override - public void sendMessage(Component message, ChatType type, UUID sender) { - } - - @Override - public void awardStat(Stat stat, int amount) { - } - - @Override - public void awardStat(Stat stat) { - } - - @Override - public boolean isInvulnerableTo(DamageSource damageSource) { - return true; - } - - @Override - public void openTextEdit(SignBlockEntity sign) { - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightWorldNativeAccess.java deleted file mode 100644 index 701e40b12..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightWorldNativeAccess.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit.adapter.ext.fawe; - -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.world.block.BlockState; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_17_R1.block.data.CraftBlockData; -import org.bukkit.event.block.BlockPhysicsEvent; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.util.Objects; - -public class PaperweightWorldNativeAccess implements - WorldNativeAccess { - - private static final int UPDATE = 1; - private static final int NOTIFY = 2; - - private final PaperweightAdapter adapter; - private final WeakReference world; - private SideEffectSet sideEffectSet; - - public PaperweightWorldNativeAccess(PaperweightAdapter adapter, WeakReference world) { - this.adapter = adapter; - this.world = world; - } - - private ServerLevel getWorld() { - return Objects.requireNonNull(world.get(), "The reference to the world was lost"); - } - - @Override - public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) { - this.sideEffectSet = sideEffectSet; - } - - @Override - public LevelChunk getChunk(int x, int z) { - return getWorld().getChunk(x, z); - } - - @Override - public net.minecraft.world.level.block.state.BlockState toNative(BlockState state) { - int stateId = BlockStateIdAccess.getBlockStateId(state); - return BlockStateIdAccess.isValidInternalId(stateId) - ? Block.stateById(stateId) - : ((CraftBlockData) BukkitAdapter.adapt(state)).getState(); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk chunk, BlockPos position) { - return chunk.getBlockState(position); - } - - @Nullable - @Override - public net.minecraft.world.level.block.state.BlockState setBlockState( - LevelChunk chunk, - BlockPos position, - net.minecraft.world.level.block.state.BlockState state - ) { - return chunk.setType(position, state, false, this.sideEffectSet.shouldApply(SideEffect.UPDATE)); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition( - net.minecraft.world.level.block.state.BlockState block, - BlockPos position - ) { - return Block.updateFromNeighbourShapes(block, getWorld(), position); - } - - @Override - public BlockPos getPosition(int x, int y, int z) { - return new BlockPos(x, y, z); - } - - @Override - public void updateLightingForBlock(BlockPos position) { - getWorld().getChunkSource().getLightEngine().checkBlock(position); - } - - @Override - public boolean updateTileEntity(final BlockPos position, final CompoundBinaryTag tag) { - return false; - } - - @Override - public void notifyBlockUpdate( - LevelChunk chunk, - BlockPos position, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { - getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY); - } - } - - @Override - public boolean isChunkTicking(LevelChunk chunk) { - return chunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING); - } - - @Override - public void markBlockChanged(LevelChunk chunk, BlockPos position) { - if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { - getWorld().getChunkSource().blockChanged(position); - } - } - - @Override - public void notifyNeighbors( - BlockPos pos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - ServerLevel world = getWorld(); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - world.updateNeighborsAt(pos, oldState.getBlock()); - } else { - // When we don't want events, manually run the physics without them. - Block block = oldState.getBlock(); - fireNeighborChanged(pos, world, block, pos.west()); - fireNeighborChanged(pos, world, block, pos.east()); - fireNeighborChanged(pos, world, block, pos.below()); - fireNeighborChanged(pos, world, block, pos.above()); - fireNeighborChanged(pos, world, block, pos.north()); - fireNeighborChanged(pos, world, block, pos.south()); - } - if (newState.hasAnalogOutputSignal()) { - world.updateNeighbourForOutputSignal(pos, newState.getBlock()); - } - } - - private void fireNeighborChanged(BlockPos pos, ServerLevel world, Block block, BlockPos neighborPos) { - world.getBlockState(neighborPos).neighborChanged(world, neighborPos, block, pos, false); - } - - @Override - public void updateNeighbors( - BlockPos pos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState, - int recursionLimit - ) { - ServerLevel world = getWorld(); - // a == updateNeighbors - // b == updateDiagonalNeighbors - oldState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - CraftWorld craftWorld = world.getWorld(); - BlockPhysicsEvent event = new BlockPhysicsEvent( - craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), - CraftBlockData.fromData(newState) - ); - world.getCraftServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - } - newState.updateNeighbourShapes(world, pos, NOTIFY, recursionLimit); - newState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); - } - - @Override - public void onBlockStateChange( - BlockPos pos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - getWorld().onBlockStateChange(pos, oldState, newState); - } - - @Override - public void flush() { - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightBlockMaterial.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightBlockMaterial.java deleted file mode 100644 index aac664459..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightBlockMaterial.java +++ /dev/null @@ -1,189 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2; - -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.util.ReflectionUtil; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.world.registry.BlockMaterial; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.EmptyBlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.material.PushReaction; -import org.bukkit.craftbukkit.v1_17_R1.block.data.CraftBlockData; - -public class PaperweightBlockMaterial implements BlockMaterial { - - private final Block block; - private final BlockState blockState; - private final Material material; - private final boolean isTranslucent; - private final CraftBlockData craftBlockData; - private final org.bukkit.Material craftMaterial; - private final int opacity; - private final CompoundTag tile; - - public PaperweightBlockMaterial(Block block) { - this(block, block.defaultBlockState()); - } - - public PaperweightBlockMaterial(Block block, BlockState blockState) { - this.block = block; - this.blockState = blockState; - this.material = blockState.getMaterial(); - this.craftBlockData = CraftBlockData.fromData(blockState); - this.craftMaterial = craftBlockData.getMaterial(); - BlockBehaviour.Properties blockInfo = ReflectionUtil.getField(BlockBehaviour.class, block, Refraction.pickName( - "properties", "aP")); - this.isTranslucent = !(boolean) ReflectionUtil.getField(BlockBehaviour.Properties.class, blockInfo, - Refraction.pickName("canOcclude", "n") - ); - opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); - BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity( - BlockPos.ZERO, - blockState - ); - tile = tileEntity == null - ? null - : new PaperweightLazyCompoundTag(Suppliers.memoize(() -> tileEntity.save(new net.minecraft.nbt.CompoundTag()))); - } - - public Block getBlock() { - return block; - } - - public BlockState getState() { - return blockState; - } - - public CraftBlockData getCraftBlockData() { - return craftBlockData; - } - - public Material getMaterial() { - return material; - } - - @Override - public boolean isAir() { - return blockState.isAir(); - } - - @Override - public boolean isFullCube() { - return craftMaterial.isOccluding(); - } - - @Override - public boolean isOpaque() { - return material.isSolidBlocking(); - } - - @Override - public boolean isPowerSource() { - return blockState.isSignalSource(); - } - - @Override - public boolean isLiquid() { - return material.isLiquid(); - } - - @Override - public boolean isSolid() { - return material.isSolid(); - } - - @Override - public float getHardness() { - return craftBlockData.getState().destroySpeed; - } - - @Override - public float getResistance() { - return block.getExplosionResistance(); - } - - @Override - public float getSlipperiness() { - return block.getFriction(); - } - - @Override - public int getLightValue() { - return blockState.getLightEmission(); - } - - @Override - public int getLightOpacity() { - return opacity; - } - - @Override - public boolean isFragileWhenPushed() { - return material.getPushReaction() == PushReaction.DESTROY; - } - - @Override - public boolean isUnpushable() { - return material.getPushReaction() == PushReaction.BLOCK; - } - - @Override - public boolean isTicksRandomly() { - return block.isRandomlyTicking(blockState); - } - - @Override - public boolean isMovementBlocker() { - return material.isSolid(); - } - - @Override - public boolean isBurnable() { - return material.isFlammable(); - } - - @Override - public boolean isToolRequired() { - // Removed in 1.16.1, this is not present in higher versions - return false; - } - - @Override - public boolean isReplacedDuringPlacement() { - return material.isReplaceable(); - } - - @Override - public boolean isTranslucent() { - return isTranslucent; - } - - @Override - public boolean hasContainer() { - return block instanceof EntityBlock; - } - - @Override - public boolean isTile() { - return block instanceof EntityBlock; - } - - @Override - public CompoundTag getDefaultTile() { - return tile; - } - - @Override - public int getMapColor() { - // rgb field - return material.getColor().col; - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java deleted file mode 100644 index ad6e6ae80..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java +++ /dev/null @@ -1,671 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2; - -import com.fastasyncworldedit.bukkit.adapter.FaweAdapter; -import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.entity.LazyBaseEntity; -import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; -import com.fastasyncworldedit.core.queue.IBatchProcessor; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket; -import com.fastasyncworldedit.core.util.NbtUtils; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.blocks.TileEntityBlock; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.ext.fawe.PaperweightAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.regen.PaperweightRegen; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.registry.state.BooleanProperty; -import com.sk89q.worldedit.registry.state.DirectionalProperty; -import com.sk89q.worldedit.registry.state.EnumProperty; -import com.sk89q.worldedit.registry.state.IntegerProperty; -import com.sk89q.worldedit.registry.state.Property; -import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.StringBinaryTag; -import com.sk89q.worldedit.world.RegenOptions; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockStateHolder; -import com.sk89q.worldedit.world.block.BlockType; -import com.sk89q.worldedit.world.block.BlockTypes; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import com.sk89q.worldedit.world.entity.EntityType; -import com.sk89q.worldedit.world.item.ItemType; -import com.sk89q.worldedit.world.registry.BlockMaterial; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Registry; -import net.minecraft.core.WritableRegistry; -import net.minecraft.nbt.IntTag; -import net.minecraft.network.protocol.game.ClientboundLevelChunkPacket; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.util.StringRepresentable; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.NamespacedKey; -import org.bukkit.World; -import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.v1_17_R1.CraftChunk; -import org.bukkit.craftbukkit.v1_17_R1.CraftServer; -import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_17_R1.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_17_R1.util.CraftNamespacedKey; -import org.bukkit.entity.Player; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.OptionalInt; -import java.util.Set; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public final class PaperweightFaweAdapter extends FaweAdapter { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private final PaperweightAdapter parent; - // ------------------------------------------------------------------------ - // Code that may break between versions of Minecraft - // ------------------------------------------------------------------------ - private final PaperweightMapChunkUtil mapUtil = new PaperweightMapChunkUtil(); - private char[] ibdToStateOrdinal = null; - private int[] ordinalToIbdID = null; - private boolean initialised = false; - private Map>> allBlockProperties = null; - - public PaperweightFaweAdapter() throws NoSuchFieldException, NoSuchMethodException { - this.parent = new PaperweightAdapter(); - } - - @Nullable - private static String getEntityId(Entity entity) { - ResourceLocation resourceLocation = net.minecraft.world.entity.EntityType.getKey(entity.getType()); - return resourceLocation == null ? null : resourceLocation.toString(); - } - - @Override - public BukkitImplAdapter getParent() { - return parent; - } - - @SuppressWarnings("unchecked") - private synchronized boolean init() { - if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) { - return false; - } - ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size - ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size - for (int i = 0; i < ibdToStateOrdinal.length; i++) { - BlockState blockState = BlockTypesCache.states[i]; - PaperweightBlockMaterial material = (PaperweightBlockMaterial) blockState.getMaterial(); - int id = Block.BLOCK_STATE_REGISTRY.getId(material.getState()); - char ordinal = blockState.getOrdinalChar(); - ibdToStateOrdinal[id] = ordinal; - ordinalToIbdID[ordinal] = id; - } - Map>> properties = new HashMap<>(); - try { - for (Field field : BlockStateProperties.class.getDeclaredFields()) { - Object obj = field.get(null); - if (!(obj instanceof net.minecraft.world.level.block.state.properties.Property state)) { - continue; - } - Property property; - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - property = new BooleanProperty( - state.getName(), - (List) ImmutableList.copyOf(state.getPossibleValues()) - ); - } else if (state instanceof DirectionProperty) { - property = new DirectionalProperty( - state.getName(), - state - .getPossibleValues() - .stream() - .map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase())) - .collect(Collectors.toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - property = new EnumProperty( - state.getName(), - state - .getPossibleValues() - .stream() - .map(e -> ((StringRepresentable) e).getSerializedName()) - .collect(Collectors.toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - property = new IntegerProperty( - state.getName(), - (List) ImmutableList.copyOf(state.getPossibleValues()) - ); - } else { - throw new IllegalArgumentException("FastAsyncWorldEdit needs an update to support " + state - .getClass() - .getSimpleName()); - } - properties.compute(property.getName().toLowerCase(Locale.ROOT), (k, v) -> { - if (v == null) { - v = new ArrayList<>(Collections.singletonList(property)); - } else { - v.add(property); - } - return v; - }); - } - } catch (IllegalAccessException e) { - e.printStackTrace(); - } finally { - allBlockProperties = ImmutableMap.copyOf(properties); - } - initialised = true; - return true; - } - - @Override - public BlockMaterial getMaterial(BlockType blockType) { - Block block = getBlock(blockType); - return new PaperweightBlockMaterial(block); - } - - @Override - public synchronized BlockMaterial getMaterial(BlockState state) { - net.minecraft.world.level.block.state.BlockState blockState = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState(); - return new PaperweightBlockMaterial(blockState.getBlock(), blockState); - } - - public Block getBlock(BlockType blockType) { - return Registry.BLOCK.get(new ResourceLocation(blockType.getNamespace(), blockType.getResource())); - } - - @Deprecated - @Override - public BlockState getBlock(Location location) { - Preconditions.checkNotNull(location); - - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - final ServerLevel handle = getServerLevel(location.getWorld()); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - BlockState state = adapt(blockData); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - return state; - } - - @Override - public BaseBlock getFullBlock(final Location location) { - Preconditions.checkNotNull(location); - - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = getServerLevel(location.getWorld()); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - BlockState state = adapt(blockData); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - if (state.getBlockType().getMaterial().hasContainer()) { - - // Read the NBT data - BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK); - if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = blockEntity.save(new net.minecraft.nbt.CompoundTag()); - return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag)); - } - } - - return state.toBaseBlock(); - } - - @Override - public Set getSupportedSideEffects() { - return SideEffectSet.defaults().getSideEffectsToApply(); - } - - @SuppressWarnings("rawtypes") - public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) { - CraftChunk craftChunk = (CraftChunk) chunk; - LevelChunk levelChunk = craftChunk.getHandle(); - Level level = levelChunk.getLevel(); - - BlockPos blockPos = new BlockPos(x, y, z); - net.minecraft.world.level.block.state.BlockState blockState = ((PaperweightBlockMaterial) state.getMaterial()).getState(); - LevelChunkSection[] levelChunkSections = levelChunk.getSections(); - int y4 = y >> 4; - LevelChunkSection section = levelChunkSections[y4]; - - net.minecraft.world.level.block.state.BlockState existing; - if (section == null) { - existing = ((PaperweightBlockMaterial) BlockTypes.AIR.getDefaultState().getMaterial()).getState(); - } else { - existing = section.getBlockState(x & 15, y & 15, z & 15); - } - - levelChunk.removeBlockEntity(blockPos); // Force delete the old tile entity - - CompoundBinaryTag compoundTag = state instanceof BaseBlock ? state.getNbt() : null; - if (compoundTag != null || existing instanceof TileEntityBlock) { - level.setBlock(blockPos, blockState, 0); - // remove tile - if (compoundTag != null) { - // We will assume that the tile entity was created for us, - // though we do not do this on the Forge version - BlockEntity blockEntity = level.getBlockEntity(blockPos); - if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeBinary(compoundTag); - tag.put("x", IntTag.valueOf(x)); - tag.put("y", IntTag.valueOf(y)); - tag.put("z", IntTag.valueOf(z)); - blockEntity.load(tag); // readTagIntoTileEntity - load data - } - } - } else { - if (existing == blockState) { - return true; - } - if (section == null) { - if (blockState.isAir()) { - return true; - } - levelChunkSections[y4] = section = new LevelChunkSection(y4 << 4); - } - levelChunk.setBlockState(blockPos, blockState, false); - } - if (update) { - level.getMinecraftWorld().sendBlockUpdated(blockPos, existing, blockState, 0); - } - return true; - } - - @Override - public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { - return new PaperweightFaweWorldNativeAccess(this, new WeakReference<>(getServerLevel(world))); - } - - @Override - public BaseEntity getEntity(org.bukkit.entity.Entity entity) { - Preconditions.checkNotNull(entity); - - CraftEntity craftEntity = ((CraftEntity) entity); - Entity mcEntity = craftEntity.getHandle(); - - String id = getEntityId(mcEntity); - - if (id != null) { - EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id); - Supplier saveTag = () -> { - final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag); - //add Id for AbstractChangeSet to work - final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag); - final Map tags = NbtUtils.getCompoundBinaryTagValues(tag); - tags.put("Id", StringBinaryTag.of(id)); - return CompoundBinaryTag.from(tags); - }; - return new LazyBaseEntity(type, saveTag); - } else { - return null; - } - } - - @Override - public Component getRichBlockName(BlockType blockType) { - return parent.getRichBlockName(blockType); - } - - @Override - public Component getRichItemName(ItemType itemType) { - return parent.getRichItemName(itemType); - } - - @Override - public Component getRichItemName(BaseItemStack itemStack) { - return parent.getRichItemName(itemStack); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockState state) { - PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial(); - net.minecraft.world.level.block.state.BlockState mcState = material.getCraftBlockData().getState(); - return OptionalInt.of(Block.BLOCK_STATE_REGISTRY.getId(mcState)); - } - - @Override - public BlockState adapt(BlockData blockData) { - CraftBlockData cbd = ((CraftBlockData) blockData); - net.minecraft.world.level.block.state.BlockState ibd = cbd.getState(); - return adapt(ibd); - } - - public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; - } - - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { - int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); - if (initialised) { - return ibdToStateOrdinal[id]; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - try { - init(); - return ibdToStateOrdinal[id]; - } catch (ArrayIndexOutOfBoundsException e1) { - LOGGER.error("Attempted to convert {} with ID {} to char. ibdToStateOrdinal length: {}. Defaulting to air!", - blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToStateOrdinal.length, e1 - ); - return BlockTypesCache.ReservedIDs.AIR; - } - } - } - - public char ibdIDToOrdinal(int id) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - init(); - return ibdToStateOrdinal[id]; - } - } - - @Override - public char[] getIbdToStateOrdinal() { - if (initialised) { - return ibdToStateOrdinal; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal; - } - init(); - return ibdToStateOrdinal; - } - } - - public int ordinalToIbdID(char ordinal) { - if (initialised) { - return ordinalToIbdID[ordinal]; - } - synchronized (this) { - if (initialised) { - return ordinalToIbdID[ordinal]; - } - init(); - return ordinalToIbdID[ordinal]; - } - } - - @Override - public int[] getOrdinalToIbdID() { - if (initialised) { - return ordinalToIbdID; - } - synchronized (this) { - if (initialised) { - return ordinalToIbdID; - } - init(); - return ordinalToIbdID; - } - } - - @Override - public > BlockData adapt(B state) { - PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial(); - return material.getCraftBlockData(); - } - - @Override - public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) { - ServerLevel nmsWorld = getServerLevel(world); - ChunkHolder map = PaperweightPlatformAdapter.getPlayerChunk(nmsWorld, chunkPacket.getChunkX(), chunkPacket.getChunkZ()); - if (map != null && map.wasAccessibleSinceLastSave()) { - boolean flag = false; - // PlayerChunk.d players = map.players; - Stream stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag) - */ Stream.empty(); - - ServerPlayer checkPlayer = player == null ? null : ((CraftPlayer) player).getHandle(); - stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer) - .forEach(entityPlayer -> { - synchronized (chunkPacket) { - ClientboundLevelChunkPacket nmsPacket = (ClientboundLevelChunkPacket) chunkPacket.getNativePacket(); - if (nmsPacket == null) { - nmsPacket = mapUtil.create(this, chunkPacket); - chunkPacket.setNativePacket(nmsPacket); - } - try { - FaweCache.INSTANCE.CHUNK_FLAG.get().set(true); - entityPlayer.connection.send(nmsPacket); - } finally { - FaweCache.INSTANCE.CHUNK_FLAG.get().set(false); - } - } - }); - } - } - - @Override - public Map> getProperties(BlockType blockType) { - return getParent().getProperties(blockType); - } - - @Override - public boolean canPlaceAt(org.bukkit.World world, BlockVector3 blockVector3, BlockState blockState) { - int internalId = BlockStateIdAccess.getBlockStateId(blockState); - net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId); - return blockState1.hasPostProcess( - getServerLevel(world), - new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ()) - ); - } - - @Override - public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) { - ItemStack stack = new ItemStack( - Registry.ITEM.get(ResourceLocation.tryParse(baseItemStack.getType().getId())), - baseItemStack.getAmount() - ); - stack.setTag(((net.minecraft.nbt.CompoundTag) fromNativeBinary(baseItemStack.getNbt()))); - return CraftItemStack.asCraftMirror(stack); - } - - @Override - protected void preCaptureStates(final ServerLevel serverLevel) { - serverLevel.captureTreeGeneration = true; - serverLevel.captureBlockStates = true; - } - - @Override - protected List getCapturedBlockStatesCopy(final ServerLevel serverLevel) { - return new ArrayList<>(serverLevel.capturedBlockStates.values()); - } - - @Override - protected void postCaptureBlockStates(final ServerLevel serverLevel) { - serverLevel.captureBlockStates = false; - serverLevel.captureTreeGeneration = false; - serverLevel.capturedBlockStates.clear(); - } - - @Override - protected ServerLevel getServerLevel(final World world) { - return ((CraftWorld) world).getHandle(); - } - - @Override - public List getEntities(org.bukkit.World world) { - // Quickly add each entity to a list copy. - List mcEntities = new ArrayList<>(); - getServerLevel(world).entityManager.getEntityGetter().getAll().forEach(mcEntities::add); - - List list = new ArrayList<>(); - mcEntities.forEach((mcEnt) -> { - org.bukkit.entity.Entity bukkitEntity = mcEnt.getBukkitEntity(); - if (bukkitEntity.isValid()) { - list.add(bukkitEntity); - } - - }); - return list; - } - - @Override - public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { - final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); - weStack.setNbt(((CompoundBinaryTag) toNativeBinary(nmsStack.getTag()))); - return weStack; - } - - @Override - public Tag toNative(net.minecraft.nbt.Tag foreign) { - return parent.toNative(foreign); - } - - @Override - public net.minecraft.nbt.Tag fromNative(Tag foreign) { - if (foreign instanceof PaperweightLazyCompoundTag) { - return ((PaperweightLazyCompoundTag) foreign).get(); - } - return parent.fromNative(foreign); - } - - @Override - public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent target, RegenOptions options) throws Exception { - return new PaperweightRegen(bukkitWorld, region, target, options).regenerate(); - } - - @Override - public IChunkGet get(org.bukkit.World world, int chunkX, int chunkZ) { - return new PaperweightGetBlocks(world, chunkX, chunkZ); - } - - @Override - public int getInternalBiomeId(BiomeType biomeType) { - final Registry registry = MinecraftServer - .getServer() - .registryAccess() - .ownedRegistryOrThrow(Registry.BIOME_REGISTRY); - ResourceLocation resourceLocation = ResourceLocation.tryParse(biomeType.getId()); - Biome biome = registry.get(resourceLocation); - return registry.getId(biome); - } - - @Override - public Iterable getRegisteredBiomes() { - WritableRegistry biomeRegistry = ((CraftServer) Bukkit.getServer()) - .getServer() - .registryAccess() - .ownedRegistryOrThrow( - Registry.BIOME_REGISTRY); - List keys = biomeRegistry.stream() - .map(biomeRegistry::getKey).filter(Objects::nonNull).toList(); - List namespacedKeys = new ArrayList<>(); - for (ResourceLocation key : keys) { - try { - namespacedKeys.add(CraftNamespacedKey.fromMinecraft(key)); - } catch (IllegalArgumentException e) { - LOGGER.error("Error converting biome key {}", key.toString(), e); - } - } - return namespacedKeys; - } - - @Override - public RelighterFactory getRelighterFactory() { - try { - Class.forName("ca.spottedleaf.starlight.light.StarLightEngine"); - if (PaperweightStarlightRelighter.isUsable()) { - return new PaperweightStarlightRelighterFactory(); - } - } catch (ThreadDeath td) { - throw td; - } catch (Throwable ignored) { - - } - return new NMSRelighterFactory(); - } - - @Override - public Map>> getAllProperties() { - if (initialised) { - return allBlockProperties; - } - synchronized (this) { - if (initialised) { - return allBlockProperties; - } - init(); - return allBlockProperties; - } - } - - @Override - public IBatchProcessor getTickingPostProcessor() { - return new PaperweightPostProcessor(); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweWorldNativeAccess.java deleted file mode 100644 index 282a6b505..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweWorldNativeAccess.java +++ /dev/null @@ -1,286 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2; - -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.math.IntPair; -import com.fastasyncworldedit.core.util.TaskManager; -import com.fastasyncworldedit.core.util.task.RunnableVal; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.world.block.BlockState; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_17_R1.block.data.CraftBlockData; -import org.bukkit.event.block.BlockPhysicsEvent; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; - -public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess { - - private static final int UPDATE = 1; - private static final int NOTIFY = 2; - private static final Direction[] NEIGHBOUR_ORDER = { - Direction.EAST, - Direction.WEST, - Direction.DOWN, - Direction.UP, - Direction.NORTH, - Direction.SOUTH - }; - private final PaperweightFaweAdapter paperweightFaweAdapter; - private final WeakReference level; - private final AtomicInteger lastTick; - private final Set cachedChanges = new HashSet<>(); - private final Set cachedChunksToSend = new HashSet<>(); - private SideEffectSet sideEffectSet; - - public PaperweightFaweWorldNativeAccess(PaperweightFaweAdapter paperweightFaweAdapter, WeakReference level) { - this.paperweightFaweAdapter = paperweightFaweAdapter; - this.level = level; - // Use the actual tick as minecraft-defined so we don't try to force blocks into the world when the server's already lagging. - // - With the caveat that we don't want to have too many cached changed (1024) so we'd flush those at 1024 anyway. - this.lastTick = new AtomicInteger(MinecraftServer.currentTick); - } - - private Level getLevel() { - return Objects.requireNonNull(level.get(), "The reference to the world was lost"); - } - - @Override - public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) { - this.sideEffectSet = sideEffectSet; - } - - @Override - public LevelChunk getChunk(int x, int z) { - return getLevel().getChunk(x, z); - } - - @Override - public net.minecraft.world.level.block.state.BlockState toNative(BlockState blockState) { - int stateId = paperweightFaweAdapter.ordinalToIbdID(blockState.getOrdinalChar()); - return BlockStateIdAccess.isValidInternalId(stateId) - ? Block.stateById(stateId) - : ((CraftBlockData) BukkitAdapter.adapt(blockState)).getState(); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk levelChunk, BlockPos blockPos) { - return levelChunk.getBlockState(blockPos); - } - - @Nullable - @Override - public synchronized net.minecraft.world.level.block.state.BlockState setBlockState( - LevelChunk levelChunk, BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState blockState - ) { - int currentTick = MinecraftServer.currentTick; - if (Fawe.isMainThread()) { - return levelChunk.setBlockState(blockPos, blockState, - this.sideEffectSet != null && this.sideEffectSet.shouldApply(SideEffect.UPDATE) - ); - } - // Since FAWE is.. Async we need to do it on the main thread (wooooo.. :( ) - cachedChanges.add(new CachedChange(levelChunk, blockPos, blockState)); - cachedChunksToSend.add(new IntPair(levelChunk.bukkitChunk.getX(), levelChunk.bukkitChunk.getZ())); - boolean nextTick = lastTick.get() > currentTick; - if (nextTick || cachedChanges.size() >= 1024) { - if (nextTick) { - lastTick.set(currentTick); - } - flushAsync(nextTick); - } - return blockState; - } - - @Override - public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition( - net.minecraft.world.level.block.state.BlockState blockState, - BlockPos blockPos - ) { - return Block.updateFromNeighbourShapes(blockState, getLevel(), blockPos); - } - - @Override - public BlockPos getPosition(int x, int y, int z) { - return new BlockPos(x, y, z); - } - - @Override - public void updateLightingForBlock(BlockPos blockPos) { - getLevel().getChunkSource().getLightEngine().checkBlock(blockPos); - } - - @Override - public boolean updateTileEntity(BlockPos blockPos, CompoundBinaryTag tag) { - // We will assume that the tile entity was created for us, - // though we do not do this on the other versions - BlockEntity blockEntity = getLevel().getBlockEntity(blockPos); - if (blockEntity == null) { - return false; - } - net.minecraft.nbt.Tag nativeTag = paperweightFaweAdapter.fromNativeBinary(tag); - blockEntity.load((CompoundTag) nativeTag); - return true; - } - - @Override - public void notifyBlockUpdate( - LevelChunk levelChunk, BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) { - getLevel().sendBlockUpdated(blockPos, oldState, newState, UPDATE | NOTIFY); - } - } - - @Override - public boolean isChunkTicking(LevelChunk levelChunk) { - return levelChunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING); - } - - @Override - public void markBlockChanged(LevelChunk levelChunk, BlockPos blockPos) { - if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) { - ((ServerChunkCache) getLevel().getChunkSource()).blockChanged(blockPos); - } - } - - @Override - public void notifyNeighbors( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - Level level = getLevel(); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - level.blockUpdated(blockPos, oldState.getBlock()); - } else { - // When we don't want events, manually run the physics without them. - // Un-nest neighbour updating - for (Direction direction : NEIGHBOUR_ORDER) { - BlockPos shifted = blockPos.relative(direction); - level.getBlockState(shifted).neighborChanged(level, shifted, oldState.getBlock(), blockPos, false); - } - } - if (newState.hasAnalogOutputSignal()) { - level.updateNeighbourForOutputSignal(blockPos, newState.getBlock()); - } - } - - @Override - public void updateNeighbors( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState, - int recursionLimit - ) { - Level level = getLevel(); - // a == updateNeighbors - // b == updateDiagonalNeighbors - oldState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - CraftWorld craftWorld = level.getWorld(); - if (craftWorld != null) { - BlockPhysicsEvent event = new BlockPhysicsEvent( - craftWorld.getBlockAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()), - CraftBlockData.fromData(newState) - ); - level.getCraftServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - } - } - newState.triggerEvent(level, blockPos, NOTIFY, recursionLimit); - newState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit); - } - - @Override - public void onBlockStateChange( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - getLevel().onBlockStateChange(blockPos, oldState, newState); - } - - private synchronized void flushAsync(final boolean sendChunks) { - final Set changes = Set.copyOf(cachedChanges); - cachedChanges.clear(); - final Set toSend; - if (sendChunks) { - toSend = Set.copyOf(cachedChunksToSend); - cachedChunksToSend.clear(); - } else { - toSend = Collections.emptySet(); - } - RunnableVal runnableVal = new RunnableVal<>() { - @Override - public void run(Object value) { - changes.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState, - sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE) - )); - if (!sendChunks) { - return; - } - for (IntPair chunk : toSend) { - PaperweightPlatformAdapter.sendChunk(getLevel().getWorld().getHandle(), chunk.x(), chunk.z(), false); - } - } - }; - TaskManager.taskManager().async(() -> TaskManager.taskManager().sync(runnableVal)); - } - - @Override - public synchronized void flush() { - RunnableVal runnableVal = new RunnableVal<>() { - @Override - public void run(Object value) { - cachedChanges.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState, - sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE) - )); - for (IntPair chunk : cachedChunksToSend) { - PaperweightPlatformAdapter.sendChunk(getLevel().getWorld().getHandle(), chunk.x(), chunk.z(), false); - } - } - }; - if (Fawe.isMainThread()) { - runnableVal.run(); - } else { - TaskManager.taskManager().sync(runnableVal); - } - cachedChanges.clear(); - cachedChunksToSend.clear(); - } - - private record CachedChange( - LevelChunk levelChunk, - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState blockState - ) { - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java deleted file mode 100644 index 214a39bc6..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java +++ /dev/null @@ -1,1096 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2; - -import com.fastasyncworldedit.bukkit.adapter.BukkitGetBlocks; -import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; -import com.fastasyncworldedit.core.math.BitArrayUnstretched; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.fastasyncworldedit.core.queue.implementation.QueueHandler; -import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks; -import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.util.collection.AdaptedMap; -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import io.papermc.lib.PaperLib; -import io.papermc.paper.event.block.BeaconDeactivatedEvent; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Registry; -import net.minecraft.core.SectionPos; -import net.minecraft.nbt.IntTag; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.util.BitStorage; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.LightLayer; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.entity.BeaconBlockEntity; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkBiomeContainer; -import net.minecraft.world.level.chunk.DataLayer; -import net.minecraft.world.level.chunk.HashMapPalette; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import net.minecraft.world.level.chunk.LinearPalette; -import net.minecraft.world.level.chunk.Palette; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.lighting.LevelLightEngine; -import org.apache.logging.log4j.Logger; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_17_R1.block.CraftBlock; -import org.bukkit.event.entity.CreatureSpawnEvent; - -import javax.annotation.Nonnull; -import java.util.AbstractSet; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Future; -import java.util.concurrent.Semaphore; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.function.Function; -import java.util.stream.Collectors; - -public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private static final Function posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ()); - private static final Function nmsTile2We = - tileEntity -> new PaperweightLazyCompoundTag(Suppliers.memoize( - () -> tileEntity.save(new net.minecraft.nbt.CompoundTag()))); - private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin - .getInstance() - .getBukkitImplAdapter()); - private final ReadWriteLock sectionLock = new ReentrantReadWriteLock(); - private final ReentrantLock callLock = new ReentrantLock(); - private final ServerLevel serverLevel; - private final int chunkX; - private final int chunkZ; - private final int minHeight; - private final int maxHeight; - private final int minSectionPosition; - private final int maxSectionPosition; - private final ConcurrentHashMap copies = new ConcurrentHashMap<>(); - private final Object sendLock = new Object(); - private LevelChunkSection[] sections; - private LevelChunk levelChunk; - private DataLayer[] blockLight; - private DataLayer[] skyLight; - private boolean createCopy = false; - private boolean forceLoadSections = true; - private boolean lightUpdate = false; - private int copyKey = 0; - - public PaperweightGetBlocks(World world, int chunkX, int chunkZ) { - this(((CraftWorld) world).getHandle(), chunkX, chunkZ); - } - - public PaperweightGetBlocks(ServerLevel serverLevel, int chunkX, int chunkZ) { - super(serverLevel.getMinBuildHeight() >> 4, (serverLevel.getMaxBuildHeight() - 1) >> 4); - this.serverLevel = serverLevel; - this.chunkX = chunkX; - this.chunkZ = chunkZ; - this.minHeight = serverLevel.getMinBuildHeight(); - this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.minSectionPosition = minHeight >> 4; - this.maxSectionPosition = maxHeight >> 4; - this.skyLight = new DataLayer[getSectionCount()]; - this.blockLight = new DataLayer[getSectionCount()]; - } - - public int getChunkX() { - return chunkX; - } - - public int getChunkZ() { - return chunkZ; - } - - @Override - public boolean isCreateCopy() { - return createCopy; - } - - @Override - public int setCreateCopy(boolean createCopy) { - if (!callLock.isHeldByCurrentThread()) { - throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); - } - this.createCopy = createCopy; - // Increment regardless of whether copy will be created or not to return null from getCopy() - return ++this.copyKey; - } - - @Override - public IChunkGet getCopy(final int key) { - return copies.remove(key); - } - - @Override - public void lockCall() { - this.callLock.lock(); - } - - @Override - public void unlockCall() { - this.callLock.unlock(); - } - - @Override - public void setLightingToGet(char[][] light, int minSectionPosition, int maxSectionPosition) { - if (light != null) { - lightUpdate = true; - try { - fillLightNibble(light, LightLayer.BLOCK, minSectionPosition, maxSectionPosition); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - @Override - public void setSkyLightingToGet(char[][] light, int minSectionPosition, int maxSectionPosition) { - if (light != null) { - lightUpdate = true; - try { - fillLightNibble(light, LightLayer.SKY, minSectionPosition, maxSectionPosition); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - @Override - public void setHeightmapToGet(HeightMapType type, int[] data) { - // height + 1 to match server internal - BitArrayUnstretched bitArray = new BitArrayUnstretched(MathMan.log2nlz(getChunk().getHeight() + 1), 256); - bitArray.fromRaw(data); - Heightmap.Types nativeType = Heightmap.Types.valueOf(type.name()); - Heightmap heightMap = getChunk().heightmaps.get(nativeType); - heightMap.setRawData(getChunk(), nativeType, bitArray.getData()); - } - - @Override - public int getMaxY() { - return maxHeight; - } - - @Override - public int getMinY() { - return minHeight; - } - - @Override - public BiomeType getBiomeType(int x, int y, int z) { - ChunkBiomeContainer index = getChunk().getBiomes(); - Biome biomes = null; - if (y == -1) { - for (y = serverLevel.getMinBuildHeight(); y < serverLevel.getMaxBuildHeight(); y += 4) { - biomes = index.getNoiseBiome(x >> 2, y >> 2, z >> 2); - if (biomes != null) { - break; - } - } - } else { - biomes = index.getNoiseBiome(x >> 2, y >> 2, z >> 2); - } - return biomes != null ? PaperweightPlatformAdapter.adapt(biomes, serverLevel) : null; - } - - @Override - public void removeSectionLighting(int layer, boolean sky) { - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = serverLevel.getChunkSource().getLightEngine().getLayerListener(LightLayer.BLOCK).getDataLayerData( - sectionPos); - if (dataLayer != null) { - lightUpdate = true; - synchronized (dataLayer) { - byte[] bytes = PaperLib.isPaper() ? dataLayer.getIfSet() : dataLayer.getData(); - if (!PaperLib.isPaper() || bytes != DataLayer.EMPTY_NIBBLE) { - Arrays.fill(bytes, (byte) 0); - } - } - } - if (sky) { - SectionPos sectionPos1 = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer1 = serverLevel - .getChunkSource() - .getLightEngine() - .getLayerListener(LightLayer.SKY) - .getDataLayerData(sectionPos1); - if (dataLayer1 != null) { - lightUpdate = true; - synchronized (dataLayer1) { - byte[] bytes = PaperLib.isPaper() ? dataLayer1.getIfSet() : dataLayer1.getData(); - if (!PaperLib.isPaper() || bytes != DataLayer.EMPTY_NIBBLE) { - Arrays.fill(bytes, (byte) 0); - } - } - } - } - } - - @Override - public CompoundTag getTile(int x, int y, int z) { - BlockEntity blockEntity = getChunk().getBlockEntity(new BlockPos((x & 15) + ( - chunkX << 4), y, (z & 15) + ( - chunkZ << 4))); - if (blockEntity == null) { - return null; - } - return new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.save(new net.minecraft.nbt.CompoundTag()))); - } - - @Override - public Map getTiles() { - Map nmsTiles = getChunk().getBlockEntities(); - if (nmsTiles.isEmpty()) { - return Collections.emptyMap(); - } - return AdaptedMap.immutable(nmsTiles, posNms2We, nmsTile2We); - } - - @Override - public int getSkyLight(int x, int y, int z) { - int layer = y >> 4; - int alayer = layer - getMinSectionPosition(); - if (skyLight[alayer] == null) { - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = - serverLevel.getChunkSource().getLightEngine().getLayerListener(LightLayer.SKY).getDataLayerData(sectionPos); - // If the server hasn't generated the section's NibbleArray yet, it will be null - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. - Arrays.fill(LAYER_COUNT, (byte) 15); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( - LightLayer.BLOCK, - sectionPos, - dataLayer, - true - ); - } - skyLight[alayer] = dataLayer; - } - return skyLight[alayer].get(x & 15, y & 15, z & 15); - } - - @Override - public int getEmittedLight(int x, int y, int z) { - int layer = y >> 4; - int alayer = layer - getMinSectionPosition(); - if (blockLight[alayer] == null) { - serverLevel.getRawBrightness(new BlockPos(1, 1, 1), 5); - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = serverLevel - .getChunkSource() - .getLightEngine() - .getLayerListener(LightLayer.BLOCK) - .getDataLayerData(sectionPos); - // If the server hasn't generated the section's DataLayer yet, it will be null - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. - Arrays.fill(LAYER_COUNT, (byte) 15); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(LightLayer.BLOCK, sectionPos, - dataLayer, true - ); - } - blockLight[alayer] = dataLayer; - } - return blockLight[alayer].get(x & 15, y & 15, z & 15); - } - - @Override - public int[] getHeightMap(HeightMapType type) { - long[] longArray = getChunk().heightmaps.get(Heightmap.Types.valueOf(type.name())).getRawData(); - BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256, longArray); - return bitArray.toRaw(new int[256]); - } - - @Override - public CompoundTag getEntity(UUID uuid) { - Entity entity = serverLevel.getEntity(uuid); - if (entity != null) { - org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity(); - return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); - } - for (CompoundTag tag : getEntities()) { - if (uuid.equals(tag.getUUID())) { - return tag; - } - } - return null; - } - - @Override - public Set getEntities() { - List entities = PaperweightPlatformAdapter.getEntities(getChunk()); - if (entities.isEmpty()) { - return Collections.emptySet(); - } - int size = entities.size(); - return new AbstractSet<>() { - @Override - public int size() { - return size; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean contains(Object get) { - if (!(get instanceof CompoundTag getTag)) { - return false; - } - UUID getUUID = getTag.getUUID(); - for (Entity entity : entities) { - UUID uuid = entity.getUUID(); - if (uuid.equals(getUUID)) { - return true; - } - } - return false; - } - - @Nonnull - @Override - public Iterator iterator() { - Iterable result = entities.stream().map(input -> { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(input, tag); - return (CompoundTag) adapter.toNative(tag); - }).collect(Collectors.toList()); - return result.iterator(); - } - }; - } - - private void removeEntity(Entity entity) { - entity.discard(); - } - - public LevelChunk ensureLoaded(ServerLevel nmsWorld, int chunkX, int chunkZ) { - return PaperweightPlatformAdapter.ensureLoaded(nmsWorld, chunkX, chunkZ); - } - - @Override - @SuppressWarnings("rawtypes") - public synchronized > T call(IChunkSet set, Runnable finalizer) { - if (!callLock.isHeldByCurrentThread()) { - throw new IllegalStateException("Attempted to call chunk GET but chunk was not call-locked."); - } - forceLoadSections = false; - PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null; - if (createCopy) { - if (copies.containsKey(copyKey)) { - throw new IllegalStateException("Copy key already used."); - } - copies.put(copyKey, copy); - } - try { - ServerLevel nmsWorld = serverLevel; - LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ); - boolean fastmode = set.isFastMode() && Settings.settings().QUEUE.NO_TICK_FASTMODE; - - // Remove existing tiles. Create a copy so that we can remove blocks - Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); - List beacons = null; - if (!chunkTiles.isEmpty()) { - for (Map.Entry entry : chunkTiles.entrySet()) { - final BlockPos pos = entry.getKey(); - final int lx = pos.getX() & 15; - final int ly = pos.getY(); - final int lz = pos.getZ() & 15; - final int layer = ly >> 4; - if (!set.hasSection(layer)) { - continue; - } - - int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { - BlockEntity tile = entry.getValue(); - if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { - if (beacons == null) { - beacons = new ArrayList<>(); - } - beacons.add(tile); - PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); - continue; - } - nmsChunk.removeBlockEntity(tile.getBlockPos()); - if (createCopy) { - copy.storeTile(tile); - } - } - } - } - - int bitMask = 0; - synchronized (nmsChunk) { - LevelChunkSection[] levelChunkSections = nmsChunk.getSections(); - - for (int layerNo = getMinSectionPosition(); layerNo <= getMaxSectionPosition(); layerNo++) { - if (!set.hasSection(layerNo)) { - continue; - } - int layer = layerNo - getMinSectionPosition(); - - bitMask |= 1 << layer; - - // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to - // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); - - // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was - // submitted to keep loaded internal chunks to queue target size. - synchronized (super.sectionLocks[layer]) { - if (createCopy) { - char[] tmpLoad = loadPrivately(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); - copy.storeSection(layer, copyArr); - } - - LevelChunkSection newSection; - LevelChunkSection existingSection = levelChunkSections[layer]; - // Don't attempt to tick section whilst we're editing - if (existingSection != null) { - PaperweightPlatformAdapter.clearCounts(existingSection); - if (PaperLib.isPaper()) { - existingSection.tickingList.clear(); - } - } - - if (existingSection == null) { - newSection = PaperweightPlatformAdapter.newChunkSection(layerNo, setArr, fastmode, adapter); - if (PaperweightPlatformAdapter.setSectionAtomic(levelChunkSections, null, newSection, layer)) { - updateGet(nmsChunk, levelChunkSections, newSection, setArr, layer); - continue; - } else { - existingSection = levelChunkSections[layer]; - if (existingSection == null) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - +layer - ); - continue; - } - } - } - - //ensure that the server doesn't try to tick the chunksection while we're editing it (again). - PaperweightPlatformAdapter.clearCounts(existingSection); - if (PaperLib.isPaper()) { - existingSection.tickingList.clear(); - } - DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(existingSection); - - // Synchronize to prevent further acquisitions - synchronized (lock) { - lock.acquire(); // Wait until we have the lock - lock.release(); - try { - sectionLock.writeLock().lock(); - if (this.getChunk() != nmsChunk) { - this.levelChunk = nmsChunk; - this.sections = null; - this.reset(); - } else if (existingSection != getSections(false)[layer]) { - this.sections[layer] = existingSection; - this.reset(); - } else if (!Arrays.equals(update(layer, new char[4096], true), loadPrivately(layerNo))) { - this.reset(layerNo); - /*} else if (lock.isModified()) { - this.reset(layerNo);*/ - } - } finally { - sectionLock.writeLock().unlock(); - } - newSection = - PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - fastmode, - adapter - ); - if (!PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - existingSection, - newSection, - layer - )) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - +layer - ); - } else { - updateGet(nmsChunk, levelChunkSections, newSection, setArr, layer); - } - } - } - } - - // Biomes - BiomeType[][] biomes = set.getBiomes(); - if (biomes != null) { - // set biomes - ChunkBiomeContainer currentBiomes = nmsChunk.getBiomes(); - if (createCopy) { - copy.storeBiomes(currentBiomes); - } - for (int layer = 0; layer < 16; layer++) { - if (biomes[layer] == null) { - continue; - } - for (int y = 0, i = 0; y < 4; y++) { - for (int z = 0; z < 4; z++) { - for (int x = 0; x < 4; x++, i++) { - final BiomeType biome = biomes[layer][i]; - if (biome != null) { - Biome nmsBiome = - nmsWorld.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).get( - ResourceLocation.tryParse(biome.getId())); - if (nmsBiome == null) { - throw new NullPointerException("BiomeBase null for BiomeType " + biome.getId()); - } - currentBiomes.setBiome(x, (layer << 2) + y, z, nmsBiome); - } - } - } - } - } - } - - Map heightMaps = set.getHeightMaps(); - for (Map.Entry entry : heightMaps.entrySet()) { - PaperweightGetBlocks.this.setHeightmapToGet(entry.getKey(), entry.getValue()); - } - PaperweightGetBlocks.this.setLightingToGet( - set.getLight(), - set.getMinSectionPosition(), - set.getMaxSectionPosition() - ); - PaperweightGetBlocks.this.setSkyLightingToGet( - set.getSkyLight(), - set.getMinSectionPosition(), - set.getMaxSectionPosition() - ); - - Runnable[] syncTasks = null; - - int bx = chunkX << 4; - int bz = chunkZ << 4; - - // Call beacon deactivate events here synchronously - // list will be null on spigot, so this is an implicit isPaper check - if (beacons != null && !beacons.isEmpty()) { - final List finalBeacons = beacons; - - syncTasks = new Runnable[4]; - - syncTasks[3] = () -> { - for (BlockEntity beacon : finalBeacons) { - BeaconBlockEntity.playSound(beacon.getLevel(), beacon.getBlockPos(), SoundEvents.BEACON_DEACTIVATE); - new BeaconDeactivatedEvent(CraftBlock.at(beacon.getLevel(), beacon.getBlockPos())).callEvent(); - } - }; - } - - Set entityRemoves = set.getEntityRemoves(); - if (entityRemoves != null && !entityRemoves.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[3]; - } - - syncTasks[2] = () -> { - Set entitiesRemoved = new HashSet<>(); - final List entities = PaperweightPlatformAdapter.getEntities(nmsChunk); - - for (Entity entity : entities) { - UUID uuid = entity.getUUID(); - if (entityRemoves.contains(uuid)) { - if (createCopy) { - copy.storeEntity(entity); - } - removeEntity(entity); - entitiesRemoved.add(uuid); - entityRemoves.remove(uuid); - } - } - if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) { - for (UUID uuid : entityRemoves) { - Entity entity = nmsWorld.entityManager.getEntityGetter().get(uuid); - if (entity != null) { - removeEntity(entity); - } - } - } - // Only save entities that were actually removed to history - set.getEntityRemoves().clear(); - set.getEntityRemoves().addAll(entitiesRemoved); - }; - } - - Set entities = set.getEntities(); - if (entities != null && !entities.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[2]; - } - - syncTasks[1] = () -> { - Iterator iterator = entities.iterator(); - while (iterator.hasNext()) { - final CompoundTag nativeTag = iterator.next(); - final Map entityTagMap = nativeTag.getValue(); - final StringTag idTag = (StringTag) entityTagMap.get("Id"); - final ListTag posTag = (ListTag) entityTagMap.get("Pos"); - final ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); - if (idTag == null || posTag == null || rotTag == null) { - LOGGER.error("Unknown entity tag: {}", nativeTag); - continue; - } - final double x = posTag.getDouble(0); - final double y = posTag.getDouble(1); - final double z = posTag.getDouble(2); - final float yaw = rotTag.getFloat(0); - final float pitch = rotTag.getFloat(1); - final String id = idTag.getValue(); - - EntityType type = EntityType.byString(id).orElse(null); - if (type != null) { - Entity entity = type.create(nmsWorld); - if (entity != null) { - final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative( - nativeTag); - for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - entity.load(tag); - entity.absMoveTo(x, y, z, yaw, pitch); - entity.setUUID(nativeTag.getUUID()); - if (!nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) { - LOGGER.warn( - "Error creating entity of type `{}` in world `{}` at location `{},{},{}`", - id, - nmsWorld.getWorld().getName(), - x, - y, - z - ); - // Unsuccessful create should not be saved to history - iterator.remove(); - } - } - } - } - }; - } - - // set tiles - Map tiles = set.getTiles(); - if (tiles != null && !tiles.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[1]; - } - - syncTasks[0] = () -> { - for (final Map.Entry entry : tiles.entrySet()) { - final CompoundTag nativeTag = entry.getValue(); - final BlockVector3 blockHash = entry.getKey(); - final int x = blockHash.getX() + bx; - final int y = blockHash.getY(); - final int z = blockHash.getZ() + bz; - final BlockPos pos = new BlockPos(x, y, z); - - synchronized (nmsWorld) { - BlockEntity tileEntity = nmsWorld.getBlockEntity(pos); - if (tileEntity == null || tileEntity.isRemoved()) { - nmsWorld.removeBlockEntity(pos); - tileEntity = nmsWorld.getBlockEntity(pos); - } - if (tileEntity != null) { - final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative( - nativeTag); - tag.put("x", IntTag.valueOf(x)); - tag.put("y", IntTag.valueOf(y)); - tag.put("z", IntTag.valueOf(z)); - tileEntity.load(tag); - } - } - } - }; - } - - Runnable callback; - if (bitMask == 0 && biomes == null && !lightUpdate) { - callback = null; - } else { - int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0; - boolean finalLightUpdate = lightUpdate; - callback = () -> { - // Set Modified - nmsChunk.setLightCorrect(true); // Set Modified - nmsChunk.mustNotSave = false; - nmsChunk.markUnsaved(); - // send to player - if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { - this.send(finalMask, finalLightUpdate); - } - if (finalizer != null) { - finalizer.run(); - } - }; - } - if (syncTasks != null) { - QueueHandler queueHandler = Fawe.instance().getQueueHandler(); - Runnable[] finalSyncTasks = syncTasks; - - // Chain the sync tasks and the callback - Callable chain = () -> { - try { - // Run the sync tasks - for (Runnable task : finalSyncTasks) { - if (task != null) { - task.run(); - } - } - if (callback == null) { - if (finalizer != null) { - finalizer.run(); - } - return null; - } else { - return queueHandler.async(callback, null); - } - } catch (Throwable e) { - e.printStackTrace(); - throw e; - } - }; - //noinspection unchecked - required at compile time - return (T) (Future) queueHandler.sync(chain); - } else { - if (callback == null) { - if (finalizer != null) { - finalizer.run(); - } - } else { - callback.run(); - } - } - } - return null; - } catch (Throwable e) { - e.printStackTrace(); - return null; - } finally { - forceLoadSections = true; - } - } - - private void updateGet( - LevelChunk nmsChunk, - LevelChunkSection[] chunkSections, - LevelChunkSection section, - char[] arr, - int layer - ) { - try { - sectionLock.writeLock().lock(); - if (this.getChunk() != nmsChunk) { - this.levelChunk = nmsChunk; - this.sections = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, this.sections, 0, chunkSections.length); - this.reset(); - } - if (this.sections == null) { - this.sections = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, this.sections, 0, chunkSections.length); - } - if (this.sections[layer] != section) { - // Not sure why it's funky, but it's what I did in commit fda7d00747abe97d7891b80ed8bb88d97e1c70d1 and I don't want to touch it >dords - this.sections[layer] = new LevelChunkSection[]{section}.clone()[0]; - } - } finally { - sectionLock.writeLock().unlock(); - } - this.blocks[layer] = arr; - } - - private char[] loadPrivately(int layer) { - layer -= getMinSectionPosition(); - if (super.sections[layer] != null) { - synchronized (super.sectionLocks[layer]) { - if (super.sections[layer].isFull() && super.blocks[layer] != null) { - return super.blocks[layer]; - } - } - } - return PaperweightGetBlocks.this.update(layer, null, true); - } - - @Override - public void send(int mask, boolean lighting) { - synchronized (sendLock) { - PaperweightPlatformAdapter.sendChunk(serverLevel, chunkX, chunkZ, lighting); - } - } - - /** - * Update a given (nullable) data array to the current data stored in the server's chunk, associated with this - * {@link PaperweightPlatformAdapter} instance. Not synchronised to the {@link PaperweightPlatformAdapter} instance as synchronisation - * is handled where necessary in the method, and should otherwise be handled correctly by this method's caller. - * - * @param layer layer index (0 may denote a negative layer in the world, e.g. at y=-32) - * @param data array to be updated/filled with data or null - * @param aggressive if the cached section array should be re-acquired. - * @return the given array to be filled with data, or a new array if null is given. - */ - @Override - @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { - LevelChunkSection section = getSections(aggressive)[layer]; - // Section is null, return empty array - if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; - } - if (data != null && data.length != 4096) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - } - Semaphore lock = PaperweightPlatformAdapter.applyLock(section); - synchronized (lock) { - // Efficiently convert ChunkSection to raw data - try { - lock.acquire(); - - final PalettedContainer blocks = section.getStates(); - final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(blocks); - final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get(blocks); - - final int bitsPerEntry = (int) PaperweightPlatformAdapter.fieldBitsPerEntry.get(bits); - final long[] blockStates = bits.getRaw(); - - new BitArrayUnstretched(bitsPerEntry, 4096, blockStates).toRaw(data); - - int num_palette; - if (palette instanceof LinearPalette || palette instanceof HashMapPalette) { - num_palette = palette.getSize(); - } else { - // The section's palette is the global block palette. - for (int i = 0; i < 4096; i++) { - char paletteVal = data[i]; - char ordinal = adapter.ibdIDToOrdinal(paletteVal); - data[i] = ordinal; - } - return data; - } - - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); - try { - if (num_palette != 1) { - for (int i = 0; i < num_palette; i++) { - char ordinal = ordinal(palette.valueFor(i), adapter); - paletteToOrdinal[i] = ordinal; - } - for (int i = 0; i < 4096; i++) { - char paletteVal = data[i]; - char val = paletteToOrdinal[paletteVal]; - if (val == Character.MAX_VALUE) { - val = ordinal(palette.valueFor(i), adapter); - paletteToOrdinal[i] = val; - } - data[i] = val; - } - } else { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); - } - } finally { - for (int i = 0; i < num_palette; i++) { - paletteToOrdinal[i] = Character.MAX_VALUE; - } - } - return data; - } catch (IllegalAccessException | InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } finally { - lock.release(); - } - } - } - - private char ordinal(net.minecraft.world.level.block.state.BlockState ibd, PaperweightFaweAdapter adapter) { - if (ibd == null) { - return BlockTypesCache.ReservedIDs.AIR; - } else { - return adapter.adaptToChar(ibd); - } - } - - public LevelChunkSection[] getSections(boolean force) { - force &= forceLoadSections; - LevelChunkSection[] tmp = sections; - if (tmp == null || force) { - try { - sectionLock.writeLock().lock(); - tmp = sections; - if (tmp == null || force) { - LevelChunkSection[] chunkSections = getChunk().getSections(); - tmp = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, tmp, 0, chunkSections.length); - sections = tmp; - } - } finally { - sectionLock.writeLock().unlock(); - } - } - return tmp; - } - - public LevelChunk getChunk() { - LevelChunk levelChunk = this.levelChunk; - if (levelChunk == null) { - synchronized (this) { - levelChunk = this.levelChunk; - if (levelChunk == null) { - this.levelChunk = levelChunk = ensureLoaded(this.serverLevel, chunkX, chunkZ); - } - } - } - return levelChunk; - } - - private void fillLightNibble(char[][] light, LightLayer lightLayer, int minSectionPosition, int maxSectionPosition) { - for (int Y = 0; Y <= maxSectionPosition - minSectionPosition; Y++) { - if (light[Y] == null) { - continue; - } - SectionPos sectionPos = SectionPos.of(levelChunk.getPos(), Y + minSectionPosition); - DataLayer dataLayer = serverLevel.getChunkSource().getLightEngine().getLayerListener(lightLayer).getDataLayerData( - sectionPos); - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - Arrays.fill(LAYER_COUNT, lightLayer == LightLayer.SKY ? (byte) 15 : (byte) 0); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( - lightLayer, - sectionPos, - dataLayer, - true - ); - } - synchronized (dataLayer) { - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - int i = y << 8 | z << 4 | x; - if (light[Y][i] < 16) { - dataLayer.set(x, y, z, light[Y][i]); - } - } - } - } - } - } - } - - @Override - public boolean hasSection(int layer) { - layer -= getMinSectionPosition(); - return getSections(false)[layer] != null; - } - - @Override - @SuppressWarnings("unchecked") - public synchronized boolean trim(boolean aggressive) { - skyLight = new DataLayer[getSectionCount()]; - blockLight = new DataLayer[getSectionCount()]; - if (aggressive) { - sectionLock.writeLock().lock(); - sections = null; - levelChunk = null; - sectionLock.writeLock().unlock(); - return super.trim(true); - } else if (sections == null) { - // don't bother trimming if there are no sections stored. - return true; - } else { - for (int i = getMinSectionPosition(); i <= getMaxSectionPosition(); i++) { - int layer = i - getMinSectionPosition(); - if (!hasSection(i) || !super.sections[layer].isFull()) { - continue; - } - LevelChunkSection existing = getSections(true)[layer]; - try { - final PalettedContainer blocksExisting = existing.getStates(); - - final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get( - blocksExisting); - int paletteSize; - - if (palette instanceof LinearPalette || palette instanceof HashMapPalette) { - paletteSize = palette.getSize(); - } else { - super.trim(false, i); - continue; - } - if (paletteSize == 1) { - //If the cached palette size is 1 then no blocks can have been changed i.e. do not need to update these chunks. - continue; - } - super.trim(false, i); - } catch (IllegalAccessException ignored) { - super.trim(false, i); - } - } - return true; - } - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks_Copy.java deleted file mode 100644 index cd9987d79..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks_Copy.java +++ /dev/null @@ -1,251 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2; - -import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; -import com.fastasyncworldedit.core.queue.IBlocks; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.ChunkBiomeContainer; -import net.minecraft.world.level.chunk.LevelChunk; - -import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Future; - -public class PaperweightGetBlocks_Copy implements IChunkGet { - - private final Map tiles = new HashMap<>(); - private final Set entities = new HashSet<>(); - private final char[][] blocks; - private final int minHeight; - private final int maxHeight; - final ServerLevel serverLevel; - final LevelChunk levelChunk; - private ChunkBiomeContainer chunkBiomeContainer; - - protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { - this.levelChunk = levelChunk; - this.serverLevel = levelChunk.level; - this.minHeight = serverLevel.getMinBuildHeight(); - this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; - } - - protected void storeTile(BlockEntity blockEntity) { - tiles.put( - BlockVector3.at( - blockEntity.getBlockPos().getX(), - blockEntity.getBlockPos().getY(), - blockEntity.getBlockPos().getZ() - ), - new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.save(new net.minecraft.nbt.CompoundTag()))) - ); - } - - @Override - public Map getTiles() { - return tiles; - } - - @Override - @Nullable - public CompoundTag getTile(int x, int y, int z) { - return tiles.get(BlockVector3.at(x, y, z)); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - protected void storeEntity(Entity entity) { - BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); - net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(entity, compoundTag); - entities.add((CompoundTag) adapter.toNative(compoundTag)); - } - - @Override - public Set getEntities() { - return this.entities; - } - - @Override - public CompoundTag getEntity(UUID uuid) { - for (CompoundTag tag : entities) { - if (uuid.equals(tag.getUUID())) { - return tag; - } - } - return null; - } - - @Override - public boolean isCreateCopy() { - return false; - } - - @Override - public int setCreateCopy(boolean createCopy) { - return -1; - } - - @Override - public void setLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) { - } - - @Override - public void setSkyLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) { - } - - @Override - public void setHeightmapToGet(HeightMapType type, int[] data) { - } - - @Override - public int getMaxY() { - return maxHeight; - } - - @Override - public int getMinY() { - return minHeight; - } - - @Override - public int getMaxSectionPosition() { - return maxHeight >> 4; - } - - @Override - public int getMinSectionPosition() { - return minHeight >> 4; - } - - protected void storeBiomes(ChunkBiomeContainer chunkBiomeContainer) { - // The to do one line below is pre-paperweight and needs to be revised - // TODO revisit last parameter, BiomeStorage[] *would* be more efficient - this.chunkBiomeContainer = new ChunkBiomeContainer(chunkBiomeContainer.biomeRegistry, serverLevel, - chunkBiomeContainer.writeBiomes() - ); - } - - @Override - public BiomeType getBiomeType(int x, int y, int z) { - Biome biome = null; - if (y == -1) { - for (y = serverLevel.getMinBuildHeight(); y <= serverLevel.getMaxBuildHeight(); y += 4) { - biome = this.chunkBiomeContainer.getNoiseBiome(x >> 2, y >> 2, z >> 2); - if (biome != null) { - break; - } - } - } else { - biome = this.chunkBiomeContainer.getNoiseBiome(x >> 2, y >> 2, z >> 2); - } - return biome != null ? PaperweightPlatformAdapter.adapt(biome, serverLevel) : null; - } - - @Override - public void removeSectionLighting(int layer, boolean sky) { - } - - @Override - public boolean trim(boolean aggressive, int layer) { - return false; - } - - @Override - public IBlocks reset() { - return null; - } - - @Override - public int getSectionCount() { - return serverLevel.getSectionsCount(); - } - - protected void storeSection(int layer, char[] data) { - blocks[layer] = data; - } - - @Override - public BaseBlock getFullBlock(int x, int y, int z) { - BlockState state = BlockTypesCache.states[get(x, y, z)]; - return state.toBaseBlock(this, x, y, z); - } - - @Override - public boolean hasSection(int layer) { - layer -= getMinSectionPosition(); - return blocks[layer] != null; - } - - @Override - public char[] load(int layer) { - layer -= getMinSectionPosition(); - if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); - } - return blocks[layer]; - } - - @Override - public char[] loadIfPresent(int layer) { - layer -= getMinSectionPosition(); - return blocks[layer]; - } - - @Override - public BlockState getBlock(int x, int y, int z) { - return BlockTypesCache.states[get(x, y, z)]; - } - - @Override - public int getSkyLight(int x, int y, int z) { - return 0; - } - - @Override - public int getEmittedLight(int x, int y, int z) { - return 0; - } - - @Override - public int[] getHeightMap(HeightMapType type) { - return new int[0]; - } - - @Override - public > T call(IChunkSet set, Runnable finalize) { - return null; - } - - public char get(int x, int y, int z) { - final int layer = (y >> 4) - getMinSectionPosition(); - final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; - } - - - @Override - public boolean trim(boolean aggressive) { - return false; - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightMapChunkUtil.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightMapChunkUtil.java deleted file mode 100644 index c9d5ed124..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightMapChunkUtil.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2; - -import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import net.minecraft.network.protocol.game.ClientboundLevelChunkPacket; - -public class PaperweightMapChunkUtil extends MapChunkUtil { - - public PaperweightMapChunkUtil() throws NoSuchFieldException { - fieldX = ClientboundLevelChunkPacket.class.getDeclaredField(Refraction.pickName("TWO_MEGABYTES", "a")); - fieldZ = ClientboundLevelChunkPacket.class.getDeclaredField(Refraction.pickName("x", "b")); - fieldBitMask = ClientboundLevelChunkPacket.class.getDeclaredField(Refraction.pickName("z", "c")); - fieldHeightMap = ClientboundLevelChunkPacket.class.getDeclaredField(Refraction.pickName("availableSections", "d")); - fieldChunkData = ClientboundLevelChunkPacket.class.getDeclaredField(Refraction.pickName("biomes", "f")); - fieldBlockEntities = ClientboundLevelChunkPacket.class.getDeclaredField(Refraction.pickName("buffer", "g")); - fieldFull = ClientboundLevelChunkPacket.class.getDeclaredField(Refraction.pickName("blockEntitiesTags", "h")); - fieldX.setAccessible(true); - fieldZ.setAccessible(true); - fieldBitMask.setAccessible(true); - fieldHeightMap.setAccessible(true); - fieldChunkData.setAccessible(true); - fieldBlockEntities.setAccessible(true); - fieldFull.setAccessible(true); - } - - @Override - public ClientboundLevelChunkPacket createPacket() { - // TODO ??? return new ClientboundLevelChunkPacket(); - throw new UnsupportedOperationException(); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java deleted file mode 100644 index 16dfd7bd8..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPlatformAdapter.java +++ /dev/null @@ -1,526 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2; - -import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter; -import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; -import com.fastasyncworldedit.bukkit.adapter.NMSAdapter; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.math.BitArrayUnstretched; -import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.util.ReflectionUtils; -import com.fastasyncworldedit.core.util.TaskManager; -import com.mojang.datafixers.util.Either; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import io.papermc.lib.PaperLib; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Registry; -import net.minecraft.core.SectionPos; -import net.minecraft.nbt.NbtUtils; -import net.minecraft.network.protocol.game.ClientboundLevelChunkPacket; -import net.minecraft.network.protocol.game.ClientboundLightUpdatePacket; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.level.TicketType; -import net.minecraft.util.BitStorage; -import net.minecraft.util.Unit; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.npc.AbstractVillager; -import net.minecraft.world.item.trading.MerchantOffers; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.ChunkBiomeContainer; -import net.minecraft.world.level.chunk.HashMapPalette; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import net.minecraft.world.level.chunk.LinearPalette; -import net.minecraft.world.level.chunk.Palette; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.gameevent.GameEventDispatcher; -import net.minecraft.world.level.gameevent.GameEventListener; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_17_R1.CraftChunk; -import sun.misc.Unsafe; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.function.Function; -import java.util.stream.Stream; - -public final class PaperweightPlatformAdapter extends NMSAdapter { - - public static final Field fieldStorage; - public static final Field fieldPalette; - public static final Field fieldBits; - - public static final Field fieldBitsPerEntry; - - private static final Field fieldTickingFluidContent; - private static final Field fieldTickingBlockCount; - private static final Field fieldNonEmptyBlockCount; - - private static final Field fieldBiomes; - - private static final MethodHandle methodGetVisibleChunk; - - private static final Field fieldLock; - - private static final Field fieldGameEventDispatcherSections; - private static final MethodHandle methodremoveBlockEntityTicker; - - private static final Field fieldOffers; - private static final MerchantOffers OFFERS = new MerchantOffers(); - - private static final Field fieldRemove; - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - static { - try { - fieldBits = PalettedContainer.class.getDeclaredField(Refraction.pickName("bits", "l")); - fieldBits.setAccessible(true); - fieldStorage = PalettedContainer.class.getDeclaredField(Refraction.pickName("storage", "c")); - fieldStorage.setAccessible(true); - fieldPalette = PalettedContainer.class.getDeclaredField(Refraction.pickName("palette", "k")); - fieldPalette.setAccessible(true); - - fieldBitsPerEntry = BitStorage.class.getDeclaredField(Refraction.pickName("bits", "c")); - fieldBitsPerEntry.setAccessible(true); - - fieldTickingFluidContent = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "h")); - fieldTickingFluidContent.setAccessible(true); - fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "g")); - fieldTickingBlockCount.setAccessible(true); - fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "f")); - fieldNonEmptyBlockCount.setAccessible(true); - - fieldBiomes = ChunkBiomeContainer.class.getDeclaredField(Refraction.pickName("biomes", "f")); - fieldBiomes.setAccessible(true); - - Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( - "getVisibleChunkIfPresent", - "getVisibleChunk" - ), long.class); - getVisibleChunkIfPresent.setAccessible(true); - methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent); - - if (!PaperLib.isPaper()) { - fieldLock = PalettedContainer.class.getDeclaredField(Refraction.pickName("lock", "m")); - fieldLock.setAccessible(true); - } else { - // in paper, the used methods are synchronized properly - fieldLock = null; - } - - fieldGameEventDispatcherSections = LevelChunk.class.getDeclaredField(Refraction.pickName( - "gameEventDispatcherSections", "x")); - fieldGameEventDispatcherSections.setAccessible(true); - Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod( - Refraction.pickName( - "removeBlockEntityTicker", - "l" - ), BlockPos.class - ); - removeBlockEntityTicker.setAccessible(true); - methodremoveBlockEntityTicker = MethodHandles.lookup().unreflect(removeBlockEntityTicker); - - fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p")); - fieldRemove.setAccessible(true); - - fieldOffers = AbstractVillager.class.getDeclaredField(Refraction.pickName("offers", "bU")); - fieldOffers.setAccessible(true); - } catch (RuntimeException e) { - throw e; - } catch (Throwable rethrow) { - rethrow.printStackTrace(); - throw new RuntimeException(rethrow); - } - } - - static boolean setSectionAtomic( - LevelChunkSection[] sections, - LevelChunkSection expected, - LevelChunkSection value, - int layer - ) { - if (layer >= 0 && layer < sections.length) { - return ReflectionUtils.compareAndSet(sections, expected, value, layer); - } - return false; - } - - // There is no point in having a functional semaphore for paper servers. - private static final ThreadLocal SEMAPHORE_THREAD_LOCAL = - ThreadLocal.withInitial(() -> new DelegateSemaphore(1, null)); - - static DelegateSemaphore applyLock(LevelChunkSection section) { - if (PaperLib.isPaper()) { - return SEMAPHORE_THREAD_LOCAL.get(); - } - try { - synchronized (section) { - PalettedContainer blocks = section.getStates(); - Semaphore currentLock = (Semaphore) fieldLock.get(blocks); - if (currentLock instanceof DelegateSemaphore delegateSemaphore) { - return delegateSemaphore; - } - DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); - fieldLock.set(blocks, newLock); - return newLock; - } - } catch (Throwable e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - public static LevelChunk ensureLoaded(ServerLevel serverLevel, int chunkX, int chunkZ) { - if (!PaperLib.isPaper()) { - LevelChunk nmsChunk = serverLevel.getChunkSource().getChunk(chunkX, chunkZ, false); - if (nmsChunk != null) { - return nmsChunk; - } - if (Fawe.isMainThread()) { - return serverLevel.getChunk(chunkX, chunkZ); - } - } else { - LevelChunk nmsChunk = serverLevel.getChunkSource().getChunkAtIfCachedImmediately(chunkX, chunkZ); - if (nmsChunk != null) { - addTicket(serverLevel, chunkX, chunkZ); - return nmsChunk; - } - nmsChunk = serverLevel.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ); - if (nmsChunk != null) { - addTicket(serverLevel, chunkX, chunkZ); - return nmsChunk; - } - // Avoid "async" methods from the main thread. - if (Fawe.isMainThread()) { - return serverLevel.getChunk(chunkX, chunkZ); - } - CompletableFuture future = serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true); - try { - CraftChunk chunk; - try { - chunk = (CraftChunk) future.get(10, TimeUnit.SECONDS); - } catch (TimeoutException e) { - String world = serverLevel.getWorld().getName(); - // We've already taken 10 seconds we can afford to wait a little here. - boolean loaded = TaskManager.taskManager().sync(() -> Bukkit.getWorld(world) != null); - if (loaded) { - LOGGER.warn("Chunk {},{} failed to load in 10 seconds in world {}. Retrying...", chunkX, chunkZ, world); - // Retry chunk load - chunk = (CraftChunk) serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true).get(); - } else { - throw new UnsupportedOperationException("Cannot load chunk from unloaded world " + world + "!"); - } - } - return chunk.getHandle(); - } catch (Throwable e) { - e.printStackTrace(); - } - } - return TaskManager.taskManager().sync(() -> serverLevel.getChunk(chunkX, chunkZ)); - } - - private static void addTicket(ServerLevel serverLevel, int chunkX, int chunkZ) { - // Ensure chunk is definitely loaded before applying a ticket - net.minecraft.server.MCUtil.MAIN_EXECUTOR.execute(() -> serverLevel - .getChunkSource() - .addRegionTicket(TicketType.PLUGIN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE)); - } - - public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) { - ChunkMap chunkMap = nmsWorld.getChunkSource().chunkMap; - try { - return (ChunkHolder) methodGetVisibleChunk.invoke(chunkMap, ChunkPos.asLong(chunkX, chunkZ)); - } catch (Throwable thr) { - throw new RuntimeException(thr); - } - } - - @SuppressWarnings("unchecked") - public static void sendChunk(ServerLevel nmsWorld, int chunkX, int chunkZ, boolean lighting) { - ChunkHolder chunkHolder = getPlayerChunk(nmsWorld, chunkX, chunkZ); - if (chunkHolder == null) { - return; - } - ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ); - // UNLOADED_CHUNK - Optional optional = ((Either) chunkHolder - .getTickingChunkFuture() - .getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left(); - if (PaperLib.isPaper()) { - // getChunkAtIfLoadedImmediately is paper only - optional = optional.or(() -> Optional.ofNullable(nmsWorld - .getChunkSource() - .getChunkAtIfLoadedImmediately(chunkX, chunkZ))); - } - if (optional.isEmpty()) { - return; - } - LevelChunk levelChunk = optional.get(); - TaskManager.taskManager().task(() -> { - ClientboundLevelChunkPacket chunkPacket = new ClientboundLevelChunkPacket(levelChunk); - nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(chunkPacket)); - if (lighting) { - //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad) - boolean trustEdges = true; - ClientboundLightUpdatePacket packet = - new ClientboundLightUpdatePacket(coordIntPair, nmsWorld.getChunkSource().getLightEngine(), null, null, - trustEdges - ); - nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); - } - }); - } - - private static Stream nearbyPlayers(ServerLevel serverLevel, ChunkPos coordIntPair) { - return serverLevel.getChunkSource().chunkMap.getPlayers(coordIntPair, false); - } - - /* - NMS conversion - */ - public static LevelChunkSection newChunkSection( - final int layer, - final char[] blocks, - boolean fastMode, - CachedBukkitAdapter adapter - ) { - return newChunkSection(layer, null, blocks, fastMode, adapter); - } - - public static LevelChunkSection newChunkSection( - final int layer, - final Function get, - char[] set, - boolean fastMode, - CachedBukkitAdapter adapter - ) { - if (set == null) { - return newChunkSection(layer); - } - final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); - final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); - final long[] blockStates = FaweCache.INSTANCE.BLOCK_STATES.get(); - final int[] blocksCopy = FaweCache.INSTANCE.SECTION_BLOCKS.get(); - try { - int num_palette; - final short[] nonEmptyBlockCount = fastMode ? new short[1] : null; - if (get == null) { - num_palette = createPalette(blockToPalette, paletteToBlock, blocksCopy, set, adapter, nonEmptyBlockCount); - } else { - num_palette = createPalette( - layer, - blockToPalette, - paletteToBlock, - blocksCopy, - get, - set, - adapter, - nonEmptyBlockCount - ); - } - // BlockStates - int bitsPerEntry = MathMan.log2nlz(num_palette - 1); - if (Settings.settings().PROTOCOL_SUPPORT_FIX || num_palette != 1) { - bitsPerEntry = Math.max(bitsPerEntry, 4); // Protocol support breaks <4 bits per entry - } else { - bitsPerEntry = Math.max(bitsPerEntry, 1); // For some reason minecraft needs 4096 bits to store 0 entries - } - if (bitsPerEntry > 8) { - bitsPerEntry = MathMan.log2nlz(Block.BLOCK_STATE_REGISTRY.size() - 1); - } - - final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry); - final int blockBitArrayEnd = MathMan.ceilZero((float) 4096 / blocksPerLong); - - if (num_palette == 1) { - for (int i = 0; i < blockBitArrayEnd; i++) { - blockStates[i] = 0; - } - } else { - final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, 4096, blockStates); - bitArray.fromRaw(blocksCopy); - } - - LevelChunkSection levelChunkSection = newChunkSection(layer); - // set palette & data bits - final PalettedContainer dataPaletteBlocks = - levelChunkSection.getStates(); - // private DataPalette h; - // protected DataBits a; - final long[] bits = Arrays.copyOfRange(blockStates, 0, blockBitArrayEnd); - final BitStorage nmsBits = new BitStorage(bitsPerEntry, 4096, bits); - final Palette blockStatePalettedContainer; - if (bitsPerEntry <= 4) { - blockStatePalettedContainer = new LinearPalette<>(Block.BLOCK_STATE_REGISTRY, bitsPerEntry, dataPaletteBlocks, - NbtUtils::readBlockState - ); - } else if (bitsPerEntry < 9) { - blockStatePalettedContainer = new HashMapPalette<>( - Block.BLOCK_STATE_REGISTRY, - bitsPerEntry, - dataPaletteBlocks, - NbtUtils::readBlockState, - NbtUtils::writeBlockState - ); - } else { - blockStatePalettedContainer = LevelChunkSection.GLOBAL_BLOCKSTATE_PALETTE; - } - - // set palette if required - if (bitsPerEntry < 9) { - for (int i = 0; i < num_palette; i++) { - final int ordinal = paletteToBlock[i]; - blockToPalette[ordinal] = Integer.MAX_VALUE; - final BlockState state = BlockTypesCache.states[ordinal]; - final net.minecraft.world.level.block.state.BlockState blockState = ((PaperweightBlockMaterial) state.getMaterial()).getState(); - blockStatePalettedContainer.idFor(blockState); - } - } - try { - fieldStorage.set(dataPaletteBlocks, nmsBits); - fieldPalette.set(dataPaletteBlocks, blockStatePalettedContainer); - fieldBits.set(dataPaletteBlocks, bitsPerEntry); - } catch (final IllegalAccessException e) { - throw new RuntimeException(e); - } - - if (!fastMode) { - levelChunkSection.recalcBlockCounts(); - } else { - try { - fieldNonEmptyBlockCount.set(levelChunkSection, nonEmptyBlockCount[0]); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - return levelChunkSection; - } catch (final Throwable e) { - throw e; - } finally { - Arrays.fill(blockToPalette, Integer.MAX_VALUE); - Arrays.fill(paletteToBlock, Integer.MAX_VALUE); - Arrays.fill(blockStates, 0); - Arrays.fill(blocksCopy, 0); - } - } - - private static LevelChunkSection newChunkSection(int layer) { - return new LevelChunkSection(layer); - } - - public static void clearCounts(final LevelChunkSection section) throws IllegalAccessException { - fieldTickingFluidContent.setShort(section, (short) 0); - fieldTickingBlockCount.setShort(section, (short) 0); - } - - public static Biome[] getBiomeArray(ChunkBiomeContainer chunkBiomeContainer) { - try { - return (Biome[]) fieldBiomes.get(chunkBiomeContainer); - } catch (IllegalAccessException e) { - e.printStackTrace(); - return null; - } - } - - public static BiomeType adapt(Biome biome, LevelAccessor levelAccessor) { - ResourceLocation resourceLocation = levelAccessor.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).getKey( - biome); - if (resourceLocation == null) { - return levelAccessor.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).getId(biome) == -1 - ? BiomeTypes.OCEAN - : null; - } - return BiomeTypes.get(resourceLocation.toString().toLowerCase(Locale.ROOT)); - } - - @SuppressWarnings("unchecked") - static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { - try { - // Do the method ourselves to avoid trying to reflect generic method parameters - if (levelChunk.loaded || levelChunk.level.isClientSide()) { - BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos()); - if (blockEntity != null) { - if (!levelChunk.level.isClientSide) { - Block block = beacon.getBlockState().getBlock(); - if (block instanceof EntityBlock) { - GameEventListener gameEventListener = ((EntityBlock) block).getListener(levelChunk.level, beacon); - if (gameEventListener != null) { - int i = SectionPos.blockToSectionCoord(beacon.getBlockPos().getY()); - GameEventDispatcher gameEventDispatcher = levelChunk.getEventDispatcher(i); - gameEventDispatcher.unregister(gameEventListener); - if (gameEventDispatcher.isEmpty()) { - try { - ((Int2ObjectMap) fieldGameEventDispatcherSections.get(levelChunk)) - .remove(i); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - } - } - } - fieldRemove.set(beacon, true); - } - } - methodremoveBlockEntityTicker.invoke(levelChunk, beacon.getBlockPos()); - } catch (Throwable throwable) { - throwable.printStackTrace(); - } - } - - static List getEntities(LevelChunk chunk) { - return chunk.level.entityManager.getEntities(chunk.getPos()); - } - - public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) { - boolean isVillager = entity instanceof AbstractVillager && !Fawe.isMainThread(); - boolean unset = false; - if (isVillager) { - try { - if (fieldOffers.get(entity) != null) { - fieldOffers.set(entity, OFFERS); - unset = true; - } - } catch (IllegalAccessException e) { - throw new RuntimeException("Failed to set offers field to villager to avoid async catcher.", e); - } - } - entity.save(compoundTag); - if (unset) { - try { - fieldOffers.set(entity, null); - } catch (IllegalAccessException e) { - throw new RuntimeException("Failed to set offers field to null again on villager.", e); - } - } - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPostProcessor.java deleted file mode 100644 index 0833c6ecb..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightPostProcessor.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2; - -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.ProcessorScope; -import com.fastasyncworldedit.core.queue.IBatchProcessor; -import com.fastasyncworldedit.core.queue.IChunk; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.fastasyncworldedit.core.registry.state.PropertyKey; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypes; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.Fluids; - -import javax.annotation.Nullable; - -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } - - @SuppressWarnings("deprecation") - @Override - public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final IChunkSet iChunkSet) { - boolean tickFluid = Settings.settings().EXPERIMENTAL.ALLOW_TICK_FLUIDS; - // The PostProcessor shouldn't be added, but just in case - if (!tickFluid) { - return; - } - PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; - layer: - for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); - if (set == null) { - // No edit means no need to process - continue; - } - char[] get = null; - for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; - boolean fromGet = false; // Used for liquids - if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { - if (get == null) { - get = getBlocks.load(layer); - } - // If this is null, then it's because we're loading a layer in the range of 0->15, but blocks aren't - // actually being set - if (get == null) { - continue layer; - } - fromGet = true; - ordinal = replacedOrdinal = get[i]; - } - if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { - continue; - } else if (!fromGet) { // if fromGet, don't do the same again - if (get == null) { - get = getBlocks.load(layer); - } - replacedOrdinal = get[i]; - } - boolean ticking = BlockTypesCache.ticking[ordinal]; - boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; - boolean replacedWasLiquid = false; - BlockState replacedState = null; - if (!ticking) { - // If the block being replaced was not ticking, it cannot be a liquid - if (!replacedWasTicking) { - continue; - } - // If the block being replaced is not fluid, we do not need to worry - if (!(replacedWasLiquid = - (replacedState = BlockState.getFromOrdinal(replacedOrdinal)).getMaterial().isLiquid())) { - continue; - } - } - BlockState state = BlockState.getFromOrdinal(ordinal); - boolean liquid = state.getMaterial().isLiquid(); - int x = i & 15; - int y = (i >> 8) & 15; - int z = (i >> 4) & 15; - BlockPos position = new BlockPos((chunk.getX() << 4) + x, (layer << 4) + y, (chunk.getZ() << 4) + z); - if (liquid || replacedWasLiquid) { - if (liquid) { - addFluid(getBlocks.serverLevel, state, position); - continue; - } - // If the replaced fluid (is?) adjacent to water. Do not bother to check adjacent chunks(sections) as this - // may be time consuming. Chances are any fluid blocks in adjacent chunks are being replaced or will end up - // being ticked anyway. We only need it to be "hit" once. - if (!wasAdjacentToWater(get, set, i, x, y, z)) { - continue; - } - addFluid(getBlocks.serverLevel, replacedState, position); - } - } - } - } - - @Nullable - @Override - public Extent construct(final Extent child) { - throw new UnsupportedOperationException("Processing only"); - } - - @Override - public ProcessorScope getScope() { - return ProcessorScope.READING_SET_BLOCKS; - } - - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - - @SuppressWarnings("deprecation") - private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { - Fluid type; - if (replacedState.getBlockType() == BlockTypes.LAVA) { - type = (int) replacedState.getState(PropertyKey.LEVEL) == 0 ? Fluids.LAVA : Fluids.FLOWING_LAVA; - } else { - type = (int) replacedState.getState(PropertyKey.LEVEL) == 0 ? Fluids.WATER : Fluids.FLOWING_WATER; - } - serverLevel.getLiquidTicks().scheduleTick( - position, - type, - type.getTickDelay(serverLevel) - ); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightStarlightRelighter.java deleted file mode 100644 index ea2afede3..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightStarlightRelighter.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2; - -import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter; -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import net.minecraft.server.MCUtil; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ThreadedLevelLightEngine; -import net.minecraft.server.level.TicketType; -import net.minecraft.util.Unit; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.chunk.ChunkStatus; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; -import java.util.function.IntConsumer; - -public class PaperweightStarlightRelighter extends StarlightRelighter { - - private static final MethodHandle RELIGHT; - private static final TicketType FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0); - private static final int LIGHT_LEVEL = MCUtil.getTicketLevelFor(ChunkStatus.LIGHT); - - static { - MethodHandle tmp = null; - try { - MethodHandles.Lookup lookup = MethodHandles.lookup(); - tmp = lookup.findVirtual( - ThreadedLevelLightEngine.class, - "relight", - MethodType.methodType( - int.class, // return type - // params - Set.class, - Consumer.class, - IntConsumer.class - ) - ); - tmp = MethodHandles.dropReturn(tmp); - } catch (NoSuchMethodException | IllegalAccessException e) { - LOGGER.error("Failed to locate 'relight' method in ThreadedLevelLightEngine. Is everything up to date?", e); - } - RELIGHT = tmp; - } - - public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent queue) { - super(serverLevel, queue); - } - - @Override - protected ChunkPos createChunkPos(final long chunkKey) { - return new ChunkPos(chunkKey); - } - - @Override - protected long asLong(final int chunkX, final int chunkZ) { - return ChunkPos.asLong(chunkX, chunkZ); - } - - @Override - protected CompletableFuture chunkLoadFuture(final ChunkPos chunkPos) { - return serverLevel.getWorld().getChunkAtAsync(chunkPos.x, chunkPos.z) - .thenAccept(c -> serverLevel.getChunkSource().addTicketAtLevel( - FAWE_TICKET, - chunkPos, - LIGHT_LEVEL, - Unit.INSTANCE - )); - } - - public static boolean isUsable() { - return RELIGHT != null; - } - - @Override - protected void invokeRelight( - Set coords, - Consumer chunkCallback, - IntConsumer processCallback - ) { - try { - RELIGHT.invokeExact( - serverLevel.getChunkSource().getLightEngine(), - coords, - chunkCallback, // callback per chunk - processCallback // callback for all chunks - ); - } catch (Throwable throwable) { - LOGGER.error("Error occurred on relighting", throwable); - } - } - - /* - * Allow the server to unload the chunks again. - * Also, if chunk packets are sent delayed, we need to do that here - */ - protected void postProcessChunks(Set coords) { - boolean delay = Settings.settings().LIGHTING.DELAY_PACKET_SENDING; - for (ChunkPos pos : coords) { - int x = pos.x; - int z = pos.z; - if (delay) { // we still need to send the block changes of that chunk - PaperweightPlatformAdapter.sendChunk(serverLevel, x, z, false); - } - serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE); - } - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightStarlightRelighterFactory.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightStarlightRelighterFactory.java deleted file mode 100644 index 9cd0a1ef8..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightStarlightRelighterFactory.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2; - -import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter; -import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode; -import com.fastasyncworldedit.core.extent.processor.lighting.Relighter; -import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import com.sk89q.worldedit.world.World; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; - -import javax.annotation.Nonnull; - -public class PaperweightStarlightRelighterFactory implements RelighterFactory { - - @Override - public @Nonnull Relighter createRelighter(RelightMode relightMode, World world, IQueueExtent queue) { - org.bukkit.World w = Bukkit.getWorld(world.getName()); - if (w == null) { - return NullRelighter.INSTANCE; - } - return new PaperweightStarlightRelighter(((CraftWorld) w).getHandle(), queue); - } - -} - diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/nbt/PaperweightLazyCompoundTag.java deleted file mode 100644 index 21bc0fe72..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/nbt/PaperweightLazyCompoundTag.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.nbt; - -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.LazyCompoundTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import net.minecraft.nbt.NumericTag; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; - -public class PaperweightLazyCompoundTag extends LazyCompoundTag { - - private final Supplier compoundTagSupplier; - private CompoundTag compoundTag; - - public PaperweightLazyCompoundTag(Supplier compoundTagSupplier) { - super(new HashMap<>()); - this.compoundTagSupplier = compoundTagSupplier; - } - - public PaperweightLazyCompoundTag(net.minecraft.nbt.CompoundTag compoundTag) { - this(() -> compoundTag); - } - - public net.minecraft.nbt.CompoundTag get() { - return compoundTagSupplier.get(); - } - - @Override - @SuppressWarnings("unchecked") - public Map getValue() { - if (compoundTag == null) { - compoundTag = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(compoundTagSupplier.get()); - } - return compoundTag.getValue(); - } - - @Override - public CompoundBinaryTag asBinaryTag() { - getValue(); - return compoundTag.asBinaryTag(); - } - - public boolean containsKey(String key) { - return compoundTagSupplier.get().contains(key); - } - - public byte[] getByteArray(String key) { - return compoundTagSupplier.get().getByteArray(key); - } - - public byte getByte(String key) { - return compoundTagSupplier.get().getByte(key); - } - - public double getDouble(String key) { - return compoundTagSupplier.get().getDouble(key); - } - - public double asDouble(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsDouble(); - } - return 0; - } - - public float getFloat(String key) { - return compoundTagSupplier.get().getFloat(key); - } - - public int[] getIntArray(String key) { - return compoundTagSupplier.get().getIntArray(key); - } - - public int getInt(String key) { - return compoundTagSupplier.get().getInt(key); - } - - public int asInt(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsInt(); - } - return 0; - } - - @SuppressWarnings("unchecked") - public List getList(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof net.minecraft.nbt.ListTag nbtList) { - ArrayList list = new ArrayList<>(); - for (net.minecraft.nbt.Tag elem : nbtList) { - if (elem instanceof net.minecraft.nbt.CompoundTag compoundTag) { - list.add(new PaperweightLazyCompoundTag(compoundTag)); - } else { - list.add(WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(elem)); - } - } - return list; - } - return Collections.emptyList(); - } - - @SuppressWarnings("unchecked") - public ListTag getListTag(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof net.minecraft.nbt.ListTag) { - return (ListTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(tag); - } - return new ListTag(StringTag.class, Collections.emptyList()); - } - - @SuppressWarnings("unchecked") - public List getList(String key, Class listType) { - ListTag listTag = getListTag(key); - if (listTag.getType().equals(listType)) { - return (List) listTag.getValue(); - } else { - return Collections.emptyList(); - } - } - - public long[] getLongArray(String key) { - return compoundTagSupplier.get().getLongArray(key); - } - - public long getLong(String key) { - return compoundTagSupplier.get().getLong(key); - } - - public long asLong(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsLong(); - } - return 0; - } - - public short getShort(String key) { - return compoundTagSupplier.get().getShort(key); - } - - public String getString(String key) { - return compoundTagSupplier.get().getString(key); - } - - @Override - public String toString() { - return compoundTagSupplier.get().toString(); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/regen/PaperweightRegen.java deleted file mode 100644 index 63d93156b..000000000 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/regen/PaperweightRegen.java +++ /dev/null @@ -1,694 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.regen; - -import com.fastasyncworldedit.bukkit.adapter.Regenerator; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.queue.IChunkCache; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.util.ReflectionUtils; -import com.fastasyncworldedit.core.util.TaskManager; -import com.google.common.collect.ImmutableList; -import com.mojang.datafixers.util.Either; -import com.mojang.serialization.Codec; -import com.mojang.serialization.Lifecycle; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.PaperweightGetBlocks; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.world.RegenOptions; -import io.papermc.lib.PaperLib; -import net.minecraft.core.MappedRegistry; -import net.minecraft.core.Registry; -import net.minecraft.data.BuiltinRegistries; -import net.minecraft.data.worldgen.biome.Biomes; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ThreadedLevelLightEngine; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.util.LinearCongruentialGenerator; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.LevelSettings; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.FixedBiomeSource; -import net.minecraft.world.level.biome.OverworldBiomeSource; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.ProtoChunk; -import net.minecraft.world.level.chunk.UpgradeData; -import net.minecraft.world.level.dimension.LevelStem; -import net.minecraft.world.level.levelgen.FlatLevelSource; -import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; -import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; -import net.minecraft.world.level.levelgen.SimpleRandomSource; -import net.minecraft.world.level.levelgen.WorldGenSettings; -import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import net.minecraft.world.level.levelgen.synth.ImprovedNoise; -import net.minecraft.world.level.newbiome.area.Area; -import net.minecraft.world.level.newbiome.area.AreaFactory; -import net.minecraft.world.level.newbiome.context.BigContext; -import net.minecraft.world.level.newbiome.layer.Layer; -import net.minecraft.world.level.newbiome.layer.Layers; -import net.minecraft.world.level.newbiome.layer.traits.PixelTransformer; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraft.world.level.storage.PrimaryLevelData; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_17_R1.CraftServer; -import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_17_R1.generator.CustomChunkGenerator; -import org.bukkit.generator.BiomeProvider; -import org.bukkit.generator.BlockPopulator; - -import javax.annotation.Nullable; -import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.nio.file.Path; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.OptionalLong; -import java.util.Random; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BooleanSupplier; -import java.util.function.LongFunction; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -public class PaperweightRegen extends Regenerator { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private static final Field worldsField; - private static final Field paperConfigField; - private static final Field generateFlatBedrockField; - private static final Field generatorSettingFlatField; - private static final Field generatorSettingBaseSupplierField; - private static final Field delegateField; - private static final Field chunkSourceField; - - //list of chunk stati in correct order without FULL - private static final Map chunkStati = new LinkedHashMap<>(); - - static { - chunkStati.put(ChunkStatus.EMPTY, Concurrency.FULL); // empty: radius -1, does nothing - chunkStati.put(ChunkStatus.STRUCTURE_STARTS, Concurrency.NONE); // structure starts: uses unsynchronized maps - chunkStati.put( - ChunkStatus.STRUCTURE_REFERENCES, - Concurrency.FULL - ); // structure refs: radius 8, but only writes to current chunk - chunkStati.put(ChunkStatus.BIOMES, Concurrency.FULL); // biomes: radius 0 - chunkStati.put(ChunkStatus.NOISE, Concurrency.RADIUS); // noise: radius 8 - chunkStati.put(ChunkStatus.SURFACE, Concurrency.NONE); // surface: radius 0, requires NONE - chunkStati.put(ChunkStatus.CARVERS, Concurrency.NONE); // carvers: radius 0, but RADIUS and FULL change results - chunkStati.put( - ChunkStatus.LIQUID_CARVERS, - Concurrency.NONE - ); // liquid carvers: radius 0, but RADIUS and FULL change results - chunkStati.put(ChunkStatus.FEATURES, Concurrency.NONE); // features: uses unsynchronized maps - chunkStati.put( - ChunkStatus.LIGHT, - Concurrency.FULL - ); // light: radius 1, but no writes to other chunks, only current chunk - chunkStati.put(ChunkStatus.SPAWN, Concurrency.FULL); // spawn: radius 0 - chunkStati.put(ChunkStatus.HEIGHTMAPS, Concurrency.FULL); // heightmaps: radius 0 - - try { - worldsField = CraftServer.class.getDeclaredField("worlds"); - worldsField.setAccessible(true); - - Field tmpPaperConfigField; - Field tmpFlatBedrockField; - try { //only present on paper - tmpPaperConfigField = Level.class.getDeclaredField("paperConfig"); - tmpPaperConfigField.setAccessible(true); - - tmpFlatBedrockField = tmpPaperConfigField.getType().getDeclaredField("generateFlatBedrock"); - tmpFlatBedrockField.setAccessible(true); - } catch (Exception e) { - tmpPaperConfigField = null; - tmpFlatBedrockField = null; - } - paperConfigField = tmpPaperConfigField; - generateFlatBedrockField = tmpFlatBedrockField; - - generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName( - "settings", "g")); - generatorSettingBaseSupplierField.setAccessible(true); - - generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "e")); - generatorSettingFlatField.setAccessible(true); - - delegateField = CustomChunkGenerator.class.getDeclaredField("delegate"); - delegateField.setAccessible(true); - - chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "C")); - chunkSourceField.setAccessible(true); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - //runtime - private ServerLevel originalServerWorld; - private ServerChunkCache originalChunkProvider; - private ServerLevel freshWorld; - private ServerChunkCache freshChunkProvider; - private LevelStorageSource.LevelStorageAccess session; - private StructureManager structureManager; - private ThreadedLevelLightEngine threadedLevelLightEngine; - private ChunkGenerator chunkGenerator; - - private Path tempDir; - - private boolean generateFlatBedrock = false; - - public PaperweightRegen(org.bukkit.World originalBukkitWorld, Region region, Extent target, RegenOptions options) { - super(originalBukkitWorld, region, target, options); - } - - @Override - protected boolean prepare() { - this.originalServerWorld = ((CraftWorld) originalBukkitWorld).getHandle(); - originalChunkProvider = originalServerWorld.getChunkSource(); - - //flat bedrock? (only on paper) - if (paperConfigField != null) { - try { - generateFlatBedrock = generateFlatBedrockField.getBoolean(paperConfigField.get(originalServerWorld)); - } catch (Exception ignored) { - } - } - - seed = options.getSeed().orElse(originalServerWorld.getSeed()); - chunkStati.forEach((s, c) -> super.chunkStatuses.put(new ChunkStatusWrap(s), c)); - - return true; - } - - @Override - protected boolean initNewWorld() throws Exception { - //world folder - tempDir = java.nio.file.Files.createTempDirectory("FastAsyncWorldEditWorldGen"); - - //prepare for world init (see upstream implementation for reference) - org.bukkit.World.Environment environment = originalBukkitWorld.getEnvironment(); - org.bukkit.generator.ChunkGenerator generator = originalBukkitWorld.getGenerator(); - LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(tempDir); - ResourceKey levelStemResourceKey = getWorldDimKey(environment); - session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey); - PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData; - - BiomeProvider biomeProvider = getBiomeProvider(); - - MinecraftServer server = originalServerWorld.getCraftServer().getServer(); - WorldGenSettings originalOpts = originalWorldData.worldGenSettings(); - WorldGenSettings newOpts = options.getSeed().isPresent() - ? originalOpts.withSeed(originalWorldData.isHardcore(), OptionalLong.of(seed)) - : originalOpts; - LevelSettings newWorldSettings = new LevelSettings( - "faweregentempworld", - originalWorldData.settings.gameType(), - originalWorldData.settings.hardcore(), - originalWorldData.settings.difficulty(), - originalWorldData.settings.allowCommands(), - originalWorldData.settings.gameRules(), - originalWorldData.settings.getDataPackConfig() - ); - PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, Lifecycle.stable()); - - //init world - freshWorld = Fawe.instance().getQueueHandler().sync((Supplier) () -> new ServerLevel( - server, - server.executor, - session, - newWorldData, - originalServerWorld.dimension(), - originalServerWorld.dimensionType(), - new RegenNoOpWorldLoadListener(), - // placeholder. Required for new ChunkProviderServer, but we create and then set it later - newOpts.dimensions().get(levelStemResourceKey).generator(), - originalServerWorld.isDebug(), - seed, - ImmutableList.of(), - false, - environment, - generator, - biomeProvider - ) { - private final Biome singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.get(ResourceLocation.tryParse( - options - .getBiomeType() - .getId())) : null; - - @Override - public void tick(BooleanSupplier shouldKeepTicking) { //no ticking - } - - @Override - public Biome getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) { - if (options.hasBiomeType()) { - return singleBiome; - } - return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome(biomeX, biomeY, biomeZ); - } - }).get(); - freshWorld.noSave = true; - removeWorldFromWorldsMap(); - newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name - if (paperConfigField != null) { - paperConfigField.set(freshWorld, originalServerWorld.paperConfig); - } - - //generator - if (originalChunkProvider.getGenerator() instanceof FlatLevelSource) { - FlatLevelGeneratorSettings generatorSettingFlat = (FlatLevelGeneratorSettings) generatorSettingFlatField.get( - originalChunkProvider.getGenerator()); - chunkGenerator = new FlatLevelSource(generatorSettingFlat); - } else if (originalChunkProvider.getGenerator() instanceof NoiseBasedChunkGenerator) { - Supplier generatorSettingBaseSupplier = (Supplier) generatorSettingBaseSupplierField - .get(originalChunkProvider.getGenerator()); - BiomeSource biomeSource; - if (options.hasBiomeType()) { - biomeSource = new FixedBiomeSource(BuiltinRegistries.BIOME.get(ResourceLocation.tryParse(options - .getBiomeType() - .getId()))); - } else { - biomeSource = originalChunkProvider.getGenerator().getBiomeSource(); - if (biomeSource instanceof OverworldBiomeSource) { - biomeSource = fastOverworldBiomeSource(biomeSource); - } - } - chunkGenerator = new NoiseBasedChunkGenerator(biomeSource, seed, generatorSettingBaseSupplier); - } else if (originalChunkProvider.getGenerator() instanceof CustomChunkGenerator) { - chunkGenerator = (ChunkGenerator) delegateField.get(originalChunkProvider.getGenerator()); - } else { - LOGGER.error("Unsupported generator type {}", originalChunkProvider.getGenerator().getClass().getName()); - return false; - } - if (generator != null) { - chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator); - generateConcurrent = generator.isParallelCapable(); - } - - freshChunkProvider = new ServerChunkCache( - freshWorld, - session, - server.getFixerUpper(), - server.getStructureManager(), - server.executor, - chunkGenerator, - freshWorld.spigotConfig.viewDistance, - server.forceSynchronousWrites(), - new RegenNoOpWorldLoadListener(), - (chunkCoordIntPair, state) -> { - }, - () -> server.overworld().getDataStorage() - ) { - // redirect to LevelChunks created in #createChunks - @Override - public ChunkAccess getChunk(int x, int z, ChunkStatus chunkstatus, boolean create) { - ChunkAccess chunkAccess = getChunkAt(x, z); - if (chunkAccess == null && create) { - chunkAccess = createChunk(getProtoChunkAt(x, z)); - } - return chunkAccess; - } - }; - - chunkSourceField.set(freshWorld, freshChunkProvider); - //let's start then - structureManager = server.getStructureManager(); - threadedLevelLightEngine = freshChunkProvider.getLightEngine(); - - return true; - } - - @Override - protected void cleanup() { - try { - session.close(); - } catch (Exception ignored) { - } - - //shutdown chunk provider - try { - Fawe.instance().getQueueHandler().sync(() -> { - try { - freshChunkProvider.close(false); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); - } catch (Exception ignored) { - } - - //remove world from server - try { - Fawe.instance().getQueueHandler().sync(this::removeWorldFromWorldsMap); - } catch (Exception ignored) { - } - - //delete directory - try { - SafeFiles.tryHardToDeleteDir(tempDir); - } catch (Exception ignored) { - } - } - - @Override - protected ProtoChunk createProtoChunk(int x, int z) { - return PaperLib.isPaper() - ? new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld, freshWorld) // paper - : new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld); // spigot - } - - @Override - protected LevelChunk createChunk(ProtoChunk protoChunk) { - return new LevelChunk( - freshWorld, - protoChunk, - null // we don't want to add entities - ); - } - - @Override - protected ChunkStatusWrap getFullChunkStatus() { - return new ChunkStatusWrap(ChunkStatus.FULL); - } - - @Override - protected List getBlockPopulators() { - return originalServerWorld.getWorld().getPopulators(); - } - - @Override - protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) { - // BlockPopulator#populate has to be called synchronously for TileEntity access - TaskManager.taskManager().task(() -> blockPopulator.populate(freshWorld.getWorld(), random, levelChunk.getBukkitChunk())); - } - - @Override - protected IChunkCache initSourceQueueCache() { - return (chunkX, chunkZ) -> new PaperweightGetBlocks(freshWorld, chunkX, chunkZ) { - @Override - public LevelChunk ensureLoaded(ServerLevel nmsWorld, int x, int z) { - return getChunkAt(x, z); - } - }; - } - - //util - @SuppressWarnings("unchecked") - private void removeWorldFromWorldsMap() { - Fawe.instance().getQueueHandler().sync(() -> { - try { - Map map = (Map) worldsField.get(Bukkit.getServer()); - map.remove("faweregentempworld"); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - }); - } - - private ResourceKey getWorldDimKey(org.bukkit.World.Environment env) { - return switch (env) { - case NETHER -> LevelStem.NETHER; - case THE_END -> LevelStem.END; - default -> LevelStem.OVERWORLD; - }; - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private BiomeSource fastOverworldBiomeSource(BiomeSource biomeSource) throws Exception { - Field legacyBiomeInitLayerField = OverworldBiomeSource.class.getDeclaredField( - Refraction.pickName("legacyBiomeInitLayer", "i")); - legacyBiomeInitLayerField.setAccessible(true); - Field largeBiomesField = OverworldBiomeSource.class.getDeclaredField(Refraction.pickName("largeBiomes", "j")); - largeBiomesField.setAccessible(true); - Field biomeRegistryField = OverworldBiomeSource.class.getDeclaredField(Refraction.pickName("biomes", "k")); - biomeRegistryField.setAccessible(true); - Field areaLazyField = Layer.class.getDeclaredField(Refraction.pickName("area", "b")); - areaLazyField.setAccessible(true); - Method initAreaFactoryMethod = Layers.class.getDeclaredMethod( - Refraction.pickName("getDefaultLayer", "a"), - boolean.class, - int.class, - int.class, - LongFunction.class - ); - initAreaFactoryMethod.setAccessible(true); - - //init new WorldChunkManagerOverworld - boolean legacyBiomeInitLayer = legacyBiomeInitLayerField.getBoolean(biomeSource); - boolean largebiomes = largeBiomesField.getBoolean(biomeSource); - Registry biomeRegistryMojang = (Registry) biomeRegistryField.get(biomeSource); - Registry biomeRegistry; - if (options.hasBiomeType()) { - Biome biome = BuiltinRegistries.BIOME.get(ResourceLocation.tryParse(options.getBiomeType().getId())); - biomeRegistry = new MappedRegistry<>( - ResourceKey.createRegistryKey(new ResourceLocation("fawe_biomes")), - Lifecycle.experimental() - ); - ((MappedRegistry) biomeRegistry).registerMapping(0, BuiltinRegistries.BIOME.getResourceKey(biome).get(), biome, - Lifecycle.experimental() - ); - } else { - biomeRegistry = biomeRegistryMojang; - } - - //replace genLayer - AreaFactory factory = (AreaFactory) initAreaFactoryMethod.invoke( - null, - legacyBiomeInitLayer, - largebiomes ? 6 : 4, - 4, - (LongFunction) (salt -> new FastWorldGenContextArea(seed, salt)) - ); - biomeSource = new FastOverworldBiomeSource(biomeRegistry, new FastGenLayer(factory)); - - return biomeSource; - } - - private static class FastOverworldBiomeSource extends BiomeSource { - - private final Registry biomeRegistry; - private final boolean isSingleRegistry; - private final FastGenLayer fastGenLayer; - - public FastOverworldBiomeSource( - Registry biomeRegistry, - FastGenLayer genLayer - ) { - super(biomeRegistry.stream().collect(Collectors.toList())); - this.biomeRegistry = biomeRegistry; - this.isSingleRegistry = biomeRegistry.entrySet().size() == 1; - this.fastGenLayer = genLayer; - } - - @Override - protected Codec codec() { - return OverworldBiomeSource.CODEC; - } - - @Override - public BiomeSource withSeed(final long seed) { - return null; - } - - @Override - public Biome getNoiseBiome(int biomeX, int biomeY, int biomeZ) { - if (this.isSingleRegistry) { - return this.biomeRegistry.byId(0); - } - return this.fastGenLayer.get(this.biomeRegistry, biomeX, biomeZ); - } - - } - - private static class FastWorldGenContextArea implements BigContext { - - private final ConcurrentHashMap sharedAreaMap = new ConcurrentHashMap<>(); - private final ImprovedNoise improvedNoise; - private final long magicrandom; - private final ConcurrentHashMap map = new ConcurrentHashMap<>(); //needed for multithreaded generation - - public FastWorldGenContextArea(long seed, long lconst) { - this.magicrandom = mix(seed, lconst); - this.improvedNoise = new ImprovedNoise(new SimpleRandomSource(seed)); - } - - private static long mix(long seed, long salt) { - long l = LinearCongruentialGenerator.next(salt, salt); - l = LinearCongruentialGenerator.next(l, salt); - l = LinearCongruentialGenerator.next(l, salt); - long m = LinearCongruentialGenerator.next(seed, l); - m = LinearCongruentialGenerator.next(m, l); - m = LinearCongruentialGenerator.next(m, l); - return m; - } - - @Override - public FastAreaLazy createResult(PixelTransformer pixelTransformer) { - return new FastAreaLazy(sharedAreaMap, pixelTransformer); - } - - @Override - public void initRandom(long x, long z) { - long l = this.magicrandom; - l = LinearCongruentialGenerator.next(l, x); - l = LinearCongruentialGenerator.next(l, z); - l = LinearCongruentialGenerator.next(l, x); - l = LinearCongruentialGenerator.next(l, z); - this.map.put(Thread.currentThread().getId(), l); - } - - @Override - public int nextRandom(int y) { - long tid = Thread.currentThread().getId(); - long e = this.map.computeIfAbsent(tid, i -> 0L); - int mod = (int) Math.floorMod(e >> 24L, (long) y); - this.map.put(tid, LinearCongruentialGenerator.next(e, this.magicrandom)); - return mod; - } - - @Override - public ImprovedNoise getBiomeNoise() { - return this.improvedNoise; - } - - } - - private static class FastGenLayer extends Layer { - - private final FastAreaLazy fastAreaLazy; - - public FastGenLayer(AreaFactory factory) { - super(() -> null); - this.fastAreaLazy = factory.make(); - } - - @Override - public Biome get(Registry registry, int x, int z) { - ResourceKey key = Biomes.byId(this.fastAreaLazy.get(x, z)); - if (key == null) { - return registry.get(Biomes.byId(0)); - } - Biome biome = registry.get(key); - if (biome == null) { - return registry.get(Biomes.byId(0)); - } - return biome; - } - - } - - private record FastAreaLazy(ConcurrentHashMap sharedMap, PixelTransformer transformer) implements Area { - - @Override - public int get(int x, int z) { - long zx = ChunkPos.asLong(x, z); - return this.sharedMap.computeIfAbsent(zx, i -> this.transformer.apply(x, z)); - } - - } - - private static class RegenNoOpWorldLoadListener implements ChunkProgressListener { - - private RegenNoOpWorldLoadListener() { - } - - @Override - public void updateSpawnPos(ChunkPos spawnPos) { - } - - @Override - public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) { - } - - @Override - public void start() { - - } - - @Override - public void stop() { - } - - // TODO Paper only(?) @Override - public void setChunkRadius(int radius) { - } - - } - - private class FastProtoChunk extends ProtoChunk { - - // avoid warning on paper - public FastProtoChunk(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor world, ServerLevel serverLevel) { - super(pos, upgradeData, world, serverLevel); - } - - // compatibility with spigot - public FastProtoChunk(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor levelHeightAccessor) { - super(pos, upgradeData, levelHeightAccessor); - } - - public boolean generateFlatBedrock() { - return generateFlatBedrock; - } - - // no one will ever see the entities! - @Override - public List getEntities() { - return Collections.emptyList(); - } - - } - - protected class ChunkStatusWrap extends ChunkStatusWrapper { - - private final ChunkStatus chunkStatus; - - public ChunkStatusWrap(ChunkStatus chunkStatus) { - this.chunkStatus = chunkStatus; - } - - @Override - public int requiredNeighborChunkRadius() { - return chunkStatus.getRange(); - } - - @Override - public String name() { - return chunkStatus.getName(); - } - - @Override - public CompletableFuture processChunk(List accessibleChunks) { - return chunkStatus.generate( - Runnable::run, // TODO revisit, we might profit from this somehow? - freshWorld, - chunkGenerator, - structureManager, - threadedLevelLightEngine, - c -> CompletableFuture.completedFuture(Either.left(c)), - accessibleChunks - ); - } - - } - -} diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index 1a922b7af..e02685954 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -210,7 +210,7 @@ tasks { versionNumber.set("${project.version}") versionType.set("release") uploadFile.set(file("build/libs/${rootProject.name}-Bukkit-${project.version}.jar")) - gameVersions.addAll(listOf("1.20.4", "1.20.3", "1.20.2", "1.20.1", "1.20", "1.19.4", "1.18.2", "1.17.1")) + gameVersions.addAll(listOf("1.20.4", "1.20.3", "1.20.2", "1.20.1", "1.20", "1.19.4", "1.18.2")) loaders.addAll(listOf("paper", "spigot")) changelog.set("The changelog is available on GitHub: https://github.com/IntellectualSites/" + "FastAsyncWorldEdit/releases/tag/${project.version}") diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java index d35ea9a28..3bf09481e 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java @@ -307,9 +307,6 @@ public class BukkitServerInterface extends AbstractPlatform implements MultiUser if (!tickFluid) { return null; } - if (Settings.settings().QUEUE.NO_TICK_FASTMODE && fastMode) { - return null; - } return this.plugin.getBukkitImplAdapter().getTickingPostProcessor(); } //FAWE end 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 009958270..89f48b697 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 @@ -511,7 +511,7 @@ public class Settings extends Config { " - A larger value will use slightly less CPU time", " - A smaller value will reduce memory usage", " - A value too small may break some operations (deform?)", - " - Values smaller than the configurated parallel-threads are not accepted", + " - Values smaller than the configured parallel-threads are not accepted", " - It is recommended this option be at least 4x greater than parallel-threads" }) @@ -544,12 +544,6 @@ public class Settings extends Config { }) public boolean POOL = true; - @Comment({ - "When using fastmode do not bother to tick existing/placed blocks/fluids", - "Only works in versions up to 1.17.1" - }) - public boolean NO_TICK_FASTMODE = true; - public static class PROGRESS { @Comment({"Display constant titles about the progress of a user's edit", From 2d0a3e6081967bb677afffbc03ba39f67745280d Mon Sep 17 00:00:00 2001 From: Jordan Date: Sun, 17 Mar 2024 13:15:28 +0100 Subject: [PATCH 041/220] fix: do not error when attempting to parse "|" as a pattern (#2625) --- .../extension/factory/parser/DefaultBlockParser.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java index 0e70a18a6..969216896 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java @@ -64,6 +64,7 @@ import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.entity.EntityTypes; import com.sk89q.worldedit.world.registry.LegacyMapper; +import javax.annotation.Nonnull; import java.util.Arrays; import java.util.HashMap; import java.util.Locale; @@ -337,9 +338,10 @@ public class DefaultBlockParser extends InputParser { return SuggestionHelper.getBlockPropertySuggestions(blockType, props); } + @Nonnull private BaseBlock parseLogic(String input, ParserContext context) throws InputParseException { //FAWE start - String[] blockAndExtraData = input.trim().split("\\|"); + String[] blockAndExtraData = input.trim().split("(?, Object> blockStates = new HashMap<>(); //FAWE end From 2d0ea9adf8832684d2bb7c73e42cc87dc9c03a7f Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Sun, 17 Mar 2024 13:16:10 +0100 Subject: [PATCH 042/220] Reword tree type message (#2628) Signed-off-by: Alexander Brandes --- .../main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index a9ba45afe..1598cb547 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -327,12 +327,12 @@ public class BukkitWorld extends AbstractWorld { treeTypeMapping.put(TreeGenerator.TreeType.RANDOM_MUSHROOM, TreeType.BROWN_MUSHROOM); for (TreeGenerator.TreeType type : TreeGenerator.TreeType.values()) { if (treeTypeMapping.get(type) == null) { - LOGGER.error("No TreeType mapping for TreeGenerator.TreeType." + type); //FAWE start + LOGGER.info("No TreeType mapping for TreeGenerator.TreeType." + type); LOGGER.info("The above message is displayed because your FAWE version is newer than {}" + " and contains features of future minecraft versions which do not exist in {} hence the tree type" + - "{} is not available. This is not an error. This version will work on your version of Minecraft." + - "This is an informative message only.", Bukkit.getVersion(), Bukkit.getVersion(), type); + " {} is not available. This is not an error. This version of FAWE will work on your version of " + + " Minecraft. This is an informative message only.", Bukkit.getVersion(), Bukkit.getVersion(), type); //FAWE end } } From dc61efe11ccf4c41a3bc0c791fea06780884019d Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Sun, 17 Mar 2024 13:17:00 +0100 Subject: [PATCH 043/220] Implement linear patterns using RandomPattern + SimpleRandom (#2630) --- .../parser/pattern/Linear2DPatternParser.java | 8 +-- .../parser/pattern/Linear3DPatternParser.java | 8 +-- .../pattern/Linear2DBlockPattern.java | 5 ++ .../pattern/Linear3DBlockPattern.java | 5 ++ .../core/math/random/Linear2DRandom.java | 50 ++++++++++++++++ .../core/math/random/Linear3DRandom.java | 58 +++++++++++++++++++ .../core/math/random/SimpleRandom.java | 18 +++++- .../collection/SimpleRandomCollection.java | 2 +- 8 files changed, 141 insertions(+), 13 deletions(-) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear2DRandom.java create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear3DRandom.java diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/Linear2DPatternParser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/Linear2DPatternParser.java index 5a310f60a..7da0b2377 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/Linear2DPatternParser.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/Linear2DPatternParser.java @@ -2,7 +2,7 @@ package com.fastasyncworldedit.core.extension.factory.parser.pattern; import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.extension.factory.parser.RichParser; -import com.fastasyncworldedit.core.function.pattern.Linear2DBlockPattern; +import com.fastasyncworldedit.core.math.random.Linear2DRandom; import com.google.common.base.Preconditions; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.command.util.SuggestionHelper; @@ -14,7 +14,6 @@ import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.world.block.BlockStateHolder; import javax.annotation.Nonnull; -import java.util.Set; import java.util.stream.Stream; public class Linear2DPatternParser extends RichParser { @@ -59,9 +58,8 @@ public class Linear2DPatternParser extends RichParser { zScale = Integer.parseInt(arguments[2]); Preconditions.checkArgument(zScale != 0); } - if (inner instanceof RandomPattern) { - Set patterns = ((RandomPattern) inner).getPatterns(); - return new Linear2DBlockPattern(patterns.toArray(new Pattern[0]), xScale, zScale); + if (inner instanceof RandomPattern rp) { + return new RandomPattern(new Linear2DRandom(xScale, zScale), rp); } throw new InputParseException(TextComponent.of("Pattern " + inner.getClass().getSimpleName() + " cannot be used with " + getPrefix())); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/Linear3DPatternParser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/Linear3DPatternParser.java index ef45e8faa..cd3a7d8db 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/Linear3DPatternParser.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/Linear3DPatternParser.java @@ -2,7 +2,7 @@ package com.fastasyncworldedit.core.extension.factory.parser.pattern; import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.extension.factory.parser.RichParser; -import com.fastasyncworldedit.core.function.pattern.Linear3DBlockPattern; +import com.fastasyncworldedit.core.math.random.Linear3DRandom; import com.google.common.base.Preconditions; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.command.util.SuggestionHelper; @@ -14,7 +14,6 @@ import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.world.block.BlockStateHolder; import javax.annotation.Nonnull; -import java.util.Set; import java.util.stream.Stream; public class Linear3DPatternParser extends RichParser { @@ -64,9 +63,8 @@ public class Linear3DPatternParser extends RichParser { zScale = Integer.parseInt(arguments[3]); Preconditions.checkArgument(zScale != 0); } - if (inner instanceof RandomPattern) { - Set patterns = ((RandomPattern) inner).getPatterns(); - return new Linear3DBlockPattern(patterns.toArray(new Pattern[0]), xScale, yScale, zScale); + if (inner instanceof RandomPattern rp) { + return new RandomPattern(new Linear3DRandom(xScale, yScale, zScale), rp); } throw new InputParseException(TextComponent.of("Pattern " + inner.getClass().getSimpleName() + " cannot be used with " + getPrefix())); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java index 7c923c4d4..523f22541 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java @@ -9,6 +9,11 @@ import com.sk89q.worldedit.world.block.BaseBlock; import static java.lang.Math.floorDiv; +/** + * @deprecated replaced by {@link com.sk89q.worldedit.function.pattern.RandomPattern} + * combined with {@link com.fastasyncworldedit.core.math.random.Linear2DRandom}. + */ +@Deprecated(forRemoval = true, since = "TODO") public class Linear2DBlockPattern extends AbstractPattern { private final Pattern[] patternsArray; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java index 04028244d..ea2e37588 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java @@ -9,6 +9,11 @@ import com.sk89q.worldedit.world.block.BaseBlock; import static java.lang.Math.floorDiv; +/** + * @deprecated replaced by {@link com.sk89q.worldedit.function.pattern.RandomPattern} + * combined with {@link com.fastasyncworldedit.core.math.random.Linear3DRandom}. + */ +@Deprecated(forRemoval = true, since = "TODO") public class Linear3DBlockPattern extends AbstractPattern { private final Pattern[] patternsArray; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear2DRandom.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear2DRandom.java new file mode 100644 index 000000000..4f039031e --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear2DRandom.java @@ -0,0 +1,50 @@ +package com.fastasyncworldedit.core.math.random; + +import static com.fastasyncworldedit.core.math.random.Linear3DRandom.doubleDiv; +import static java.lang.Math.floorDiv; + +/** + * A {@link SimpleRandom} that deterministically maps coordinates + * to values. + * @since TODO + */ +public class Linear2DRandom implements SimpleRandom { + private final int xScale; + private final int zScale; + + /** + * Creates a new {@link Linear2DRandom} instance + * + * @param xScale the scale applied to the x component of a coordinate + * @param zScale the scale applied to the z component of a coordinate + */ + public Linear2DRandom(final int xScale, final int zScale) { + this.xScale = xScale; + this.zScale = zScale; + } + + @Override + public double nextDouble(final int x, final int y, final int z) { + return nextDouble(x, y, z, 1d); + } + + @Override + public double nextDouble(final int x, final int y, final int z, double bound) { + double index = (doubleDiv(x, this.xScale) + doubleDiv(z, this.zScale)) % bound; + if (index < 0) { + index += bound; + } + return index; + + } + + @Override + public int nextInt(final int x, final int y, final int z, final int bound) { + int index = (floorDiv(x, this.xScale) + floorDiv(z, this.zScale)) % bound; + if (index < 0) { + index += bound; + } + return index; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear3DRandom.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear3DRandom.java new file mode 100644 index 000000000..87f350fe4 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear3DRandom.java @@ -0,0 +1,58 @@ +package com.fastasyncworldedit.core.math.random; + +import static java.lang.Math.floorDiv; + +/** + * A {@link SimpleRandom} that deterministically maps coordinates + * to values. + * @since TODO + */ +public class Linear3DRandom implements SimpleRandom { + + private final int xScale; + private final int yScale; + private final int zScale; + + /** + * Creates a new {@link Linear3DRandom} instance + * + * @param xScale the scale applied to the x component of a coordinate + * @param yScale the scale applied to the y component of a coordinate + * @param zScale the scale applied to the z component of a coordinate + */ + public Linear3DRandom(final int xScale, final int yScale, final int zScale) { + this.xScale = xScale; + this.yScale = yScale; + this.zScale = zScale; + } + + @Override + public double nextDouble(final int x, final int y, final int z) { + return nextDouble(x, y, z, 1d); + } + + @Override + public double nextDouble(final int x, final int y, final int z, double bound) { + double index = (doubleDiv(x, this.xScale) + doubleDiv(y, this.yScale) + doubleDiv(z, this.zScale)) % bound; + if (index < 0) { + index += bound; + } + return index; + } + + // used to avoid explicit conversion at call site + static double doubleDiv(double dividend, double divisor) { + // add a minimal value to avoid too many integral values hitting the exact weight of an entry in SimpleRandomCollection + return Math.nextUp(dividend) / divisor; + } + + @Override + public int nextInt(final int x, final int y, final int z, final int bound) { + int index = (floorDiv(x, this.xScale) + floorDiv(y, this.yScale) + floorDiv(z, this.zScale)) % bound; + if (index < 0) { + index += bound; + } + return index; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/SimpleRandom.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/SimpleRandom.java index e38214936..8b22b66a2 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/SimpleRandom.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/SimpleRandom.java @@ -13,6 +13,20 @@ public interface SimpleRandom { */ double nextDouble(int x, int y, int z); + /** + * Generate a random double from three integer components. + * The generated value is between 0 (inclusive) and {@code bound} (exclusive). + * + * @param x the first component + * @param y the second component + * @param z the third component + * @param bound upper bound (exclusive) + * @return a double between 0 (inclusive) and {@code bound} (exclusive) + */ + default double nextDouble(int x, int y, int z, double bound) { + return nextDouble(x, y, z) * bound; + } + /** * Generate a random integer from three integer components. * The generated value is between 0 (inclusive) and 1 (exclusive) @@ -24,8 +38,8 @@ public interface SimpleRandom { * @return a random integer between 0 (inclusive) and {@code bound} (exclusive) */ default int nextInt(int x, int y, int z, int bound) { - double val = nextDouble(x, y, z); - return (int) (val * bound); + double val = nextDouble(x, y, z, bound); + return (int) val; } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/SimpleRandomCollection.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/SimpleRandomCollection.java index dc2107559..5b7dca98f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/SimpleRandomCollection.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/SimpleRandomCollection.java @@ -36,7 +36,7 @@ public class SimpleRandomCollection extends RandomCollection { @Override public E next(int x, int y, int z) { - return map.ceilingEntry(getRandom().nextDouble(x, y, z) * this.total).getValue(); + return map.ceilingEntry(getRandom().nextDouble(x, y, z, this.total)).getValue(); } } From d2ca3ed6fe8ca58ca31a441a3ebecdc943f4431f Mon Sep 17 00:00:00 2001 From: Jordan Date: Sun, 17 Mar 2024 20:25:09 +0100 Subject: [PATCH 044/220] fix: better image reading errors (#2632) - closes #2593 --- .../core/command/tool/brush/HeightBrush.java | 2 +- .../core/util/MainUtil.java | 21 +++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/HeightBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/HeightBrush.java index fea4884f1..2c6ea5ec0 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/HeightBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/HeightBrush.java @@ -53,7 +53,7 @@ public class HeightBrush implements Brush { try { heightMap = ScalableHeightMap.fromPNG(stream); } catch (IOException e) { - throw new FaweException(Caption.of("fawe.worldedit.brush.brush.height.invalid")); + throw new FaweException(Caption.of("fawe.worldedit.brush.brush.height.invalid", e.getMessage())); } } else if (clipboard != null) { heightMap = ScalableHeightMap.fromClipboard(clipboard, minY, maxY); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java index 8122a840c..cbe9c6897 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java @@ -38,6 +38,8 @@ import org.apache.logging.log4j.Logger; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.imageio.ImageIO; +import javax.imageio.ImageReadParam; +import javax.imageio.ImageReader; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.BufferedOutputStream; @@ -70,6 +72,7 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; @@ -519,8 +522,22 @@ public class MainUtil { return destFile; } - public static BufferedImage readImage(InputStream in) throws IOException { - return MainUtil.toRGB(ImageIO.read(in)); + public static BufferedImage readImage(InputStream stream) throws IOException { + Iterator iter = ImageIO.getImageReaders(stream); + if (!iter.hasNext()) { + throw new IOException("Could not get image reader from stream."); + } + ImageReader reader = iter.next(); + ImageReadParam param = reader.getDefaultReadParam(); + reader.setInput(stream, true, true); + BufferedImage bi; + try { + bi = reader.read(0, param); + } finally { + reader.dispose(); + stream.close(); + } + return MainUtil.toRGB(bi); } public static BufferedImage readImage(URL url) throws IOException { From b93f01c5b30871ddf0a8ca6e26a8d525280bad9a Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Sun, 17 Mar 2024 20:25:29 +0100 Subject: [PATCH 045/220] Update paperweight 1.20.4 - isOpaque does not exist (anymore) (#2629) * chore/fix: update paperweight 1.20.4 - isOpaque does not exist (anymore) * chore: update paperweight yet again (i feel scammed) * chore: missing invert of canOcclude in isTranslucent --- .../adapters/adapter-1_20_4/build.gradle.kts | 2 +- .../v1_20_R3/PaperweightBlockMaterial.java | 22 +++++-------------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 02f5a3c53..f18ef582f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240106.182028-62") + the().paperDevBundle("1.20.4-R0.1-20240316.193646-135") compileOnly(libs.paperlib) } diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightBlockMaterial.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightBlockMaterial.java index edbe268fe..74b1c035c 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightBlockMaterial.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightBlockMaterial.java @@ -2,18 +2,15 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R3; import com.google.common.base.Suppliers; import com.sk89q.jnbt.CompoundTag; -import com.sk89q.util.ReflectionUtil; -import com.sk89q.worldedit.bukkit.adapter.Refraction; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R3.nbt.PaperweightLazyCompoundTag; import com.sk89q.worldedit.world.registry.BlockMaterial; import net.minecraft.core.BlockPos; import net.minecraft.world.level.EmptyBlockGetter; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.LiquidBlock; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluids; import net.minecraft.world.level.material.PushReaction; import org.bukkit.craftbukkit.v1_20_R3.block.data.CraftBlockData; @@ -21,7 +18,6 @@ public class PaperweightBlockMaterial implements BlockMaterial { private final Block block; private final BlockState blockState; - private final boolean isTranslucent; private final CraftBlockData craftBlockData; private final org.bukkit.Material craftMaterial; private final int opacity; @@ -36,11 +32,6 @@ public class PaperweightBlockMaterial implements BlockMaterial { this.blockState = blockState; this.craftBlockData = CraftBlockData.fromData(blockState); this.craftMaterial = craftBlockData.getMaterial(); - BlockBehaviour.Properties blockInfo = ReflectionUtil.getField(BlockBehaviour.class, block, - Refraction.pickName("properties", "aP")); - this.isTranslucent = !(boolean) ReflectionUtil.getField(BlockBehaviour.Properties.class, blockInfo, - Refraction.pickName("canOcclude", "n") - ); opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity( BlockPos.ZERO, @@ -75,7 +66,7 @@ public class PaperweightBlockMaterial implements BlockMaterial { @Override public boolean isOpaque() { - return blockState.isOpaque(); + return blockState.canOcclude(); } @Override @@ -85,14 +76,13 @@ public class PaperweightBlockMaterial implements BlockMaterial { @Override public boolean isLiquid() { - // TODO: Better check ? - return block instanceof LiquidBlock; + return !blockState.getFluidState().is(Fluids.EMPTY); } @Override public boolean isSolid() { - // TODO: Replace - return blockState.isSolid(); + // No access to world -> EmptyBlockGetter + return blockState.isSolidRender(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); } @Override @@ -158,7 +148,7 @@ public class PaperweightBlockMaterial implements BlockMaterial { @Override public boolean isTranslucent() { - return isTranslucent; + return !blockState.canOcclude(); } @Override From b512182e1f6e417501236abab56d6b39a6080229 Mon Sep 17 00:00:00 2001 From: Jordan Date: Sun, 17 Mar 2024 20:25:43 +0100 Subject: [PATCH 046/220] feat: save region selector to session store (#2621) * feat: save region selector to session store - closes #2397 * Move new gson adapters to FAWE packages --- .../core}/util/gson/ItemTypeAdapter.java | 2 +- .../core/util/gson/RegionSelectorAdapter.java | 33 +++++++++++++++++ .../com/sk89q/worldedit/LocalSession.java | 5 ++- .../worldedit/command/SelectionCommands.java | 8 +---- .../regions/selector/RegionSelectorType.java | 35 ++++++++++++++++++- .../sk89q/worldedit/util/gson/GsonUtil.java | 7 +++- 6 files changed, 79 insertions(+), 11 deletions(-) rename worldedit-core/src/main/java/com/{sk89q/worldedit => fastasyncworldedit/core}/util/gson/ItemTypeAdapter.java (94%) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/RegionSelectorAdapter.java diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/ItemTypeAdapter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/ItemTypeAdapter.java similarity index 94% rename from worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/ItemTypeAdapter.java rename to worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/ItemTypeAdapter.java index 5f8d6d9a2..fe684fb8c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/ItemTypeAdapter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/ItemTypeAdapter.java @@ -1,4 +1,4 @@ -package com.sk89q.worldedit.util.gson; +package com.fastasyncworldedit.core.util.gson; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/RegionSelectorAdapter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/RegionSelectorAdapter.java new file mode 100644 index 000000000..d817185ee --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/RegionSelectorAdapter.java @@ -0,0 +1,33 @@ +package com.fastasyncworldedit.core.util.gson; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.sk89q.worldedit.regions.RegionSelector; +import com.sk89q.worldedit.regions.selector.RegionSelectorType; + +import java.lang.reflect.Type; + +public class RegionSelectorAdapter implements JsonDeserializer, JsonSerializer { + + @Override + public RegionSelector deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { + RegionSelectorType regionType = RegionSelectorType.valueOf(json.getAsString()); + return regionType.createSelector(); + } + + @Override + public JsonElement serialize(RegionSelector selector, Type type, JsonSerializationContext context) { + RegionSelectorType regionType = RegionSelectorType.getForSelector(selector); + // Cannot nicely deserialize Fuzzy region type + if (regionType == null || regionType == RegionSelectorType.FUZZY) { + return null; + } + return new JsonPrimitive(regionType.toString()); + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index a00b26702..5a5fa654e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -125,7 +125,9 @@ public class LocalSession implements TextureHolder { private transient int cuiVersion = CUI_VERSION_UNINITIALIZED; // Session related - private transient RegionSelector selector = new CuboidRegionSelector(); + //FAWE start - allow saving to session store + private RegionSelector selector = new CuboidRegionSelector(); + //FAWE end private transient boolean placeAtPos1 = false; //FAWE start private final transient List history = Collections.synchronizedList(new LinkedList<>() { @@ -771,6 +773,7 @@ public class LocalSession implements TextureHolder { checkNotNull(selector); selector.setWorld(world); this.selector = selector; + setDirty(); if (hasWorldOverride() && !world.equals(getWorldOverride())) { setWorldOverride(null); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index 64e3c8a81..a643742d2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -755,13 +755,7 @@ public class SelectionCommands { } if (setDefaultSelector) { - RegionSelectorType found = null; - for (RegionSelectorType type : RegionSelectorType.values()) { - if (type.getSelectorClass() == newSelector.getClass()) { - found = type; - break; - } - } + RegionSelectorType found = RegionSelectorType.getForSelector(newSelector); if (found != null) { session.setDefaultRegionSelector(found); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/RegionSelectorType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/RegionSelectorType.java index 61e46aeab..5c8655893 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/RegionSelectorType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/RegionSelectorType.java @@ -19,8 +19,14 @@ package com.sk89q.worldedit.regions.selector; +import com.fastasyncworldedit.core.regions.selector.FuzzyRegionSelector; +import com.fastasyncworldedit.core.regions.selector.PolyhedralRegionSelector; import com.sk89q.worldedit.regions.RegionSelector; +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; + /** * An enum of default region selector types. */ @@ -32,7 +38,21 @@ public enum RegionSelectorType { SPHERE(SphereRegionSelector.class), ELLIPSOID(EllipsoidRegionSelector.class), POLYGON(Polygonal2DRegionSelector.class), - CONVEX_POLYHEDRON(ConvexPolyhedralRegionSelector.class); + CONVEX_POLYHEDRON(ConvexPolyhedralRegionSelector.class), + //FAWE start + POLYHEDRAL(PolyhedralRegionSelector.class), + FUZZY(FuzzyRegionSelector.class); + //FAWE end + + //FAWE start + private static final Map, RegionSelectorType> VALUE_MAP = new HashMap<>(); + + static { + for (RegionSelectorType type : values()) { + VALUE_MAP.put(type.getSelectorClass(), type); + } + } + //FAWE end private final Class selectorClass; @@ -40,6 +60,19 @@ public enum RegionSelectorType { this.selectorClass = selectorClass; } + //FAWE start + /** + * Get a {@link RegionSelectorType} for the given {@link RegionSelector} + * + * @param selector Region selector to get type enum for + * @since TODO + */ + @Nullable + public static RegionSelectorType getForSelector(RegionSelector selector) { + return VALUE_MAP.get(selector.getClass()); + } + //FAWE end + /** * Get the selector class. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java index d31750e11..e5d05ee6d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java @@ -19,12 +19,14 @@ package com.sk89q.worldedit.util.gson; +import com.fastasyncworldedit.core.util.gson.ItemTypeAdapter; +import com.fastasyncworldedit.core.util.gson.RegionSelectorAdapter; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; +import com.sk89q.worldedit.regions.RegionSelector; import com.sk89q.worldedit.world.item.ItemType; -import com.sk89q.worldedit.world.item.ItemTypes; /** * Utility methods for Google's GSON library. @@ -43,7 +45,10 @@ public final class GsonUtil { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(Vector3.class, new VectorAdapter()); gsonBuilder.registerTypeAdapter(BlockVector3.class, new BlockVectorAdapter()); + //FAWE start + gsonBuilder.registerTypeAdapter(RegionSelector.class, new RegionSelectorAdapter()); gsonBuilder.registerTypeAdapter(ItemType.class, new ItemTypeAdapter()); + //FAWE end return gsonBuilder; } From 38242068f043f190b491b84f10b2008cc2fd3a73 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 22:18:17 +0000 Subject: [PATCH 047/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.1.21 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a6acb6c2e..1b9bef60e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.1.20" +towny = "0.100.1.21" plotsquared = "7.3.6" # Third party From 36da507cf7972a83a45b0fb46de4ceed470e39a3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Mar 2024 19:22:41 +0000 Subject: [PATCH 048/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240319.191757-136 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index f18ef582f..d1250a94f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240316.193646-135") + the().paperDevBundle("1.20.4-R0.1-20240319.191757-136") compileOnly(libs.paperlib) } From 63d5852b6c73c2851d40a0135bcf897e1c6e999c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 20:46:11 +0000 Subject: [PATCH 049/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240320.194253-137 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index d1250a94f..bc85e188f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240319.191757-136") + the().paperDevBundle("1.20.4-R0.1-20240320.194253-137") compileOnly(libs.paperlib) } From 68eb24a2f92a084c8a368b8d9bef725248d5f017 Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Wed, 20 Mar 2024 23:39:36 +0100 Subject: [PATCH 050/220] fix: imgur image resolution, image input stream reading (#2637) --- .../core/util/MainUtil.java | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java index cbe9c6897..41c4e5704 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java @@ -40,6 +40,7 @@ import javax.annotation.Nullable; import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.BufferedOutputStream; @@ -58,6 +59,9 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; @@ -94,6 +98,10 @@ import static java.lang.System.arraycopy; public class MainUtil { private static final Logger LOGGER = LogManagerCompat.getLogger(); + private static final String CURL_USER_AGENT = "curl/8.1.1"; + private static final HttpClient HTTP_CLIENT = HttpClient.newBuilder() + .followRedirects(HttpClient.Redirect.NORMAL) + .build(); public static List filter(String prefix, List suggestions) { if (prefix.isEmpty()) { @@ -523,25 +531,52 @@ public class MainUtil { } public static BufferedImage readImage(InputStream stream) throws IOException { - Iterator iter = ImageIO.getImageReaders(stream); + final ImageInputStream imageStream = ImageIO.createImageInputStream(stream); + if (imageStream == null) { + throw new IOException("Can't find suitable ImageInputStream"); + } + Iterator iter = ImageIO.getImageReaders(imageStream); if (!iter.hasNext()) { throw new IOException("Could not get image reader from stream."); } ImageReader reader = iter.next(); ImageReadParam param = reader.getDefaultReadParam(); - reader.setInput(stream, true, true); + reader.setInput(imageStream, true, true); BufferedImage bi; try { bi = reader.read(0, param); } finally { reader.dispose(); stream.close(); + imageStream.close(); } return MainUtil.toRGB(bi); } public static BufferedImage readImage(URL url) throws IOException { - return readImage(url.openStream()); + try { + final URI uri = url.toURI(); + HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(uri).GET(); + + if (uri.getHost().equalsIgnoreCase("i.imgur.com")) { + requestBuilder = requestBuilder.setHeader("User-Agent", CURL_USER_AGENT); + } + + final HttpResponse response = HTTP_CLIENT.send( + requestBuilder.build(), + HttpResponse.BodyHandlers.ofInputStream() + ); + try (final InputStream body = response.body()) { + if (response.statusCode() > 299) { + throw new IOException("Expected 2xx as response code, but received " + response.statusCode()); + } + return readImage(body); + } + } catch (InterruptedException e) { + throw new IOException("request was interrupted", e); + } catch (URISyntaxException e) { + throw new IOException("failed to parse url to uri reference", e); + } } public static BufferedImage readImage(File file) throws IOException { From 07011e242063317bad97ee197afeee66ef0cb380 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 22:40:52 +0000 Subject: [PATCH 051/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240320.215354-140 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index bc85e188f..b225a6875 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240320.194253-137") + the().paperDevBundle("1.20.4-R0.1-20240320.215354-140") compileOnly(libs.paperlib) } From a957af38c09fb8756202bf8bf978bd66f8d71b7f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Mar 2024 22:40:43 +0000 Subject: [PATCH 052/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.1.22 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1b9bef60e..dd3e3d38e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.1.21" +towny = "0.100.1.22" plotsquared = "7.3.6" # Third party From 4b91f6410f519103dec01b6603404fbd6ffee4f8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Mar 2024 17:29:04 +0000 Subject: [PATCH 053/220] Update dependency gradle to v8.7 --- gradle/wrapper/gradle-wrapper.jar | Bin 43462 -> 43453 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd4917707c1f8861d8cb53dd15194d4248596..e6441136f3d4ba8a0da8d277868979cfbc8ad796 100644 GIT binary patch delta 34118 zcmY(qRX`kF)3u#IAjsf0xCD212@LM;?(PINyAue(f;$XO2=4Cg1P$=#e%|lo zKk1`B>Q#GH)wNd-&cJofz}3=WfYndTeo)CyX{fOHsQjGa<{e=jamMNwjdatD={CN3>GNchOE9OGPIqr)3v>RcKWR3Z zF-guIMjE2UF0Wqk1)21791y#}ciBI*bAenY*BMW_)AeSuM5}vz_~`+1i!Lo?XAEq{TlK5-efNFgHr6o zD>^vB&%3ZGEWMS>`?tu!@66|uiDvS5`?bF=gIq3rkK(j<_TybyoaDHg8;Y#`;>tXI z=tXo~e9{U!*hqTe#nZjW4z0mP8A9UUv1}C#R*@yu9G3k;`Me0-BA2&Aw6f`{Ozan2 z8c8Cs#dA-7V)ZwcGKH}jW!Ja&VaUc@mu5a@CObzNot?b{f+~+212lwF;!QKI16FDS zodx>XN$sk9;t;)maB^s6sr^L32EbMV(uvW%or=|0@U6cUkE`_!<=LHLlRGJx@gQI=B(nn z-GEjDE}*8>3U$n(t^(b^C$qSTI;}6q&ypp?-2rGpqg7b}pyT zOARu2x>0HB{&D(d3sp`+}ka+Pca5glh|c=M)Ujn_$ly^X6&u z%Q4Y*LtB_>i6(YR!?{Os-(^J`(70lZ&Hp1I^?t@~SFL1!m0x6j|NM!-JTDk)%Q^R< z@e?23FD&9_W{Bgtr&CG&*Oer3Z(Bu2EbV3T9FeQ|-vo5pwzwQ%g&=zFS7b{n6T2ZQ z*!H(=z<{D9@c`KmHO&DbUIzpg`+r5207}4D=_P$ONIc5lsFgn)UB-oUE#{r+|uHc^hzv_df zV`n8&qry%jXQ33}Bjqcim~BY1?KZ}x453Oh7G@fA(}+m(f$)TY%7n=MeLi{jJ7LMB zt(mE*vFnep?YpkT_&WPV9*f>uSi#n#@STJmV&SLZnlLsWYI@y+Bs=gzcqche=&cBH2WL)dkR!a95*Ri)JH_4c*- zl4pPLl^as5_y&6RDE@@7342DNyF&GLJez#eMJjI}#pZN{Y8io{l*D+|f_Y&RQPia@ zNDL;SBERA|B#cjlNC@VU{2csOvB8$HzU$01Q?y)KEfos>W46VMh>P~oQC8k=26-Ku)@C|n^zDP!hO}Y z_tF}0@*Ds!JMt>?4y|l3?`v#5*oV-=vL7}zehMON^=s1%q+n=^^Z{^mTs7}*->#YL z)x-~SWE{e?YCarwU$=cS>VzmUh?Q&7?#Xrcce+jeZ|%0!l|H_=D_`77hBfd4Zqk&! zq-Dnt_?5*$Wsw8zGd@?woEtfYZ2|9L8b>TO6>oMh%`B7iBb)-aCefM~q|S2Cc0t9T zlu-ZXmM0wd$!gd-dTtik{bqyx32%f;`XUvbUWWJmpHfk8^PQIEsByJm+@+-aj4J#D z4#Br3pO6z1eIC>X^yKk|PeVwX_4B+IYJyJyc3B`4 zPrM#raacGIzVOexcVB;fcsxS=s1e&V;Xe$tw&KQ`YaCkHTKe*Al#velxV{3wxx}`7@isG zp6{+s)CG%HF#JBAQ_jM%zCX5X;J%-*%&jVI?6KpYyzGbq7qf;&hFprh?E5Wyo=bZ) z8YNycvMNGp1836!-?nihm6jI`^C`EeGryoNZO1AFTQhzFJOA%Q{X(sMYlzABt!&f{ zoDENSuoJQIg5Q#@BUsNJX2h>jkdx4<+ipUymWKFr;w+s>$laIIkfP6nU}r+?J9bZg zUIxz>RX$kX=C4m(zh-Eg$BsJ4OL&_J38PbHW&7JmR27%efAkqqdvf)Am)VF$+U3WR z-E#I9H6^)zHLKCs7|Zs<7Bo9VCS3@CDQ;{UTczoEprCKL3ZZW!ffmZFkcWU-V|_M2 zUA9~8tE9<5`59W-UgUmDFp11YlORl3mS3*2#ZHjv{*-1#uMV_oVTy{PY(}AqZv#wF zJVks)%N6LaHF$$<6p8S8Lqn+5&t}DmLKiC~lE{jPZ39oj{wR&fe*LX-z0m}9ZnZ{U z>3-5Bh{KKN^n5i!M79Aw5eY=`6fG#aW1_ZG;fw7JM69qk^*(rmO{|Z6rXy?l=K=#_ zE-zd*P|(sskasO(cZ5L~_{Mz&Y@@@Q)5_8l<6vB$@226O+pDvkFaK8b>%2 zfMtgJ@+cN@w>3)(_uR;s8$sGONbYvoEZ3-)zZk4!`tNzd<0lwt{RAgplo*f@Z)uO` zzd`ljSqKfHJOLxya4_}T`k5Ok1Mpo#MSqf~&ia3uIy{zyuaF}pV6 z)@$ZG5LYh8Gge*LqM_|GiT1*J*uKes=Oku_gMj&;FS`*sfpM+ygN&yOla-^WtIU#$ zuw(_-?DS?6DY7IbON7J)p^IM?N>7x^3)(7wR4PZJu(teex%l>zKAUSNL@~{czc}bR z)I{XzXqZBU3a;7UQ~PvAx8g-3q-9AEd}1JrlfS8NdPc+!=HJ6Bs( zCG!0;e0z-22(Uzw>hkEmC&xj?{0p|kc zM}MMXCF%RLLa#5jG`+}{pDL3M&|%3BlwOi?dq!)KUdv5__zR>u^o|QkYiqr(m3HxF z6J*DyN#Jpooc$ok=b7{UAVM@nwGsr6kozSddwulf5g1{B=0#2)zv!zLXQup^BZ4sv*sEsn)+MA?t zEL)}3*R?4(J~CpeSJPM!oZ~8;8s_=@6o`IA%{aEA9!GELRvOuncE`s7sH91 zmF=+T!Q6%){?lJn3`5}oW31(^Of|$r%`~gT{eimT7R~*Mg@x+tWM3KE>=Q>nkMG$U za7r>Yz2LEaA|PsMafvJ(Y>Xzha?=>#B!sYfVob4k5Orb$INFdL@U0(J8Hj&kgWUlO zPm+R07E+oq^4f4#HvEPANGWLL_!uF{nkHYE&BCH%l1FL_r(Nj@M)*VOD5S42Gk-yT z^23oAMvpA57H(fkDGMx86Z}rtQhR^L!T2iS!788E z+^${W1V}J_NwdwdxpXAW8}#6o1(Uu|vhJvubFvQIH1bDl4J4iDJ+181KuDuHwvM?` z%1@Tnq+7>p{O&p=@QT}4wT;HCb@i)&7int<0#bj8j0sfN3s6|a(l7Bj#7$hxX@~iP z1HF8RFH}irky&eCN4T94VyKqGywEGY{Gt0Xl-`|dOU&{Q;Ao;sL>C6N zXx1y^RZSaL-pG|JN;j9ADjo^XR}gce#seM4QB1?S`L*aB&QlbBIRegMnTkTCks7JU z<0(b+^Q?HN1&$M1l&I@>HMS;!&bb()a}hhJzsmB?I`poqTrSoO>m_JE5U4=?o;OV6 zBZjt;*%1P>%2{UL=;a4(aI>PRk|mr&F^=v6Fr&xMj8fRCXE5Z2qdre&;$_RNid5!S zm^XiLK25G6_j4dWkFqjtU7#s;b8h?BYFxV?OE?c~&ME`n`$ix_`mb^AWr+{M9{^^Rl;~KREplwy2q;&xe zUR0SjHzKVYzuqQ84w$NKVPGVHL_4I)Uw<$uL2-Ml#+5r2X{LLqc*p13{;w#E*Kwb*1D|v?e;(<>vl@VjnFB^^Y;;b3 z=R@(uRj6D}-h6CCOxAdqn~_SG=bN%^9(Ac?zfRkO5x2VM0+@_qk?MDXvf=@q_* z3IM@)er6-OXyE1Z4sU3{8$Y$>8NcnU-nkyWD&2ZaqX1JF_JYL8y}>@V8A5%lX#U3E zet5PJM`z79q9u5v(OE~{by|Jzlw2<0h`hKpOefhw=fgLTY9M8h+?37k@TWpzAb2Fc zQMf^aVf!yXlK?@5d-re}!fuAWu0t57ZKSSacwRGJ$0uC}ZgxCTw>cjRk*xCt%w&hh zoeiIgdz__&u~8s|_TZsGvJ7sjvBW<(C@}Y%#l_ID2&C`0;Eg2Z+pk;IK}4T@W6X5H z`s?ayU-iF+aNr5--T-^~K~p;}D(*GWOAYDV9JEw!w8ZYzS3;W6*_`#aZw&9J ziXhBKU3~zd$kKzCAP-=t&cFDeQR*_e*(excIUxKuD@;-twSlP6>wWQU)$|H3Cy+`= z-#7OW!ZlYzZxkdQpfqVDFU3V2B_-eJS)Fi{fLtRz!K{~7TR~XilNCu=Z;{GIf9KYz zf3h=Jo+1#_s>z$lc~e)l93h&RqW1VHYN;Yjwg#Qi0yzjN^M4cuL>Ew`_-_wRhi*!f zLK6vTpgo^Bz?8AsU%#n}^EGigkG3FXen3M;hm#C38P@Zs4{!QZPAU=m7ZV&xKI_HWNt90Ef zxClm)ZY?S|n**2cNYy-xBlLAVZ=~+!|7y`(fh+M$#4zl&T^gV8ZaG(RBD!`3?9xcK zp2+aD(T%QIgrLx5au&TjG1AazI;`8m{K7^!@m>uGCSR;Ut{&?t%3AsF{>0Cm(Kf)2 z?4?|J+!BUg*P~C{?mwPQ#)gDMmro20YVNsVx5oWQMkzQ? zsQ%Y>%7_wkJqnSMuZjB9lBM(o zWut|B7w48cn}4buUBbdPBW_J@H7g=szrKEpb|aE>!4rLm+sO9K%iI75y~2HkUo^iw zJ3se$8$|W>3}?JU@3h@M^HEFNmvCp|+$-0M?RQ8SMoZ@38%!tz8f8-Ptb@106heiJ z^Bx!`0=Im z1!NUhO=9ICM*+||b3a7w*Y#5*Q}K^ar+oMMtekF0JnO>hzHqZKH0&PZ^^M(j;vwf_ z@^|VMBpcw8;4E-9J{(u7sHSyZpQbS&N{VQ%ZCh{c1UA5;?R} z+52*X_tkDQ(s~#-6`z4|Y}3N#a&dgP4S_^tsV=oZr4A1 zaSoPN1czE(UIBrC_r$0HM?RyBGe#lTBL4~JW#A`P^#0wuK)C-2$B6TvMi@@%K@JAT_IB^T7Zfqc8?{wHcSVG_?{(wUG%zhCm=%qP~EqeqKI$9UivF zv+5IUOs|%@ypo6b+i=xsZ=^G1yeWe)z6IX-EC`F=(|_GCNbHbNp(CZ*lpSu5n`FRA zhnrc4w+Vh?r>her@Ba_jv0Omp#-H7avZb=j_A~B%V0&FNi#!S8cwn0(Gg-Gi_LMI{ zCg=g@m{W@u?GQ|yp^yENd;M=W2s-k7Gw2Z(tsD5fTGF{iZ%Ccgjy6O!AB4x z%&=6jB7^}pyftW2YQpOY1w@%wZy%}-l0qJlOSKZXnN2wo3|hujU+-U~blRF!^;Tan z0w;Srh0|Q~6*tXf!5-rCD)OYE(%S|^WTpa1KHtpHZ{!;KdcM^#g8Z^+LkbiBHt85m z;2xv#83lWB(kplfgqv@ZNDcHizwi4-8+WHA$U-HBNqsZ`hKcUI3zV3d1ngJP-AMRET*A{> zb2A>Fk|L|WYV;Eu4>{a6ESi2r3aZL7x}eRc?cf|~bP)6b7%BnsR{Sa>K^0obn?yiJ zCVvaZ&;d_6WEk${F1SN0{_`(#TuOOH1as&#&xN~+JDzX(D-WU_nLEI}T_VaeLA=bc zl_UZS$nu#C1yH}YV>N2^9^zye{rDrn(rS99>Fh&jtNY7PP15q%g=RGnxACdCov47= zwf^9zfJaL{y`R#~tvVL#*<`=`Qe zj_@Me$6sIK=LMFbBrJps7vdaf_HeX?eC+P^{AgSvbEn?n<}NDWiQGQG4^ZOc|GskK z$Ve2_n8gQ-KZ=s(f`_X!+vM5)4+QmOP()2Fe#IL2toZBf+)8gTVgDSTN1CkP<}!j7 z0SEl>PBg{MnPHkj4wj$mZ?m5x!1ePVEYI(L_sb0OZ*=M%yQb?L{UL(2_*CTVbRxBe z@{)COwTK1}!*CK0Vi4~AB;HF(MmQf|dsoy(eiQ>WTKcEQlnKOri5xYsqi61Y=I4kzAjn5~{IWrz_l))|Ls zvq7xgQs?Xx@`N?f7+3XKLyD~6DRJw*uj*j?yvT3}a;(j_?YOe%hUFcPGWRVBXzpMJ zM43g6DLFqS9tcTLSg=^&N-y0dXL816v&-nqC0iXdg7kV|PY+js`F8dm z2PuHw&k+8*&9SPQ6f!^5q0&AH(i+z3I7a?8O+S5`g)>}fG|BM&ZnmL;rk)|u{1!aZ zEZHpAMmK_v$GbrrWNP|^2^s*!0waLW=-h5PZa-4jWYUt(Hr@EA(m3Mc3^uDxwt-me^55FMA9^>hpp26MhqjLg#^Y7OIJ5%ZLdNx&uDgIIqc zZRZl|n6TyV)0^DDyVtw*jlWkDY&Gw4q;k!UwqSL6&sW$B*5Rc?&)dt29bDB*b6IBY z6SY6Unsf6AOQdEf=P1inu6(6hVZ0~v-<>;LAlcQ2u?wRWj5VczBT$Op#8IhppP-1t zfz5H59Aa~yh7EN;BXJsLyjkjqARS5iIhDVPj<=4AJb}m6M@n{xYj3qsR*Q8;hVxDyC4vLI;;?^eENOb5QARj#nII5l$MtBCI@5u~(ylFi$ zw6-+$$XQ}Ca>FWT>q{k)g{Ml(Yv=6aDfe?m|5|kbGtWS}fKWI+})F6`x@||0oJ^(g|+xi zqlPdy5;`g*i*C=Q(aGeDw!eQg&w>UUj^{o?PrlFI=34qAU2u@BgwrBiaM8zoDTFJ< zh7nWpv>dr?q;4ZA?}V}|7qWz4W?6#S&m>hs4IwvCBe@-C>+oohsQZ^JC*RfDRm!?y zS4$7oxcI|##ga*y5hV>J4a%HHl^t$pjY%caL%-FlRb<$A$E!ws?8hf0@(4HdgQ!@> zds{&g$ocr9W4I84TMa9-(&^_B*&R%^=@?Ntxi|Ejnh;z=!|uVj&3fiTngDPg=0=P2 zB)3#%HetD84ayj??qrxsd9nqrBem(8^_u_UY{1@R_vK-0H9N7lBX5K(^O2=0#TtUUGSz{ z%g>qU8#a$DyZ~EMa|8*@`GOhCW3%DN%xuS91T7~iXRr)SG`%=Lfu%U~Z_`1b=lSi?qpD4$vLh$?HU6t0MydaowUpb zQr{>_${AMesCEffZo`}K0^~x>RY_ZIG{(r39MP>@=aiM@C;K)jUcfQV8#?SDvq>9D zI{XeKM%$$XP5`7p3K0T}x;qn)VMo>2t}Ib(6zui;k}<<~KibAb%p)**e>ln<=qyWU zrRDy|UXFi9y~PdEFIAXejLA{K)6<)Q`?;Q5!KsuEw({!#Rl8*5_F{TP?u|5(Hijv( ztAA^I5+$A*+*e0V0R~fc{ET-RAS3suZ}TRk3r)xqj~g_hxB`qIK5z(5wxYboz%46G zq{izIz^5xW1Vq#%lhXaZL&)FJWp0VZNO%2&ADd?+J%K$fM#T_Eke1{dQsx48dUPUY zLS+DWMJeUSjYL453f@HpRGU6Dv)rw+-c6xB>(=p4U%}_p>z^I@Ow9`nkUG21?cMIh9}hN?R-d)*6%pr6d@mcb*ixr7 z)>Lo<&2F}~>WT1ybm^9UO{6P9;m+fU^06_$o9gBWL9_}EMZFD=rLJ~&e?fhDnJNBI zKM=-WR6g7HY5tHf=V~6~QIQ~rakNvcsamU8m28YE=z8+G7K=h%)l6k zmCpiDInKL6*e#)#Pt;ANmjf`8h-nEt&d}(SBZMI_A{BI#ck-_V7nx)K9_D9K-p@?Zh81#b@{wS?wCcJ%og)8RF*-0z+~)6f#T` zWqF7_CBcnn=S-1QykC*F0YTsKMVG49BuKQBH%WuDkEy%E?*x&tt%0m>>5^HCOq|ux zuvFB)JPR-W|%$24eEC^AtG3Gp4qdK%pjRijF5Sg3X}uaKEE z-L5p5aVR!NTM8T`4|2QA@hXiLXRcJveWZ%YeFfV%mO5q#($TJ`*U>hicS+CMj%Ip# zivoL;dd*araeJK9EA<(tihD50FHWbITBgF9E<33A+eMr2;cgI3Gg6<-2o|_g9|> zv5}i932( zYfTE9?4#nQhP@a|zm#9FST2 z!y+p3B;p>KkUzH!K;GkBW}bWssz)9b>Ulg^)EDca;jDl+q=243BddS$hY^fC6lbpM z(q_bo4V8~eVeA?0LFD6ZtKcmOH^75#q$Eo%a&qvE8Zsqg=$p}u^|>DSWUP5i{6)LAYF4E2DfGZuMJ zMwxxmkxQf}Q$V3&2w|$`9_SQS^2NVbTHh;atB>=A%!}k-f4*i$X8m}Ni^ppZXk5_oYF>Gq(& z0wy{LjJOu}69}~#UFPc;$7ka+=gl(FZCy4xEsk);+he>Nnl>hb5Ud-lj!CNicgd^2 z_Qgr_-&S7*#nLAI7r()P$`x~fy)+y=W~6aNh_humoZr7MWGSWJPLk}$#w_1n%(@? z3FnHf1lbxKJbQ9c&i<$(wd{tUTX6DAKs@cXIOBv~!9i{wD@*|kwfX~sjKASrNFGvN zrFc=!0Bb^OhR2f`%hrp2ibv#KUxl)Np1aixD9{^o=)*U%n%rTHX?FSWL^UGpHpY@7 z74U}KoIRwxI#>)Pn4($A`nw1%-D}`sGRZD8Z#lF$6 zOeA5)+W2qvA%m^|$WluUU-O+KtMqd;Pd58?qZj})MbxYGO<{z9U&t4D{S2G>e+J9K ztFZ?}ya>SVOLp9hpW)}G%kTrg*KXXXsLkGdgHb+R-ZXqdkdQC0_)`?6mqo8(EU#d( zy;u&aVPe6C=YgCRPV!mJ6R6kdY*`e+VGM~`VtC>{k27!9vAZT)x2~AiX5|m1Rq}_= z;A9LX^nd$l-9&2%4s~p5r6ad-siV`HtxKF}l&xGSYJmP=z!?Mlwmwef$EQq~7;#OE z)U5eS6dB~~1pkj#9(}T3j!((8Uf%!W49FfUAozijoxInUE7z`~U3Y^}xc3xp){#9D z<^Tz2xw}@o@fdUZ@hnW#dX6gDOj4R8dV}Dw`u!h@*K)-NrxT8%2`T}EvOImNF_N1S zy?uo6_ZS>Qga4Xme3j#aX+1qdFFE{NT0Wfusa$^;eL5xGE_66!5_N8!Z~jCAH2=${ z*goHjl|z|kbmIE{cl-PloSTtD+2=CDm~ZHRgXJ8~1(g4W=1c3=2eF#3tah7ho`zm4 z05P&?nyqq$nC?iJ-nK_iBo=u5l#|Ka3H7{UZ&O`~t-=triw=SE7ynzMAE{Mv-{7E_ zViZtA(0^wD{iCCcg@c{54Ro@U5p1QZq_XlEGtdBAQ9@nT?(zLO0#)q55G8_Ug~Xnu zR-^1~hp|cy&52iogG@o?-^AD8Jb^;@&Ea5jEicDlze6%>?u$-eE};bQ`T6@(bED0J zKYtdc?%9*<<$2LCBzVx9CA4YV|q-qg*-{yQ;|0=KIgI6~z0DKTtajw2Oms3L zn{C%{P`duw!(F@*P)lFy11|Z&x`E2<=$Ln38>UR~z6~za(3r;45kQK_^QTX%!s zNzoIFFH8|Y>YVrUL5#mgA-Jh>j7)n)5}iVM4%_@^GSwEIBA2g-;43* z*)i7u*xc8jo2z8&=8t7qo|B-rsGw)b8UXnu`RgE4u!(J8yIJi(5m3~aYsADcfZ!GG zzqa7p=sg`V_KjiqI*LA-=T;uiNRB;BZZ)~88 z`C%p8%hIev2rxS12@doqsrjgMg3{A&N8A?%Ui5vSHh7!iC^ltF&HqG~;=16=h0{ygy^@HxixUb1XYcR36SB}}o3nxu z_IpEmGh_CK<+sUh@2zbK9MqO!S5cao=8LSQg0Zv4?ju%ww^mvc0WU$q@!oo#2bv24 z+?c}14L2vlDn%Y0!t*z=$*a!`*|uAVu&NO!z_arim$=btpUPR5XGCG0U3YU`v>yMr z^zmTdcEa!APX zYF>^Q-TP11;{VgtMqC}7>B^2gN-3KYl33gS-p%f!X<_Hr?`rG8{jb9jmuQA9U;BeG zHj6Pk(UB5c6zwX%SNi*Py*)gk^?+729$bAN-EUd*RKN7{CM4`Q65a1qF*-QWACA&m zrT)B(M}yih{2r!Tiv5Y&O&=H_OtaHUz96Npo_k0eN|!*s2mLe!Zkuv>^E8Xa43ZwH zOI058AZznYGrRJ+`*GmZzMi6yliFmGMge6^j?|PN%ARns!Eg$ufpcLc#1Ns!1@1 zvC7N8M$mRgnixwEtX{ypBS^n`k@t2cCh#_6L6WtQb8E~*Vu+Rr)YsKZRX~hzLG*BE zaeU#LPo?RLm(Wzltk79Jd1Y$|6aWz1)wf1K1RtqS;qyQMy@H@B805vQ%wfSJB?m&&=^m4i* zYVH`zTTFbFtNFkAI`Khe4e^CdGZw;O0 zqkQe2|NG_y6D%h(|EZNf&77_!NU%0y={^E=*gKGQ=)LdKPM3zUlM@otH2X07Awv8o zY8Y7a1^&Yy%b%m{mNQ5sWNMTIq96Wtr>a(hL>Qi&F(ckgKkyvM0IH<_}v~Fv-GqDapig=3*ZMOx!%cYY)SKzo7ECyem z9Mj3C)tCYM?C9YIlt1?zTJXNOo&oVxu&uXKJs7i+j8p*Qvu2PAnY}b`KStdpi`trk ztAO}T8eOC%x)mu+4ps8sYZ=vYJp16SVWEEgQyFKSfWQ@O5id6GfL`|2<}hMXLPszS zgK>NWOoR zBRyKeUPevpqKKShD|MZ`R;~#PdNMB3LWjqFKNvH9k+;(`;-pyXM55?qaji#nl~K8m z_MifoM*W*X9CQiXAOH{cZcP0;Bn10E1)T@62Um>et2ci!J2$5-_HPy(AGif+BJpJ^ ziHWynC_%-NlrFY+(f7HyVvbDIM$5ci_i3?22ZkF>Y8RPBhgx-7k3M2>6m5R24C|~I z&RPh9xpMGzhN4bii*ryWaN^d(`0 zTOADlU)g`1p+SVMNLztd)c+;XjXox(VHQwqzu>FROvf0`s&|NEv26}(TAe;@=FpZq zaVs6mp>W0rM3Qg*6x5f_bPJd!6dQGmh?&v0rpBNfS$DW-{4L7#_~-eA@7<2BsZV=X zow){3aATmLZOQrs>uzDkXOD=IiX;Ue*B(^4RF%H zeaZ^*MWn4tBDj(wj114r(`)P96EHq4th-;tWiHhkp2rDlrklX}I@ib-nel0slFoQO zOeTc;Rh7sMIebO`1%u)=GlEj+7HU;c|Nj>2j)J-kpR)s3#+9AiB zd$hAk6;3pu9(GCR#)#>aCGPYq%r&i02$0L9=7AlIGYdlUO5%eH&M!ZWD&6^NBAj0Y9ZDcPg@r@8Y&-}e!aq0S(`}NuQ({;aigCPnq75U9cBH&Y7 ze)W0aD>muAepOKgm7uPg3Dz7G%)nEqTUm_&^^3(>+eEI;$ia`m>m0QHEkTt^=cx^JsBC68#H(3zc~Z$E9I)oSrF$3 zUClHXhMBZ|^1ikm3nL$Z@v|JRhud*IhOvx!6X<(YSX(9LG#yYuZeB{=7-MyPF;?_8 zy2i3iVKG2q!=JHN>~!#Bl{cwa6-yB@b<;8LSj}`f9pw7#x3yTD>C=>1S@H)~(n_K4 z2-yr{2?|1b#lS`qG@+823j;&UE5|2+EdU4nVw5=m>o_gj#K>>(*t=xI7{R)lJhLU{ z4IO6!x@1f$aDVIE@1a0lraN9!(j~_uGlks)!&davUFRNYHflp<|ENwAxsp~4Hun$Q z$w>@YzXp#VX~)ZP8`_b_sTg(Gt7?oXJW%^Pf0UW%YM+OGjKS}X`yO~{7WH6nX8S6Z ztl!5AnM2Lo*_}ZLvo%?iV;D2z>#qdpMx*xY2*GGlRzmHCom`VedAoR=(A1nO)Y>;5 zCK-~a;#g5yDgf7_phlkM@)C8s!xOu)N2UnQhif-v5kL$*t=X}L9EyBRq$V(sI{90> z=ghTPGswRVbTW@dS2H|)QYTY&I$ljbpNPTc_T|FEJkSW7MV!JM4I(ksRqQ8)V5>}v z2Sf^Z9_v;dKSp_orZm09jb8;C(vzFFJgoYuWRc|Tt_&3k({wPKiD|*m!+za$(l*!gNRo{xtmqjy1=kGzFkTH=Nc>EL@1Um0BiN1)wBO$i z6rG={bRcT|%A3s3xh!Bw?=L&_-X+6}L9i~xRj2}-)7fsoq0|;;PS%mcn%_#oV#kAp zGw^23c8_0~ ze}v9(p};6HM0+qF5^^>BBEI3d=2DW&O#|(;wg}?3?uO=w+{*)+^l_-gE zSw8GV=4_%U4*OU^hibDV38{Qb7P#Y8zh@BM9pEM_o2FuFc2LWrW2jRRB<+IE)G=Vx zuu?cp2-`hgqlsn|$nx@I%TC!`>bX^G00_oKboOGGXLgyLKXoo$^@L7v;GWqfUFw3< zekKMWo0LR;TaFY}Tt4!O$3MU@pqcw!0w0 zA}SnJ6Lb597|P5W8$OsEHTku2Kw9y4V=hx*K%iSn!#LW9W#~OiWf^dXEP$^2 zaok=UyGwy3GRp)bm6Gqr>8-4h@3=2`Eto2|JE6Sufh?%U6;ut1v1d@#EfcQP2chCt z+mB{Bk5~()7G>wM3KYf7Xh?LGbwg1uWLotmc_}Z_o;XOUDyfU?{9atAT$={v82^w9 z(MW$gINHt4xB3{bdbhRR%T}L?McK?!zkLK3(e>zKyei(yq%Nsijm~LV|9mll-XHavFcc$teX7v);H>=oN-+E_Q{c|! zp
    JV~-9AH}jxf6IF!PxrB9is{_9s@PYth^`pb%DkwghLdAyDREz(csf9)HcVRq z+2Vn~>{(S&_;bq_qA{v7XbU?yR7;~JrLfo;g$Lkm#ufO1P`QW_`zWW+4+7xzQZnO$ z5&GyJs4-VGb5MEDBc5=zxZh9xEVoY(|2yRv&!T7LAlIs@tw+4n?v1T8M>;hBv}2n) zcqi+>M*U@uY>4N3eDSAH2Rg@dsl!1py>kO39GMP#qOHipL~*cCac2_vH^6x@xmO|E zkWeyvl@P$2Iy*mCgVF+b{&|FY*5Ygi8237i)9YW#Fp& z?TJTQW+7U)xCE*`Nsx^yaiJ0KSW}}jc-ub)8Z8x(|K7G>`&l{Y&~W=q#^4Gf{}aJ%6kLXsmv6cr=Hi*uB`V26;dr4C$WrPnHO>g zg1@A%DvIWPDtXzll39kY6#%j;aN7grYJP9AlJgs3FnC?crv$wC7S4_Z?<_s0j;MmE z75yQGul2=bY%`l__1X3jxju2$Ws%hNv75ywfAqjgFO7wFsFDOW^)q2%VIF~WhwEW0 z45z^+r+}sJ{q+>X-w(}OiD(!*&cy4X&yM`!L0Fe+_RUfs@=J{AH#K~gArqT=#DcGE z!FwY(h&+&811rVCVoOuK)Z<-$EX zp`TzcUQC256@YWZ*GkE@P_et4D@qpM92fWA6c$MV=^qTu7&g)U?O~-fUR&xFqNiY1 zRd=|zUs_rmFZhKI|H}dcKhy%Okl(#y#QuMi81zsY56Y@757xBQqDNkd+XhLQhp2BB zBF^aJ__D676wLu|yYo6jNJNw^B+Ce;DYK!f$!dNs1*?D^97u^jKS++7S z5qE%zG#HY-SMUn^_yru=T6v`)CM%K<>_Z>tPe|js`c<|y7?qol&)C=>uLWkg5 zmzNcSAG_sL)E9or;i+O}tY^70@h7+=bG1;YDlX{<4zF_?{)K5B&?^tKZ6<$SD%@>F zY0cl2H7)%zKeDX%Eo7`ky^mzS)s;842cP{_;dzFuyd~Npb4u!bwkkhf8-^C2e3`q8>MuPhgiv0VxHxvrN9_`rJv&GX0fWz-L-Jg^B zrTsm>)-~j0F1sV=^V?UUi{L2cp%YwpvHwwLaSsCIrGI#({{QfbgDxLKsUC6w@m?y} zg?l=7aMX-RnMxvLn_4oSB|9t;)Qf2%m-GKo_07?N1l^ahJ+Wf8C>h5~=-o1BJzV@5HBTB-ACNpsHnGt6_ku37M z{vIEB^tR=--4SEg{jfF=gEogtGwi&A$mwk7E+SV$$ZuU}#F3Y7t}o{!w4LJh8v4PW%8HfUK@dta#l*z@w*9Xzz(i)r#WXi`r1D#oBPtNM7M?Hkq zhhS1)ea5(6VY45|)tCTr*@yc$^Zc!zQzsNXU?aRN6mh7zVu~i=qTrX^>de+f6HYfDsW@6PBlw0CsDBcOWUmt&st>Z zYNJEsRCP1#g0+Htb=wITvexBY@fOpAmR7?szQNR~nM)?sPWIj)0)jG-EF8U@nnBaQZy z)ImpVYQL>lBejMDjlxA$#G4%y+^_>N;}r@Zoe2|u-9-x@vvD^ZWnV>Gm=pZa7REAf zOnomhCxBaGZgT+4kiE%aS&lH2sI1mSCM<%)Cr*Sli;#!aXcUb&@Z|Hj{VPsJyClqD%>hy`Y7z(GASs8Mqas3!D zSQE83*%uctlD|p%4)v`arra4y>yP5m25V*_+n)Ry1v>z_Fz!TV6t+N?x?#iH$q=m= z8&X{uW%LVRO87dVl=$Y*>dabJVq{o|Kx`7(D2$5DVX&}XGbg|Ua(*5b=;5qzW9;|w>m{hIO(Tu-z(ey8H=EMluJNyK4BJmGpX~ZM2O61 zk*O7js{-MBqwq>Urf0igN+6soGGc!Y?SP6hiXuJzZ1V4WZqE*?h;PG84gvG~dds6~484!kPM zMP87IP?dhdc;%|cS&LxY*Ib6P3%p|9)E3IgRmhhwtUR3eRK6iZ_6fiGW}jnL4(I|t ze`2yLvmuY42lNwO6>I#Son3$R4NOoP*WUm1R4jl#agtSLE}fSu-Z>{+*?pQIn7`s3LAzF#1pSxCAo?clr9 z9PUj#REq28*ZkJnxs$aK%8^5?P<_Q!#Z?%JH0FKVF;&zH3F#J^fz|ahl$Ycs~kFij_XP;U<`FcaDYyXYPM~&jEe1Xj1n;wyRdD;lmnq&FEro=;+Z$=v-&fYM9eK*S_D&oTXFW#b0 zRY}Y7R#bLzTfg9i7{s?=P9~qjA?$-U2p5;0?gPPu`1JY|*?*8IPO!eX>oiX=O#F!A zl`S%e5Y(csR1f)I(iKMf-;5%_rPP7h&}5Fc(8byKUH1*d7?9%QC|4aADj3L8yuo6GOv#%HDgU3bN(UHw1+(99&Om%f!DY(RYSf4&Uny% zH}*&rEXc$W5+eyeEg|I|E-HnkIO0!$1sV7Z&NXxiCZJ@`kH4eEi5}q~!Vv5qQq{MI zi4^`GYoUN-7Q(jy^SKXL4$G4K+FQXR)B}ee=pS0RyK=YC8c2bGnMA~rrOh&jd3_AT zxVaq37w^-;OU3+C`Kko-Z%l_2FC^maa=Ae0Fm@PEtXEg@cX*oka1Lt&h@jES<6?o1Oi1C9>}7+U(Ve zQ$=8RlzcnfCd59CsJ=gG^A!2Bb_PY~K2sSau{)?Ge03G7US&qrgV!3NUi>UHWZ*lo zS;~0--vn{ot+7UWMV{a(X3rZ8Z06Ps3$-sd|CWE(Y#l`swvcDbMjuReGsoA`rmZ`^ z=AaArdbeU0EtwnOuzq@u5P1rlZjH#gNgh6HIhG(>dX%4m{_!&DNTQE)8= zXD-vcpcSi|DSm3aUMnrV;DQY?svz?9*#GT$NXb~Hem=24iy>7xj367(!#RjnrHtrP-Q`T2W*PEvAR-=j ztY2|#<|JvHNVnM-tNdoS_yRSo=yFqukTZmB$|>Vclj)o=YzC9!ph8)ZOH5X=%Aq|9gNgc}^KFVLht!Lyw54v5u&D zW%vT%z`H{Ax>Ry+bD&QjHQke_wEA;oj(&E!s4|OURButQKSc7Ar-PzIiFa8F@ezkaY2J9&PH+VI1!G+{JgsQ7%da*_Gr!exT*OgJld)b-?cd)xI+|v_C`h(Cg`N~oj0`SQPTma z{@vc8L^D-rBXwS#00jT#@=-n1H-C3hvg61r2jx#ok&cr#BV~9JdPaVihyrGq*lb>bm$H6rIoc}ifaSn6mTD9% z$FRJxbNozOo6y}!OUci1VBv-7{TYZ4GkOM@46Y9?8%mSH9?l&lU59)T#Fjg(h%6I} z?ib zZ(xb8Rwr+vv>@$h{WglT2lL`#V=-9tP^c)cjvnz(g|VL^h8^CPVv12dE(o}WQ@0OP z^2-&ssBXP^#Oh`X5@F+~$PCB6kK-T7sFUK|>$lNDSkvAy%{y2qgq-&v zv}^&gm`wiYztWgMS<{^qQKYNV=>CQaOeglAY~EZvr}n~tW=yg)_+fzqF%~+*V_$3h z2hDW`e$qR;QMg?(wKE>%H_6ASS@6bkOi-m- zg6B7AzD;gBS1%OD7|47a%3BykN{w}P!Wn-nQOfpKUpx8Mk{$IO62D!%U9$kr!e%T> zlqQih?3(U&5%r!KZFZPdbwZ0laAJCj!c&pEFVzrH&_&i5m68Y_*J+-Qjlnz}Q{3oAD)`d14H zKUGmbwC|beC9Mtp>SbL~NVrlctU3WBpHz(UeIa~_{u^_4OaHs_LQt>bUwcyD`_Bbh zC=x|1vSjL)JvVHLw|xKynEvq2m)7O-6qdmjht7pZ*z|o%NA17v$9H*(5D5(MXiNo1 z72Tv}QASqr$!mY58s_Q{hHa9MY+QZ`2zX-FT@Kd?`8pczcV^9IeOKDG4WKqiP7N|S z+O977=VQTk8k5dafK`vd(4?_3pBdB?YG9*Z=R@y|$S+d%1sJf-Ka++I&v9hH)h#}} zw-MjQWJ?ME<7PR(G<1#*Z-&M?%=yzhQw$Lki(R+Pq$X~Q!9BO=fP9FyCIS8zE3n04 z8ScD%XmJnIv=pMTgt6VSxBXOZucndRE@7^aU0wefJYueY(Cb%?%0rz)zWEnsNsKhQ z+&o6d^x=R;Pt7fUa_`JVb1HPHYbXg{Jvux|atQ^bV#_|>7QZNC~P^IKUThB6{kvz2pr2*Cyxj zy37Nri8za8J!@Iw9rbt~#^<9zOaM8LOi$kPBcAGqPq-DB^-93Qeup{9@9&=zV6KQN zL)ic5S%n1!F(7b>MQ973$~<0|9MY-G!?wk?j-cQhMQlM2n{&7JoTBGsP;=fC6CBJn zxlpk^%x=B16rfb-W9pYV#9IRHQL9VG4?Uh>pN>2}0-MST2AB2pQjf*rT+TLCX-+&m z9I{ic2ogXoh=HwdI#igr(JC>>NUP|M>SA?-ux<2&>Jyx>Iko!B<3vS}{g*dKqxYW7 z0i`&U#*v)jot+keO#G&wowD!VvD(j`Z9a*-_RALKn0b(KnZ37d#Db7royLhBW~*7o zRa`=1fo9C4dgq;;R)JpP++a9^{xd)8``^fPW9!a%MCDYJc;3yicPs8IiQM>DhUX*; zeIrxE#JRrr|D$@bKgOm4C9D+e!_hQKj3LC`Js)|Aijx=J!rlgnpKeF>b+QlKhI^4* zf%Of^RmkW|xU|p#Lad44Y5LvIUIR>VGH8G zz7ZEIREG%UOy4)C!$muX6StM4@Fsh&Goa}cj10RL(#>oGtr6h~7tZDDQ_J>h)VmYlKK>9ns8w4tdx6LdN5xJQ9t-ABtTf_ zf1dKVv!mhhQFSN=ggf(#$)FtN-okyT&o6Ms+*u72Uf$5?4)78EErTECzweDUbbU)) zc*tt+9J~Pt%!M352Y5b`Mwrjn^Orp+)L_U1ORHJ}OUsB78YPcIRh4p5jzoDB7B*fb z4v`bouQeCAW#z9b1?4(M3dcwNn2F2plwC^RVHl#h&b-8n#5^o+Ll20OlJ^gOYiK2< z;MQuR!t!>`i}CAOa4a+Rh5IL|@kh4EdEL*O=3oGx4asg?XCTcUOQnmHs^6nLu6WcI zSt9q7nl*?2TIikKNb?3JZBo$cW6)b#;ZKzi+(~D-%0Ec+QW=bZZm@w|prGiThO3dy zU#TQ;RYQ+xU~*@Zj;Rf~z~iL8Da`RT!Z)b3ILBhnIl@VX9K0PSj5owH#*FJXX3vZ= zg_Zyn^G&l!WR6wN9GWvt)sM?g2^CA8&F#&t2z3_MiluRqvNbV{Me6yZ&X-_ zd6#Xdh%+6tCmSNTdCBusVkRwJ_A~<^Nd6~MNOvS;YDixM43`|8e_bmc*UWi7TLA})`T_F ztk&Nd=dgFUss#Ol$LXTRzP9l1JOSvAws~^X%(`ct$?2Im?UNpXjBec_-+8YK%rq#P zT9=h8&gCtgx?=Oj$Yr2jI3`VVuZ`lH>*N+*K11CD&>>F)?(`yr~54vHJftY*z?EorK zm`euBK<$(!XO%6-1=m>qqp6F`S@Pe3;pK5URT$8!Dd|;`eOWdmn916Ut5;iXWQoXE z0qtwxlH=m_NONP3EY2eW{Qwr-X1V3;5tV;g7tlL4BRilT#Y&~o_!f;*hWxWmvA;Pg zRb^Y$#PipnVlLXQIzKCuQP9IER0Ai4jZp+STb1Xq0w(nVn<3j(<#!vuc?7eJEZC<- zPhM7ObhgabN2`pm($tu^MaBkRLzx&jdh;>BP|^$TyD1UHt9Qvr{ZcBs^l!JI4~d-Py$P5QOYO&8eQOFe)&G zZm+?jOJioGs7MkkQBCzJSFJV6DiCav#kmdxc@IJ9j5m#&1)dhJt`y8{T!uxpBZ>&z zD^V~%GEaODak5qGj|@cA7HSH{#jHW;Q0KRdTp@PJO#Q1gGI=((a1o%X*{knz&_`ym zkRLikN^fQ%Gy1|~6%h^vx>ToJ(#aJDxoD8qyOD{CPbSvR*bC>Nm+mkw>6mD0mlD0X zGepCcS_x7+6X7dH;%e`aIfPr-NXSqlu&?$Br1R}3lSF2 zWOXDtG;v#EVLSQ!>4323VX-|E#qb+x%IxzUBDI~N23x? zXUHfTTV#_f9T$-2FPG@t)rpc9u9!@h^!4=fL^kg9 zVv%&KY3!?bU*V4X)wNT%Chr;YK()=~lc%$auOB_|oH`H)Xot@1cmk{^qdt&1C55>k zYnIkdoiAYW41zrRBfqR?9r^cpWIEqfS;|R#bIs4$cqA zoq~$yl8h{IXTSdSdH?;`ky6i%+Oc?HvwH+IS`%_a!d#CqQob9OTNIuhUnOQsX;nl_ z;1w99qO9lAb|guQ9?p4*9TmIZ5{su!h?v-jpOuShq!{AuHUYtmZ%brpgHl$BKLK_L z6q5vZodM$)RE^NNO>{ZWPb%Ce111V4wIX}?DHA=uzTu0$1h8zy!SID~m5t)(ov$!6 zB^@fP#vpx3enbrbX=vzol zj^Bg7V$Qa53#3Lptz<6Dz=!f+FvUBVIBtYPN{(%t(EcveSuxi3DI>XQ*$HX~O{KLK5Dh{H2ir87E^!(ye{9H&2U4kFxtKHkw zZPOTIa*29KbXx-U4hj&iH<9Z@0wh8B6+>qQJn{>F0mGnrj|0_{nwN}Vw_C!rm0!dC z>iRlEf}<+z&?Z4o3?C>QrLBhXP!MV0L#CgF{>;ydIBd5A{bd-S+VFn zLqq4a*HD%65IqQ5BxNz~vOGU=JJv|NG{OcW%2PU~MEfy6(bl#^TfT7+az5M-I`i&l z#g!HUfN}j#adA-21x7jbP6F;`99c8Qt|`_@u@fbhZF+Wkmr;IdVHj+F=pDb4MY?fU znDe##Hn){D}<>vVhYL#)+6p9eAT3T$?;-~bZU%l7MpPNh_mPc(h@79 z;LPOXk>e3nmIxl9lno5cI5G@Q!pE&hQ`s{$Ae4JhTebeTsj*|!6%0;g=wH?B1-p{P z`In#EP12q6=xXU)LiD+mLidPrYGHaKbe5%|vzApq9(PI6I5XjlGf<_uyy59iw8W;k zdLZ|8R8RWDc`#)n2?~}@5)vvksY9UaLW`FM=2s|vyg>Remm=QGthdNL87$nR&TKB*LB%*B}|HkG64 zZ|O4=Yq?Zwl>_KgIG@<8i{Zw#P3q_CVT7Dt zoMwoI)BkpQj8u(m!>1dfOwin(50}VNiLA>A2OG&TBXcP=H(3I;!WdPFe?r_e{%>bc6(Zk?6~Ew&;#ZxBJ| zAd1(sAHqlo_*rP;nTk)kAORe3cF&tj>m&LsvB)`-y9#$4XU=Dd^+CzvoAz%9216#f0cS`;kERxrtjbl^7pmO;_y zYBGOL7R1ne7%F9M2~0a7Srciz=MeaMU~ zV%Y#m_KV$XReYHtsraWLrdJItLtRiRo98T3J|x~(a>~)#>JHDJ z|4j!VO^qWQfCm9-$N29SpHUqvz62%#%98;2FNIF*?c9hZ7GAu$q>=0 zX_igPSK8Et(fmD)V=CvbtA-V(wS?z6WV|RX2`g=w=4D)+H|F_N(^ON!jHf72<2nCJ z^$hEygTAq7URR{Vq$)BsmFKTZ+i1i(D@SJuTGBN3W8{JpJ^J zkF=gBTz|P;Xxo1NIypGzJq8GK^#4tl)S%8$PP6E8c|GkkQ)vZ1OiB%mH#@hO1Z%Hp zv%2~Mlar^}7TRN-SscvQ*xVv+i1g8CwybQHCi3k;o$K@bmB%^-U8dILX)7b~#iPu@ z&D&W7YY2M3v`s(lNm2#^dCRFd;UYMUw1Rh2mto8laH1m`n0u;>okp5XmbsShOhQwo z@EYOehg-KNab)Rieib?m&NXls+&31)MB&H-zj_WmJsGjc1sCSOz0!2Cm1vV?y@kkQ z<1k6O$hvTQnGD*esux*aD3lEm$mUi0td0NiOtz3?7}h;Bt*vIC{tDBr@D)9rjhP^< zY*uKu^BiuSO%)&FL>C?Ng!HYZHLy`R>`rgq+lJhdXfo|df zmkzpQf{6o9%^|7Yb5v{Tu& zsP*Y~<#jK$S_}uEisRC;=y{zbq`4Owc@JyvB->nPzb#&vcMKi5n66PVV{Aub>*>q8 z=@u7jYA4Ziw2{fSED#t4QLD7Rt`au^y(Ggp3y(UcwIKtI(OMi@GHxs!bj$v~j(FZK zbdcP^gExtXQqQ8^Q#rHy1&W8q!@^aL>g1v2R45T(KErWB)1rB@rU`#n&-?g2Ti~xXCrexrLgajgzNy=N9|A6K=RZ zc3yk>w5sz1zsg~tO~-Ie?%Aplh#)l3`s632mi#CCl^75%i6IY;dzpuxu+2fliEjQn z&=~U+@fV4>{Fp=kk0oQIvBdqS#yY`Z+>Z|T&K{d;v3}=JqzKx05XU3M&@D5!uPTGydasyeZ5=1~IX-?HlM@AGB9|Mzb{{Dt@bUU8{KUPU@EX zv0fpQNvG~nD2WiOe{Vn=hE^rQD(5m+!$rs%s{w9;yg9oxRhqi0)rwsd245)igLmv* zJb@Xlet$+)oS1Ra#qTB@U|lix{Y4lGW-$5*4xOLY{9v9&RK<|K!fTd0wCKYZ)h&2f zEMcTCd+bj&YVmc#>&|?F!3?br3ChoMPTA{RH@NF(jmGMB2fMyW(<0jUT=8QFYD7-% zS0ydgp%;?W=>{V9>BOf=p$q5U511~Q0-|C!85)W0ov7eb35%XV;3mdUI@f5|x5C)R z$t?xLFZOv}A(ZjjSbF+8&%@RChpRvo>)sy>-IO8A@>i1A+8bZd^5J#(lgNH&A=V4V z*HUa0{zT{u-_FF$978RziwA@@*XkV{<-CE1N=Z!_!7;wq*xt3t((m+^$SZKaPim3K zO|Gq*w5r&7iqiQ!03SY{@*LKDkzhkHe*TzQaYAkz&jNxf^&A_-40(aGs53&}$dlKz zsel3=FvHqdeIf!UYwL&Mg3w_H?utbE_(PL9B|VAyaOo8k4qb>EvNYHrVmj^ocJQTf zL%4vl{qgmJf#@uWL@)WiB>Lm>?ivwB%uO|)i~;#--nFx4Kr6{TruZU0N_t_zqkg`? zwPFK|WiC4sI%o1H%$!1ANyq6_0OSPQJybh^vFriV=`S;kSsYkExZwB{68$dTODWJQ z@N57kBhwN(y~OHW_M}rX2W13cl@*i_tjW`TMfa~Y;I}1hzApXgWqag@(*@(|EMOg- z^qMk(s~dL#ps>>`oWZD=i1XI3(;gs7q#^Uj&L`gVu#4zn$i!BIHMoOZG!YoPO^=Gu z5`X-(KoSsHL77c<7^Y*IM2bI!dzg5j>;I@2-EeB$LgW|;csQTM&Z|R)q>yEjk@Sw% z6FQk*&zHWzcXalUJSoa&pgH24n`wKkg=2^ta$b1`(BBpBT2Ah9yQF&Kh+3jTaSE|=vChGz2_R^{$C;D`Ua(_=|OO11uLm;+3k%kO19EA`U065i;fRBoH z{Hq$cgHKRFPf0#%L?$*KeS@FDD;_TfJ#dwP7zzO5F>xntH(ONK{4)#jYUDQr6N(N< zp+fAS9l9)^c4Ss8628Zq5AzMq4zc(In_yJSXAT57Dtl}@= zvZoD7iq0cx7*#I{{r9m{%~g6@Hdr|*njKBb_5}mobCv=&X^`D9?;x6cHwRcwnlO^h zl;MiKr#LaoB*PELm8+8%btnC)b^E12!^ zMmVA!z>59e7n+^!P{PA?f9M^2FjKVw1%x~<`RY5FcXJE)AE}MTopGFDkyEjGiE|C6 z(ad%<3?v*?p;LJGopSEY18HPu2*}U!Nm|rfewc6(&y(&}B#j85d-5PeQ{}zg>>Rvl zDQ3H4E%q_P&kjuAQ>!0bqgAj){vzHpnn+h(AjQ6GO9v**l0|aCsCyXVE@uh?DU;Em zE*+7EU9tDH````D`|rM6WUlzBf1e{ht8$62#ilA6Dcw)qAzSRwu{czZJAcKv8w(Q6 zx)b$aq*=E=b5(UH-5*u)3iFlD;XQyklZrwHy}+=h6=aKtTriguHP@Inf+H@q32_LL z2tX|+X}4dMYB;*EW9~^5bydv)_!<%q#%Ocyh=1>FwL{rtZ?#2Scp{Q55%Fd-LgLU$ zM2u#|F{%vi%+O2^~uK3)?$6>9cc7_}F zWU72eFrzZ~x3ZIBH;~EMtD%51o*bnW;&QuzwWd$ds=O>Ev807cu%>Ac^ZK&7bCN;Ftk#eeQL4pG0p!W{Ri@tGw>nhIo`rC zi!Z6?70nYrNf92V{Y_i(a4DG=5>RktP=?%GcHEx?aKN$@{w{uj#Cqev$bXefo?yC6KI%Rol z%~$974WCymg;BBhd9Mv}_MeNro_8IB4!evgo*je4h?B-CAkEW-Wr-Q_V9~ef(znU& z{f-OHnj>@lZH(EcUb2TpOkc70@1BPiY0B#++1EPY5|UU?&^Vpw|C`k4ZWiB-3oAQM zgmG%M`2qDw5BMY|tG++34My2fE|^kvMSp(d+~P(Vk*d+RW1833i_bX^RYbg9tDtX` zox?y^YYfs-#fX|y7i(FN7js)66jN!`p9^r7oildEU#6J1(415H3h>W*p(p9@dI|c7 z&c*Aqzksg}o`D@i+o@WIw&jjvL!(`)JglV5zwMn)praO2M05H&CDeps0Wq8(8AkuE zPm|8MB6f0kOzg(gw}k>rzhQyo#<#sVdht~Wdk`y`=%0!jbd1&>Kxed8lS{Xq?Zw>* zU5;dM1tt``JH+A9@>H%-9f=EnW)UkRJe0+e^iqm0C5Z5?iEn#lbp}Xso ztleC}hl&*yPFcoCZ@sgvvjBA_Ew6msFml$cfLQY_(=h03WS_z+Leeh$M3#-?f9YT^Q($z z+pgaEv$rIa*9wST`WHASQio=9IaVS7l<87%;83~X*`{BX#@>>p=k`@FYo ze!K5_h8hOc`m0mK0p}LxsguM}w=9vw6Ku8y@RNrXSRPh&S`t4UQY=e-B8~3YCt1Fc zU$CtRW%hbcy{6K{>v0F*X<`rXVM3a{!muAeG$zBf`a(^l${EA9w3>J{aPwJT?mKVN2ba+v)Mp*~gQ_+Ws6= zy@D?85!U@VY0z9T=E9LMbe$?7_KIg)-R$tD)9NqIt84fb{B;f7C)n+B8)Cvo*F0t! zva6LeeC}AK4gL#d#N_HvvD& z0;mdU3@7%d5>h(xX-NBmJAOChtb(pX-qUtRLF5f$ z`X?Kpu?ENMc88>O&ym_$Jc7LZ> z#73|xJ|aa@l}PawS4Mpt9n)38w#q^P1w2N|rYKdcG;nb!_nHMZA_09L!j)pBK~e+j?tb-_A`wF8 zIyh>&%v=|n?+~h}%i1#^9UqZ?E9W!qJ0d0EHmioSt@%v7FzF`eM$X==#oaPESHBm@ zYzTXVo*y|C0~l_)|NF|F(If~YWJVkQAEMf5IbH{}#>PZpbXZU;+b^P8LWmlmDJ%Zu)4CajvRL!g_Faph`g0hpA2)D0|h zYy0h5+@4T81(s0D=crojdj|dYa{Y=<2zKp@xl&{sHO;#|!uTHtTey25f1U z#=Nyz{rJy#@SPk3_U|aALcg%vEjwIqSO$LZI59^;Mu~Swb53L+>oxWiN7J{;P*(2b@ao*aU~}-_j10 z@fQiaWnb}fRrHhNKrxKmi{aC#34BRP(a#0K>-J8D+v_2!~(V-6J%M@L{s?fU5ChwFfqn)2$siOUKw z?SmIRlbE8ot5P^z0J&G+rQ5}H=JE{FNsg`^jab7g-c}o`s{JS{-#}CRdW@hO`HfEp z1eR0DsN! zt5xmsYt{Uu;ZM`CgW)VYk=!$}N;w+Ct$Wf!*Z-7}@pA62F^1e$Ojz9O5H;TyT&rV( zr#IBM8te~-2t2;kv2xm&z%tt3pyt|s#vg2EOx1XkfsB*RM;D>ab$W-D6#Jdf zJ3{yD;P4=pFNk2GL$g~+5x;f9m*U2!ovWMK^U5`mAgBRhGpu)e`?#4vsE1aofu)iT zDm;aQIK6pNd8MMt@}h|t9c$)FT7PLDvu3e)y`otVe1SU4U=o@d!gn(DB9kC>Ac1wJ z?`{Hq$Q!rGb9h&VL#z+BKsLciCttdLJe9EmZF)J)c1MdVCrxg~EM80_b3k{ur=jVjrVhDK1GTjd3&t#ORvC0Q_&m|n>&TF1C_>k^8&ylR7oz#rG?mE%V| zepj0BlD|o?p8~LK_to`GINhGyW{{jZ{xqaO*SPvH)BYy1eH22DL_Kkn28N!0z3fzj z_+xZ3{ph_Tgkd)D$OjREak$O{F~mODA_D`5VsoobVnpxI zV0F_79%JB!?@jPs=cY73FhGuT!?fpVX1W=Wm zK5}i7(Pfh4o|Z{Ur=Y>bM1BDo2OdXBB(4Y#Z!61A8C6;7`6v-(P{ou1mAETEV?Nt< zMY&?ucJcJ$NyK0Zf@b;U#3ad?#dp`>zmNn=H1&-H`Y+)ai-TfyZJX@O&nRB*7j$ zDQF!q#a7VHL3z#Hc?Ca!MRbgL`daF zW#;L$yiQP|5VvgvRLluk3>-1cS+7MQ1)DC&DpYyS9j;!Rt$HdXK1}tG3G_)ZwXvGH zG;PB^f@CFrbEK4>3gTVj73~Tny+~k_pEHt|^eLw{?6NbG&`Ng9diB9XsMr(ztNC!{FhW8Hi!)TI`(Q|F*b z-z;#*c1T~kN67omP(l7)ZuTlxaC_XI(K8$VPfAzj?R**AMb0*p@$^PsN!LB@RYQ4U zA^xYY9sX4+;7gY%$i%ddfvneGfzbE4ZTJT5Vk3&1`?ULTy28&D#A&{dr5ZlZH&NTz zdfZr%Rw*Ukmgu@$C5$}QLOyb|PMA5syQns?iN@F|VFEvFPK321mTW^uv?GGNH6rnM zR9a2vB`}Y++T3Wumy$6`W)_c0PS*L;;0J^(T7<)`s{}lZVp`e)fM^?{$ zLbNw>N&6aw5Hlf_M)h8=)x0$*)V-w-Pw5Kh+EY{^$?#{v)_Y{9p5K{DjLnJ(ZUcyk*y(6D8wHB8=>Y)fb_Pw0v)Xybk`Sw@hNEaHP$-n`DtYP ziJyiauEXtuMpWyQjg$gdJR?e+=8w+=5GO-OT8pRaVFP1k^vI|I&agGjN-O*bJEK!M z`kt^POhUexh+PA&@And|vk-*MirW?>qB(f%y{ux z*d44UXxQOs+C`e-x4KSWhPg-!gO~kavIL8X3?!Ac2ih-dkK~Ua2qlcs1b-AIWg*8u z0QvL~51vS$LnmJSOnV4JUCUzg&4;bSsR5r_=FD@y|)Y2R_--e zMWJ;~*r=vJssF5_*n?wF0DO_>Mja=g+HvT=Yd^uBU|aw zRixHUQJX0Pgt-nFV+8&|;-n>!jNUj!8Y_YzH*%M!-_uWt6& z|Ec+lAD``i^do;u_?<(RpzsYZVJ8~}|NjUFgXltofbjhf!v&208g^#0h-x?`z8cInq!9kfVwJ|HQ;VK>p_-fn@(3q?e51Keq(=U-7C0#as-q z8Or}Ps07>O2@AAXz_%3bTOh{tKm#uRe}Sqr=w6-Wz$FCdfF3qNabEaj`-OfipxaL- zPh2R*l&%ZbcV?lv4C3+t2DAVSFaRo20^W_n4|0t(_*`?KmmUHG2sNZ*CRZlCFIyZbJqLdBCj)~%if)g|4NJr(8!R!E0iBbm$;`m;1n2@(8*E%B zH!g{hK|WK?1jUfM9zX?hlV#l%!6^p$$P+~rg}OdKg|d^Ed4WTY1$1J@WWHr$Os_(L z;-Zu1FJqhR4LrCUl)C~E7gA!^wtA6YIh10In9rX@LGSjnTPtLp+gPGp6u z3}{?J1!yT~?FwqT;O_-1%37f#4ek&DL){N}MX3RbNfRb-T;U^wXhx#De&QssA$lu~ mWkA_K7-+yz9tH*t6hj_Qg(_m7JaeTomk=)l!_+yTk^le-`GmOu delta 34176 zcmX7vV`H6d(}mmEwr$(CZQE$vU^m*aZQE(=WXEZ2+l}qF_w)XN>&rEBu9;)4>7EB0 zo(HR^Mh47P)@z^^pH!4#b(O8!;$>N+S+v5K5f8RrQ+Qv0_oH#e!pI2>yt4ij>fI9l zW&-hsVAQg%dpn3NRy$kb_vbM2sr`>bZ48b35m{D=OqX;p8A${^Dp|W&J5mXvUl#_I zN!~GCBUzj~C%K?<7+UZ_q|L)EGG#_*2Zzko-&Kck)Qd2%CpS3{P1co1?$|Sj1?E;PO z7alI9$X(MDly9AIEZ-vDLhpAKd1x4U#w$OvBtaA{fW9)iD#|AkMrsSaNz(69;h1iM1#_ z?u?O_aKa>vk=j;AR&*V-p3SY`CI}Uo%eRO(Dr-Te<99WQhi>y&l%UiS%W2m(d#woD zW?alFl75!1NiUzVqgqY98fSQNjhX3uZ&orB08Y*DFD;sjIddWoJF;S_@{Lx#SQk+9 zvSQ-620z0D7cy8-u_7u?PqYt?R0m2k%PWj%V(L|MCO(@3%l&pzEy7ijNv(VXU9byn z@6=4zL|qk*7!@QWd9imT9i%y}1#6+%w=s%WmsHbw@{UVc^?nL*GsnACaLnTbr9A>B zK)H-$tB`>jt9LSwaY+4!F1q(YO!E7@?SX3X-Ug4r($QrmJnM8m#;#LN`kE>?<{vbCZbhKOrMpux zTU=02hy${;n&ikcP8PqufhT9nJU>s;dyl;&~|Cs+o{9pCu{cRF+0{iyuH~6=tIZXVd zR~pJBC3Hf-g%Y|bhTuGyd~3-sm}kaX5=T?p$V?48h4{h2;_u{b}8s~Jar{39PnL7DsXpxcX#3zx@f9K zkkrw9s2*>)&=fLY{=xeIYVICff2Id5cc*~l7ztSsU@xuXYdV1(lLGZ5)?mXyIDf1- zA7j3P{C5s?$Y-kg60&XML*y93zrir8CNq*EMx)Kw)XA(N({9t-XAdX;rjxk`OF%4-0x?ne@LlBQMJe5+$Ir{Oj`@#qe+_-z!g5qQ2SxKQy1ex_x^Huj%u+S@EfEPP-70KeL@7@PBfadCUBt%`huTknOCj{ z;v?wZ2&wsL@-iBa(iFd)7duJTY8z-q5^HR-R9d*ex2m^A-~uCvz9B-1C$2xXL#>ow z!O<5&jhbM&@m=l_aW3F>vjJyy27gY}!9PSU3kITbrbs#Gm0gD?~Tub8ZFFK$X?pdv-%EeopaGB#$rDQHELW!8bVt`%?&>0 zrZUQ0!yP(uzVK?jWJ8^n915hO$v1SLV_&$-2y(iDIg}GDFRo!JzQF#gJoWu^UW0#? z*OC-SPMEY!LYY*OO95!sv{#-t!3Z!CfomqgzFJld>~CTFKGcr^sUai5s-y^vI5K={ z)cmQthQuKS07e8nLfaIYQ5f}PJQqcmokx?%yzFH*`%k}RyXCt1Chfv5KAeMWbq^2MNft;@`hMyhWg50(!jdAn;Jyx4Yt)^^DVCSu?xRu^$*&&=O6#JVShU_N3?D)|$5pyP8A!f)`| z>t0k&S66T*es5(_cs>0F=twYJUrQMqYa2HQvy)d+XW&rai?m;8nW9tL9Ivp9qi2-` zOQM<}D*g`28wJ54H~1U!+)vQh)(cpuf^&8uteU$G{9BUhOL| zBX{5E1**;hlc0ZAi(r@)IK{Y*ro_UL8Ztf8n{Xnwn=s=qH;fxkK+uL zY)0pvf6-iHfX+{F8&6LzG;&d%^5g`_&GEEx0GU=cJM*}RecV-AqHSK@{TMir1jaFf&R{@?|ieOUnmb?lQxCN!GnAqcii9$ z{a!Y{Vfz)xD!m2VfPH=`bk5m6dG{LfgtA4ITT?Sckn<92rt@pG+sk>3UhTQx9ywF3 z=$|RgTN<=6-B4+UbYWxfQUOe8cmEDY3QL$;mOw&X2;q9x9qNz3J97)3^jb zdlzkDYLKm^5?3IV>t3fdWwNpq3qY;hsj=pk9;P!wVmjP|6Dw^ez7_&DH9X33$T=Q{>Nl zv*a*QMM1-2XQ)O=3n@X+RO~S`N13QM81^ZzljPJIFBh%x<~No?@z_&LAl)ap!AflS zb{yFXU(Uw(dw%NR_l7%eN2VVX;^Ln{I1G+yPQr1AY+0MapBnJ3k1>Zdrw^3aUig*! z?xQe8C0LW;EDY(qe_P!Z#Q^jP3u$Z3hQpy^w7?jI;~XTz0ju$DQNc4LUyX}+S5zh> zGkB%~XU+L?3pw&j!i|x6C+RyP+_XYNm9`rtHpqxvoCdV_MXg847oHhYJqO+{t!xxdbsw4Ugn($Cwkm^+36&goy$vkaFs zrH6F29eMPXyoBha7X^b+N*a!>VZ<&Gf3eeE+Bgz7PB-6X7 z_%2M~{sTwC^iQVjH9#fVa3IO6E4b*S%M;#WhHa^L+=DP%arD_`eW5G0<9Tk=Ci?P@ z6tJXhej{ZWF=idj32x7dp{zmQY;;D2*11&-(~wifGXLmD6C-XR=K3c>S^_+x!3OuB z%D&!EOk;V4Sq6eQcE{UEDsPMtED*;qgcJU^UwLwjE-Ww54d73fQ`9Sv%^H>juEKmxN+*aD=0Q+ZFH1_J(*$~9&JyUJ6!>(Nj zi3Z6zWC%Yz0ZjX>thi~rH+lqv<9nkI3?Ghn7@!u3Ef){G(0Pvwnxc&(YeC=Kg2-7z zr>a^@b_QClXs?Obplq@Lq-l5>W);Y^JbCYk^n8G`8PzCH^rnY5Zk-AN6|7Pn=oF(H zxE#8LkI;;}K7I^UK55Z)c=zn7OX_XVgFlEGSO}~H^y|wd7piw*b1$kA!0*X*DQ~O` z*vFvc5Jy7(fFMRq>XA8Tq`E>EF35{?(_;yAdbO8rrmrlb&LceV%;U3haVV}Koh9C| zTZnR0a(*yN^Hp9u*h+eAdn)d}vPCo3k?GCz1w>OOeme(Mbo*A7)*nEmmUt?eN_vA; z=~2}K_}BtDXJM-y5fn^v>QQo+%*FdZQFNz^j&rYhmZHgDA-TH47#Wjn_@iH4?6R{J z%+C8LYIy>{3~A@|y4kN8YZZp72F8F@dOZWp>N0-DyVb4UQd_t^`P)zsCoygL_>>x| z2Hyu7;n(4G&?wCB4YVUIVg0K!CALjRsb}&4aLS|}0t`C}orYqhFe7N~h9XQ_bIW*f zGlDCIE`&wwyFX1U>}g#P0xRRn2q9%FPRfm{-M7;}6cS(V6;kn@6!$y06lO>8AE_!O z{|W{HEAbI0eD$z9tQvWth7y>qpTKQ0$EDsJkQxAaV2+gE28Al8W%t`Pbh zPl#%_S@a^6Y;lH6BfUfZNRKwS#x_keQ`;Rjg@qj zZRwQXZd-rWngbYC}r6X)VCJ-=D54A+81%(L*8?+&r7(wOxDSNn!t(U}!;5|sjq zc5yF5$V!;%C#T+T3*AD+A({T)#p$H_<$nDd#M)KOLbd*KoW~9E19BBd-UwBX1<0h9 z8lNI&7Z_r4bx;`%5&;ky+y7PD9F^;Qk{`J@z!jJKyJ|s@lY^y!r9p^75D)_TJ6S*T zLA7AA*m}Y|5~)-`cyB+lUE9CS_`iB;MM&0fX**f;$n($fQ1_Zo=u>|n~r$HvkOUK(gv_L&@DE0b4#ya{HN)8bNQMl9hCva zi~j0v&plRsp?_zR zA}uI4n;^_Ko5`N-HCw_1BMLd#OAmmIY#ol4M^UjLL-UAat+xA+zxrFqKc@V5Zqan_ z+LoVX-Ub2mT7Dk_ z<+_3?XWBEM84@J_F}FDe-hl@}x@v-s1AR{_YD!_fMgagH6s9uyi6pW3gdhauG>+H? zi<5^{dp*5-9v`|m*ceT&`Hqv77oBQ+Da!=?dDO&9jo;=JkzrQKx^o$RqAgzL{ zjK@n)JW~lzxB>(o(21ibI}i|r3e;17zTjdEl5c`Cn-KAlR7EPp84M@!8~CywES-`mxKJ@Dsf6B18_!XMIq$Q3rTDeIgJ3X zB1)voa#V{iY^ju>*Cdg&UCbx?d3UMArPRHZauE}c@Fdk;z85OcA&Th>ZN%}=VU%3b9={Q(@M4QaeuGE(BbZ{U z?WPDG+sjJSz1OYFpdImKYHUa@ELn%n&PR9&I7B$<-c3e|{tPH*u@hs)Ci>Z@5$M?lP(#d#QIz}~()P7mt`<2PT4oHH}R&#dIx4uq943D8gVbaa2&FygrSk3*whGr~Jn zR4QnS@83UZ_BUGw;?@T zo5jA#potERcBv+dd8V$xTh)COur`TQ^^Yb&cdBcesjHlA3O8SBeKrVj!-D3+_p6%P zP@e{|^-G-C(}g+=bAuAy8)wcS{$XB?I=|r=&=TvbqeyXiuG43RR>R72Ry7d6RS;n^ zO5J-QIc@)sz_l6%Lg5zA8cgNK^GK_b-Z+M{RLYk5=O|6c%!1u6YMm3jJg{TfS*L%2 zA<*7$@wgJ(M*gyTzz8+7{iRP_e~(CCbGB}FN-#`&1ntct@`5gB-u6oUp3#QDxyF8v zOjxr}pS{5RpK1l7+l(bC)0>M;%7L?@6t}S&a zx0gP8^sXi(g2_g8+8-1~hKO;9Nn%_S%9djd*;nCLadHpVx(S0tixw2{Q}vOPCWvZg zjYc6LQ~nIZ*b0m_uN~l{&2df2*ZmBU8dv`#o+^5p>D5l%9@(Y-g%`|$%nQ|SSRm0c zLZV)45DS8d#v(z6gj&6|ay@MP23leodS8-GWIMH8_YCScX#Xr)mbuvXqSHo*)cY9g z#Ea+NvHIA)@`L+)T|f$Etx;-vrE3;Gk^O@IN@1{lpg&XzU5Eh3!w;6l=Q$k|%7nj^ z|HGu}c59-Ilzu^w<93il$cRf@C(4Cr2S!!E&7#)GgUH@py?O;Vl&joXrep=2A|3Vn zH+e$Ctmdy3B^fh%12D$nQk^j|v=>_3JAdKPt2YVusbNW&CL?M*?`K1mK*!&-9Ecp~>V1w{EK(429OT>DJAV21fG z=XP=%m+0vV4LdIi#(~XpaUY$~fQ=xA#5?V%xGRr_|5WWV=uoG_Z&{fae)`2~u{6-p zG>E>8j({w7njU-5Lai|2HhDPntQ(X@yB z9l?NGoKB5N98fWrkdN3g8ox7Vic|gfTF~jIfXkm|9Yuu-p>v3d{5&hC+ZD%mh|_=* zD5v*u(SuLxzX~owH!mJQi%Z=ALvdjyt9U6baVY<88B>{HApAJ~>`buHVGQd%KUu(d z5#{NEKk6Vy08_8*E(?hqZe2L?P2$>!0~26N(rVzB9KbF&JQOIaU{SumX!TsYzR%wB z<5EgJXDJ=1L_SNCNZcBWBNeN+Y`)B%R(wEA?}Wi@mp(jcw9&^1EMSM58?68gwnXF` zzT0_7>)ep%6hid-*DZ42eU)tFcFz7@bo=<~CrLXpNDM}tv*-B(ZF`(9^RiM9W4xC%@ZHv=>w(&~$Wta%)Z;d!{J;e@z zX1Gkw^XrHOfYHR#hAU=G`v43E$Iq}*gwqm@-mPac0HOZ0 zVtfu7>CQYS_F@n6n#CGcC5R%4{+P4m7uVlg3axX}B(_kf((>W?EhIO&rQ{iUO$16X zv{Abj3ZApUrcar7Ck}B1%RvnR%uocMlKsRxV9Qqe^Y_5C$xQW@9QdCcF%W#!zj;!xWc+0#VQ*}u&rJ7)zc+{vpw+nV?{tdd&Xs`NV zKUp|dV98WbWl*_MoyzM0xv8tTNJChwifP!9WM^GD|Mkc75$F;j$K%Y8K@7?uJjq-w zz*|>EH5jH&oTKlIzueAN2926Uo1OryC|CmkyoQZABt#FtHz)QmQvSX35o`f z<^*5XXxexj+Q-a#2h4(?_*|!5Pjph@?Na8Z>K%AAjNr3T!7RN;7c)1SqAJfHY|xAV z1f;p%lSdE8I}E4~tRH(l*rK?OZ>mB4C{3e%E-bUng2ymerg8?M$rXC!D?3O}_mka? zm*Y~JMu+_F7O4T;#nFv)?Ru6 z92r|old*4ZB$*6M40B;V&2w->#>4DEu0;#vHSgXdEzm{+VS48 z7U1tVn#AnQ3z#gP26$!dmS5&JsXsrR>~rWA}%qd{92+j zu+wYAqrJYOA%WC9nZ>BKH&;9vMSW_59z5LtzS4Q@o5vcrWjg+28#&$*8SMYP z!l5=|p@x6YnmNq>23sQ(^du5K)TB&K8t{P`@T4J5cEFL@qwtsCmn~p>>*b=37y!kB zn6x{#KjM{S9O_otGQub*K)iIjtE2NfiV~zD2x{4r)IUD(Y8%r`n;#)ujIrl8Sa+L{ z>ixGoZJ1K@;wTUbRRFgnltN_U*^EOJS zRo4Y+S`cP}e-zNtdl^S5#%oN#HLjmq$W^(Y6=5tM#RBK-M14RO7X(8Gliy3+&9fO; zXn{60%0sWh1_g1Z2r0MuGwSGUE;l4TI*M!$5dm&v9pO7@KlW@j_QboeDd1k9!7S)jIwBza-V#1)(7ht|sjY}a19sO!T z2VEW7nB0!zP=Sx17-6S$r=A)MZikCjlQHE)%_Ka|OY4+jgGOw=I3CM`3ui^=o0p7u z?xujpg#dRVZCg|{%!^DvoR*~;QBH8ia6%4pOh<#t+e_u!8gjuk_Aic=|*H24Yq~Wup1dTRQs0nlZOy+30f16;f7EYh*^*i9hTZ`h`015%{i|4 z?$7qC3&kt#(jI#<76Biz=bl=k=&qyaH>foM#zA7}N`Ji~)-f-t&tR4^do)-5t?Hz_Q+X~S2bZx{t+MEjwy3kGfbv(ij^@;=?H_^FIIu*HP_7mpV)NS{MY-Rr7&rvWo@Wd~{Lt!8|66rq`GdGu% z@<(<7bYcZKCt%_RmTpAjx=TNvdh+ZiLkMN+hT;=tC?%vQQGc7WrCPIYZwYTW`;x|N zrlEz1yf95FiloUU^(onr3A3>+96;;6aL?($@!JwiQ2hO|^i)b4pCJ7-y&a~B#J`#FO!3uBp{5GBvM2U@K85&o0q~6#LtppE&cVY z3Bv{xQ-;i}LN-60B2*1suMd=Fi%Y|7@52axZ|b=Wiwk^5eg{9X4}(q%4D5N5_Gm)` zg~VyFCwfkIKW(@@ZGAlTra6CO$RA_b*yz#){B82N7AYpQ9)sLQfhOAOMUV7$0|d$=_y&jl>va$3u-H z_+H*|UXBPLe%N2Ukwu1*)kt!$Y>(IH3`YbEt; znb1uB*{UgwG{pQnh>h@vyCE!6B~!k}NxEai#iY{$!_w54s5!6jG9%pr=S~3Km^EEA z)sCnnau+ZY)(}IK#(3jGGADw8V7#v~<&y5cF=5_Ypkrs3&7{}%(4KM7) zuSHVqo~g#1kzNwXc39%hL8atpa1Wd#V^uL=W^&E)fvGivt)B!M)?)Y#Ze&zU6O_I?1wj)*M;b*dE zqlcwgX#eVuZj2GKgBu@QB(#LHMd`qk<08i$hG1@g1;zD*#(9PHjVWl*5!;ER{Q#A9 zyQ%fu<$U?dOW=&_#~{nrq{RRyD8upRi}c-m!n)DZw9P>WGs>o1vefI}ujt_`O@l#Z z%xnOt4&e}LlM1-0*dd?|EvrAO-$fX8i{aTP^2wsmSDd!Xc9DxJB=x1}6|yM~QQPbl z0xrJcQNtWHgt*MdGmtj%x6SWYd?uGnrx4{m{6A9bYx`m z$*UAs@9?3s;@Jl19%$!3TxPlCkawEk12FADYJClt0N@O@Pxxhj+Kk(1jK~laR0*KGAc7%C4nI^v2NShTc4#?!p{0@p0T#HSIRndH;#Ts0YECtlSR}~{Uck+keoJq6iH)(Zc~C!fBe2~4(Wd> zR<4I1zMeW$<0xww(@09!l?;oDiq zk8qjS9Lxv$<5m#j(?4VLDgLz;8b$B%XO|9i7^1M;V{aGC#JT)c+L=BgCfO5k>CTlI zOlf~DzcopV29Dajzt*OcYvaUH{UJPaD$;spv%>{y8goE+bDD$~HQbON>W*~JD`;`- zZEcCPSdlCvANe z=?|+e{6AW$f(H;BND>uy1MvQ`pri>SafK5bK!YAE>0URAW9RS8#LWUHBOc&BNQ9T+ zJpg~Eky!u!9WBk)!$Z?!^3M~o_VPERYnk1NmzVYaGH;1h+;st==-;jzF~2LTn+x*k zvywHZg7~=aiJe=OhS@U>1fYGvT1+jsAaiaM;) zay2xsMKhO+FIeK?|K{G4SJOEt*eX?!>K8jpsZWW8c!X|JR#v(1+Ey5NM^TB1n|_40 z@Db2gH}PNT+3YEyqXP8U@)`E|Xat<{K5K;eK7O0yV72m|b!o43!e-!P>iW>7-9HN7 zmmc7)JX0^lPzF#>$#D~nU^3f!~Q zQWly&oZEb1847&czU;dg?=dS>z3lJkADL1innNtE(f?~OxM`%A_PBp?Lj;zDDomf$ z;|P=FTmqX|!sHO6uIfCmh4Fbgw@`DOn#`qAPEsYUiBvUlw zevH{)YWQu>FPXU$%1!h*2rtk_J}qNkkq+StX8Wc*KgG$yH#p-kcD&)%>)Yctb^JDB zJe>=!)5nc~?6hrE_3n^_BE<^;2{}&Z>Dr)bX>H{?kK{@R)`R5lnlO6yU&UmWy=d03 z*(jJIwU3l0HRW1PvReOb|MyZT^700rg8eFp#p<3Et%9msiCxR+jefK%x81+iN0=hG z;<`^RUVU+S)Iv-*5y^MqD@=cp{_cP4`s=z)Ti3!Bf@zCmfpZTwf|>|0t^E8R^s`ad z5~tA?0x7OM{*D;zb6bvPu|F5XpF11`U5;b*$p zNAq7E6c=aUnq>}$JAYsO&=L^`M|DdSSp5O4LA{|tO5^8%Hf1lqqo)sj=!aLNKn9(3 zvKk($N`p`f&u+8e^Z-?uc2GZ_6-HDQs@l%+pWh!|S9+y3!jrr3V%cr{FNe&U6(tYs zLto$0D+2}K_9kuxgFSeQ!EOXjJtZ$Pyl_|$mPQ9#fES=Sw8L% zO7Jij9cscU)@W+$jeGpx&vWP9ZN3fLDTp zaYM$gJD8ccf&g>n?a56X=y zec%nLN`(dVCpSl9&pJLf2BN;cR5F0Nn{(LjGe7RjFe7efp3R_2JmHOY#nWEc2TMhMSj5tBf-L zlxP3sV`!?@!mRnDTac{35I7h@WTfRjRiFw*Q*aD8)n)jdkJC@)jD-&mzAdK6Kqdct8P}~dqixq;n zjnX!pb^;5*Rr?5ycT7>AB9)RED^x+DVDmIbHKjcDv2lHK;apZOc=O@`4nJ;k|iikKk66v4{zN#lmSn$lh z_-Y3FC)iV$rFJH!#mNqWHF-DtSNbI)84+VLDWg$ph_tkKn_6+M1RZ!)EKaRhY={el zG-i@H!fvpH&4~$5Q+zHU(Ub=;Lzcrc3;4Cqqbr$O`c5M#UMtslK$3r+Cuz>xKl+xW?`t2o=q`1djXC=Q6`3C${*>dm~I{ z(aQH&Qd{{X+&+-4{epSL;q%n$)NOQ7kM}ea9bA++*F+t$2$%F!U!U}(&y7Sd0jQMV zkOhuJ$+g7^kb<`jqFiq(y1-~JjP13J&uB=hfjH5yAArMZx?VzW1~>tln~d5pt$uWR~TM!lIg+D)prR zocU0N2}_WTYpU`@Bsi1z{$le`dO{-pHFQr{M}%iEkX@0fv!AGCTcB90@e|slf#unz z*w4Cf>(^XI64l|MmWih1g!kwMJiifdt4C<5BHtaS%Ra>~3IFwjdu;_v*7BL|fPu+c zNp687`{}e@|%)5g4U*i=0zlSWXzz=YcZ*&Bg zr$r(SH0V5a%oHh*t&0y%R8&jDI=6VTWS_kJ!^WN!ET@XfEHYG-T1jJsDd`yEgh!^* z+!P62=v`R2=TBVjt=h}|JIg7N^RevZuyxyS+jsk>=iLA52Ak+7L?2$ZDUaWdi1PgB z_;*Uae_n&7o27ewV*y(wwK~8~tU<#Np6UUIx}zW6fR&dKiPq|$A{BwG_-wVfkm+EP zxHU@m`im3cD#fH63>_X`Il-HjZN_hqOVMG;(#7RmI13D-s_>41l|vDH1BglPsNJ+p zTniY{Hwoief+h%C^|@Syep#722=wmcTR7awIzimAcye?@F~f|n<$%=rM+Jkz9m>PF70$)AK@|h_^(zn?!;={;9Zo7{ zBI7O?6!J2Ixxk;XzS~ScO9{K1U9swGvR_d+SkromF040|Slk%$)M;9O_8h0@WPe4= z%iWM^ust8w$(NhO)7*8uq+9CycO$3m-l}O70sBi<4=j0CeE_&3iRUWJkDM$FIfrkR zHG2|hVh3?Nt$fdI$W?<|Qq@#hjDijk@7eUr1&JHYI>(_Q4^3$+Zz&R)Z`WqhBIvjo zX#EbA8P0Qla-yACvt)%oAVHa#kZi3Y8|(IOp_Z6J-t{)98*OXQ#8^>vTENsV@(M}^ z(>8BXw`{+)BfyZB!&85hT0!$>7$uLgp9hP9M7v=5@H`atsri1^{1VDxDqizj46-2^ z?&eA9udH#BD|QY2B7Zr$l;NJ-$L!u8G{MZoX)~bua5J=0p_JnM`$(D4S!uF}4smWq zVo%kQ~C~X?cWCH zo4s#FqJ)k|D{c_ok+sZ8`m2#-Uk8*o)io`B+WTD0PDA!G`DjtibftJXhPVjLZj~g& z=MM9nF$7}xvILx}BhM;J-Xnz0=^m1N2`Mhn6@ct+-!ijIcgi6FZ*oIPH(tGYJ2EQ0 z{;cjcc>_GkAlWEZ2zZLA_oa-(vYBp7XLPbHCBcGH$K9AK6nx}}ya%QB2=r$A;11*~ z_wfru1SkIQ0&QUqd)%eAY^FL!G;t@7-prQ|drDn#yDf%Uz8&kGtrPxKv?*TqkC(}g zUx10<;3Vhnx{gpWXM8H zKc0kkM~gIAts$E!X-?3DWG&^knj4h(q5(L;V81VWyC@_71oIpXfsb0S(^Js#N_0E} zJ%|XX&EeVPyu}? zz~(%slTw+tcY3ZMG$+diC8zed=CTN}1fB`RXD_v2;{evY z@MCG$l9Az+F()8*SqFyrg3jrN7k^x3?;A?L&>y{ZUi$T8!F7Dv8s}}4r9+Wo0h^m= zAob@CnJ;IR-{|_D;_w)? zcH@~&V^(}Ag}%A90);X2AhDj(-YB>$>GrW1F4C*1S5`u@N{T|;pYX1;E?gtBbPvS* zlv3r#rw2KCmLqX0kGT8&%#A6Sc(S>apOHtfn+UdYiN4qPawcL{Sb$>&I)Ie>Xs~ej z7)a=-92!sv-A{-7sqiG-ysG0k&beq6^nX1L!Fs$JU#fsV*CbsZqBQ|y z{)}zvtEwO%(&mIG|L?qs2Ou1rqTZHV@H+sm8Nth(+#dp0DW4VXG;;tCh`{BpY)THY z_10NNWpJuzCG%Q@#Aj>!v7Eq8eI6_JK3g2CsB2jz)2^bWiM{&U8clnV7<2?Qx5*k_ zl9B$P@LV7Sani>Xum{^yJ6uYxM4UHnw4zbPdM|PeppudXe}+OcX z!nr!xaUA|xYtA~jE|436iL&L={H3e}H`M1;2|pLG)Z~~Ug9X%_#D!DW>w}Es!D{=4 zxRPBf5UWm2{}D>Em;v43miQ~2{>%>O*`wA{7j;yh;*DV=C-bs;3p{AD;>VPcn>E;V zLgtw|Y{|Beo+_ABz`lofH+cdf33LjIf!RdcW~wWgmsE%2yCQGbst4TS_t%6nS8a+m zFEr<|9TQzQC@<(yNN9GR4S$H-SA?xiLIK2O2>*w-?cdzNPsG4D3&%$QOK{w)@Dk}W z|3_Z>U`XBu7j6Vc=es(tz}c7k4al1$cqDW4a~|xgE9zPX(C`IsN(QwNomzsBOHqjd zi{D|jYSv5 zC>6#uB~%#!!*?zXW`!yHWjbjwm!#eo3hm;>nJ!<`ZkJamE6i>>WqkoTpbm(~b%G_v z`t3Z#ERips;EoA_0c?r@WjEP|ulD+hue5r8946Sd0kuBD$A!=dxigTZn)u3>U;Y8l zX9j(R*(;;i&HrB&M|Xnitzf@><3#)aKy=bFCf5Hz@_);{nlL?J!U>%fL$Fk~Ocs3& zB@-Ek%W>h9#$QIYg07&lS_CG3d~LrygXclO!Ws-|PxMsn@n{?77wCaq?uj`dd7lllDCGd?ed&%5k{RqUhiN1u&?uz@Fq zNkv_4xmFcl?vs>;emR1R<$tg;*Ayp@rl=ik z=x2Hk zJqsM%++e|*+#camAiem6f;3-khtIgjYmNL0x|Mz|y{r{6<@_&a7^1XDyE>v*uo!qF zBq^I8PiF#w<-lFvFx9xKoi&0j)4LX~rWsK$%3hr@ebDv^($$T^4m4h#Q-(u*Mbt6F zE%y0Fvozv=WAaTj6EWZ)cX{|9=AZDvPQuq>2fUkU(!j1GmdgeYLX`B0BbGK(331ME zu3yZ3jQ@2)WW5!C#~y}=q5Av=_;+hNi!%gmY;}~~e!S&&^{4eJuNQ2kud%Olf8TRI zW-Dze987Il<^!hCO{AR5tLW{F1WLuZ>nhPjke@CSnN zzoW{m!+PSCb7byUf-1b;`{0GU^zg7b9c!7ueJF`>L;|akVzb&IzoLNNEfxp7b7xMN zKs9QG6v@t7X)yYN9}3d4>*ROMiK-Ig8(Do$3UI&E}z!vcH2t(VIk-cLyC-Y%`)~>Ce23A=dQsc<( ziy;8MmHki+5-(CR8$=lRt{(9B9W59Pz|z0^;`C!q<^PyE$KXt!KibFH*xcB9V%xTD zn;YlZ*tTukwr$(mWMka@|8CW-J8!zCXI{P1-&=wSvZf&%9SZ7m`1&2^nV#D z6T*)`Mz3wGUC69Fg0Xk!hwY}ykk!TE%mr57TLX*U4ygwvM^!#G`HYKLIN>gT;?mo% zAxGgzSnm{}vRG}K)8n(XjG#d+IyAFnozhk|uwiey(p@ zu>j#n4C|Mhtd=0G?Qn5OGh{{^MWR)V*geNY8d)py)@5a85G&_&OSCx4ASW8g&AEXa zC}^ET`eORgG*$$Q1L=9_8MCUO4Mr^1IA{^nsB$>#Bi(vN$l8+p(U^0dvN_{Cu-UUm zQyJc!8>RWp;C3*2dGp49QVW`CRR@no(t+D|@nl138lu@%c1VCy3|v4VoKZ4AwnnjF z__8f$usTzF)TQ$sQ^|#(M}-#0^3Ag%A0%5vA=KK$37I`RY({kF-z$(P50pf3_20YTr%G@w+bxE_V+Tt^YHgrlu$#wjp7igF!=o8e2rqCs|>XM9+M7~TqI&fcx z=pcX6_MQQ{TIR6a0*~xdgFvs<2!yaA1F*4IZgI!)xnzJCwsG&EElg_IpFbrT}nr)UQy}GiK;( zDlG$cksync34R3J^FqJ=={_y9x_pcd%$B*u&vr7^ItxqWFIAkJgaAQiA)pioK1JQ| zYB_6IUKc$UM*~f9{Xzw*tY$pUglV*?BDQuhsca*Fx!sm`9y`V&?lVTH%%1eJ74#D_ z7W+@8@7LAu{aq)sPys{MM~;`k>T%-wPA)E2QH7(Z4XEUrQ5YstG`Uf@w{n_Oc!wem z7=8z;k$N{T74B*zVyJI~4d60M09FYG`33;Wxh=^Ixhs69U_SG_deO~_OUO1s9K-8p z5{HmcXAaKqHrQ@(t?d@;63;Pnj2Kk<;Hx=kr>*Ko`F*l){%GVDj5nkohSU)B&5Vrc zo0u%|b%|VITSB)BXTRPQC=Bv=qplloSI#iKV#~z#t#q*jcS`3s&w-z^m--CYDI7n2 z%{LHFZ*(1u4DvhES|Dc*n%JL8%8?h7boNf|qxl8D)np@5t~VORwQn)TuSI07b-T=_ zo8qh+0yf|-6=x;Ra$w&WeVZhUO%3v6Ni*}i&sby3s_(?l5Er{K9%0_dE<`7^>8mLr zZ|~l#Bi@5}8{iZ$(d9)!`}@2~#sA~?uH|EbrJQcTw|ssG)MSJJIF96-_gf&* zy~I&$m6e0nnLz^M2;G|IeUk?s+afSZ){10*P~9W%RtYeSg{Nv5FG<2QaWpj?d`;}<4( z>V1i|wNTpH`jJtvTD0C3CTws410U9HS_%Ti2HaB~%^h6{+$@5`K9}T=eQL;dMZ?=Y zX^z?B3ZU_!E^OW%Z*-+t&B-(kLmDwikb9+F9bj;NFq-XHRB=+L)Rew{w|7p~7ph{#fRT}}K zWA)F7;kJBCk^aFILnkV^EMs=B~#qh*RG2&@F|x2$?7QTX_T6qL?i$c6J*-cNQC~E6dro zR)CGIoz;~V?=>;(NF4dihkz~Koqu}VNPE9^R{L@e6WkL{fK84H?C*uvKkO(!H-&y( zq|@B~juu*x#J_i3gBrS0*5U*%NDg+Ur9euL*5QaF^?-pxxieMM6k_xAP;S}sfKmIa zj(T6o{4RfARHz25YWzv=QaJ4P!O$LHE(L~6fB89$`6+olZR!#%y?_v+Cf+g)5#!ZM zkabT-y%v|ihYuV}Y%-B%pxL264?K%CXlbd_s<GY5BG*`kYQjao$QHiC_qPk5uE~AO+F=eOtTWJ1vm*cU(D5kvs3kity z$IYG{$L<8|&I>|WwpCWo5K3!On`)9PIx(uWAq>bSQTvSW`NqgprBIuV^V>C~?+d(w$ZXb39Vs`R=BX;4HISfN^qW!{4 z^amy@Nqw6oqqobiNlxzxU*z2>2Q;9$Cr{K;*&l!;Y??vi^)G|tefJG9utf|~4xh=r3UjmRlADyLC*i`r+m;$7?7*bL!oR4=yU<8<-3XVA z%sAb`xe&4RV(2vj+1*ktLs<&m~mGJ@RuJ)1c zLxZyjg~*PfOeAm8R>7e&#FXBsfU_?azU=uxBm=E6z7FSr7J>{XY z1qUT>dh`X(zHRML_H-7He^P_?148AkDqrb>;~1M-k+xHVy>;D7p!z=XBgxMGQX2{* z-xMCOwS33&K^~3%#k`eIjKWvNe1f3y#}U4;J+#-{;=Xne^6+eH@eGJK#i|`~dgV5S zdn%`RHBsC!=9Q=&=wNbV#pDv6rgl?k1wM03*mN`dQBT4K%uRoyoH{e=ZL5E*`~X|T zbKG9aWI}7NGTQtjc3BYDTY3LbkgBNSHG$5xVx8gc@dEuJqT~QPBD=Scf53#kZzZ6W zM^$vkvMx+-0$6R^{{hZ2qLju~e85Em>1nDcRN3-Mm7x;87W#@RSIW9G>TT6Q{4e~b z8DN%n83FvXWdpr|I_8TaMv~MCqq0TA{AXYO-(~l=ug42gpMUvOjG_pWSEdDJ2Bxqz z!em;9=7y3HW*XUtK+M^)fycd8A6Q@B<4biGAR)r%gQf>lWI%WmMbij;un)qhk$bff zQxb{&L;`-1uvaCE7Fm*83^0;!QA5-zeSvKY}WjbwE68)jqnOmj^CTBHaD zvK6}Mc$a39b~Y(AoS|$%ePoHgMjIIux?;*;=Y|3zyfo)^fM=1GBbn7NCuKSxp1J|z zC>n4!X_w*R8es1ofcPrD>%e=E*@^)7gc?+JC@mJAYsXP;10~gZv0!Egi~){3mjVzs z^PrgddFewu>Ax_G&tj-!L=TuRl0FAh#X0gtQE#~}(dSyPO=@7yd zNC6l_?zs_u5&x8O zQ|_JvKf!WHf43F0R%NQwGQi-Dy7~PGZ@KRKMp?kxlaLAV=X{UkKgaTu2!qzPi8aJ z-;n$}unR?%uzCkMHwb56T%IUV)h>qS(XiuRLh3fdlr!Cri|{fZf0x9GVYUOlsKgxLA7vHrkpQddcSsg4JfibzpB zwR!vYiL)7%u8JG7^x@^px(t-c_Xt|9Dm)C@_zGeW_3nMLZBA*9*!fLTV$Uf1a0rDt zJI@Z6pdB9J(a|&T_&AocM2WLNB;fpLnlOFtC9yE6cb39?*1@wy8UgruTtX?@=<6YW zF%82|(F7ANWQ`#HPyPqG6~ggFlhJW#R>%p@fzrpL^K)Kbwj(@#7s97r`)iJ{&-ToR z$7(mQI@~;lwY+8dSKP~0G|#sjL2lS0LQP3Oe=>#NZ|JKKYd6s6qwe#_6Xz_^L4PJ5TM_|#&~zy= zabr|kkr3Osj;bPz`B0s;c&kzzQ2C8|tC9tz;es~zr{hom8bT?t$c|t;M0t2F{xI;G z`0`ADc_nJSdT`#PYCWu4R0Rmbk#PARx(NBfdU>8wxzE(`jA}atMEsaG6zy8^^nCu| z9_tLj90r-&Xc~+p%1vyt>=q_hQsDYB&-hPj(-OGxFpesWm;A(Lh>UWy4SH9&+mB(A z2jkTQ2C&o(Q4wC_>|c()M8_kF?qKhNB+PW6__;U+?ZUoDp2GNr<|*j(CC*#v0{L2E zgVBw6|3c(~V4N*WgJsO(I3o>8)EO5;p7Xg8yU&%rZ3QSRB6Ig6MK7Wn5r+xo2V}fM z0QpfDB9^xJEi}W*Fv6>=p4%@eP`K5k%kCE0YF2Eu5L!DM1ZY7wh`kghC^NwxrL}90dRXjQx=H>8 zOWP@<+C!tcw8EL8aCt9{|4aT+x|70i6m*LP*lhp;kGr5f#OwRy`(60LK@rd=to5yk^%N z6MTSk)7)#!cGDV@pbQ>$N8i2rAD$f{8T{QM+|gaj^sBt%24UJGF4ufrG1_Ag$Rn?c zzICg9`ICT>9N_2vqvVG#_lf9IEd%G5gJ_!j)1X#d^KUJBkE9?|K03AEe zo>5Rql|WuUU=LhLRkd&0rH4#!!>sMg@4Wr=z2|}dpOa`4c;_DqN{3Pj`AgSnc;h%# z{ny1lK%7?@rwZO(ZACq#8mL)|vy8tO0d1^4l;^e?hU+zuH%-8Y^5YqM9}sRzr-XC0 zPzY1l($LC-yyy*1@eoEANoTLQAZ2lVto2r7$|?;PPQX`}rbxPDH-a$8ez@J#v0R5n z7P*qT3aHj02*cK)WzZmoXkw?e3XNu&DkElGZ0Nk~wBti%yLh+l2DYx&U1lD_NW_Yt zGN>yOF?u%ksMW?^+~2&p@NoPzk`T)8qifG_owD>@iwI3@u^Y;Mqaa!2DGUKi{?U3d z|Efe=CBc!_ZDoa~LzZr}%;J|I$dntN24m4|1(#&Tw0R}lP`a`?uT;>szf^0mDJx3u z6IJvpeOpS$OV!Xw21p>Xu~MZ(Nas5Iim-#QSLIYSNhYgx1V!AR>b zf5b7O`ITTvW5z%X8|7>&BeEs8~J1i47l;`7Y#MUMReQ4z!IL1rh8UauKNPG?7rV_;#Y zG*6Vrt^SsTMOpV7mkui}l_S8UNOBcYi+DzcMF>YKrs3*(q5fwVCr;_zO?gpGx*@%O zl`KOwYMSUs4e&}eM#FhB3(RIDJ9ZRn6NN{2Nf+ z2jcz%-u6IPq{n7N3wLH{9c+}4G(NyZa`UmDr5c-SPgj0Sy$VN#Vxxr;kF>-P;5k!w zuAdrP(H+v{Dybn78xM6^*Ym@UGxx?L)m}WY#R>6M2zXnPL_M9#h($ECz^+(4HmKN7 zA>E;`AEqouHJd7pegrq4zkk>kHh`TEb`^(_ea;v{?MW3Sr^FXegkqAQPM-h^)$#Jn z?bKbnXR@k~%*?q`TPL=sD8C+n^I#08(}d$H(@Y;3*{~nv4RLZLw`v=1M0-%j>CtT( zTp#U03GAv{RFAtj4vln4#E4eLOvt zs;=`m&{S@AJbcl1q^39VOtmN^Zm(*x(`(SUgF(=6#&^7oA8T_ojX>V5sJx@*cV|29 z)6_%P6}e}`58Sd;LY2cWv~w}fer&_c1&mlY0`YNNk9q=TRg@Khc5E$N`aYng=!afD z@ewAv^jl$`U5;q4OxFM4ab%X_Jv>V!98w$8ZN*`D-)0S7Y^6xW$pQ%g3_lEmW9Ef^ zGmFsQw`E!ATjDvy@%mdcqrD-uiKB}!)ZRwpZRmyu+x|RUXS+oQ*_jIZKAD~U=3B|t zz>9QQr91qJihg9j9rWHww{v@+SYBzCfc0kI=4Gr{ZLcC~mft^EkJ`CMl?8fZ z3G4ix71=2dQ`5QuTOYA0(}f`@`@U<#K?1TI(XO9c*()q!Hf}JUCaUmg#y?ffT9w1g zc)e=JcF-9J`hK{0##K#A>m^@ZFx!$g09WSBdc8O^IdP&JE@O{i0&G!Ztvt{L4q%x& zGE2s!RVi6ZN9)E*(c33HuMf7#X2*VPVThdmrVz-Fyqxcs&aI4DvP#bfW={h$9>K0HsBTUf z2&!G;( z^oOVIYJv~OM=-i`6=r4Z1*hC8Fcf3rI9?;a_rL*nr@zxwKNlxf(-#Kgn@C~4?BdKk zYvL?QcQeDwwR5_S(`sn&{PL6FYxwb-qSh_rUUo{Yi-GZz5rZotG4R<+!PfsGg`MVtomw z5kzOZJrh(#rMR_87KeP0Q=#^5~r_?y1*kN?3Fq% zvnzHw$r!w|Soxz8Nbx2d&{!#w$^Hua%fx!xUbc2SI-<{h>e2I;$rJL)4)hnT5cx^* zIq#+{3;Leun3Xo=C(XVjt_z)F#PIoAw%SqJ=~DMQeB zNWQ={d|1qtlDS3xFik}#j*8%DG0<^6fW~|NGL#P_weHnJ(cYEdJtI9#1-Pa8M}(r{ zwnPJB_qB?IqZw5h!hRwW2WIEb?&F<52Ruxpr77O2K>=t*3&Z@=5(c^Uy&JSph}{Q^ z0Tl|}gt=&vK;Rb9Tx{{jUvhtmF>;~k$8T7kp;EV`C!~FKW|r$n^d6=thh`)^uYgBd zydgnY9&mm$?B@pKK+_QreOm?wnl5l}-wA$RZCZukfC$slxbqv9uKq0o^QeSID96{Rm^084kZ)*`P zk))V~+<4-_7d6<~)PL%!+%JP`Dn23vUpH47h~xnA=B_a}rLy|7U-f0W+fH`{wnyh2 zD$JYdXuygeP5&OAqpl2)BZ|X){~G;E|7{liYf%AZFmXXyA@32qLA)tuuQz`n^iH1Y z=)pAzxK$jw0Xq?7`M`=kN2WeQFhz)p;QhjbKg#SB zP~_Vqo0SGbc5Q;v4Q7vm6_#iT+p9B>%{s`8H}r|hAL5I8Q|ceJAL*eruzD8~_m>fg26HvLpik&#{3Zd#|1C_>l&-RW2nBBzSO zQ3%G{nI*T}jBjr%3fjG*&G#ruH^ioDM>0 zb0vSM8ML?tPU*y%aoCq;V%x%~!W*HaebuDn9qeT*vk0%X>fq-4zrrQf{Uq5zI1rEy zjQ@V|Cp~$AoBu=VgnVl@Yiro>ZF{uB=5)~i1rZzmDTIzLBy`8Too!#Z4nE$Z{~uB( z_=o=gKuhVpy&`}-c&f%**M&(|;2iy+nZy2Su}GOAH_GT9z`!ogwn$+Bi&1ZhtPF zVS&LO5#Bq}cew$kvE7*t8W^{{7&7WaF{upy0mj*K&xbnXvSP9V$6m6cesHGC!&Us36ld9f*Pn8gbJb3`PPT|ZG zri2?uIu09i>6Y-0-8sREOU?WaGke0+rHPb^sp;*E{Z5P7kFJ@RiLZTO`cN2mRR#Nz zxjJ##Nk+Uy-2N-8K_@576L(kJ>$UhP+)|w!SQHkkz+e62*hpzyfmY4eQLZtZUhEdG zIZluDOoPDlt5#iw+2epC3vEATfok^?SDT`TzBwtgKjY z>ZImbO)i~T=IYAfw$3j2mF1Cj*_yqK(qw(U^r-!gcUKvWQrDG@E{lEyWDWOPtA9v{ z5($&mxw{nZWo_Ov??S#Bo1;+YwVfx%M23|o$24Hdf^&4hQeV=Cffa5MMYOu2NZLSC zQ4UxWvn+8%YVGDg(Y*1iHbUyT^=gP*COcE~QkU|&6_3h z-GOS6-@o9+Vd(D7x#NYt{Bvx2`P&ZuCx#^l0bR89Hr6Vm<||c3Waq(KO0eZ zH(|B;X}{FaZ8_4yyWLdK!G_q9AYZcoOY}Jlf3R;%oR5dwR(rk7NqyF%{r>F4s^>li z`R~-fh>YIAC1?%!O?mxLx!dq*=%IRCj;vXX628aZ;+^M0CDFUY0Rc<1P5e(OVX8n- z*1UOrX{J}b2N)6m5&_xw^WSN=Lp$I$T>f8K6|J_bj%ZsIYKNs1$TFt!RuCWF48;98`7D(XPVnk+~~i=U$} zR#;!ZRo4eVqlDxjDeE^3+8)bzG_o~VRwdxqvD^HNh#@o>1My$0*Y_`wfQ$y}az|Uz zM47oEaYNTH?J^w9EVNnvfmmbV+GHDe)Kf;$^@6?9DrSHnk@*{PuJ>ra|9KO!qQ-Fp zNNcZB4ZdAI>jEh@3Mt(E1Fy!^gH-Zx6&lr8%=duIgI^~gC{Q;4yoe;#F7B`w9daIe z{(I;y)=)anc;C;)#P`8H6~iAG_q-4rPJb(6rn4pjclGi6$_L79sFAj#CTv;t@94S6 zz`Id7?k!#3JItckcwOf?sj=Xr6oKvAyt1=jiWN@XBFoW6dw_+c9O9x2i4or?*~8f& zm<>yzc6Aw_E-gsGAa`6`cjK~k^TJt(^`E1^_h)5(8)1kzAsBxjd4+!hJ&&T!qklDN z`?j#za=(^wRCvEI75uE^K#IBe5!5g2XW}|lUqAmdmIQb7xJtP}G9^(=!V`ZS_7#RZ zjXq#Cekw>fE*YS-?Qea|7~H?)bbLK;G&(~%!B@H`o#LYAuu6;-c~jFfjY7GKZ|9~{ zE!`!d@@rhY_@5fDbuQ8gRI~R_vs4%fR5$?yot4hDPJ28k_Wzmc^0yzwMr#*(OXq@g zRUgQmJA?E>3GO=5N8iWIfBP{&QM%!Oa*iwTlbd0Fbm*QCX>oRb*2XfG-=Bz1Qz0$v zn#X!2C!LqE601LEMq;X7`P*5nurdKZAmmsI-zZ|rTH;AFxNDyZ_#hN2m4W(|YB64E z470#yh$;8QzsdA;6vbNvc95HLvZvyT4{C>F(fwy&izvNDuvfO1Z;`Ss#4a_c6pm*{0t|_i9z{@84^lffQa5zG4<{(+p5-S z^>lG-^GJR#V>;5f3~y%n=`U_jBp~WgB0cp;Lx5VZYPYCH&(evw#}AYRlGJ>vcoeVr z3%#-QUBgeH!GB>XLw;rT&oMI9ynP;leDwh4O2uM!oIWo&Qxk{^9#nX&^3GJ z(U~5{S9aw@yHH^yuQGso=~*JOC9Zdi6(TFP+IddkfK5Eu9q;+F9?PPNAe-O;;P_Aa zPJ{Dqa1gQb%dZ|0I{#B0(z|r(qq!A4CxlW92-LwXFjYfOzAT1DDK`9rm4AB~l&oVv zi6_{)M9L1%JP}i52y@`!T9RB~!CRel53wl?amNHqcuElq%hn)|#BPvW5_m51RVb|? zXQ&B*eAD}}QamG>o{?i~usG5X6IDa3+Xkb8w%7;C8|Cln70biA+ZH}fxkH^Wei$vZPnuqIT!Mmy26;mLfU z3Bbv4M^vvMlz-I+46=g>0^wWkmA!hlYj*I!%it^x9Kx(d{L|+L{rW?Y#hLHWJfd5X z>B=Swk8=;mRtIz}Hr3NE_garb5W*!7fnNM{+m2_>!cHZZlNEeof~7M#FBEQ+f&gJ3 z^zv*t?XV)jQi%0-Ra|ISiW-fx)DsK-> zI}Fv%uee$#-1PKJwr=lU89eh=M{>Nk7IlJ)U33U)lLW+OOU%A|9-Lf;`@c*+vX{W2 z{{?0QoP!#?8=5%yL=fP%iF+?n$0#iHz`P;1{Ra6iwr=V7v^8;NoLJ5)QxIyIx>ur?lMwV=mBo0BA?28kMow8SX=Ax5L%S~x4+EQi#Ig`(ht%)D(F#Pa!)SiHy&PvUp32=VtAsR|6|NZR@jkad zX^aEgojf9(-)rNOZ=NVA&a;6Cljkb=H-bY9m^_I)`pBHB16QW)sU27zF13ypefeATJc1Wzy39GrKF{UntHsIU59AdXp?j{eh2R)IbU&omd zk6(qzvE@hve1yM6dgkbz>5HDR&MD~yi$yymQ}?b;RfL$N-#l7(u?T^Wlu+Q;fo|jd zBe^jzGMHY(2=5l?bEIh+zgE$1TEQ&!p3fH;AW`P?W5Hkj3eJnT>dqg! zf~}A*SZU5HHDCbdywQ^l_PqssHRlrySYN=`hAv2sVrtcF!`kyEu%XeeRUTJU7vB%h zY0*)N$mLo6d=tJfe}IPIeiH~>AKwCpkn&WEfYgl?3anq5#-F$6$v-(G_j0*S9mdsn zg@ek_ut4(?+JP_9-n`YqoD(gAz+Ttm1#t za96D}oQR(o=e8wwes19_(p4g(A1vSGwPAp~Hh3hh!fc>u{1E^+^}AzwilFVf6^vbL zc&NnRs`u)N-P|Cu4()yTiuE{j_V&=K?iP!IUBf~ei2}~_KBvUAlXa;R#Wl`gOBtJ$Y5(L))@`riLB)v*r>9*8VfmQt<72?+fdwP{BA@?_qo>mN7yzICUCaeG(+>Rb~8wg~6U(P)NlDLuhQgjbC}=)HuZgC}0Z-qLX4lJ7^)8~!!*qP0=~`Y_(A z{@15*ZevZSI^s|OnpCeCwLXf#tgbq8y~R*GB5anmZ;_N!+-3>!wu@NBFCNJ$#y?{? zMI!?s*=_xA;V&aX)ROxzVW8*de+&P#2zucA|8mksdgCXBsZ*TM=%{L1Tk5LB_*^@&S?O=ot{h)1xRVSn27&Tk8>rF|6ruzYb;Nq) z;qvlmrP^SL$mhe4Ai)xpl6Wx&y;z8o!7-+6$qj;ZLXvfR71I@w(R|6lyuP6v-lP&r z@KK-TEmGQfMmk1c0^fd7!^si}T%b5a2%>T-Drh|^Cf z$}qxIv@zxbmJ#qjK6Q_aGDe{ciVT20V1lW52Xs!}x(4_j)sUXYdm4 zwYC9FOa;X*c*LxL;xE5ov?|?^7gWXyALy_D2GvDo-8%0-Y%9TkkO_Tcr2qIUg3(OC z%3wt?hyn*+e^z%(~2#!2dvMFa$mzgwk1I1X;naFMjXSbnmZ!zd%7u)=cgi z*0&@Scrl&BDfU(9Pks8#;!~v~r7~DN{G6WE&_;7i{{a*?oiCao(l%2ruxX0fAt69e2vLgL%Mf_)!*(Tz zNKW>sW@YB2vBfP>C&L|-pq)Uq^PsG_THu;8iEcqafO?0k$IQp1KyWyOoTxwmKvlc^ zO9$%Tt8;%qQxwy5;CsJ)V}a7I6}SvQ%0_H53Kcqx=m83fIzpLSGgfVe^SPdc*xPdciI5dg}#{Etv$e<)gGD=qm0v=!aN@*?$s zLhzD%4w{vf-g6FHQjG9XyC+4=bewb?Mz%!u8%oP{G9{UJFTLTcCi3R(=Nm&t&Sl(? zr>pj?=ECdDVa}-g%`LF^1EY@>7d}%VhYpKFSDPH)D(zB+gPe1m7E}W>TiW=8L0&(D&YG=0<&7G4Bu{;-#Ud;-1%Ta9V}U6fyK1YX z`Rq|i-X(loPZ)M$H%m@j7bGx>uj~y=0)!t#dc|c}+hT%~Sq>fefez0Ul|jOJHta~u zx7*mV6~Jpt(FkY(pQN91>aFk7VS%Sa^oLaq$*)W?fy`xuFJgH<2s=!Rz}_(qdmdF~ zlr2f=)q_vpi8X;Jq>5^$GweJ{iS`Khw2f)fsvKpgh;U~13a+9 zfaw}UuGiBy;q10pI^Avb#X3D=k_r(T{N;-xA)OM}2Py5L##<96NU*Sr7GQqhfrPej z?;B$Bt_sTxuSAPXfTSC{zr?@$$0iHxC@z*5F52j*PG87hh`0w3At8jPf*rjNE~_Gj z2)fjeUFJ(#l9uWuw&5#@13|AQ1;pdA?EL4YKq0JDR5T8I?aWGxI=J9}vdyH;gQ@iE z>+UnC2iwT0f80-VuE^bY!N@(}9?bOXyy%rTqSNDN4rO4Zt#(kZwcGgTp&3((F+nsd ze~B)%K6oP4WX_w1>|QImC;9q zy}4p+s%^Too2(gE>yo%+yY#F{)phtmNqsJPVQQ0lGR|H9q>aA&AtU4M+EZ%`xvQLb zbigBOc`dL}&j3er?EOI`!W)N#>+uwp_!h^5FspaEylq!e(FPY-6T3~WeNmZ<$?Y6y z-!bM1kD7ZF8xl+Pi6fiv1?)q%`aNxn#pK%)ct||L&Xnf8Gu&3g;Of{B8Pt=u`e+Mn zA(DmU#3cF#Nr7W;X0V4ksFHMcNDAf4G&D8VjLeZ^|5-f$>_|71>P3xuu)?4NJed*w z6GR_RB5HQLzT(h+`Y?-3esxeue{-Q%b+!&o>IJ!#=}#_&q+hwJga>fkt(*(WdoN5vSta z#$mMN6}YzYRpaBZ)j)EL91-oL1(|d(>%UclsTUOyXyWM&(hNqLwqtn`!E>HJM{ zh>M~xa1@*U^cwx-k5QjePr5=B6u*jpJ)C0{C?f7Yga+I^4$TleyX$x&jm9z@c!?cC z<2kY7)p^+W{AXd@l1C09_yB*TG|yzb96BYk z8Wpj81vB>zcR+qM4m~A44w1n7$fxB$-?MV}S?Fh}c_|2FXg`cZ?750i;Cdl-_nGK# zta)h)6!*AsQ-z8caSh)%5JY>_yCeJs~FpAzdY8 zF@SU_hN#~ip5I;UACFzx1v0yf{j97l&)e-=`d#1Kp6A(Kj&HC!%vK!wEdK3HFJ?|6 za;WwUczZ+&<$g!Td^48@lJtfW@doXL#jY6)dK_RDCQAZ}l&OdD+?Yl5-bqpsHZR^( zF{u_cR(x>u(c4i5f(^8!h6CV0#ZxRFhLlunWiGDLO6yoRb(wV<(P^8=fOU7Hp{AHE z;Yg%kg@6&tL3Z*IrbkDeQ$%rbalVP39D@LVrC2xSavnTp%PorXPf1DVzHyqjDsDnS zL=mv0a2s60bHKGQM)ue>npH0SCp;XtZFUzm?R-x7D*(PxMmuJ4J*K2eY&ebe0yQHe zVG&*qe{pot{PM^xQv`H_rn2FcYOrEN+I#uX^1`Id%J$;Hi2cNCU!0Hlc0TjxLzkss zHxmC;hQBu5U4J0XflWM;{uH`_47Sg)QyZ{8D&T0;bdc3{^^<=q7P?C_2E-}PQn>*= z2T5q^J|Q_2+x%Qt`i3m6=6V$)BxIx{2KAFkMb#q`iMCD|L>+}_dYVA$wBr1Zr}YOF z^MMGO@PHGGh>g|^yF`PvvtDwN@kxt?ClLcG<+murHMz1Asj!$l=b)4{d}SqOJ}>Y< zSeAyP@ZEcpx`ayIdp>{--UVLYC_cZZURh_!4u2(*#x@Tk(QJa}4BqqZ$6%LhF-HB~ zAcc?$I6KP}IxANcAteEBX$Ys?T=JB|Fnd3*UAO0mYAXCgWf~?7Z_G7G5`H4;S^QKK zG*2l75vI@DHQC*es>6&|r^#RHKRQ5rwv_l4`!(!I3%)Z$P1fnZ8N@27zyg}54ElO%SjQ_4uujX)4ta@Gz2)_>4b~vX|rhRIH-eqdD zL)xaEpW3K|a>daQRRR*_$W>rWOsW-IE4VQl3L$3}=-PFU)s@XG&9+DFivH-;2&w~$ES_nJZJH!?1mO!CnP)Jb{mW9=f`bDpo^PI6i4|YurK)Q1 z^Ys1oHRdr!$X4RuyR%kgp!a*Lz*_AAoJ$EVAdsNCoPA^VZE1pGO@D3UStACE+%vs6 z$io@E>DmB|3VV~GbOt2oc+K;t zdn3gaFvYz;vRN-+2+Qk{8|O}e86nVck)fZn3sg$j#dLVham{yGkc$I#!HF7mRS%f* z!+NdzG49K(qaO^SBlp@K@D?|^rAq;8{*@kRc4sYSNQmoy7@_RS_ksWl2T_38h2A)# ziU2WXWD03(NqS&Mu*?0-iK8X_Z3w`}c7MPv0qZ7iM|L3xdTnR{y!7{#82$}uJCiGT zqa=8<9L05hu6 z1N+2n7OzT{NEf?gS@eq7@buCDFe9mAxY%THo^b@BHckKK>jg6{@)>n z43cPs%$Qi0iwyZ+{C491>FRu5+6baJ{&XXXC@Sp+b!QE|{7_d?lm5K=B z)myKEcxjFm74+drF|JCYcxdY%ASig#YoRBRUV7An7f-%rqj%PHECbxh#5476cEq@NQL?dI6gUqvS@w zq!WmD(aR0{NxItAZCKDCVw=Zu{9WGDu^i?2g zLerPiOU*HSaXg^3CdOX^F6c9MiHINP339N%)a96`^Z-c#&EogcxMSYo0Cb4{-}q1( zRrJine`P|6WRkm8u4Ja1QRYq$AR>b7tugd#EsT-VmXN-t!TYjZy}i!uKi6$u>EJ?w zvdHZg+hp+5ree?>fdJAX)5#Wtm#2M-{~2jfX2{G`)?D6UD1MevdeeU;;HCi}AtJr( SGW6ptSs!X7{rG*o_g?|vpSEZK diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a80b22ce5..b82aa23a4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 0182d52c02884284068fec30dadad75dc6e2fc7b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Mar 2024 21:14:32 +0000 Subject: [PATCH 054/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.1.23 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dd3e3d38e..85d7a18c8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.1.22" +towny = "0.100.1.23" plotsquared = "7.3.6" # Third party From 9d20df9e6b81896b3244115515df3a0f896f6658 Mon Sep 17 00:00:00 2001 From: Zeranny Date: Sat, 23 Mar 2024 19:26:13 +0000 Subject: [PATCH 055/220] Fix queryRel returning data value for block at absolute coordinates (#2645) * Replace toWorld with toWorldRel for relative data * re-add accidentally deleted annotation --- .../worldedit/regions/shape/WorldEditExpressionEnvironment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/WorldEditExpressionEnvironment.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/WorldEditExpressionEnvironment.java index 4b87ebcc6..2284b9733 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/WorldEditExpressionEnvironment.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/WorldEditExpressionEnvironment.java @@ -85,7 +85,7 @@ public class WorldEditExpressionEnvironment implements ExpressionEnvironment { @SuppressWarnings("deprecation") @Override public int getBlockDataRel(double x, double y, double z) { - return extent.getBlock(toWorld(x, y, z)).getBlockType().getLegacyCombinedId() & 0xF; + return extent.getBlock(toWorldRel(x, y, z).toBlockPoint()).getBlockType().getLegacyCombinedId() & 0xF; } //FAWE start From 4c98ac2bd877062572507886d5fea0fe8447c4db Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 23 Mar 2024 19:27:44 +0000 Subject: [PATCH 056/220] Update eps1lon/actions-label-merge-conflict action to v3 --- .github/workflows/label-merge-conflicts.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/label-merge-conflicts.yaml b/.github/workflows/label-merge-conflicts.yaml index d189f5520..fa6f3d72d 100644 --- a/.github/workflows/label-merge-conflicts.yaml +++ b/.github/workflows/label-merge-conflicts.yaml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Label conflicting PRs - uses: eps1lon/actions-label-merge-conflict@v2.1.0 + uses: eps1lon/actions-label-merge-conflict@v3.0.0 with: dirtyLabel: "unresolved-merge-conflict" repoToken: "${{ secrets.GITHUB_TOKEN }}" From 5e234a7003e00674460eed65140f1a619a128d27 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 23 Mar 2024 21:56:42 +0000 Subject: [PATCH 057/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240323.213332-142 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index b225a6875..088dd6f41 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240320.215354-140") + the().paperDevBundle("1.20.4-R0.1-20240323.213332-142") compileOnly(libs.paperlib) } From c10f58ac950ef1a5ac343e4bcdecd7ede067dcaf Mon Sep 17 00:00:00 2001 From: Zeranny Date: Sun, 24 Mar 2024 14:49:58 +0000 Subject: [PATCH 058/220] Fix Linear pattern index incrementing above array length (#2626) * Fix index incrementing above array length in async * Add fork method --- .../function/pattern/LinearBlockPattern.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java index 086cf3a31..0b6ef1be9 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java @@ -1,5 +1,6 @@ package com.fastasyncworldedit.core.function.pattern; +import com.fastasyncworldedit.core.queue.Filter; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.pattern.AbstractPattern; @@ -7,6 +8,8 @@ import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; +import java.util.Arrays; + public class LinearBlockPattern extends AbstractPattern implements ResettablePattern { private final Pattern[] patternsArray; @@ -15,7 +18,7 @@ public class LinearBlockPattern extends AbstractPattern implements ResettablePat /** * Create a new {@link Pattern} instance * - * @param patterns array of patterns to linearly choose from based on x/z coordinates + * @param patterns array of patterns to linearly choose from */ public LinearBlockPattern(Pattern[] patterns) { this.patternsArray = patterns; @@ -23,18 +26,20 @@ public class LinearBlockPattern extends AbstractPattern implements ResettablePat @Override public BaseBlock applyBlock(BlockVector3 position) { - if (index == patternsArray.length) { - index = 0; - } - return patternsArray[index++].applyBlock(position); + index = (index + 1) % patternsArray.length; + return patternsArray[index].applyBlock(position); } @Override public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { - if (index == patternsArray.length) { - index = 0; - } - return patternsArray[index++].apply(extent, get, set); + index = (index + 1) % patternsArray.length; + return patternsArray[index].apply(extent, get, set); + } + + @Override + public Filter fork() { + final Pattern[] forked = Arrays.stream(this.patternsArray).map(Pattern::fork).toArray(Pattern[]::new); + return new LinearBlockPattern(forked); } @Override From 2dee197f2b1fad53827a2a2dcb2f02d84fb2e7a4 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Sun, 24 Mar 2024 18:02:16 +0100 Subject: [PATCH 059/220] Use correct find class in ExtentTraverser (#2649) use correct find class in ExtentTraverser --- .../com/fastasyncworldedit/core/util/ExtentTraverser.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/ExtentTraverser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/ExtentTraverser.java index e7038deaa..6ae147765 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/ExtentTraverser.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/ExtentTraverser.java @@ -51,11 +51,10 @@ public class ExtentTraverser { return last; } - @SuppressWarnings("unchecked") @Nullable - public U findAndGet(Class clazz) { - ExtentTraverser traverser = find(clazz); - return (traverser != null) ? (U) traverser.get() : null; + public U findAndGet(Class clazz) { + ExtentTraverser traverser = find(clazz); + return (traverser != null) ? traverser.get() : null; } @SuppressWarnings("unchecked") From c68544d66d095102511f971bd70ab2533eb9e343 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:51:53 +0000 Subject: [PATCH 060/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240325.123556-143 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 088dd6f41..d55d44a76 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240323.213332-142") + the().paperDevBundle("1.20.4-R0.1-20240325.123556-143") compileOnly(libs.paperlib) } From 8095111effa158f1d0e7991768e2ea1317321f6c Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Wed, 27 Mar 2024 15:15:42 +0100 Subject: [PATCH 061/220] Simplify processor ordering (#2651) --- .../extent/processor/MultiBatchProcessor.java | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/MultiBatchProcessor.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/MultiBatchProcessor.java index e57ccb490..c266fd544 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/MultiBatchProcessor.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/MultiBatchProcessor.java @@ -19,12 +19,9 @@ import org.apache.logging.log4j.Logger; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; import java.util.function.Supplier; @@ -80,28 +77,18 @@ public class MultiBatchProcessor implements IBatchProcessor { @Override public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { - Map> ordered = new HashMap<>(); + Map> ordered = new HashMap<>(); IChunkSet chunkSet = set; for (IBatchProcessor processor : processors) { if (processor.getScope() != ProcessorScope.ADDING_BLOCKS) { - ordered.merge( - processor.getScope().intValue(), - new HashSet<>(Collections.singleton(processor)), - (existing, theNew) -> { - existing.add(processor); - return existing; - } - ); + ordered.computeIfAbsent(processor.getScope().intValue(), k -> new ArrayList<>()) + .add(processor); continue; } chunkSet = processSet(processor, chunk, get, chunkSet); } - if (ordered.size() > 0) { - for (int i = 1; i <= 4; i++) { - Set processors = ordered.get(i); - if (processors == null) { - continue; - } + if (!ordered.isEmpty()) { + for (List processors : ordered.values()) { for (IBatchProcessor processor : processors) { chunkSet = processSet(processor, chunk, get, chunkSet); if (chunkSet == null) { From 7b8c7894bae20f30acb1504028d591e205a025b7 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Wed, 27 Mar 2024 15:16:06 +0100 Subject: [PATCH 062/220] Make usage of stateful patterns thread-safe (#2633) * Make usage of No(Axis)Patterns thread-safe * make more pattern usage thread-safe * make more WE patterns thread safe * remove StatefulPattern --- .../core/function/pattern/ExpressionPattern.java | 6 ++++++ .../function/pattern/Linear2DBlockPattern.java | 8 ++++++++ .../function/pattern/Linear3DBlockPattern.java | 8 ++++++++ .../core/function/pattern/LinearBlockPattern.java | 6 ++++++ .../core/function/pattern/MaskedPattern.java | 5 +++++ .../core/function/pattern/NoXPattern.java | 5 +++++ .../core/function/pattern/NoYPattern.java | 5 +++++ .../core/function/pattern/NoZPattern.java | 6 ++++++ .../core/function/pattern/OffsetPattern.java | 5 +++++ .../function/pattern/RandomOffsetPattern.java | 5 +++++ .../core/function/pattern/RelativePattern.java | 7 +++++++ .../pattern/SolidRandomOffsetPattern.java | 5 +++++ .../pattern/SurfaceRandomOffsetPattern.java | 5 +++++ .../extent/buffer/ForgetfulExtentBuffer.java | 7 +++++++ .../pattern/ExtentBufferedCompositePattern.java | 10 ++++++++++ .../sk89q/worldedit/function/pattern/Pattern.java | 5 +++++ .../worldedit/function/pattern/RandomPattern.java | 15 +++++++++++++++ .../function/pattern/StateApplyingPattern.java | 5 ++++- 18 files changed, 117 insertions(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/ExpressionPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/ExpressionPattern.java index a9c1ec962..638872ea8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/ExpressionPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/ExpressionPattern.java @@ -1,6 +1,7 @@ package com.fastasyncworldedit.core.function.pattern; import com.sk89q.worldedit.function.pattern.AbstractPattern; +import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.internal.expression.EvaluationException; import com.sk89q.worldedit.internal.expression.Expression; import com.sk89q.worldedit.internal.expression.ExpressionException; @@ -57,4 +58,9 @@ public class ExpressionPattern extends AbstractPattern { } } + @Override + public Pattern fork() { + return new ExpressionPattern(this.expression.clone()); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java index 523f22541..e99383d06 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java @@ -7,6 +7,8 @@ import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; +import java.util.Arrays; + import static java.lang.Math.floorDiv; /** @@ -52,4 +54,10 @@ public class Linear2DBlockPattern extends AbstractPattern { return patternsArray[index].apply(extent, get, set); } + @Override + public Pattern fork() { + final Pattern[] forked = Arrays.stream(this.patternsArray).map(Pattern::fork).toArray(Pattern[]::new); + return new Linear2DBlockPattern(forked, this.xScale, this.zScale); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java index ea2e37588..e4d3822cc 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java @@ -7,6 +7,8 @@ import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; +import java.util.Arrays; + import static java.lang.Math.floorDiv; /** @@ -56,4 +58,10 @@ public class Linear3DBlockPattern extends AbstractPattern { return patternsArray[index].apply(extent, get, set); } + @Override + public Pattern fork() { + final Pattern[] forked = Arrays.stream(this.patternsArray).map(Pattern::fork).toArray(Pattern[]::new); + return new Linear3DBlockPattern(forked, this.xScale, this.yScale, this.zScale); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java index 0b6ef1be9..c65918e89 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java @@ -47,4 +47,10 @@ public class LinearBlockPattern extends AbstractPattern implements ResettablePat index = 0; } + @Override + public Pattern fork() { + final Pattern[] forked = Arrays.stream(this.patternsArray).map(Pattern::fork).toArray(Pattern[]::new); + return new LinearBlockPattern(forked); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/MaskedPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/MaskedPattern.java index 5d840d771..a5210feba 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/MaskedPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/MaskedPattern.java @@ -43,4 +43,9 @@ public class MaskedPattern extends AbstractPattern { return secondary.apply(extent, get, set); } + @Override + public Pattern fork() { + return new MaskedPattern(this.mask.copy(), this.primary.fork(), this.secondary.fork()); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoXPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoXPattern.java index d9fefb1bc..b4e9aac37 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoXPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoXPattern.java @@ -36,4 +36,9 @@ public class NoXPattern extends AbstractPattern { return pattern.apply(extent, mutable, set); } + @Override + public Pattern fork() { + return new NoXPattern(this.pattern.fork()); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoYPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoYPattern.java index 05d26f496..2fefaedfc 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoYPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoYPattern.java @@ -36,4 +36,9 @@ public class NoYPattern extends AbstractPattern { return pattern.apply(extent, mutable, set); } + @Override + public Pattern fork() { + return new NoYPattern(this.pattern.fork()); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoZPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoZPattern.java index faebb59aa..8c100c5e3 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoZPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoZPattern.java @@ -1,6 +1,7 @@ package com.fastasyncworldedit.core.function.pattern; import com.fastasyncworldedit.core.math.MutableBlockVector3; +import com.fastasyncworldedit.core.queue.Filter; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.pattern.AbstractPattern; @@ -36,4 +37,9 @@ public class NoZPattern extends AbstractPattern { return pattern.apply(extent, mutable, set); } + @Override + public Pattern fork() { + return new NoZPattern(this.pattern.fork()); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java index 894f9d06a..628b848e8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java @@ -60,4 +60,9 @@ public class OffsetPattern extends AbstractPattern { return pattern.apply(extent, get, mutable); } + @Override + public Pattern fork() { + return new OffsetPattern(this.pattern.fork(), this.dx, this.dy, this.dz, this.minY, this.maxY); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java index 3eb5c3b77..c0afd02e3 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java @@ -72,4 +72,9 @@ public class RandomOffsetPattern extends AbstractPattern { return pattern.apply(extent, get, mutable); } + @Override + public Pattern fork() { + return new RandomOffsetPattern(this.pattern.fork(), this.dx, this.dy, this.dz, this.minY, this.maxY); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RelativePattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RelativePattern.java index cda875f04..541aaa494 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RelativePattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RelativePattern.java @@ -63,4 +63,11 @@ public class RelativePattern extends AbstractPattern implements ResettablePatter origin = null; } + @Override + public Pattern fork() { + RelativePattern forked = new RelativePattern(this.pattern.fork(), this.minY, this.maxY); + forked.origin = this.origin; // maintain origin for forks + return forked; + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SolidRandomOffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SolidRandomOffsetPattern.java index 12b64a497..54ecf6676 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SolidRandomOffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SolidRandomOffsetPattern.java @@ -94,4 +94,9 @@ public class SolidRandomOffsetPattern extends AbstractPattern { return pattern.apply(extent, get, set); } + @Override + public Pattern fork() { + return new SolidRandomOffsetPattern(this.pattern.fork(), this.dx, this.dy, this.dz, this.minY, this.maxY); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java index 73327f94a..34866fc54 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java @@ -129,4 +129,9 @@ public class SurfaceRandomOffsetPattern extends AbstractPattern { return !block.getBlockType().getMaterial().isMovementBlocker(); } + @Override + public Pattern fork() { + return new SurfaceRandomOffsetPattern(this.pattern.fork(), this.moves, this.minY, this.maxY); + } + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ForgetfulExtentBuffer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ForgetfulExtentBuffer.java index f569acd00..ca2bfd965 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ForgetfulExtentBuffer.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ForgetfulExtentBuffer.java @@ -235,4 +235,11 @@ public class ForgetfulExtentBuffer extends AbstractDelegateExtent implements Pat }; } + //FAWE - stateful pattern + @Override + public Pattern fork() { + return new ForgetfulExtentBuffer(extent, mask.copy()); + } + //FAWE end + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentBufferedCompositePattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentBufferedCompositePattern.java index 49e7f5472..863cf1e25 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentBufferedCompositePattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentBufferedCompositePattern.java @@ -25,6 +25,8 @@ import com.sk89q.worldedit.extent.buffer.ExtentBuffer; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; +import java.util.Arrays; + import static com.google.common.base.Preconditions.checkArgument; /** @@ -64,4 +66,12 @@ public class ExtentBufferedCompositePattern extends AbstractExtentPattern { return lastBlock; } + //FAWE - stateful pattern + @Override + public Pattern fork() { + final Pattern[] forkedPatterns = Arrays.stream(patterns).map(Pattern::fork).toArray(Pattern[]::new); + return new ExtentBufferedCompositePattern(getExtent(), forkedPatterns); + } + //FAWE end + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java index 801b07a65..ab284c0cf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java @@ -59,6 +59,11 @@ public interface Pattern extends Filter { apply(block, block, block); } + @Override + default Pattern fork() { // covariant return type + return this; + } + //FAWE end /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java index 1d2df7223..c45629e5f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java @@ -67,6 +67,13 @@ public class RandomPattern extends AbstractPattern { this.collection = RandomCollection.of(weights, random); this.patterns = parent.patterns; } + + private RandomPattern(SimpleRandom random, Map weights) { + this.random = random; + this.weights = weights; + this.collection = RandomCollection.of(weights, random); + this.patterns = new LinkedHashSet<>(weights.keySet()); + } //FAWE end /** @@ -107,6 +114,14 @@ public class RandomPattern extends AbstractPattern { public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { return collection.next(get.getBlockX(), get.getBlockY(), get.getBlockZ()).apply(extent, get, set); } + + @Override + public Pattern fork() { + final LinkedHashMap newWeights = new LinkedHashMap<>(); + this.weights.forEach((p, w) -> newWeights.put(p.fork(), w)); + return new RandomPattern(this.random, newWeights); + } + //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java index 3d834f76b..b328e78ea 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java @@ -29,13 +29,16 @@ import com.sk89q.worldedit.world.block.BlockType; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; import static com.sk89q.worldedit.blocks.Blocks.resolveProperties; public class StateApplyingPattern extends AbstractExtentPattern { private final Map states; - private final Map, Object>> cache = Maps.newHashMap(); + //FAWE - avoid race conditions + private final Map, Object>> cache = new ConcurrentHashMap<>(); + //FAWE end public StateApplyingPattern(Extent extent, Map statesToSet) { super(extent); From c1c3a5f7ed4d7223150e9fe23173ce8d75101796 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 27 Mar 2024 16:32:11 +0000 Subject: [PATCH 063/220] fix: git did not find conflict here, remove duplicate fork method --- .../core/function/pattern/LinearBlockPattern.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java index c65918e89..1490bf37d 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java @@ -36,12 +36,6 @@ public class LinearBlockPattern extends AbstractPattern implements ResettablePat return patternsArray[index].apply(extent, get, set); } - @Override - public Filter fork() { - final Pattern[] forked = Arrays.stream(this.patternsArray).map(Pattern::fork).toArray(Pattern[]::new); - return new LinearBlockPattern(forked); - } - @Override public void reset() { index = 0; From 4a767926c1ddaed7c9dc48f3024820790f1c2a9c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 21:58:06 +0000 Subject: [PATCH 064/220] Update dependency io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin to v1.5.12 --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index e4227d576..878f1b845 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -24,7 +24,7 @@ dependencies { implementation(gradleApi()) implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2") implementation("com.github.johnrengelman:shadow:8.1.1") - implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.11") + implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.12") } kotlin { From b60a0c532c6b76d9b943a5f19a9cfca211242845 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 19:56:45 +0000 Subject: [PATCH 065/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240329.175742-144 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index d55d44a76..3e2bbe382 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240325.123556-143") + the().paperDevBundle("1.20.4-R0.1-20240329.175742-144") compileOnly(libs.paperlib) } From 23bcdb0409e46f59776526946e7121f4e37c10bf Mon Sep 17 00:00:00 2001 From: Jordan Date: Sat, 30 Mar 2024 10:31:52 +0100 Subject: [PATCH 066/220] fix: introduce approx size to patterns and use in ScatterBrush (#2631) * fix: introduce approx size to patterns and use in ScatterBrush - fixes #2610 * Do not use patternsize in blockvectorset offset --- .../core/command/tool/brush/ScatterBrush.java | 34 +++++++- .../core/command/tool/brush/ShatterBrush.java | 5 +- .../core/function/pattern/OffsetPattern.java | 7 ++ .../pattern/RandomFullClipboardPattern.java | 16 ++++ .../function/pattern/RandomOffsetPattern.java | 5 ++ .../pattern/SurfaceRandomOffsetPattern.java | 5 ++ .../core/math/BlockVectorSet.java | 43 +++++++++++ .../core/math/LocalBlockVectorSet.java | 31 ++------ .../core/math/MutableBlockVector3.java | 16 ++++ .../core/util/collection/BlockVector3Set.java | 77 +++++++++++++++---- .../worldedit/function/pattern/Pattern.java | 11 +++ 11 files changed, 208 insertions(+), 42 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterBrush.java index 7ea15e421..5e6c9ac52 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterBrush.java @@ -5,6 +5,7 @@ import com.fastasyncworldedit.core.function.mask.RadiusMask; import com.fastasyncworldedit.core.function.mask.SurfaceMask; import com.fastasyncworldedit.core.math.BlockVectorSet; import com.fastasyncworldedit.core.math.LocalBlockVectorSet; +import com.fastasyncworldedit.core.util.collection.BlockVector3Set; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.command.tool.brush.Brush; @@ -64,8 +65,9 @@ public class ScatterBrush implements Brush { length = 1; visited.add(position); } - LocalBlockVectorSet placed = new LocalBlockVectorSet(); - placed.setOffset(position.getX(), position.getZ()); + BlockVector3 patternSize = pattern.size(); + BlockVector3Set placed = BlockVector3Set.getAppropriateVectorSet(patternSize.add(distance, distance, distance)); + placed.setOffset(position.getX(), position.getY(), position.getZ()); int maxFails = 1000; for (int i = 0; i < count; i++) { int index = ThreadLocalRandom.current().nextInt(length); @@ -88,7 +90,20 @@ public class ScatterBrush implements Brush { finish(editSession, placed, position, pattern, size); } + /** + * @deprecated Use {@link ScatterBrush#finish(EditSession, BlockVector3Set, BlockVector3, Pattern, double)} + */ + @Deprecated(forRemoval = true, since = "TODO") public void finish(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pos, Pattern pattern, double size) { + finish(editSession, (BlockVector3Set) placed, pos, pattern, size); + } + + /** + * Complete the scatter brush process. + * + * @since TODO + */ + public void finish(EditSession editSession, BlockVector3Set placed, BlockVector3 pos, Pattern pattern, double size) { } public boolean canApply(BlockVector3 pos) { @@ -99,8 +114,23 @@ public class ScatterBrush implements Brush { return surface.direction(pt); } + + /** + * @deprecated Use {@link ScatterBrush#apply(EditSession, BlockVector3Set, BlockVector3, Pattern, double)} + */ + @Deprecated(forRemoval = true, since = "TODO") public void apply(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pt, Pattern p, double size) throws MaxChangedBlocksException { + apply(editSession, (BlockVector3Set) placed, pt, p, size); + } + + /** + * Apply the scatter brush to a given position + * + * @since TODO + */ + public void apply(EditSession editSession, BlockVector3Set placed, BlockVector3 pt, Pattern p, double size) throws + MaxChangedBlocksException { editSession.setBlock(pt, p); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ShatterBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ShatterBrush.java index 58fdb4997..41b36e12c 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ShatterBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ShatterBrush.java @@ -3,6 +3,7 @@ package com.fastasyncworldedit.core.command.tool.brush; import com.fastasyncworldedit.core.function.mask.SurfaceMask; import com.fastasyncworldedit.core.math.LocalBlockVectorSet; import com.fastasyncworldedit.core.math.MutableBlockVector3; +import com.fastasyncworldedit.core.util.collection.BlockVector3Set; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.function.mask.Mask; @@ -24,7 +25,7 @@ public class ShatterBrush extends ScatterBrush { @Override public void apply( final EditSession editSession, - final LocalBlockVectorSet placed, + final BlockVector3Set placed, final BlockVector3 position, Pattern p, double size @@ -34,7 +35,7 @@ public class ShatterBrush extends ScatterBrush { @Override public void finish( EditSession editSession, - LocalBlockVectorSet placed, + BlockVector3Set placed, final BlockVector3 position, Pattern pattern, double size diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java index 628b848e8..9a5ca2ceb 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java @@ -60,6 +60,13 @@ public class OffsetPattern extends AbstractPattern { return pattern.apply(extent, get, mutable); } + @Override + public BlockVector3 size() { + // Not exactly the "size" but offset should be taken into consideration in most + // places where the "size" matters + return BlockVector3.at(dx, dy, dz); + } + @Override public Pattern fork() { return new OffsetPattern(this.pattern.fork(), this.dx, this.dy, this.dz, this.minY, this.maxY); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomFullClipboardPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomFullClipboardPattern.java index 52348780b..957cf2617 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomFullClipboardPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomFullClipboardPattern.java @@ -1,7 +1,9 @@ package com.fastasyncworldedit.core.function.pattern; +import com.fastasyncworldedit.core.math.MutableBlockVector3; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.function.pattern.AbstractPattern; import com.sk89q.worldedit.function.pattern.Pattern; @@ -9,6 +11,8 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.math.transform.Transform; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.world.block.BaseBlock; @@ -23,6 +27,7 @@ public class RandomFullClipboardPattern extends AbstractPattern { private final boolean randomRotate; private final boolean randomFlip; private final Vector3 flipVector = Vector3.at(1, 0, 0).multiply(-2).add(1, 1, 1); + private final BlockVector3 size; /** * Create a new {@link Pattern} instance @@ -34,6 +39,12 @@ public class RandomFullClipboardPattern extends AbstractPattern { public RandomFullClipboardPattern(List clipboards, boolean randomRotate, boolean randomFlip) { checkNotNull(clipboards); this.clipboards = clipboards; + MutableBlockVector3 mut = new MutableBlockVector3(); + clipboards.stream().flatMap(c -> c.getClipboards().stream()).map(c -> { + Region region = c.getRegion(); + return region.getMaximumPoint().subtract(c.getOrigin().getMinimum(region.getMinimumPoint())); + }).forEach(mut::getMaximum); + this.size = mut.toImmutable(); this.randomRotate = randomRotate; this.randomFlip = randomFlip; } @@ -66,4 +77,9 @@ public class RandomFullClipboardPattern extends AbstractPattern { throw new IllegalStateException("Incorrect use. This pattern can only be applied to an extent!"); } + @Override + public BlockVector3 size() { + return size; + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java index c0afd02e3..c68bb24b1 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java @@ -72,6 +72,11 @@ public class RandomOffsetPattern extends AbstractPattern { return pattern.apply(extent, get, mutable); } + @Override + public BlockVector3 size() { + return BlockVector3.at(dx2, dy2, dz2); + } + @Override public Pattern fork() { return new RandomOffsetPattern(this.pattern.fork(), this.dx, this.dy, this.dz, this.minY, this.maxY); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java index 34866fc54..03e3126be 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java @@ -129,6 +129,11 @@ public class SurfaceRandomOffsetPattern extends AbstractPattern { return !block.getBlockType().getMaterial().isMovementBlocker(); } + @Override + public BlockVector3 size() { + return BlockVector3.at(moves, moves, moves); + } + @Override public Pattern fork() { return new SurfaceRandomOffsetPattern(this.pattern.fork(), this.moves, this.minY, this.maxY); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BlockVectorSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BlockVectorSet.java index e904244de..67aeadec8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BlockVectorSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BlockVectorSet.java @@ -78,6 +78,49 @@ public class BlockVectorSet extends AbstractCollection implements return localMap != null && localMap.contains(x & 2047, ((y + 128) & 511) - 128, z & 2047); } + @Override + public void setOffset(final int x, final int z) { + // Do nothing + } + + @Override + public void setOffset(final int x, final int y, final int z) { + // Do nothing + } + + @Override + public boolean containsRadius(final int x, final int y, final int z, final int radius) { + if (radius <= 0) { + return contains(x, y, z); + } + // Quick corners check + if (!contains(x - radius, y, z - radius)) { + return false; + } + if (!contains(x + radius, y, z + radius)) { + return false; + } + if (!contains(x - radius, y, z + radius)) { + return false; + } + if (!contains(x + radius, y, z - radius)) { + return false; + } + // Slow but if someone wants to think of an elegant way then feel free to add it + for (int xx = -radius; xx <= radius; xx++) { + int rx = x + xx; + for (int yy = -radius; yy <= radius; yy++) { + int ry = y + yy; + for (int zz = -radius; zz <= radius; zz++) { + if (contains(rx, ry, z + zz)) { + return true; + } + } + } + } + return false; + } + @Override public boolean contains(Object o) { if (o instanceof BlockVector3 v) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/LocalBlockVectorSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/LocalBlockVectorSet.java index 8e6cdabe8..2ed3a2f63 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/LocalBlockVectorSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/LocalBlockVectorSet.java @@ -100,14 +100,7 @@ public class LocalBlockVectorSet implements BlockVector3Set { return new LocalBlockVectorSet(offsetX, offsetY, offsetZ, set.clone()); } - /** - * If a radius is contained by the set - * - * @param x x radius center - * @param y y radius center - * @param z z radius center - * @return if radius is contained by the set - */ + @Override public boolean containsRadius(int x, int y, int z, int radius) { if (radius <= 0) { return contains(x, y, z); @@ -130,9 +123,11 @@ public class LocalBlockVectorSet implements BlockVector3Set { return false; } for (int xx = -radius; xx <= radius; xx++) { + int rx = x + xx; for (int yy = -radius; yy <= radius; yy++) { + int ry = y + yy; for (int zz = -radius; zz <= radius; zz++) { - if (contains(x + xx, y + yy, z + zz)) { + if (contains(rx, ry, z + zz)) { return true; } } @@ -141,27 +136,13 @@ public class LocalBlockVectorSet implements BlockVector3Set { return false; } - /** - * Set the offset applied to values when storing and reading to keep the values within -1024 to 1023. Uses default y offset - * of 128 to allow -64 -> 320 world height use. - * - * @param x x offset - * @param z z offset - */ + @Override public void setOffset(int x, int z) { this.offsetX = x; this.offsetZ = z; } - /** - * Set the offset applied to values when storing and reading to keep the x and z values within -1024 to 1023. Y values - * require keeping withing -256 and 255. - * - * @param x x offset - * @param y y offset - * @param z z offset - * @since 2.2.0 - */ + @Override public void setOffset(int x, int y, int z) { this.offsetX = x; this.offsetY = y; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/MutableBlockVector3.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/MutableBlockVector3.java index baa20163f..6ebabae1d 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/MutableBlockVector3.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/MutableBlockVector3.java @@ -61,6 +61,22 @@ public class MutableBlockVector3 extends BlockVector3 { return z; } + @Override + public BlockVector3 getMinimum(BlockVector3 v2) { + this.x = Math.min(v2.getX(), x); + this.y = Math.min(v2.getY(), y); + this.z = Math.min(v2.getZ(), z); + return this; + } + + @Override + public BlockVector3 getMaximum(BlockVector3 v2) { + this.x = Math.max(v2.getX(), x); + this.y = Math.max(v2.getY(), y); + this.z = Math.max(v2.getZ(), z); + return this; + } + @Override public MutableBlockVector3 mutX(double x) { this.x = (int) x; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockVector3Set.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockVector3Set.java index 881aaf9f3..83a639ead 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockVector3Set.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockVector3Set.java @@ -9,29 +9,80 @@ import java.util.Set; public interface BlockVector3Set extends Set { + /** + * Get the appropriate {@link BlockVector3Set} implementation for the given region. Either {@link LocalBlockVectorSet} or + * {@link BlockVectorSet}. Sets the offset if using {@link LocalBlockVectorSet}. + * + * @param region Region to get for + * @return Appropriate {@link BlockVector3Set} implementation + */ static BlockVector3Set getAppropriateVectorSet(Region region) { BlockVector3 max = region.getMaximumPoint(); BlockVector3 min = region.getMinimumPoint(); - BlockVector3 size = region.getDimensions(); + BlockVector3Set set = getAppropriateVectorSet(region.getDimensions()); + // Set default offset as many operations utilising a region are likely to start in a corner, this initialising the + // LocalBlockVectorSet poorly + // This needs to be ceiling as LocalBlockVector extends 1 block further "negative" + int offsetX = (int) Math.ceil((min.getX() + max.getX()) / 2d); + int offsetZ = (int) Math.ceil((min.getZ() + max.getZ()) / 2d); + int offsetY; + if (region.getMinimumY() < -128 || region.getMaximumY() > 320) { + offsetY = (min.getY() + max.getY()) / 2; + } else { + offsetY = 128; + } + set.setOffset(offsetX, offsetY, offsetZ); + return set; + } + + /** + * Get the appropriate {@link BlockVector3Set} implementation for the given dimensions. Either {@link LocalBlockVectorSet} or + * {@link BlockVectorSet}. The offset should be manually set. + * + * @param size Dimensions to get for + * @return Appropriate {@link BlockVector3Set} implementation + */ + static BlockVector3Set getAppropriateVectorSet(BlockVector3 size) { if (size.getBlockX() > 2048 || size.getBlockZ() > 2048 || size.getBlockY() > 512) { return new BlockVectorSet(); } else { - // Set default offset as many operations utilising a region are likely to start in a corner, this initialising the - // LocalBlockVectorSet poorly - // This needs to be ceiling as LocalBlockVector extends 1 block further "negative" - int offsetX = (int) Math.ceil((min.getX() + max.getX()) / 2d); - int offsetZ = (int) Math.ceil((min.getZ() + max.getZ()) / 2d); - int offsetY; - if (region.getMinimumY() < -128 || region.getMaximumY() > 320) { - offsetY = (min.getY() + max.getY()) / 2; - } else { - offsetY = 128; - } - return new LocalBlockVectorSet(offsetX, offsetY, offsetZ); + return new LocalBlockVectorSet(); } } boolean add(int x, int y, int z); boolean contains(int x, int y, int z); + /** + * Set the offset applied to values when storing and reading to keep the values within -1024 to 1023. Uses default y offset + * of 128 to allow -64 -> 320 world height use. + * + * @param x x offset + * @param z z offset + * @since TODO + */ + void setOffset(int x, int z); + + /** + * Set the offset applied to values when storing and reading to keep the x and z values within -1024 to 1023. Y values + * require keeping withing -256 and 255. + * + * @param x x offset + * @param y y offset + * @param z z offset + * @since TODO + */ + void setOffset(int x, int y, int z); + + /** + * If a radius is contained by the set + * + * @param x x radius center + * @param y y radius center + * @param z z radius center + * @return if radius is contained by the set + * @since TODO + */ + boolean containsRadius(int x, int y, int z, int radius); + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java index ab284c0cf..e44a1c19d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java @@ -25,6 +25,7 @@ import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.world.block.BaseBlock; /** @@ -74,4 +75,14 @@ public interface Pattern extends Filter { */ BaseBlock applyBlock(BlockVector3 position); + /** + * Get the likely maximum size of the volume this pattern will affect + * + * @return Pattern size + * @since TODO + */ + default BlockVector3 size() { + return BlockVector3.ONE; + } + } From 673233c777f5637cfad37412b62563bf6fa347ca Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 30 Mar 2024 09:33:30 +0000 Subject: [PATCH 067/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.1.24 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 85d7a18c8..8862924f5 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.1.23" +towny = "0.100.1.24" plotsquared = "7.3.6" # Third party From 628d894244282ffa4e6a9d2600bd2c8050f6bf22 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 31 Mar 2024 04:21:01 +0000 Subject: [PATCH 068/220] Update piston to v0.5.9 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8862924f5..5d66014f2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -43,7 +43,7 @@ serverlib = "2.3.4" ## Internal text-adapter = "3.0.6" text = "3.0.4" -piston = "0.5.8" +piston = "0.5.9" # Tests mockito = "5.11.0" From 91b4393190d6ec51f08dc871ad5b505e5020e374 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 31 Mar 2024 19:27:29 +0000 Subject: [PATCH 069/220] Update piston to v0.5.10 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5d66014f2..f6d16d21d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -43,7 +43,7 @@ serverlib = "2.3.4" ## Internal text-adapter = "3.0.6" text = "3.0.4" -piston = "0.5.9" +piston = "0.5.10" # Tests mockito = "5.11.0" From af547e072c0d8bc78fbcd667d5bc411ebfaf24b7 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Mon, 1 Apr 2024 12:34:19 +0200 Subject: [PATCH 070/220] List FAWE class additions in Javadocs (#2659) * List FAWE class additions in Javadocs Signed-off-by: Alexander Brandes * Update worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/package-info.java --------- Signed-off-by: Alexander Brandes --- .../com/sk89q/worldedit/cli/package-info.java | 2 +- .../command/argument/package-info.java | 4 ++-- .../sk89q/worldedit/command/package-info.java | 2 +- .../command/util/annotation/package-info.java | 18 +++++++++--------- .../function/operation/package-info.java | 2 +- .../worldedit/world/block/package-info.java | 2 +- .../worldedit/world/chunk/package-info.java | 4 ++-- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/package-info.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/package-info.java index 11ccf05d1..60e756259 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/package-info.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/package-info.java @@ -1,6 +1,6 @@ /** * The following classes are FAWE additions: * - * @see com.sk89q.worldedit.cli.AccessPoint + * {@link com.sk89q.worldedit.cli.AccessPoint} */ package com.sk89q.worldedit.cli; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/package-info.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/package-info.java index 270468aa1..d1bd7bbd3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/package-info.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/package-info.java @@ -20,8 +20,8 @@ /** * The following classes are FAWE additions: * - * @see com.sk89q.worldedit.command.argument.ExpressionConverter - * @see com.sk89q.worldedit.command.argument.LocationConverter + * {@link com.sk89q.worldedit.command.argument.ExpressionConverter}, + * {@link com.sk89q.worldedit.command.argument.LocationConverter} */ @org.enginehub.piston.util.NonnullByDefault package com.sk89q.worldedit.command.argument; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/package-info.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/package-info.java index 61d4ea41d..4ffda131d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/package-info.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/package-info.java @@ -1,6 +1,6 @@ /** * The following classes are FAWE additions: * - * @see com.sk89q.worldedit.command.HistorySubCommands + * {@link com.sk89q.worldedit.command.HistorySubCommands} */ package com.sk89q.worldedit.command; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/package-info.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/package-info.java index dc15d98d6..006432a73 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/package-info.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/package-info.java @@ -1,14 +1,14 @@ /** * The following classes are FAWE additions: * - * @see com.sk89q.worldedit.command.util.annotation.AllowedRegion - * @see com.sk89q.worldedit.command.util.annotation.Confirm - * @see com.sk89q.worldedit.command.util.annotation.ConfirmHandler - * @see com.sk89q.worldedit.command.util.annotation.Link - * @see com.sk89q.worldedit.command.util.annotation.PatternList - * @see com.sk89q.worldedit.command.util.annotation.Preload - * @see com.sk89q.worldedit.command.util.annotation.PreloadHandler - * @see com.sk89q.worldedit.command.util.annotation.Step - * @see com.sk89q.worldedit.command.util.annotation.Time + * {@link com.sk89q.worldedit.command.util.annotation.AllowedRegion}, + * {@link com.sk89q.worldedit.command.util.annotation.Confirm}, + * {@link com.sk89q.worldedit.command.util.annotation.ConfirmHandler}, + * {@link com.sk89q.worldedit.command.util.annotation.Link}, + * {@link com.sk89q.worldedit.command.util.annotation.PatternList}, + * {@link com.sk89q.worldedit.command.util.annotation.Preload}, + * {@link com.sk89q.worldedit.command.util.annotation.PreloadHandler}, + * {@link com.sk89q.worldedit.command.util.annotation.Step}, + * {@link com.sk89q.worldedit.command.util.annotation.Time} */ package com.sk89q.worldedit.command.util.annotation; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/package-info.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/package-info.java index 5b9eb7485..13a3d4e7c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/package-info.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/package-info.java @@ -1,6 +1,6 @@ /** * The following classes are FAWE additions: * - * @see com.sk89q.worldedit.function.operation.BackwardsExtentBlockCopy + * {@link com.sk89q.worldedit.function.operation.BackwardsExtentBlockCopy} */ package com.sk89q.worldedit.function.operation; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/package-info.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/package-info.java index b8e54bc04..46a6490c9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/package-info.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/package-info.java @@ -1,6 +1,6 @@ /** * The following classes are FAWE additions: * - * @see com.sk89q.worldedit.world.block.BlockTypesCache + * {@link com.sk89q.worldedit.world.block.BlockTypesCache} */ package com.sk89q.worldedit.world.block; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/package-info.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/package-info.java index ecb29c521..5ec273554 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/package-info.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/package-info.java @@ -1,7 +1,7 @@ /** * The following classes are FAWE additions: * - * @see com.sk89q.worldedit.world.chunk.AnvilChunk15 - * @see com.sk89q.worldedit.world.chunk.AnvilChunk17 + * {@link com.sk89q.worldedit.world.chunk.AnvilChunk15}, + * {@link com.sk89q.worldedit.world.chunk.AnvilChunk17} */ package com.sk89q.worldedit.world.chunk; From 4ac3f5ba1a2d4e3bace137913f1640ae1e450c24 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 09:32:10 +0000 Subject: [PATCH 071/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.2.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f6d16d21d..f1c25e764 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.1.24" +towny = "0.100.2.0" plotsquared = "7.3.6" # Third party From 778c212e853b6c08c8ce65b2e1af9fb17c6d9dde Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Apr 2024 14:08:53 +0000 Subject: [PATCH 072/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240402.103709-145 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 3e2bbe382..e4539cd79 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240329.175742-144") + the().paperDevBundle("1.20.4-R0.1-20240402.103709-145") compileOnly(libs.paperlib) } From 5e10c98915795206be8cacf3dd2a3b46f3412786 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Thu, 4 Apr 2024 21:56:07 +0200 Subject: [PATCH 073/220] Release 2.9.2 Signed-off-by: Alexander Brandes --- build.gradle.kts | 2 +- .../core/command/tool/brush/ScatterBrush.java | 8 ++++---- .../fastasyncworldedit/core/extent/TransformExtent.java | 2 +- .../core/function/pattern/Linear2DBlockPattern.java | 2 +- .../core/function/pattern/Linear3DBlockPattern.java | 2 +- .../core/math/random/Linear2DRandom.java | 2 +- .../core/math/random/Linear3DRandom.java | 2 +- .../core/util/collection/BlockVector3Set.java | 6 +++--- .../com/sk89q/worldedit/function/pattern/Pattern.java | 2 +- .../worldedit/regions/selector/RegionSelectorType.java | 2 +- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 15845439a..8c2685561 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -52,7 +52,7 @@ ext { } } -version = String.format("%s-%s", rootVersion, buildNumber) +version = String.format("%s", rootVersion) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterBrush.java index 5e6c9ac52..e14d0c599 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterBrush.java @@ -93,7 +93,7 @@ public class ScatterBrush implements Brush { /** * @deprecated Use {@link ScatterBrush#finish(EditSession, BlockVector3Set, BlockVector3, Pattern, double)} */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.9.2") public void finish(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pos, Pattern pattern, double size) { finish(editSession, (BlockVector3Set) placed, pos, pattern, size); } @@ -101,7 +101,7 @@ public class ScatterBrush implements Brush { /** * Complete the scatter brush process. * - * @since TODO + * @since 2.9.2 */ public void finish(EditSession editSession, BlockVector3Set placed, BlockVector3 pos, Pattern pattern, double size) { } @@ -118,7 +118,7 @@ public class ScatterBrush implements Brush { /** * @deprecated Use {@link ScatterBrush#apply(EditSession, BlockVector3Set, BlockVector3, Pattern, double)} */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.9.2") public void apply(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pt, Pattern p, double size) throws MaxChangedBlocksException { apply(editSession, (BlockVector3Set) placed, pt, p, size); @@ -127,7 +127,7 @@ public class ScatterBrush implements Brush { /** * Apply the scatter brush to a given position * - * @since TODO + * @since 2.9.2 */ public void apply(EditSession editSession, BlockVector3Set placed, BlockVector3 pt, Pattern p, double size) throws MaxChangedBlocksException { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java index 64b940d97..250227439 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java @@ -15,7 +15,7 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; /** * @deprecated Unused internal, will be removed in v3 */ -@Deprecated(forRemoval = true, since = "TODO") +@Deprecated(forRemoval = true, since = "2.9.2") public class TransformExtent extends BlockTransformExtent { private final MutableVector3 mutable1 = new MutableVector3(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java index e99383d06..13df9ca6f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java @@ -15,7 +15,7 @@ import static java.lang.Math.floorDiv; * @deprecated replaced by {@link com.sk89q.worldedit.function.pattern.RandomPattern} * combined with {@link com.fastasyncworldedit.core.math.random.Linear2DRandom}. */ -@Deprecated(forRemoval = true, since = "TODO") +@Deprecated(forRemoval = true, since = "2.9.2") public class Linear2DBlockPattern extends AbstractPattern { private final Pattern[] patternsArray; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java index e4d3822cc..6c9d039d0 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java @@ -15,7 +15,7 @@ import static java.lang.Math.floorDiv; * @deprecated replaced by {@link com.sk89q.worldedit.function.pattern.RandomPattern} * combined with {@link com.fastasyncworldedit.core.math.random.Linear3DRandom}. */ -@Deprecated(forRemoval = true, since = "TODO") +@Deprecated(forRemoval = true, since = "2.9.2") public class Linear3DBlockPattern extends AbstractPattern { private final Pattern[] patternsArray; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear2DRandom.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear2DRandom.java index 4f039031e..04a837b72 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear2DRandom.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear2DRandom.java @@ -6,7 +6,7 @@ import static java.lang.Math.floorDiv; /** * A {@link SimpleRandom} that deterministically maps coordinates * to values. - * @since TODO + * @since 2.9.2 */ public class Linear2DRandom implements SimpleRandom { private final int xScale; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear3DRandom.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear3DRandom.java index 87f350fe4..a1ab87045 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear3DRandom.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/Linear3DRandom.java @@ -5,7 +5,7 @@ import static java.lang.Math.floorDiv; /** * A {@link SimpleRandom} that deterministically maps coordinates * to values. - * @since TODO + * @since 2.9.2 */ public class Linear3DRandom implements SimpleRandom { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockVector3Set.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockVector3Set.java index 83a639ead..cadc35fc8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockVector3Set.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockVector3Set.java @@ -59,7 +59,7 @@ public interface BlockVector3Set extends Set { * * @param x x offset * @param z z offset - * @since TODO + * @since 2.9.2 */ void setOffset(int x, int z); @@ -70,7 +70,7 @@ public interface BlockVector3Set extends Set { * @param x x offset * @param y y offset * @param z z offset - * @since TODO + * @since 2.9.2 */ void setOffset(int x, int y, int z); @@ -81,7 +81,7 @@ public interface BlockVector3Set extends Set { * @param y y radius center * @param z z radius center * @return if radius is contained by the set - * @since TODO + * @since 2.9.2 */ boolean containsRadius(int x, int y, int z, int radius); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java index e44a1c19d..69563af87 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java @@ -79,7 +79,7 @@ public interface Pattern extends Filter { * Get the likely maximum size of the volume this pattern will affect * * @return Pattern size - * @since TODO + * @since 2.9.2 */ default BlockVector3 size() { return BlockVector3.ONE; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/RegionSelectorType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/RegionSelectorType.java index 5c8655893..c76b058b1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/RegionSelectorType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/RegionSelectorType.java @@ -65,7 +65,7 @@ public enum RegionSelectorType { * Get a {@link RegionSelectorType} for the given {@link RegionSelector} * * @param selector Region selector to get type enum for - * @since TODO + * @since 2.9.2 */ @Nullable public static RegionSelectorType getForSelector(RegionSelector selector) { From a39ee6e045a28eb3f5cb83eb4fff71b79a48e8e2 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Thu, 4 Apr 2024 22:31:51 +0200 Subject: [PATCH 074/220] Back to snaptshot for development Signed-off-by: Alexander Brandes --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8c2685561..ae8df13a5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,7 +34,7 @@ logger.lifecycle(""" ******************************************* """) -var rootVersion by extra("2.9.2") +var rootVersion by extra("2.9.3") var snapshot by extra("SNAPSHOT") var revision: String by extra("") var buildNumber by extra("") @@ -52,7 +52,7 @@ ext { } } -version = String.format("%s", rootVersion) +version = String.format("%s-%s", rootVersion, buildNumber) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") From 08f89b9a6976da6bd9237467a680543d66322b1b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 20:32:52 +0000 Subject: [PATCH 075/220] Update plotsquared to v7.3.7 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f1c25e764..24872b49a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" towny = "0.100.2.0" -plotsquared = "7.3.6" +plotsquared = "7.3.7" # Third party bstats = "3.0.2" From 96f7ff4408711565ac1ab060385108ffe2b7c747 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 23:56:33 +0000 Subject: [PATCH 076/220] Update dependency io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin to v1.5.13 --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 878f1b845..c703a6c3a 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -24,7 +24,7 @@ dependencies { implementation(gradleApi()) implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2") implementation("com.github.johnrengelman:shadow:8.1.1") - implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.12") + implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.13") } kotlin { From 58fd4ac288960351978cafef613eea3c7644c727 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 11:03:19 +0000 Subject: [PATCH 077/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240405.071722-146 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index e4539cd79..d0188257f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240402.103709-145") + the().paperDevBundle("1.20.4-R0.1-20240405.071722-146") compileOnly(libs.paperlib) } From 8b597418cc9d484bd1e869c64e241d58eac13ae1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 Apr 2024 07:36:53 +0000 Subject: [PATCH 078/220] Update plugin io.github.gradle-nexus.publish-plugin to v2 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index ae8df13a5..8086d4bda 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ import java.time.format.DateTimeFormatter import xyz.jpenilla.runpaper.task.RunServer plugins { - id("io.github.gradle-nexus.publish-plugin") version "1.3.0" + id("io.github.gradle-nexus.publish-plugin") version "2.0.0" id("xyz.jpenilla.run-paper") version "2.2.3" } From 606e07bfdfb967d97895c5a4c8e69ec30b99dcec Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 Apr 2024 22:27:02 +0000 Subject: [PATCH 079/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240406.215857-153 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index d0188257f..72a2e29a3 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240405.071722-146") + the().paperDevBundle("1.20.4-R0.1-20240406.215857-153") compileOnly(libs.paperlib) } From b4c3ec3a64ca630ecce34398a951289fd7ee89bb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 7 Apr 2024 00:51:03 +0000 Subject: [PATCH 080/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240406.235646-156 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 72a2e29a3..478c29e59 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240406.215857-153") + the().paperDevBundle("1.20.4-R0.1-20240406.235646-156") compileOnly(libs.paperlib) } From d16cb8eb916ae6bf501334ebdd5bd20f9b9956f2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 7 Apr 2024 03:11:18 +0000 Subject: [PATCH 081/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240407.005218-157 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 478c29e59..888646fb0 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240406.235646-156") + the().paperDevBundle("1.20.4-R0.1-20240407.005218-157") compileOnly(libs.paperlib) } From fa6e924f567bccac4bc4288c85c8bfa455923618 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 08:03:47 +0000 Subject: [PATCH 082/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240408.052944-158 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 888646fb0..5c69ec443 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240407.005218-157") + the().paperDevBundle("1.20.4-R0.1-20240408.052944-158") compileOnly(libs.paperlib) } From ca2c18e0069a9dc5ce2a8bc012c0f91eebf4f5a5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 21:42:05 +0000 Subject: [PATCH 083/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.2.1 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 24872b49a..84eb05c9c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.2.0" +towny = "0.100.2.1" plotsquared = "7.3.7" # Third party From d0b676210b49c695ce2319d1261f2c52311f8554 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 00:33:15 +0000 Subject: [PATCH 084/220] Update dependency io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin to v1.5.15 --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index c703a6c3a..f3058a653 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -24,7 +24,7 @@ dependencies { implementation(gradleApi()) implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2") implementation("com.github.johnrengelman:shadow:8.1.1") - implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.13") + implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.15") } kotlin { From a0ef151341016b3ae9e024dc777f0330a922bab9 Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Fri, 12 Apr 2024 20:55:40 +0200 Subject: [PATCH 085/220] Fix heightmap brush with imgur images (#2680) fix: heightmap brush with imgur / remote images --- .../core/util/MainUtil.java | 20 +++++++++++-------- .../core/util/image/ImageUtil.java | 6 +++--- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java index 41c4e5704..1c5fe044a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java @@ -554,8 +554,15 @@ public class MainUtil { } public static BufferedImage readImage(URL url) throws IOException { + try (final InputStream stream = readImageStream(url.toURI())) { + return readImage(stream); + } catch (URISyntaxException e) { + throw new IOException("failed to parse url to uri reference", e); + } + } + + public static InputStream readImageStream(final URI uri) throws IOException { try { - final URI uri = url.toURI(); HttpRequest.Builder requestBuilder = HttpRequest.newBuilder(uri).GET(); if (uri.getHost().equalsIgnoreCase("i.imgur.com")) { @@ -566,16 +573,13 @@ public class MainUtil { requestBuilder.build(), HttpResponse.BodyHandlers.ofInputStream() ); - try (final InputStream body = response.body()) { - if (response.statusCode() > 299) { - throw new IOException("Expected 2xx as response code, but received " + response.statusCode()); - } - return readImage(body); + final InputStream body = response.body(); + if (response.statusCode() > 299) { + throw new IOException("Expected 2xx as response code, but received " + response.statusCode()); } + return body; } catch (InterruptedException e) { throw new IOException("request was interrupted", e); - } catch (URISyntaxException e) { - throw new IOException("failed to parse url to uri reference", e); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/image/ImageUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/image/ImageUtil.java index f99a17e6f..c7c8edda3 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/image/ImageUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/image/ImageUtil.java @@ -176,8 +176,8 @@ public class ImageUtil { } public static BufferedImage load(URI uri) throws InputParseException { - try { - return MainUtil.readImage(getInputStream(uri)); + try (final InputStream stream = getInputStream(uri)) { + return MainUtil.readImage(stream); } catch (IOException e) { throw new InputParseException(TextComponent.of(e.getMessage())); } @@ -190,7 +190,7 @@ public class ImageUtil { File file = new File(uri.getPath()); return new FileInputStream(file); } - return new URL(uriStr).openStream(); + return MainUtil.readImageStream(uri); } catch (IOException e) { throw new InputParseException(TextComponent.of(e.getMessage())); } From c1e2f23f94711bb42c17b29a9eb7c6ad4ceff4f4 Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Fri, 12 Apr 2024 20:55:58 +0200 Subject: [PATCH 086/220] Fix error on adapting custom entities / entity types (#2674) chore/fix: entity type adaption, more in line with upstream --- .../bukkit/adapter/IBukkitAdapter.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java index 29162b607..9792f9344 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java @@ -31,6 +31,8 @@ import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemTypes; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.Registry; import org.bukkit.TreeType; import org.bukkit.block.Biome; import org.bukkit.block.data.BlockData; @@ -186,10 +188,12 @@ public interface IBukkitAdapter { } default org.bukkit.entity.EntityType adapt(EntityType entityType) { - if (!entityType.getId().startsWith("minecraft:")) { - throw new IllegalArgumentException("Bukkit only supports vanilla entities"); + NamespacedKey entityKey = NamespacedKey.fromString(entityType.toString()); + if (entityKey == null) { + throw new IllegalArgumentException("Entity key '" + entityType + "' does not map to Bukkit"); } - return org.bukkit.entity.EntityType.fromName(entityType.getId().substring(10).toLowerCase(Locale.ROOT)); + + return Registry.ENTITY_TYPE.get(entityKey); } /** @@ -343,7 +347,7 @@ public interface IBukkitAdapter { * @return WorldEdit EntityType */ default EntityType adapt(org.bukkit.entity.EntityType entityType) { - return EntityTypes.get(entityType.getName().toLowerCase(Locale.ROOT)); + return EntityTypes.get(entityType.getKey().toString()); } /** From e76904f228e6869932184abf72403cacc5ee7688 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 18:56:45 +0000 Subject: [PATCH 087/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240412.173131-159 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 5c69ec443..108bce749 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240408.052944-158") + the().paperDevBundle("1.20.4-R0.1-20240412.173131-159") compileOnly(libs.paperlib) } From ed38f96f92767e93d3a6e6867bda7f1945aa398a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 21:18:25 +0000 Subject: [PATCH 088/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240412.201522-163 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 108bce749..361fd380a 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240412.173131-159") + the().paperDevBundle("1.20.4-R0.1-20240412.201522-163") compileOnly(libs.paperlib) } From 34dc1ddcd715a09e121c035f2d554367a10c4cad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 01:00:20 +0000 Subject: [PATCH 089/220] Update gradle/wrapper-validation-action action to v3 --- .github/workflows/build-pr.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/upload-release-assets.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index de239164e..0d3ffdfdd 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -11,7 +11,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v2 + uses: gradle/wrapper-validation-action@v3 - name: Setup Java uses: actions/setup-java@v4 with: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 675f0cc1c..8e80ad997 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v2 + uses: gradle/wrapper-validation-action@v3 - name: Setup Java uses: actions/setup-java@v4 with: diff --git a/.github/workflows/upload-release-assets.yml b/.github/workflows/upload-release-assets.yml index a621e9d13..b88961eb4 100644 --- a/.github/workflows/upload-release-assets.yml +++ b/.github/workflows/upload-release-assets.yml @@ -9,7 +9,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v2 + uses: gradle/wrapper-validation-action@v3 - name: Setup Java uses: actions/setup-java@v4 with: From e426e7c8ee293cdb6ba2ad4b63f2285606d016e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 01:00:14 +0000 Subject: [PATCH 090/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240412.212303-164 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 361fd380a..460b1a0de 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240412.201522-163") + the().paperDevBundle("1.20.4-R0.1-20240412.212303-164") compileOnly(libs.paperlib) } From 41af66e86b42ac5e1e2042563f2215d28ed0cf62 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 20:31:18 +0000 Subject: [PATCH 091/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.2.2 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 84eb05c9c..91a96e24f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.2.1" +towny = "0.100.2.2" plotsquared = "7.3.7" # Third party From 1d79f2705a13ef19e27c9d3a56d67f6f9924aec1 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Sun, 14 Apr 2024 10:37:46 +0200 Subject: [PATCH 092/220] Update wrapper validation Signed-off-by: Alexander Brandes --- .github/workflows/build-pr.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/upload-release-assets.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 0d3ffdfdd..fbb90ab03 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -11,7 +11,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v3 + uses: gradle/actions/wrapper-validation@v3 - name: Setup Java uses: actions/setup-java@v4 with: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8e80ad997..d6072de2f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v3 + uses: gradle/actions/wrapper-validation@v3 - name: Setup Java uses: actions/setup-java@v4 with: diff --git a/.github/workflows/upload-release-assets.yml b/.github/workflows/upload-release-assets.yml index b88961eb4..bff53a6b2 100644 --- a/.github/workflows/upload-release-assets.yml +++ b/.github/workflows/upload-release-assets.yml @@ -9,7 +9,7 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - name: Validate Gradle Wrapper - uses: gradle/wrapper-validation-action@v3 + uses: gradle/actions/wrapper-validation@v3 - name: Setup Java uses: actions/setup-java@v4 with: From cdad55ef777b283700319f64ce054ae50a085a8f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 14 Apr 2024 11:41:30 +0000 Subject: [PATCH 093/220] Update dependency dev.notmyfault.serverlib:ServerLib to v2.3.5 --- worldedit-bukkit/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index e02685954..12c451485 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -169,7 +169,7 @@ tasks.named("shadowJar") { include(dependency("it.unimi.dsi:fastutil")) } relocate("org.incendo.serverlib", "com.fastasyncworldedit.serverlib") { - include(dependency("dev.notmyfault.serverlib:ServerLib:2.3.4")) + include(dependency("dev.notmyfault.serverlib:ServerLib:2.3.5")) } relocate("com.intellectualsites.paster", "com.fastasyncworldedit.paster") { include(dependency("com.intellectualsites.paster:Paster")) From 595a17c903cefae258a82eacfbf1c77fa8bd6d89 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 14 Apr 2024 11:41:23 +0000 Subject: [PATCH 094/220] Update dependency dev.notmyfault.serverlib:ServerLib to v2.3.5 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 91a96e24f..187a0516c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,7 +39,7 @@ commons-cli = "1.6.0" paperlib = "1.0.8" paster = "1.1.5" vault = "1.7.1" -serverlib = "2.3.4" +serverlib = "2.3.5" ## Internal text-adapter = "3.0.6" text = "3.0.4" From ccc8b15664cb1a393480dd19f0bf40c1418511cf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 14 Apr 2024 14:35:45 +0000 Subject: [PATCH 095/220] Update dependency dev.notmyfault.serverlib:ServerLib to v2.3.6 --- worldedit-bukkit/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index 12c451485..8705c931c 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -169,7 +169,7 @@ tasks.named("shadowJar") { include(dependency("it.unimi.dsi:fastutil")) } relocate("org.incendo.serverlib", "com.fastasyncworldedit.serverlib") { - include(dependency("dev.notmyfault.serverlib:ServerLib:2.3.5")) + include(dependency("dev.notmyfault.serverlib:ServerLib:2.3.6")) } relocate("com.intellectualsites.paster", "com.fastasyncworldedit.paster") { include(dependency("com.intellectualsites.paster:Paster")) From 11c09333251b13f3dbfb914201cab64b70878e6f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 14 Apr 2024 14:35:41 +0000 Subject: [PATCH 096/220] Update dependency dev.notmyfault.serverlib:ServerLib to v2.3.6 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 187a0516c..c605e3817 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,7 +39,7 @@ commons-cli = "1.6.0" paperlib = "1.0.8" paster = "1.1.5" vault = "1.7.1" -serverlib = "2.3.5" +serverlib = "2.3.6" ## Internal text-adapter = "3.0.6" text = "3.0.4" From 015b79d33309ec20eabaa3920efddac442107194 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 18:10:57 +0000 Subject: [PATCH 097/220] Update dependency com.intellectualsites.paster:Paster to v1.1.6 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c605e3817..90e306b00 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -37,7 +37,7 @@ lz4-java = "1.8.0" lz4-stream = "1.0.0" commons-cli = "1.6.0" paperlib = "1.0.8" -paster = "1.1.5" +paster = "1.1.6" vault = "1.7.1" serverlib = "2.3.6" ## Internal From 7afebdbc61f9f6995d49cd669c900b843657286d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 22:27:42 +0000 Subject: [PATCH 098/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240416.195429-165 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 460b1a0de..85964a8c5 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240412.212303-164") + the().paperDevBundle("1.20.4-R0.1-20240416.195429-165") compileOnly(libs.paperlib) } From 59aa3dfdfca2421e9ac2047088c849189c05bc42 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 22:27:58 +0000 Subject: [PATCH 099/220] Update dependency me.lucko:fabric-permissions-api to v0.3 --- worldedit-fabric/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-fabric/build.gradle.kts b/worldedit-fabric/build.gradle.kts index 88f1998b4..05bf8aa1f 100644 --- a/worldedit-fabric/build.gradle.kts +++ b/worldedit-fabric/build.gradle.kts @@ -100,7 +100,7 @@ dependencies { } // No need for this at runtime - "modCompileOnly"("me.lucko:fabric-permissions-api:0.1-SNAPSHOT") + "modCompileOnly"("me.lucko:fabric-permissions-api:0.3") // Hook these up manually, because Fabric doesn't seem to quite do it properly. "compileOnly"("net.fabricmc:sponge-mixin:${project.versions.mixin}") From a3661227be3f2a34df9a5184b626002883b7883e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 01:10:47 +0000 Subject: [PATCH 100/220] Update dependency me.lucko:fabric-permissions-api to v0.3.1 --- worldedit-fabric/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-fabric/build.gradle.kts b/worldedit-fabric/build.gradle.kts index 05bf8aa1f..4ba08c6eb 100644 --- a/worldedit-fabric/build.gradle.kts +++ b/worldedit-fabric/build.gradle.kts @@ -100,7 +100,7 @@ dependencies { } // No need for this at runtime - "modCompileOnly"("me.lucko:fabric-permissions-api:0.3") + "modCompileOnly"("me.lucko:fabric-permissions-api:0.3.1") // Hook these up manually, because Fabric doesn't seem to quite do it properly. "compileOnly"("net.fabricmc:sponge-mixin:${project.versions.mixin}") From 1bf46c6227f0914ae6431192986f501e2e2975d0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 06:04:34 +0000 Subject: [PATCH 101/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.2.3 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 90e306b00..d05d61861 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.2.2" +towny = "0.100.2.3" plotsquared = "7.3.7" # Third party From 341c7a5e8854f8fac08c5c5282b3891c63b67002 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 11:20:49 +0000 Subject: [PATCH 102/220] Update plotsquared to v7.3.8 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d05d61861..3d56b9c9e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" towny = "0.100.2.3" -plotsquared = "7.3.7" +plotsquared = "7.3.8" # Third party bstats = "3.0.2" From 65fd3312325b725af78039676a1f85cba9a590a7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 22:06:46 +0000 Subject: [PATCH 103/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240419.201130-167 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 85964a8c5..96d97d0bf 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240416.195429-165") + the().paperDevBundle("1.20.4-R0.1-20240419.201130-167") compileOnly(libs.paperlib) } From a3832515965e52ccc70ea749d9416ae74dac76b2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 20 Apr 2024 05:05:26 +0000 Subject: [PATCH 104/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240420.033107-168 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 96d97d0bf..900503d18 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240419.201130-167") + the().paperDevBundle("1.20.4-R0.1-20240420.033107-168") compileOnly(libs.paperlib) } From fdd6b86aeb6820e5f645c6cc2a36b65f53613e5e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 20 Apr 2024 18:49:33 +0000 Subject: [PATCH 105/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240420.181647-171 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 900503d18..dd0babcbd 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240420.033107-168") + the().paperDevBundle("1.20.4-R0.1-20240420.181647-171") compileOnly(libs.paperlib) } From 3dfc4f8f79b2302b2c4077c8b47a922c71aafd40 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 20 Apr 2024 21:27:10 +0000 Subject: [PATCH 106/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240420.200855-173 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index dd0babcbd..d626798e0 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240420.181647-171") + the().paperDevBundle("1.20.4-R0.1-20240420.200855-173") compileOnly(libs.paperlib) } From 1a31f39d1fad882d466ab92c47d92fbba149a60d Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Sun, 21 Apr 2024 13:16:43 +0200 Subject: [PATCH 107/220] Run renovate weekly Signed-off-by: Alexander Brandes --- .github/renovate.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/renovate.json b/.github/renovate.json index 3d0f91b5a..6b7783c42 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -2,7 +2,8 @@ "$schema" : "https://docs.renovatebot.com/renovate-schema.json", "extends" : [ "config:recommended", - ":semanticCommitsDisabled" + ":semanticCommitsDisabled", + "schedule:earlyMondays" ], "automerge" : true, "ignoreDeps" : [ From 45e18d0104b37688b177244029f5eb03d461e3a5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 28 Apr 2024 13:58:34 +0000 Subject: [PATCH 108/220] Update dependency commons-cli:commons-cli to v1.7.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3d56b9c9e..873a68c09 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -35,7 +35,7 @@ jlibnoise = "1.0.0" jchronic = "0.2.4a" lz4-java = "1.8.0" lz4-stream = "1.0.0" -commons-cli = "1.6.0" +commons-cli = "1.7.0" paperlib = "1.0.8" paster = "1.1.6" vault = "1.7.1" From b09310d745e6eeadbc7bcee4201a8efd3c9c71ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 01:14:01 +0000 Subject: [PATCH 109/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.2.6 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 873a68c09..b4b5f642d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.2.3" +towny = "0.100.2.6" plotsquared = "7.3.8" # Third party From 3c206f44a517dfd27a054fc78f2d3b9da5cb9de0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 01:14:09 +0000 Subject: [PATCH 110/220] Update dependency paperweight-userdev to v1.20.4-R0.1-20240424.165410-174 --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index d626798e0..821b6c52d 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240420.200855-173") + the().paperDevBundle("1.20.4-R0.1-20240424.165410-174") compileOnly(libs.paperlib) } From 3310686509fcf5c9693c300b1c5d2c3d9a253c1a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 03:27:13 +0000 Subject: [PATCH 111/220] Update plugin xyz.jpenilla.run-paper to v2.2.4 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8086d4bda..3a5d41523 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ import xyz.jpenilla.runpaper.task.RunServer plugins { id("io.github.gradle-nexus.publish-plugin") version "2.0.0" - id("xyz.jpenilla.run-paper") version "2.2.3" + id("xyz.jpenilla.run-paper") version "2.2.4" } if (!File("$rootDir/.git").exists()) { From 1b2e2fe12ab23903ecf84d37469689293ec0b575 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 03:27:19 +0000 Subject: [PATCH 112/220] Update dependency io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin to v1.6.2 --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index f3058a653..ad4afd071 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -24,7 +24,7 @@ dependencies { implementation(gradleApi()) implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2") implementation("com.github.johnrengelman:shadow:8.1.1") - implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.15") + implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.6.2") } kotlin { From debfabff08c829cf2eadd4130f9f7573ea10e2ac Mon Sep 17 00:00:00 2001 From: Jordan Date: Wed, 1 May 2024 17:31:06 +0900 Subject: [PATCH 113/220] feat: introduce migrating config nodes to new locations (#2642) - Initial case of moving schematic limits from experimental to limits - Closes #2533 --- .../core/configuration/Config.java | 121 ++++++++++++------ .../core/configuration/Settings.java | 32 +++-- .../core/limit/FaweLimit.java | 10 ++ .../worldedit/command/SchematicCommands.java | 16 +-- 4 files changed, 123 insertions(+), 56 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java index bc300d584..c3f223dc2 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java @@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.configuration; import com.fastasyncworldedit.core.configuration.file.YamlConfiguration; import com.fastasyncworldedit.core.util.StringMan; +import com.sk89q.util.StringUtil; import com.sk89q.worldedit.internal.util.LogManagerCompat; import org.apache.logging.log4j.Logger; @@ -14,8 +15,10 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.invoke.MethodHandles; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; @@ -27,6 +30,9 @@ public class Config { private static final Logger LOGGER = LogManagerCompat.getLogger(); + private final Map removedKeyVals = new HashMap<>(); + private List existingMigrateNodes = null; + public Config() { save(new PrintWriter(new ByteArrayOutputStream(0)), getClass(), this, 0); } @@ -43,7 +49,8 @@ public class Config { try { return (T) field.get(instance); } catch (IllegalAccessException e) { - e.printStackTrace(); + LOGGER.error("Failed to get config option: {}", key, e); + return null; } } } @@ -67,6 +74,10 @@ public class Config { if (field.getAnnotation(Final.class) != null) { return; } + Migrate migrate = field.getAnnotation(Migrate.class); + if (existingMigrateNodes != null && migrate != null) { + existingMigrateNodes.add(migrate.value()); + } if (field.getType() == String.class && !(value instanceof String)) { value = value + ""; } @@ -74,17 +85,22 @@ public class Config { field.set(instance, value); return; } catch (Throwable e) { - e.printStackTrace(); + LOGGER.error("Failed to set config option: {}", key); } } } - LOGGER.error("Failed to set config option: {}: {} | {} | {}.yml", key, value, instance, root.getSimpleName()); + removedKeyVals.put(key, value); + LOGGER.error( + "Failed to set config option: {}: {} | {} | {}.yml. This is likely because it was removed.", + key, + value, + instance, + root.getSimpleName() + ); } public boolean load(File file) { - if (!file.exists()) { - return false; - } + existingMigrateNodes = new ArrayList<>(); YamlConfiguration yml = YamlConfiguration.loadConfiguration(file); for (String key : yml.getKeys(true)) { Object value = yml.get(key); @@ -93,6 +109,10 @@ public class Config { } set(key, value, getClass()); } + for (String node : existingMigrateNodes) { + removedKeyVals.remove(node); + } + existingMigrateNodes = null; return true; } @@ -113,7 +133,7 @@ public class Config { save(writer, getClass(), instance, 0); writer.close(); } catch (Throwable e) { - e.printStackTrace(); + LOGGER.error("Failed to save config file: {}", file, e); } } @@ -166,6 +186,19 @@ public class Config { } + /** + * Indicates that a field should be instantiated / created. + * + * @since TODO + */ + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.FIELD}) + public @interface Migrate { + + String value(); + + } + @Ignore // This is not part of the config public static class ConfigBlock { @@ -222,7 +255,6 @@ public class Config { try { String CTRF = System.lineSeparator(); String spacing = StringMan.repeat(" ", indent); - HashMap, Object> instances = new HashMap<>(); for (Field field : clazz.getFields()) { if (field.getAnnotation(Ignore.class) != null) { continue; @@ -239,31 +271,14 @@ public class Config { } if (current == ConfigBlock.class) { current = (Class) ((ParameterizedType) (field.getGenericType())).getActualTypeArguments()[0]; - comment = current.getAnnotation(Comment.class); - if (comment != null) { - for (String commentLine : comment.value()) { - writer.write(spacing + "# " + commentLine + CTRF); - } - } - BlockName blockNames = current.getAnnotation(BlockName.class); - if (blockNames != null) { - writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF); - ConfigBlock configBlock = (ConfigBlock) field.get(instance); - if (configBlock == null || configBlock.getInstances().isEmpty()) { - configBlock = new ConfigBlock(); - field.set(instance, configBlock); - for (String blockName : blockNames.value()) { - configBlock.put(blockName, current.getDeclaredConstructor().newInstance()); - } - } - // Save each instance - for (Map.Entry entry : ((Map) configBlock.getRaw()).entrySet()) { - String key = entry.getKey(); - writer.write(spacing + " " + toNodeName(key) + ":" + CTRF); - save(writer, current, entry.getValue(), indent + 4); - } - } + handleConfigBlockSave(writer, instance, indent, field, spacing, CTRF, current); continue; + } else if (!removedKeyVals.isEmpty()) { + Migrate migrate = field.getAnnotation(Migrate.class); + Object value; + if (migrate != null && (value = removedKeyVals.remove(migrate.value())) != null) { + field.set(instance, value); + } } Create create = field.getAnnotation(Create.class); if (create != null) { @@ -281,7 +296,6 @@ public class Config { writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF); if (value == null) { field.set(instance, value = current.getDeclaredConstructor().newInstance()); - instances.put(current, value); } save(writer, current, value, indent + 2); } else { @@ -292,7 +306,42 @@ public class Config { } } } catch (Throwable e) { - e.printStackTrace(); + LOGGER.error("Failed to save config file", e); + } + } + + private void handleConfigBlockSave( + PrintWriter writer, + Object instance, + int indent, + Field field, + String spacing, + String CTRF, + Class current + ) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException { + Comment comment = current.getAnnotation(Comment.class); + if (comment != null) { + for (String commentLine : comment.value()) { + writer.write(spacing + "# " + commentLine + CTRF); + } + } + BlockName blockNames = current.getAnnotation(BlockName.class); + if (blockNames != null) { + writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF); + ConfigBlock configBlock = (ConfigBlock) field.get(instance); + if (configBlock == null || configBlock.getInstances().isEmpty()) { + configBlock = new ConfigBlock<>(); + field.set(instance, configBlock); + for (String blockName : blockNames.value()) { + configBlock.put(blockName, current.getDeclaredConstructor().newInstance()); + } + } + // Save each instance + for (Map.Entry entry : configBlock.getRaw().entrySet()) { + String key = entry.getKey(); + writer.write(spacing + " " + toNodeName(key) + ":" + CTRF); + save(writer, current, entry.getValue(), indent + 4); + } } } @@ -311,7 +360,7 @@ public class Config { return field; } catch (Throwable ignored) { LOGGER.warn( - "Invalid config field: {} for {}", + "Invalid config field: {} for {}. It is possible this is because it has been removed.", StringMan.join(split, "."), toNodeName(instance.getClass().getSimpleName()) ); @@ -379,7 +428,7 @@ public class Config { return null; } } catch (Throwable e) { - e.printStackTrace(); + LOGGER.error("Failed retrieving instance for config node: {}", StringUtil.joinString(split, "."), e); } return null; } 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 89f48b697..8c8077d66 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 @@ -145,6 +145,14 @@ public class Settings extends Config { limit.MAX_HISTORY, newLimit.MAX_HISTORY_MB != -1 ? newLimit.MAX_HISTORY_MB : Integer.MAX_VALUE ); + limit.SCHEM_FILE_NUM_LIMIT = Math.max( + limit.SCHEM_FILE_NUM_LIMIT, + newLimit.SCHEM_FILE_NUM_LIMIT != -1 ? newLimit.SCHEM_FILE_NUM_LIMIT : Integer.MAX_VALUE + ); + limit.SCHEM_FILE_SIZE_LIMIT = Math.max( + limit.SCHEM_FILE_SIZE_LIMIT, + newLimit.SCHEM_FILE_SIZE_LIMIT != -1 ? newLimit.SCHEM_FILE_SIZE_LIMIT : Integer.MAX_VALUE + ); limit.MAX_EXPRESSION_MS = Math.max( limit.MAX_EXPRESSION_MS, newLimit.MAX_EXPRESSION_MS != -1 ? newLimit.MAX_EXPRESSION_MS : Integer.MAX_VALUE @@ -353,6 +361,18 @@ public class Settings extends Config { " - History on disk or memory will be deleted", }) public int MAX_HISTORY_MB = -1; + @Comment({ + "Sets a maximum limit (in kb) for the size of a player's schematics directory (per-player mode only)", + "Set to -1 to disable" + }) + @Migrate("experimental.per-player-file-size-limit") + public int SCHEM_FILE_SIZE_LIMIT = -1; + @Comment({ + "Sets a maximum limit for the amount of schematics in a player's schematics directory (per-player mode only)", + "Set to -1 to disable" + }) + @Migrate("experimental.per-player-file-num-limit") + public int SCHEM_FILE_NUM_LIMIT = -1; @Comment("Maximum time in milliseconds //calc can execute") public int MAX_EXPRESSION_MS = 50; @Comment({ @@ -615,18 +635,6 @@ public class Settings extends Config { }) public boolean ALLOW_TICK_FLUIDS = false; - @Comment({ - "Sets a maximum limit (in kb) for the size of a player's schematics directory (per-player mode only)", - "Set to -1 to disable" - }) - public int PER_PLAYER_FILE_SIZE_LIMIT = -1; - - @Comment({ - "Sets a maximum limit for the amount of schematics in a player's schematics directory (per-player mode only)", - "Set to -1 to disable" - }) - public int PER_PLAYER_FILE_NUM_LIMIT = -1; - } @Comment({"Web/HTTP connection related settings"}) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java index 00a47178c..e02e3abc9 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java @@ -15,6 +15,8 @@ public class FaweLimit { public int MAX_BLOCKSTATES = 0; public int MAX_ENTITIES = 0; public int MAX_HISTORY = 0; + public int SCHEM_FILE_SIZE_LIMIT = 0; + public int SCHEM_FILE_NUM_LIMIT = 0; public int MAX_EXPRESSION_MS = 0; public int INVENTORY_MODE = Integer.MAX_VALUE; public int SPEED_REDUCTION = Integer.MAX_VALUE; @@ -111,6 +113,8 @@ public class FaweLimit { MAX.MAX_BLOCKSTATES = Integer.MAX_VALUE; MAX.MAX_ENTITIES = Integer.MAX_VALUE; MAX.MAX_HISTORY = Integer.MAX_VALUE; + MAX.SCHEM_FILE_NUM_LIMIT = Integer.MAX_VALUE; + MAX.SCHEM_FILE_SIZE_LIMIT = Integer.MAX_VALUE; MAX.MAX_EXPRESSION_MS = 50; MAX.FAST_PLACEMENT = true; MAX.CONFIRM_LARGE = true; @@ -237,6 +241,8 @@ public class FaweLimit { && MAX_BLOCKSTATES == Integer.MAX_VALUE && MAX_ENTITIES == Integer.MAX_VALUE && MAX_HISTORY == Integer.MAX_VALUE + && SCHEM_FILE_SIZE_LIMIT == Integer.MAX_VALUE + && SCHEM_FILE_NUM_LIMIT == Integer.MAX_VALUE && INVENTORY_MODE == 0 && SPEED_REDUCTION == 0 && FAST_PLACEMENT @@ -256,6 +262,8 @@ public class FaweLimit { MAX_FAILS = limit.MAX_FAILS; MAX_ITERATIONS = limit.MAX_ITERATIONS; MAX_HISTORY = limit.MAX_HISTORY; + SCHEM_FILE_NUM_LIMIT = limit.SCHEM_FILE_NUM_LIMIT; + SCHEM_FILE_SIZE_LIMIT = limit.SCHEM_FILE_SIZE_LIMIT; INVENTORY_MODE = limit.INVENTORY_MODE; SPEED_REDUCTION = limit.SPEED_REDUCTION; FAST_PLACEMENT = limit.FAST_PLACEMENT; @@ -279,6 +287,8 @@ public class FaweLimit { limit.MAX_FAILS = MAX_FAILS; limit.MAX_ITERATIONS = MAX_ITERATIONS; limit.MAX_HISTORY = MAX_HISTORY; + limit.SCHEM_FILE_SIZE_LIMIT = SCHEM_FILE_SIZE_LIMIT; + limit.SCHEM_FILE_NUM_LIMIT = SCHEM_FILE_NUM_LIMIT; limit.FAST_PLACEMENT = FAST_PLACEMENT; limit.CONFIRM_LARGE = CONFIRM_LARGE; limit.RESTRICT_HISTORY_TO_REGIONS = RESTRICT_HISTORY_TO_REGIONS; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java index 1158a7847..3bd62f02b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java @@ -700,10 +700,10 @@ public class SchematicCommands { String headerBytesElem = String.format("%.1fkb", totalBytes / 1000.0); - if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_SIZE_LIMIT > -1) { + if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && actor.getLimit().SCHEM_FILE_SIZE_LIMIT > -1) { headerBytesElem += String.format( " / %dkb", - Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_SIZE_LIMIT + actor.getLimit().SCHEM_FILE_SIZE_LIMIT ); } @@ -837,7 +837,7 @@ public class SchematicCommands { //FAWE start boolean checkFilesize = Settings.settings().PATHS.PER_PLAYER_SCHEMATICS - && Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_SIZE_LIMIT > -1; + && actor.getLimit().SCHEM_FILE_SIZE_LIMIT > -1; double directorysizeKb = 0; String curFilepath = file.getAbsolutePath(); @@ -867,7 +867,7 @@ public class SchematicCommands { } - if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_NUM_LIMIT > -1) { + if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && actor.getLimit().SCHEM_FILE_NUM_LIMIT > -1) { if (numFiles == -1) { numFiles = 0; @@ -880,7 +880,7 @@ public class SchematicCommands { } } } - int limit = Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_NUM_LIMIT; + int limit = actor.getLimit().SCHEM_FILE_NUM_LIMIT; if (numFiles >= limit) { TextComponent noSlotsErr = TextComponent.of( //TODO - to be moved into captions/translatablecomponents @@ -931,7 +931,7 @@ public class SchematicCommands { if (checkFilesize) { double curKb = filesizeKb + directorysizeKb; - int allocatedKb = Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_SIZE_LIMIT; + int allocatedKb = actor.getLimit().SCHEM_FILE_SIZE_LIMIT; if (overwrite) { curKb -= oldKbOverwritten; @@ -966,11 +966,11 @@ public class SchematicCommands { actor.print(kbRemainingNotif); } - if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_NUM_LIMIT > -1) { + if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && actor.getLimit().SCHEM_FILE_NUM_LIMIT > -1) { TextComponent slotsRemainingNotif = TextComponent.of( //TODO - to be moved into captions/translatablecomponents - "You have " + (Settings.settings().EXPERIMENTAL.PER_PLAYER_FILE_NUM_LIMIT - numFiles) + "You have " + (actor.getLimit().SCHEM_FILE_NUM_LIMIT - numFiles) + " schematic file slots left.", TextColor.GRAY ); From d79bbce73a9f1f03e536e5e826e909fd093acfeb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 00:46:47 +0000 Subject: [PATCH 114/220] Update dependency org.mozilla:rhino-runtime to v1.7.15 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b4b5f642d..87bc9496b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -27,7 +27,7 @@ checkerqual = "3.42.0" truezip = "6.8.4" auto-value = "1.10.4" findbugs = "3.0.2" -rhino-runtime = "1.7.14" +rhino-runtime = "1.7.15" zstd-jni = "1.4.8-1" # Not latest as it can be difficult to obtain latest ZSTD libs antlr4 = "4.13.1" json-simple = "1.1.1" From a96b620b790477afd46754ae8706ccc78d69bb1b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 00:46:41 +0000 Subject: [PATCH 115/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.2.7 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 87bc9496b..f0db6139b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.2.6" +towny = "0.100.2.7" plotsquared = "7.3.8" # Third party From c297cd6849c2a36a0b73d83e18dda2cbc5753dc7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 03:35:14 +0000 Subject: [PATCH 116/220] Update dependency org.checkerframework:checker-qual to v3.43.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f0db6139b..a309f127c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,7 +23,7 @@ sparsebitset = "1.3" parallelgzip = "1.0.5" adventure = "4.16.0" adventure-bukkit = "4.3.2" -checkerqual = "3.42.0" +checkerqual = "3.43.0" truezip = "6.8.4" auto-value = "1.10.4" findbugs = "3.0.2" From 991d93d8ce3f0603f9ffb5e36bcf0bf866ddac73 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 03:35:09 +0000 Subject: [PATCH 117/220] Update dependency io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin to v1.7.0 --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index ad4afd071..68ac32256 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -24,7 +24,7 @@ dependencies { implementation(gradleApi()) implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2") implementation("com.github.johnrengelman:shadow:8.1.1") - implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.6.2") + implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.7.0") } kotlin { From 9bc09c6a4c1e9e90344eec5671c0622a641a3e3c Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Sun, 12 May 2024 10:41:48 +0200 Subject: [PATCH 118/220] Integrate WE Schematic Share system (#2619) * Integrate WE Schematic Share system (cherry picked from commit 303f5a76b2df70d63480f2126c9ef4b228eb3c59) * disable feature for now --------- Co-authored-by: Madeline Miller --- .../worldedit/command/SchematicCommands.java | 117 ++++++++++++++++-- .../util/paste/ActorCallbackPaste.java | 22 ++++ .../worldedit/util/paste/EngineHubPaste.java | 23 +++- .../worldedit/util/paste/PasteMetadata.java | 26 ++++ .../sk89q/worldedit/util/paste/Paster.java | 6 +- 5 files changed, 181 insertions(+), 13 deletions(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/PasteMetadata.java diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java index 3bd62f02b..e711e61ee 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java @@ -26,6 +26,7 @@ import com.fastasyncworldedit.core.extent.clipboard.MultiClipboardHolder; import com.fastasyncworldedit.core.extent.clipboard.URIClipboardHolder; import com.fastasyncworldedit.core.extent.clipboard.io.schematic.MinecraftStructure; import com.fastasyncworldedit.core.util.MainUtil; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Multimap; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; @@ -60,15 +61,19 @@ import com.sk89q.worldedit.util.formatting.text.format.TextColor; import com.sk89q.worldedit.util.io.Closer; import com.sk89q.worldedit.util.io.file.FilenameException; import org.apache.logging.log4j.Logger; +import com.sk89q.worldedit.util.paste.EngineHubPaste; +import com.sk89q.worldedit.util.paste.PasteMetadata; import org.enginehub.piston.annotation.Command; import org.enginehub.piston.annotation.CommandContainer; import org.enginehub.piston.annotation.param.Arg; import org.enginehub.piston.annotation.param.ArgFlag; import org.enginehub.piston.annotation.param.Switch; +import org.enginehub.piston.exception.CommandException; import org.enginehub.piston.exception.StopExecutionException; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -79,9 +84,12 @@ import java.net.URISyntaxException; import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Base64; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -536,6 +544,42 @@ public class SchematicCommands { .buildAndExec(worldEdit.getExecutorService()); } + @Command( + name = "share", + desc = "Share your clipboard as a schematic online" + ) + @CommandPermissions({ "worldedit.clipboard.share", "worldedit.schematic.share" }) + public void share(Actor actor, LocalSession session, + @Arg(desc = "Schematic name. Defaults to name-millis", def = "") + String schematicName, + @Arg(desc = "Format name.", def = "sponge") + String formatName) throws WorldEditException { + if (true) { + throw new UnsupportedOperationException("This feature is currently not implemented"); + } + if (worldEdit.getPlatformManager().queryCapability(Capability.GAME_HOOKS).getDataVersion() == -1) { + actor.printError(TranslatableComponent.of("worldedit.schematic.unsupported-minecraft-version")); + return; + } + + ClipboardFormat format = ClipboardFormats.findByAlias(formatName); + if (format == null) { + actor.printError(TranslatableComponent.of("worldedit.schematic.unknown-format", TextComponent.of(formatName))); + return; + } + + ClipboardHolder holder = session.getClipboard(); + + SchematicShareTask task = new SchematicShareTask(actor, format, holder, schematicName); + AsyncCommandBuilder.wrap(task, actor) + .registerWithSupervisor(worldEdit.getSupervisor(), "Sharing schematic") + .setDelayMessage(TranslatableComponent.of("worldedit.schematic.save.saving")) + .setWorkingMessage(TranslatableComponent.of("worldedit.schematic.save.still-saving")) + .onSuccess("Shared", (url -> actor.printInfo(TextComponent.of(url.toExternalForm() + ".schem").clickEvent(ClickEvent.openUrl(url.toExternalForm() + ".schem"))))) + .onFailure("Failed to share schematic", worldEdit.getPlatformManager().getPlatformCommandManager().getExceptionConverter()) + .buildAndExec(worldEdit.getExecutorService()); + } + @Command( name = "formats", aliases = {"listformats", "f"}, @@ -804,14 +848,48 @@ public class SchematicCommands { } - private static class SchematicSaveTask implements Callable { + private abstract static class SchematicOutputTask implements Callable { + protected final Actor actor; + protected final ClipboardFormat format; + protected final ClipboardHolder holder; - private final Actor actor; - private final ClipboardFormat format; - private final ClipboardHolder holder; + SchematicOutputTask( + Actor actor, + ClipboardFormat format, + ClipboardHolder holder + ) { + this.actor = actor; + this.format = format; + this.holder = holder; + } + + protected void writeToOutputStream(OutputStream outputStream) throws Exception { + Clipboard clipboard = holder.getClipboard(); + Transform transform = holder.getTransform(); + Clipboard target; + // If we have a transform, bake it into the copy + if (transform.isIdentity()) { + target = clipboard; + } else { + FlattenedClipboardTransform result = FlattenedClipboardTransform.transform(clipboard, transform); + target = new BlockArrayClipboard(result.getTransformedRegion()); + target.setOrigin(clipboard.getOrigin()); + Operations.completeLegacy(result.copyTo(target)); + } + + try (Closer closer = Closer.create()) { + OutputStream stream = closer.register(outputStream); + BufferedOutputStream bos = closer.register(new BufferedOutputStream(stream)); + ClipboardWriter writer = closer.register(format.getWriter(bos)); + writer.write(target); + } + } + } + + private static class SchematicSaveTask extends SchematicOutputTask { + private File file; private final boolean overwrite; private final File rootDir; - private File file; SchematicSaveTask( Actor actor, @@ -821,11 +899,9 @@ public class SchematicCommands { ClipboardHolder holder, boolean overwrite ) { - this.actor = actor; + super(actor, format, holder); this.file = file; this.rootDir = rootDir; - this.format = format; - this.holder = holder; this.overwrite = overwrite; } @@ -984,7 +1060,32 @@ public class SchematicCommands { //FAWE end return null; } + } + private static class SchematicShareTask extends SchematicOutputTask { + private final String name; + + SchematicShareTask(Actor actor, ClipboardFormat format, ClipboardHolder holder, String name) { + super(actor, format, holder); + this.name = name; + } + + @Override + public URL call() throws Exception { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + writeToOutputStream(baos); + } catch (Exception e) { + throw new CommandException(TextComponent.of(e.getMessage()), e, ImmutableList.of()); + } + + EngineHubPaste pasteService = new EngineHubPaste(); + PasteMetadata metadata = new PasteMetadata(); + metadata.author = this.actor.getName(); + metadata.extension = "schem"; + metadata.name = name == null ? actor.getName() + "-" + System.currentTimeMillis() : name; + return pasteService.paste(new String(Base64.getEncoder().encode(baos.toByteArray()), StandardCharsets.UTF_8), metadata).call(); + } } private static class SchematicListTask implements Callable { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/ActorCallbackPaste.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/ActorCallbackPaste.java index 680dbed0d..152dcfea3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/ActorCallbackPaste.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/ActorCallbackPaste.java @@ -83,4 +83,26 @@ public final class ActorCallbackPaste { .buildAndExec(Pasters.getExecutor()); } + + /** + * Submit data to a pastebin service and inform the sender of + * success or failure. + * + * @param supervisor The supervisor instance + * @param sender The sender + * @param content The content + * @param pasteMetadata The paste metadata + * @param successMessage The message builder, given the URL as an arg + */ + public static void pastebin(Supervisor supervisor, final Actor sender, String content, PasteMetadata pasteMetadata, final TranslatableComponent.Builder successMessage) { + Callable task = paster.paste(content, pasteMetadata); + + AsyncCommandBuilder.wrap(task, sender) + .registerWithSupervisor(supervisor, "Submitting content to a pastebin service.") + .setDelayMessage(TranslatableComponent.of("worldedit.pastebin.uploading")) + .onSuccess((String) null, url -> sender.printInfo(successMessage.args(TextComponent.of(url.toString())).build())) + .onFailure("Failed to submit paste", null) + .buildAndExec(Pasters.getExecutor()); + } + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/EngineHubPaste.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/EngineHubPaste.java index f9bf84375..037cea727 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/EngineHubPaste.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/EngineHubPaste.java @@ -33,23 +33,38 @@ public class EngineHubPaste implements Paster { private static final Gson GSON = new Gson(); @Override - public Callable paste(String content) { - return new PasteTask(content); + public Callable paste(String content, PasteMetadata metadata) { + return new PasteTask(content, metadata); } private static final class PasteTask implements Callable { private final String content; + private final PasteMetadata metadata; - private PasteTask(String content) { + private PasteTask(String content, PasteMetadata metadata) { this.content = content; + this.metadata = metadata; } @Override public URL call() throws IOException, InterruptedException { URL initialUrl = HttpRequest.url("https://paste.enginehub.org/signed_paste"); - SignedPasteResponse response = GSON.fromJson(HttpRequest.get(initialUrl) + HttpRequest requestBuilder = HttpRequest.get(initialUrl); + + requestBuilder.header("x-paste-meta-from", "EngineHub"); + if (metadata.name != null) { + requestBuilder.header("x-paste-meta-name", metadata.name); + } + if (metadata.author != null) { + requestBuilder.header("x-paste-meta-author", metadata.author); + } + if (metadata.extension != null) { + requestBuilder.header("x-paste-meta-extension", metadata.extension); + } + + SignedPasteResponse response = GSON.fromJson(requestBuilder .execute() .expectResponseCode(200) .returnContent() diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/PasteMetadata.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/PasteMetadata.java new file mode 100644 index 000000000..5654e6ae5 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/PasteMetadata.java @@ -0,0 +1,26 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.util.paste; + +public class PasteMetadata { + public String name; + public String extension; + public String author; +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/Paster.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/Paster.java index 0b7652b91..ccd5780b0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/Paster.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/Paster.java @@ -24,6 +24,10 @@ import java.util.concurrent.Callable; public interface Paster { - Callable paste(String content); + default Callable paste(String content) { + return paste(content, new PasteMetadata()); + } + + Callable paste(String content, PasteMetadata metadata); } From 1d9e8b60abd630854f2b72affbb58abc7c50dba2 Mon Sep 17 00:00:00 2001 From: Jordan Date: Sun, 12 May 2024 11:05:00 +0100 Subject: [PATCH 119/220] fix: add missing blocktypes and some minor cleanup (#2722) - fixes #2713 --- .../worldedit/world/block/BlockTypes.java | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java index 4b3204be4..513a00557 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java @@ -483,6 +483,10 @@ public final class BlockTypes { @Nullable public static final BlockType COPPER_GRATE = init(); @Nullable + public static final BlockType COPPER_ORE = init(); + @Nullable + public static final BlockType COPPER_TRAPDOOR = init(); + @Nullable public static final BlockType CORNFLOWER = init(); @Nullable public static final BlockType CRACKED_DEEPSLATE_BRICKS = init(); @@ -495,6 +499,8 @@ public final class BlockTypes { @Nullable public static final BlockType CRACKED_STONE_BRICKS = init(); @Nullable + public static final BlockType CRAFTER = init(); + @Nullable public static final BlockType CRAFTING_TABLE = init(); @Nullable public static final BlockType CREEPER_HEAD = init(); @@ -685,8 +691,6 @@ public final class BlockTypes { @Nullable public static final BlockType DEEPSLATE_COPPER_ORE = init(); @Nullable - public static final BlockType COPPER_TRAPDOOR = init(); - @Nullable public static final BlockType DEEPSLATE_DIAMOND_ORE = init(); @Nullable public static final BlockType DEEPSLATE_EMERALD_ORE = init(); @@ -747,8 +751,6 @@ public final class BlockTypes { @Nullable public static final BlockType ENDER_CHEST = init(); @Nullable - public static final BlockType EXPOSED_CHISELED_COPPER = init(); - @Nullable public static final BlockType END_GATEWAY = init(); @Nullable public static final BlockType END_PORTAL = init(); @@ -767,6 +769,8 @@ public final class BlockTypes { @Nullable public static final BlockType END_STONE_BRICK_WALL = init(); @Nullable + public static final BlockType EXPOSED_CHISELED_COPPER = init(); + @Nullable public static final BlockType EXPOSED_COPPER = init(); @Nullable public static final BlockType EXPOSED_COPPER_BULB = init(); @@ -836,6 +840,9 @@ public final class BlockTypes { public static final BlockType GRASS = init(); @Nullable public static final BlockType GRASS_BLOCK = init(); + @Deprecated + @Nullable + public static final BlockType GRASS_PATH = init(); @Nullable public static final BlockType GRAVEL = init(); @Nullable @@ -925,8 +932,6 @@ public final class BlockTypes { @Nullable public static final BlockType INFESTED_CRACKED_STONE_BRICKS = init(); @Nullable - public static final BlockType CRAFTER = init(); - @Nullable public static final BlockType INFESTED_DEEPSLATE = init(); @Nullable public static final BlockType INFESTED_MOSSY_STONE_BRICKS = init(); @@ -1954,10 +1959,12 @@ public final class BlockTypes { @Nullable public static final BlockType TWISTING_VINES = init(); @Nullable - public static final BlockType VERDANT_FROGLIGHT = init(); - @Nullable public static final BlockType TWISTING_VINES_PLANT = init(); @Nullable + public static final BlockType VAULT = init(); + @Nullable + public static final BlockType VERDANT_FROGLIGHT = init(); + @Nullable public static final BlockType VINE = init(); @Nullable public static final BlockType VOID_AIR = init(); @@ -2026,7 +2033,7 @@ public final class BlockTypes { public static final BlockType WAXED_CUT_COPPER_SLAB = init(); @Nullable public static final BlockType WAXED_CUT_COPPER_STAIRS = init(); - @ Nullable + @Nullable public static final BlockType WAXED_EXPOSED_CHISELED_COPPER = init(); @Nullable public static final BlockType WAXED_EXPOSED_COPPER = init(); From 69dbf760a84c33ce90be8600adcf7568195e8615 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 01:53:18 +0000 Subject: [PATCH 120/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.2.8 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a309f127c..99f1ff6fc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.2.7" +towny = "0.100.2.8" plotsquared = "7.3.8" # Third party From ae4d0236cc4c7f8ef899bae600c5f180a507703e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 01:53:27 +0000 Subject: [PATCH 121/220] Update dependency io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin to v1.7.1 --- buildSrc/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 68ac32256..ef4a18fe7 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -24,7 +24,7 @@ dependencies { implementation(gradleApi()) implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2") implementation("com.github.johnrengelman:shadow:8.1.1") - implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.7.0") + implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.7.1") } kotlin { From c9b2f441c1837df0e68031d5f122a9521cf5d188 Mon Sep 17 00:00:00 2001 From: Jordan Date: Tue, 14 May 2024 20:30:34 +0100 Subject: [PATCH 122/220] feat: only unstuck a player if configured to do so (#2723) - also add unstuck to a couple of other commands - closes #2675 --- .../core/configuration/Settings.java | 11 +++++++++++ .../worldedit/command/GenerationCommands.java | 14 ++++++++++---- .../sk89q/worldedit/command/RegionCommands.java | 6 +++++- 3 files changed, 26 insertions(+), 5 deletions(-) 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 8c8077d66..63f37fd6b 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 @@ -79,6 +79,8 @@ public class Settings extends Config { @Create public REGION_RESTRICTIONS_OPTIONS REGION_RESTRICTIONS_OPTIONS; @Create + public GENERAL GENERAL; + @Create public ConfigBlock LIMITS; private Settings() { @@ -752,4 +754,13 @@ public class Settings extends Config { } + public static class GENERAL { + + @Comment({ + "If the player should be relocated/unstuck when a generation command would bury them", + }) + public boolean UNSTUCK_ON_GENERATE = true; + + } + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java index dbd698b24..d3d456965 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java @@ -184,6 +184,9 @@ public class GenerationCommands { BlockVector3 pos = session.getPlacementPosition(actor); int affected = editSession.makeCylinder(pos, pattern, radiusX, radiusZ, height, !hollow); + if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) { + ((Player) actor).findFreePosition(); + } actor.print(Caption.of("worldedit.cyl.created", TextComponent.of(affected))); return affected; } @@ -227,6 +230,9 @@ public class GenerationCommands { BlockVector3 pos = session.getPlacementPosition(actor); int affected = editSession.makeCone(pos, pattern, radiusX, radiusZ, height, !hollow, thickness); + if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) { + ((Player) actor).findFreePosition(); + } actor.printInfo(Caption.of("worldedit.cone.created", TextComponent.of(affected))); return affected; } @@ -293,7 +299,7 @@ public class GenerationCommands { } int affected = editSession.makeSphere(pos, pattern, radiusX, radiusY, radiusZ, !hollow); - if (actor instanceof Player) { + if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) { ((Player) actor).findFreePosition(); } actor.print(Caption.of("worldedit.sphere.created", TextComponent.of(affected))); @@ -379,7 +385,7 @@ public class GenerationCommands { worldEdit.checkMaxRadius(size); BlockVector3 pos = session.getPlacementPosition(actor); int affected = editSession.makePyramid(pos, pattern, size, !hollow); - if (actor instanceof Player) { + if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) { ((Player) actor).findFreePosition(); } actor.print(Caption.of("worldedit.pyramid.created", TextComponent.of(affected))); @@ -457,7 +463,7 @@ public class GenerationCommands { hollow, session.getTimeout() ); - if (actor instanceof Player) { + if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) { ((Player) actor).findFreePosition(); } actor.print(Caption.of("worldedit.generate.created", TextComponent.of(affected))); @@ -741,7 +747,7 @@ public class GenerationCommands { radius.divide(max), sphericity / 100 ); - if (actor instanceof Player) { + if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) { ((Player) actor).findFreePosition(); } actor.print(Caption.of("worldedit.sphere.created", TextComponent.of(affected))); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java index a72cba4b3..73cb34274 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java @@ -22,6 +22,7 @@ package com.sk89q.worldedit.command; import com.fastasyncworldedit.core.FaweAPI; import com.fastasyncworldedit.core.FaweCache; import com.fastasyncworldedit.core.configuration.Caption; +import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode; import com.fastasyncworldedit.core.limit.FaweLimit; import com.fastasyncworldedit.core.util.MaskTraverser; @@ -715,6 +716,9 @@ public class RegionCommands { session.setSourceMask(mask); //FAWE end } + if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) { + ((Player) actor).findFreePosition(); + } if (success) { actor.print(Caption.of("worldedit.regen.regenerated")); } else { @@ -788,7 +792,7 @@ public class RegionCommands { String.join(" ", expression), session.getTimeout() ); - if (actor instanceof Player) { + if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) { ((Player) actor).findFreePosition(); } actor.print(Caption.of("worldedit.deform.deformed", TextComponent.of(affected))); From a353c12df017bc810748a90fa6c113737db32ead Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Sun, 19 May 2024 13:32:18 +0200 Subject: [PATCH 123/220] Support for 1.20.5/6 (#2721) * 1.20.6 Signed-off-by: Alexander Brandes * work Signed-off-by: Alexander Brandes * More work Signed-off-by: Alexander Brandes * chore: address more removed fields and methods, make it run * chore: don't allocate unnecessary arrays (by maps) * chore: the comment might still be noteworthy * chore: no need to synchronize twice * fix obfuscation changes * remove unneeded deprecation * make regen work without throwing exceptions - but slow * fix: error when adapting BaseItemStacks without nbt * fix annoying paper api breakage --------- Signed-off-by: Alexander Brandes Co-authored-by: Alexander Brandes Co-authored-by: Pierre Maurice Schwang --- .github/ISSUE_TEMPLATE/bug_report.yml | 3 +- .github/workflows/build-pr.yml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/codeql.yml | 2 +- .github/workflows/upload-release-assets.yml | 2 +- COMPILING.adoc | 6 +- Jenkinsfile | 2 +- build.gradle.kts | 2 +- buildSrc/build.gradle.kts | 14 +- buildSrc/src/main/kotlin/CommonConfig.kt | 2 +- buildSrc/src/main/kotlin/CommonJavaConfig.kt | 4 +- buildSrc/src/main/kotlin/LibsConfig.kt | 4 +- gradle/libs.versions.toml | 2 +- settings.gradle.kts | 2 +- .../v1_20_R3/PaperweightPlatformAdapter.java | 1 - .../build.gradle.kts | 4 +- .../v1_20_R4}/PaperweightAdapter.java | 458 ++++--- .../v1_20_R4}/PaperweightDataConverters.java | 1114 +++++++---------- .../v1_20_R4}/PaperweightFakePlayer.java | 27 +- .../PaperweightWorldNativeAccess.java | 61 +- .../v1_20_R4}/PaperweightBlockMaterial.java | 53 +- .../v1_20_R4}/PaperweightFaweAdapter.java | 181 ++- .../PaperweightFaweWorldNativeAccess.java | 17 +- .../fawe/v1_20_R4}/PaperweightGetBlocks.java | 123 +- .../v1_20_R4}/PaperweightGetBlocks_Copy.java | 26 +- .../v1_20_R4}/PaperweightMapChunkUtil.java | 8 +- .../v1_20_R4}/PaperweightPlatformAdapter.java | 186 ++- .../v1_20_R4}/PaperweightPostProcessor.java | 2 +- .../PaperweightStarlightRelighter.java | 8 +- .../PaperweightStarlightRelighterFactory.java | 4 +- .../nbt/PaperweightLazyCompoundTag.java | 2 +- .../v1_20_R4}/regen/PaperweightRegen.java | 252 ++-- worldedit-bukkit/build.gradle.kts | 3 +- .../bukkit/adapter/Regenerator.java | 130 +- .../bukkit/listener/ChunkListener.java | 2 +- .../bukkit/util/CommandRegistration.java | 8 +- worldedit-core/doctools/build.gradle.kts | 6 +- .../sk89q/worldedit/WorldEditManifest.java | 5 +- .../sk89q/worldedit/entity/BaseEntity.java | 2 + .../extent/validation/BlockChangeLimiter.java | 1 + .../util/io/ForwardSeekableInputStream.java | 8 +- .../sk89q/worldedit/util/net/HttpRequest.java | 10 +- .../worldedit/util/paste/EngineHubPaste.java | 3 +- .../util/task/FutureForwardingTask.java | 13 +- .../world/block/BlockCategories.java | 9 + .../worldedit/world/block/BlockType.java | 1 + .../worldedit/world/block/BlockTypes.java | 2 + .../worldedit/world/chunk/AnvilChunk13.java | 2 +- .../worldedit/world/entity/EntityTypes.java | 8 + .../worldedit/world/item/ItemCategories.java | 54 +- .../sk89q/worldedit/world/item/ItemType.java | 4 +- .../sk89q/worldedit/world/item/ItemTypes.java | 39 + 52 files changed, 1527 insertions(+), 1359 deletions(-) rename worldedit-bukkit/adapters/{adapter-1_18_2 => adapter-1_20_5}/build.gradle.kts (78%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4}/PaperweightAdapter.java (77%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4}/PaperweightDataConverters.java (94%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4}/PaperweightFakePlayer.java (78%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4}/PaperweightWorldNativeAccess.java (74%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4}/PaperweightBlockMaterial.java (69%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4}/PaperweightFaweAdapter.java (82%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4}/PaperweightFaweWorldNativeAccess.java (94%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4}/PaperweightGetBlocks.java (94%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4}/PaperweightGetBlocks_Copy.java (86%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4}/PaperweightMapChunkUtil.java (88%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4}/PaperweightPlatformAdapter.java (80%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4}/PaperweightPostProcessor.java (99%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4}/PaperweightStarlightRelighter.java (90%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4}/PaperweightStarlightRelighterFactory.java (88%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4}/nbt/PaperweightLazyCompoundTag.java (98%) rename worldedit-bukkit/adapters/{adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2 => adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4}/regen/PaperweightRegen.java (69%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index bc78076bd..1de1aa8df 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -27,10 +27,9 @@ body: description: Which server version version you using? If your server version is not listed, it is not supported. Update to a supported version first. multiple: false options: - - '1.20.4' + - '1.20.5/6' - '1.20' - '1.19.4' - - '1.18.2' validations: required: true diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index fbb90ab03..e6ad24a7f 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -17,7 +17,7 @@ jobs: with: distribution: temurin cache: gradle - java-version: 17 + java-version: 21 - name: Build on ${{ matrix.os }} run: ./gradlew build -s - name: Archive artifacts diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d6072de2f..5b44758dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ jobs: with: distribution: temurin cache: gradle - java-version: 17 + java-version: 21 - name: Clean Build run: ./gradlew clean build --no-daemon - name: Determine release status diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index b7e9c61ed..0cd6f4443 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -25,7 +25,7 @@ jobs: with: distribution: temurin cache: gradle - java-version: 17 + java-version: 21 - name: Initialize CodeQL uses: github/codeql-action/init@v3 with: diff --git a/.github/workflows/upload-release-assets.yml b/.github/workflows/upload-release-assets.yml index bff53a6b2..22d6c6083 100644 --- a/.github/workflows/upload-release-assets.yml +++ b/.github/workflows/upload-release-assets.yml @@ -15,7 +15,7 @@ jobs: with: distribution: temurin cache: gradle - java-version: 17 + java-version: 21 - name: Clean Build run: ./gradlew clean build --no-daemon - name: Upload Release Assets diff --git a/COMPILING.adoc b/COMPILING.adoc index 87b21b685..bdd30ba62 100644 --- a/COMPILING.adoc +++ b/COMPILING.adoc @@ -3,12 +3,12 @@ = Compiling -You can compile FastAsyncWorldEdit as long as you have some version of Java greater than or equal to 17 installed. Gradle will download JDK 17 specifically if needed, +You can compile FastAsyncWorldEdit as long as you have some version of Java greater than or equal to 21 installed. Gradle will download JDK 21 specifically if needed, but it needs some version of Java to bootstrap from. -Note that if you have JRE 8 installed, Gradle will currently attempt to use that to compile, which will not work. It is easiest to uninstall JRE 8 and replace it with JDK 17. +Note that if you have JRE 8 installed, Gradle will currently attempt to use that to compile, which will not work. It is easiest to uninstall JRE 8 and replace it with JDK 21. -You can get the JDK 17 link:https://adoptium.net/[here] from Adoptium. +You can get the JDK 21 link:https://adoptium.net/[here] from Adoptium. The build process uses Gradle, which you do *not* need to download. FastAsyncWorldEdit is a multi-module project with three active modules: diff --git a/Jenkinsfile b/Jenkinsfile index 61000e9fb..94db4eda2 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -7,7 +7,7 @@ pipeline { stage('Build') { steps { withEnv([ - "PATH+JAVA=${tool 'Temurin-17.0.7_7'}/bin" + "PATH+JAVA=${tool 'Temurin-21.0.3_9'}/bin" ]) { sh './gradlew clean build' } diff --git a/build.gradle.kts b/build.gradle.kts index 3a5d41523..aed748cdb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -83,7 +83,7 @@ allprojects { } applyCommonConfiguration() -val supportedVersions = listOf("1.18.2", "1.19.4", "1.20", "1.20.4") +val supportedVersions = listOf("1.19.4", "1.20", "1.20.4", "1.20.5", "1.20.6") tasks { supportedVersions.forEach { diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index ef4a18fe7..f116fd23e 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -25,10 +25,22 @@ dependencies { implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2") implementation("com.github.johnrengelman:shadow:8.1.1") implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.7.1") + constraints { + val asmVersion = "[9.7,)" + implementation("org.ow2.asm:asm:$asmVersion") { + because("Need Java 21 support in shadow") + } + implementation("org.ow2.asm:asm-commons:$asmVersion") { + because("Need Java 21 support in shadow") + } + implementation("org.vafer:jdependency:[2.10,)") { + because("Need Java 21 support in shadow") + } + } } kotlin { jvmToolchain { - (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(17)) + (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(21)) } } diff --git a/buildSrc/src/main/kotlin/CommonConfig.kt b/buildSrc/src/main/kotlin/CommonConfig.kt index 6a6d552aa..e8fd3db87 100644 --- a/buildSrc/src/main/kotlin/CommonConfig.kt +++ b/buildSrc/src/main/kotlin/CommonConfig.kt @@ -33,7 +33,7 @@ fun Project.applyCommonConfiguration() { plugins.withId("java") { the().toolchain { - languageVersion.set(JavaLanguageVersion.of(17)) + languageVersion.set(JavaLanguageVersion.of(21)) } } diff --git a/buildSrc/src/main/kotlin/CommonJavaConfig.kt b/buildSrc/src/main/kotlin/CommonJavaConfig.kt index 8a111a2e7..f915c2e0c 100644 --- a/buildSrc/src/main/kotlin/CommonJavaConfig.kt +++ b/buildSrc/src/main/kotlin/CommonJavaConfig.kt @@ -21,7 +21,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean .matching { it.name == "compileJava" || it.name == "compileTestJava" } .configureEach { val disabledLint = listOf( - "processing", "path", "fallthrough", "serial" + "processing", "path", "fallthrough", "serial", "overloads", "this-escape", ) options.release.set(17) options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" }) @@ -31,7 +31,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean } configurations.all { - attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17) + attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21) } tasks.withType().configureEach { diff --git a/buildSrc/src/main/kotlin/LibsConfig.kt b/buildSrc/src/main/kotlin/LibsConfig.kt index 5d6e7892b..2c957880a 100644 --- a/buildSrc/src/main/kotlin/LibsConfig.kt +++ b/buildSrc/src/main/kotlin/LibsConfig.kt @@ -122,7 +122,7 @@ fun Project.applyLibrariesConfiguration() { attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED)) attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR)) - attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17) + attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21) } outgoing.artifact(tasks.named("jar")) } @@ -137,7 +137,7 @@ fun Project.applyLibrariesConfiguration() { attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED)) attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR)) - attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17) + attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21) } outgoing.artifact(tasks.named("jar")) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 99f1ff6fc..c02ba9098 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] # Minecraft expectations -paper = "1.20.4-R0.1-SNAPSHOT" +paper = "1.20.6-R0.1-SNAPSHOT" fastutil = "8.5.9" guava = "31.1-jre" log4j = "2.19.0" diff --git a/settings.gradle.kts b/settings.gradle.kts index 74cba1396..48318b908 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,7 +2,7 @@ rootProject.name = "FastAsyncWorldEdit" include("worldedit-libs") -listOf("1_18_2", "1_19_4", "1_20", "1_20_2", "1_20_4").forEach { +listOf("1_19_4", "1_20", "1_20_2", "1_20_4", "1_20_5").forEach { include("worldedit-bukkit:adapters:adapter-$it") } diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java index 147ec5be7..23de00ade 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java @@ -58,7 +58,6 @@ import net.minecraft.world.level.entity.PersistentEntitySectionManager; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_20_R3.CraftChunk; -import sun.misc.Unsafe; import javax.annotation.Nonnull; import javax.annotation.Nullable; diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts similarity index 78% rename from worldedit-bukkit/adapters/adapter-1_18_2/build.gradle.kts rename to worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts index 3713af207..e1a518cbb 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts @@ -11,7 +11,7 @@ repositories { } dependencies { - // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.18.2-R0.1-SNAPSHOT - the().paperDevBundle("1.18.2-R0.1-20220920.010157-167") + // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/ + the().paperDevBundle("1.20.6-R0.1-20240516.001739-55") compileOnly(libs.paperlib) } diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R2/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java similarity index 77% rename from worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R2/PaperweightAdapter.java rename to worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java index 1edc3be1d..e629c4611 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R2/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java @@ -17,24 +17,23 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2; +package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.util.concurrent.Futures; -import com.mojang.datafixers.util.Either; +import com.mojang.serialization.Codec; import com.mojang.serialization.Lifecycle; +import com.sk89q.jnbt.NBTConstants; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.PaperweightPlatformAdapter; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extension.platform.Watchdog; import com.sk89q.worldedit.extent.Extent; @@ -81,14 +80,20 @@ import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.item.ItemType; import net.minecraft.Util; import net.minecraft.core.BlockPos; -import net.minecraft.core.Registry; +import net.minecraft.core.Holder; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.nbt.Tag; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ChunkResult; import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.progress.ChunkProgressListener; @@ -112,10 +117,10 @@ import net.minecraft.world.level.block.entity.StructureBlockEntity; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.DirectionProperty; import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.dimension.LevelStem; -import net.minecraft.world.level.levelgen.WorldGenSettings; +import net.minecraft.world.level.levelgen.WorldOptions; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; import net.minecraft.world.phys.BlockHitResult; @@ -124,13 +129,13 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World.Environment; import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.v1_18_R2.CraftServer; -import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_18_R2.util.CraftMagicNumbers; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.block.data.CraftBlockData; +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.entity.Player; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.generator.ChunkGenerator; @@ -155,7 +160,6 @@ import java.util.Set; import java.util.TreeMap; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ForkJoinPool; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -166,33 +170,28 @@ import static com.google.common.base.Preconditions.checkState; public final class PaperweightAdapter implements BukkitImplAdapter { - private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( - SideEffect.NEIGHBORS, - SideEffect.LIGHTING, - SideEffect.VALIDATION, - SideEffect.ENTITY_AI, - SideEffect.EVENTS, - SideEffect.UPDATE - ); + private static final Codec COMPONENTS_CODEC = DataComponentPatch.CODEC.optionalFieldOf( + "components", DataComponentPatch.EMPTY + ).codec(); + + private final Logger logger = Logger.getLogger(getClass().getCanonicalName()); + private final Field serverWorldsField; private final Method getChunkFutureMethod; private final Field chunkProviderExecutorField; - private final Logger LOGGER = Logger.getLogger(getClass().getCanonicalName()); + private final Watchdog watchdog; // ------------------------------------------------------------------------ // Code that may break between versions of Minecraft // ------------------------------------------------------------------------ - private final Watchdog watchdog; - private final LoadingCache fakePlayers - = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new)); public PaperweightAdapter() throws NoSuchFieldException, NoSuchMethodException { // A simple test CraftServer.class.cast(Bukkit.getServer()); int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion(); - if (dataVersion != 2975) { - throw new UnsupportedClassVersionError("Not 1.18.2!"); + if (dataVersion != 3837 && dataVersion != 3839) { + throw new UnsupportedClassVersionError("Not 1.20.(5/6)!"); } serverWorldsField = CraftServer.class.getDeclaredField("worlds"); @@ -209,7 +208,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter> biomeTypeToNMSCache = new HashMap<>(); + private static final HashMap, BiomeType> biomeTypeFromNMSCache = new HashMap<>(); + @Override public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { - return new PaperweightWorldNativeAccess( - this, - new WeakReference<>(((CraftWorld) world).getHandle()) - ); + return new PaperweightWorldNativeAccess(this, new WeakReference<>(((CraftWorld) world).getHandle())); + } + + private static net.minecraft.core.Direction adapt(Direction face) { + switch (face) { + case NORTH: + return net.minecraft.core.Direction.NORTH; + case SOUTH: + return net.minecraft.core.Direction.SOUTH; + case WEST: + return net.minecraft.core.Direction.WEST; + case EAST: + return net.minecraft.core.Direction.EAST; + case DOWN: + return net.minecraft.core.Direction.DOWN; + case UP: + default: + return net.minecraft.core.Direction.UP; + } } @SuppressWarnings({"rawtypes", "unchecked"}) @@ -429,16 +446,19 @@ public final class PaperweightAdapter implements BukkitImplAdapter (CompoundBinaryTag) toNativeBinary(tag)) ); - //FAWE end } @Nullable @@ -471,6 +491,22 @@ public final class PaperweightAdapter implements BukkitImplAdapter> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader>() { - @Override - public Property load(net.minecraft.world.level.block.state.properties.Property state) throws Exception { - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else if (state instanceof DirectionProperty) { - return new DirectionalProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).collect(Collectors.toList())); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - return new EnumProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).collect(Collectors.toList())); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else { - throw new IllegalArgumentException("FastAsyncWorldEdit needs an update to support " + state.getClass().getSimpleName()); - } - } - }); + private static final LoadingCache> PROPERTY_CACHE = CacheBuilder + .newBuilder() + .build(new CacheLoader>() { + @Override + public Property load(net.minecraft.world.level.block.state.properties.Property state) throws Exception { + if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { + return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else if (state instanceof DirectionProperty) { + return new DirectionalProperty( + state.getName(), + (List) state + .getPossibleValues() + .stream() + .map(e -> Direction.valueOf(((StringRepresentable) e) + .getSerializedName() + .toUpperCase(Locale.ROOT))) + .collect(Collectors.toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { + return new EnumProperty( + state.getName(), + (List) state + .getPossibleValues() + .stream() + .map(e -> ((StringRepresentable) e).getSerializedName()) + .collect(Collectors.toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { + return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else { + throw new IllegalArgumentException("WorldEdit needs an update to support " + state + .getClass() + .getSimpleName()); + } + } + }); - @SuppressWarnings({ "rawtypes" }) + @SuppressWarnings({"rawtypes"}) @Override public Map> getProperties(BlockType blockType) { Map> properties = new TreeMap<>(); @@ -520,50 +574,68 @@ public final class PaperweightAdapter implements BukkitImplAdapter CompoundTag @Override public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) { - ((CraftPlayer) player).getHandle().networkManager.send(ClientboundBlockEntityDataPacket.create( - new StructureBlockEntity( - new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()), - Blocks.STRUCTURE_BLOCK.defaultBlockState() - ), - __ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) + var structureBlock = new StructureBlockEntity( + new BlockPos(pos.getX(), pos.getY(), pos.getZ()), + Blocks.STRUCTURE_BLOCK.defaultBlockState() + ); + structureBlock.setLevel(((CraftPlayer) player).getHandle().level()); + ((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create( + structureBlock, + (blockEntity, registryAccess) -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) )); } - //FAWE end @Override public void sendFakeOP(Player player) { - ((CraftPlayer) player).getHandle().networkManager.send(new ClientboundEntityEventPacket( + ((CraftPlayer) player).getHandle().connection.send(new ClientboundEntityEventPacket( ((CraftPlayer) player).getHandle(), (byte) 28 )); } @Override public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) { - ItemStack stack = new ItemStack(Registry.ITEM.get(ResourceLocation.tryParse(item.getType().getId())), item.getAmount()); - stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData()))); + final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess(); + ItemStack stack = new ItemStack( + registryAccess.registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(item.getType().getId())), + item.getAmount() + ); + final CompoundTag nbt = (net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData()); + final DataComponentPatch patch = COMPONENTS_CODEC + .parse(registryAccess.createSerializationContext(NbtOps.INSTANCE), nbt) + .getOrThrow(); + stack.applyComponents(patch); return CraftItemStack.asCraftMirror(stack); } @Override public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { + final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess(); final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); - //FAWE start - CBT > CT - weStack.setNbt(((CompoundBinaryTag) toNativeBinary(nmsStack.getTag()))); - //FAWE end - return weStack; + final Tag tag = COMPONENTS_CODEC.encodeStart( + registryAccess.createSerializationContext(NbtOps.INSTANCE), + nmsStack.getComponentsPatch() + ).getOrThrow(); + return new BaseItemStack( + BukkitAdapter.asItemType(itemStack.getType()), + LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag)), + itemStack.getAmount() + ); } + private final LoadingCache fakePlayers + = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new)); + @Override public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) { CraftWorld craftWorld = (CraftWorld) world; ServerLevel worldServer = craftWorld.getHandle(); - ItemStack stack = CraftItemStack.asNMSCopy(BukkitAdapter.adapt(item instanceof BaseItemStack - ? ((BaseItemStack) item) : new BaseItemStack(item.getType(), item.getNbtData(), 1))); - stack.setTag((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData())); + ItemStack stack = CraftItemStack.asNMSCopy(adapt( + item instanceof BaseItemStack + ? ((BaseItemStack) item) + : new BaseItemStack(item.getType(), item.getNbtReference(), 1) + )); PaperweightFakePlayer fakePlayer; try { @@ -572,20 +644,20 @@ public final class PaperweightAdapter implements BukkitImplAdapter worldDimKey = getWorldDimKey(env); try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("faweregentempworld", worldDimKey)) { ServerLevel originalWorld = ((CraftWorld) bukkitWorld).getHandle(); PrimaryLevelData levelProperties = (PrimaryLevelData) originalWorld.getServer() .getWorldData().overworldData(); - WorldGenSettings originalOpts = levelProperties.worldGenSettings(); + WorldOptions originalOpts = levelProperties.worldGenOptions(); long seed = options.getSeed().orElse(originalWorld.getSeed()); - WorldGenSettings newOpts = options.getSeed().isPresent() - ? originalOpts.withSeed(levelProperties.isHardcore(), OptionalLong.of(seed)) + WorldOptions newOpts = options.getSeed().isPresent() + ? originalOpts.withSeed(OptionalLong.of(seed)) : originalOpts; LevelSettings newWorldSettings = new LevelSettings( @@ -642,23 +714,40 @@ public final class PaperweightAdapter implements BukkitImplAdapter>) + ((CompletableFuture>) getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true)) - .thenApply(either -> either.left().orElse(null)) + .thenApply(either -> either.orElse(null)) ); } catch (IllegalAccessException | InvocationTargetException e) { throw new IllegalStateException("Couldn't load chunk for regen.", e); @@ -769,6 +856,15 @@ public final class PaperweightAdapter implements BukkitImplAdapter SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( + SideEffect.NEIGHBORS, + SideEffect.LIGHTING, + SideEffect.VALIDATION, + SideEffect.ENTITY_AI, + SideEffect.EVENTS, + SideEffect.UPDATE + ); + @Override public Set getSupportedSideEffects() { return SUPPORTED_SIDE_EFFECTS; @@ -797,7 +893,6 @@ public final class PaperweightAdapter implements BukkitImplAdapter values = ListBinaryTag.builder(); + ListBinaryTag.Builder values = ListBinaryTag.builder(); for (net.minecraft.nbt.Tag tag : foreign) { values.add(toNativeBinary(tag)); @@ -895,8 +990,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter. */ -package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2; +package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -29,18 +29,21 @@ import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; +import com.mojang.datafixers.DSL; import com.mojang.datafixers.DSL.TypeReference; import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.DataFixerBuilder; import com.mojang.datafixers.schemas.Schema; import com.mojang.serialization.Dynamic; +import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4.PaperweightAdapter; import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import net.minecraft.core.Direction; import net.minecraft.nbt.NbtOps; +import net.minecraft.nbt.StringTag; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; -import net.minecraft.network.chat.TextComponent; import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; import net.minecraft.util.GsonHelper; import net.minecraft.util.StringUtil; import net.minecraft.util.datafix.DataFixers; @@ -66,252 +69,19 @@ import javax.annotation.Nullable; /** * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2) - *

    + * * We register a DFU Fixer per Legacy Data Version and apply the fixes using legacy strategy * which is safer, faster and cleaner code. - *

    + * * The pre DFU code did not fail when the Source version was unknown. - *

    + * * This class also provides util methods for converting compounds to wrap the update call to * receive the source version in the compound */ -@SuppressWarnings({"rawtypes", "unchecked"}) -class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.worldedit.world.DataFixer { +@SuppressWarnings({ "rawtypes", "unchecked" }) +public class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.worldedit.world.DataFixer { - private static final NbtOps OPS_NBT = NbtOps.INSTANCE; - private static final int LEGACY_VERSION = 1343; - private static final Map DFU_TO_LEGACY = new HashMap<>(); - private static final Map OLD_ID_TO_KEY_MAP = new HashMap<>(); - static PaperweightDataConverters INSTANCE; - private static int DATA_VERSION; - - static { - final Map map = OLD_ID_TO_KEY_MAP; - map.put("EntityItem", new ResourceLocation("item")); - map.put("EntityExperienceOrb", new ResourceLocation("xp_orb")); - map.put("EntityAreaEffectCloud", new ResourceLocation("area_effect_cloud")); - map.put("EntityGuardianElder", new ResourceLocation("elder_guardian")); - map.put("EntitySkeletonWither", new ResourceLocation("wither_skeleton")); - map.put("EntitySkeletonStray", new ResourceLocation("stray")); - map.put("EntityEgg", new ResourceLocation("egg")); - map.put("EntityLeash", new ResourceLocation("leash_knot")); - map.put("EntityPainting", new ResourceLocation("painting")); - map.put("EntityTippedArrow", new ResourceLocation("arrow")); - map.put("EntitySnowball", new ResourceLocation("snowball")); - map.put("EntityLargeFireball", new ResourceLocation("fireball")); - map.put("EntitySmallFireball", new ResourceLocation("small_fireball")); - map.put("EntityEnderPearl", new ResourceLocation("ender_pearl")); - map.put("EntityEnderSignal", new ResourceLocation("eye_of_ender_signal")); - map.put("EntityPotion", new ResourceLocation("potion")); - map.put("EntityThrownExpBottle", new ResourceLocation("xp_bottle")); - map.put("EntityItemFrame", new ResourceLocation("item_frame")); - map.put("EntityWitherSkull", new ResourceLocation("wither_skull")); - map.put("EntityTNTPrimed", new ResourceLocation("tnt")); - map.put("EntityFallingBlock", new ResourceLocation("falling_block")); - map.put("EntityFireworks", new ResourceLocation("fireworks_rocket")); - map.put("EntityZombieHusk", new ResourceLocation("husk")); - map.put("EntitySpectralArrow", new ResourceLocation("spectral_arrow")); - map.put("EntityShulkerBullet", new ResourceLocation("shulker_bullet")); - map.put("EntityDragonFireball", new ResourceLocation("dragon_fireball")); - map.put("EntityZombieVillager", new ResourceLocation("zombie_villager")); - map.put("EntityHorseSkeleton", new ResourceLocation("skeleton_horse")); - map.put("EntityHorseZombie", new ResourceLocation("zombie_horse")); - map.put("EntityArmorStand", new ResourceLocation("armor_stand")); - map.put("EntityHorseDonkey", new ResourceLocation("donkey")); - map.put("EntityHorseMule", new ResourceLocation("mule")); - map.put("EntityEvokerFangs", new ResourceLocation("evocation_fangs")); - map.put("EntityEvoker", new ResourceLocation("evocation_illager")); - map.put("EntityVex", new ResourceLocation("vex")); - map.put("EntityVindicator", new ResourceLocation("vindication_illager")); - map.put("EntityIllagerIllusioner", new ResourceLocation("illusion_illager")); - map.put("EntityMinecartCommandBlock", new ResourceLocation("commandblock_minecart")); - map.put("EntityBoat", new ResourceLocation("boat")); - map.put("EntityMinecartRideable", new ResourceLocation("minecart")); - map.put("EntityMinecartChest", new ResourceLocation("chest_minecart")); - map.put("EntityMinecartFurnace", new ResourceLocation("furnace_minecart")); - map.put("EntityMinecartTNT", new ResourceLocation("tnt_minecart")); - map.put("EntityMinecartHopper", new ResourceLocation("hopper_minecart")); - map.put("EntityMinecartMobSpawner", new ResourceLocation("spawner_minecart")); - map.put("EntityCreeper", new ResourceLocation("creeper")); - map.put("EntitySkeleton", new ResourceLocation("skeleton")); - map.put("EntitySpider", new ResourceLocation("spider")); - map.put("EntityGiantZombie", new ResourceLocation("giant")); - map.put("EntityZombie", new ResourceLocation("zombie")); - map.put("EntitySlime", new ResourceLocation("slime")); - map.put("EntityGhast", new ResourceLocation("ghast")); - map.put("EntityPigZombie", new ResourceLocation("zombie_pigman")); - map.put("EntityEnderman", new ResourceLocation("enderman")); - map.put("EntityCaveSpider", new ResourceLocation("cave_spider")); - map.put("EntitySilverfish", new ResourceLocation("silverfish")); - map.put("EntityBlaze", new ResourceLocation("blaze")); - map.put("EntityMagmaCube", new ResourceLocation("magma_cube")); - map.put("EntityEnderDragon", new ResourceLocation("ender_dragon")); - map.put("EntityWither", new ResourceLocation("wither")); - map.put("EntityBat", new ResourceLocation("bat")); - map.put("EntityWitch", new ResourceLocation("witch")); - map.put("EntityEndermite", new ResourceLocation("endermite")); - map.put("EntityGuardian", new ResourceLocation("guardian")); - map.put("EntityShulker", new ResourceLocation("shulker")); - map.put("EntityPig", new ResourceLocation("pig")); - map.put("EntitySheep", new ResourceLocation("sheep")); - map.put("EntityCow", new ResourceLocation("cow")); - map.put("EntityChicken", new ResourceLocation("chicken")); - map.put("EntitySquid", new ResourceLocation("squid")); - map.put("EntityWolf", new ResourceLocation("wolf")); - map.put("EntityMushroomCow", new ResourceLocation("mooshroom")); - map.put("EntitySnowman", new ResourceLocation("snowman")); - map.put("EntityOcelot", new ResourceLocation("ocelot")); - map.put("EntityIronGolem", new ResourceLocation("villager_golem")); - map.put("EntityHorse", new ResourceLocation("horse")); - map.put("EntityRabbit", new ResourceLocation("rabbit")); - map.put("EntityPolarBear", new ResourceLocation("polar_bear")); - map.put("EntityLlama", new ResourceLocation("llama")); - map.put("EntityLlamaSpit", new ResourceLocation("llama_spit")); - map.put("EntityParrot", new ResourceLocation("parrot")); - map.put("EntityVillager", new ResourceLocation("villager")); - map.put("EntityEnderCrystal", new ResourceLocation("ender_crystal")); - map.put("TileEntityFurnace", new ResourceLocation("furnace")); - map.put("TileEntityChest", new ResourceLocation("chest")); - map.put("TileEntityEnderChest", new ResourceLocation("ender_chest")); - map.put("TileEntityRecordPlayer", new ResourceLocation("jukebox")); - map.put("TileEntityDispenser", new ResourceLocation("dispenser")); - map.put("TileEntityDropper", new ResourceLocation("dropper")); - map.put("TileEntitySign", new ResourceLocation("sign")); - map.put("TileEntityMobSpawner", new ResourceLocation("mob_spawner")); - map.put("TileEntityNote", new ResourceLocation("noteblock")); - map.put("TileEntityPiston", new ResourceLocation("piston")); - map.put("TileEntityBrewingStand", new ResourceLocation("brewing_stand")); - map.put("TileEntityEnchantTable", new ResourceLocation("enchanting_table")); - map.put("TileEntityEnderPortal", new ResourceLocation("end_portal")); - map.put("TileEntityBeacon", new ResourceLocation("beacon")); - map.put("TileEntitySkull", new ResourceLocation("skull")); - map.put("TileEntityLightDetector", new ResourceLocation("daylight_detector")); - map.put("TileEntityHopper", new ResourceLocation("hopper")); - map.put("TileEntityComparator", new ResourceLocation("comparator")); - map.put("TileEntityFlowerPot", new ResourceLocation("flower_pot")); - map.put("TileEntityBanner", new ResourceLocation("banner")); - map.put("TileEntityStructure", new ResourceLocation("structure_block")); - map.put("TileEntityEndGateway", new ResourceLocation("end_gateway")); - map.put("TileEntityCommand", new ResourceLocation("command_block")); - map.put("TileEntityShulkerBox", new ResourceLocation("shulker_box")); - map.put("TileEntityBed", new ResourceLocation("bed")); - } - - private final PaperweightAdapter adapter; - private final Map> converters = new EnumMap<>(LegacyType.class); - private final Map> inspectors = new EnumMap<>(LegacyType.class); - // Set on build - private DataFixer fixer; - - PaperweightDataConverters(int dataVersion, PaperweightAdapter adapter) { - super(dataVersion); - DATA_VERSION = dataVersion; - INSTANCE = this; - this.adapter = adapter; - registerConverters(); - registerInspectors(); - } - - private static net.minecraft.nbt.CompoundTag stateToNBT(String blockState) { - int propIdx = blockState.indexOf('['); - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - if (propIdx < 0) { - tag.putString("Name", blockState); - } else { - tag.putString("Name", blockState.substring(0, propIdx)); - net.minecraft.nbt.CompoundTag propTag = new net.minecraft.nbt.CompoundTag(); - String props = blockState.substring(propIdx + 1, blockState.length() - 1); - String[] propArr = props.split(","); - for (String pair : propArr) { - final String[] split = pair.split("="); - propTag.putString(split[0], split[1]); - } - tag.put("Properties", propTag); - } - return tag; - } - - private static String fixName(String key, int srcVer, TypeReference type) { - return INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, net.minecraft.nbt.StringTag.valueOf(key)), srcVer, DATA_VERSION) - .getValue().getAsString(); - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp) { - return convert(type.getDFUType(), cmp); - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { - return convert(type.getDFUType(), cmp, sourceVer); - } - - public static net.minecraft.nbt.CompoundTag convert( - LegacyType type, - net.minecraft.nbt.CompoundTag cmp, - int sourceVer, - int targetVer - ) { - return convert(type.getDFUType(), cmp, sourceVer, targetVer); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp) { - int i = cmp.contains("DataVersion", 99) ? cmp.getInt("DataVersion") : -1; - return convert(type, cmp, i); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { - return convert(type, cmp, sourceVer, DATA_VERSION); - } - - public static net.minecraft.nbt.CompoundTag convert( - TypeReference type, - net.minecraft.nbt.CompoundTag cmp, - int sourceVer, - int targetVer - ) { - if (sourceVer >= targetVer) { - return cmp; - } - return (net.minecraft.nbt.CompoundTag) INSTANCE.fixer - .update(type, new Dynamic<>(OPS_NBT, cmp), sourceVer, targetVer) - .getValue(); - } - - private static ResourceLocation getKey(String type) { - final ResourceLocation key = OLD_ID_TO_KEY_MAP.get(type); - if (key == null) { - throw new IllegalArgumentException("Unknown mapping for " + type); - } - return key; - } - - private static void convertCompound( - LegacyType type, - net.minecraft.nbt.CompoundTag cmp, - String key, - int sourceVer, - int targetVer - ) { - cmp.put(key, convert(type, cmp.getCompound(key), sourceVer, targetVer)); - } - - private static void convertItem(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { - if (nbttagcompound.contains(key, 10)) { - convertCompound(LegacyType.ITEM_INSTANCE, nbttagcompound, key, sourceVer, targetVer); - } - } - - private static void convertItems(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { - if (nbttagcompound.contains(key, 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound.getList(key, 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ITEM_INSTANCE, nbttaglist.getCompound(j), sourceVer, targetVer)); - } - } - - } - - //FAWE start - CBT > CT + //FAWE start - BinaryTag @SuppressWarnings("unchecked") @Override public T fixUp(FixType type, T original, int srcVer) { @@ -353,12 +123,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo private String fixBlockState(String blockState, int srcVer) { net.minecraft.nbt.CompoundTag stateNBT = stateToNBT(blockState); Dynamic dynamic = new Dynamic<>(OPS_NBT, stateNBT); - net.minecraft.nbt.CompoundTag fixed = (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update( - References.BLOCK_STATE, - dynamic, - srcVer, - DATA_VERSION - ).getValue(); + net.minecraft.nbt.CompoundTag fixed = (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update(References.BLOCK_STATE, dynamic, srcVer, DATA_VERSION).getValue(); return nbtToState(fixed); } @@ -368,16 +133,31 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo if (tagCompound.contains("Properties", 10)) { sb.append('['); net.minecraft.nbt.CompoundTag props = tagCompound.getCompound("Properties"); - sb.append(props - .getAllKeys() - .stream() - .map(k -> k + "=" + props.getString(k).replace("\"", "")) - .collect(Collectors.joining(","))); + sb.append(props.getAllKeys().stream().map(k -> k + "=" + props.getString(k).replace("\"", "")).collect(Collectors.joining(","))); sb.append(']'); } return sb.toString(); } + private static net.minecraft.nbt.CompoundTag stateToNBT(String blockState) { + int propIdx = blockState.indexOf('['); + net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); + if (propIdx < 0) { + tag.putString("Name", blockState); + } else { + tag.putString("Name", blockState.substring(0, propIdx)); + net.minecraft.nbt.CompoundTag propTag = new net.minecraft.nbt.CompoundTag(); + String props = blockState.substring(propIdx + 1, blockState.length() - 1); + String[] propArr = props.split(","); + for (String pair : propArr) { + final String[] split = pair.split("="); + propTag.putString(split[0], split[1]); + } + tag.put("Properties", propTag); + } + return tag; + } + private String fixBiome(String key, int srcVer) { return fixName(key, srcVer, References.BIOME); } @@ -386,12 +166,158 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return fixName(key, srcVer, References.ITEM_NAME); } + private static String fixName(String key, int srcVer, TypeReference type) { + return INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, net.minecraft.nbt.StringTag.valueOf(key)), srcVer, DATA_VERSION) + .getValue().getAsString(); + } + + private final PaperweightAdapter adapter; + + private static final NbtOps OPS_NBT = NbtOps.INSTANCE; + private static final int LEGACY_VERSION = 1343; + private static int DATA_VERSION; + public static PaperweightDataConverters INSTANCE; + + private final Map> converters = new EnumMap<>(LegacyType.class); + private final Map> inspectors = new EnumMap<>(LegacyType.class); + + // Set on build + private DataFixer fixer; + private static final Map DFU_TO_LEGACY = new HashMap<>(); + + public enum LegacyType { + LEVEL(References.LEVEL), + PLAYER(References.PLAYER), + CHUNK(References.CHUNK), + BLOCK_ENTITY(References.BLOCK_ENTITY), + ENTITY(References.ENTITY), + ITEM_INSTANCE(References.ITEM_STACK), + OPTIONS(References.OPTIONS), + STRUCTURE(References.STRUCTURE); + + private final TypeReference type; + + LegacyType(TypeReference type) { + this.type = type; + DFU_TO_LEGACY.put(type.typeName(), this); + } + + public TypeReference getDFUType() { + return type; + } + } + + public PaperweightDataConverters(int dataVersion, PaperweightAdapter adapter) { + super(dataVersion); + DATA_VERSION = dataVersion; + INSTANCE = this; + this.adapter = adapter; + registerConverters(); + registerInspectors(); + } + + // Called after fixers are built and ready for FIXING @Override - public DataFixer build(final Executor executor) { + public DataFixer buildUnoptimized() { return this.fixer = new WrappedDataFixer(DataFixers.getDataFixer()); } + @Override + public DataFixer buildOptimized(final Set requiredTypes, Executor executor) { + return buildUnoptimized(); + } + + @SuppressWarnings("unchecked") + private class WrappedDataFixer implements DataFixer { + private final DataFixer realFixer; + + WrappedDataFixer(DataFixer realFixer) { + this.realFixer = realFixer; + } + + @Override + public Dynamic update(TypeReference type, Dynamic dynamic, int sourceVer, int targetVer) { + LegacyType legacyType = DFU_TO_LEGACY.get(type.typeName()); + if (sourceVer < LEGACY_VERSION && legacyType != null) { + net.minecraft.nbt.CompoundTag cmp = (net.minecraft.nbt.CompoundTag) dynamic.getValue(); + int desiredVersion = Math.min(targetVer, LEGACY_VERSION); + + cmp = convert(legacyType, cmp, sourceVer, desiredVersion); + sourceVer = desiredVersion; + dynamic = new Dynamic(OPS_NBT, cmp); + } + return realFixer.update(type, dynamic, sourceVer, targetVer); + } + + private net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int desiredVersion) { + List converters = PaperweightDataConverters.this.converters.get(type); + if (converters != null && !converters.isEmpty()) { + for (DataConverter converter : converters) { + int dataVersion = converter.getDataVersion(); + if (dataVersion > sourceVer && dataVersion <= desiredVersion) { + cmp = converter.convert(cmp); + } + } + } + + List inspectors = PaperweightDataConverters.this.inspectors.get(type); + if (inspectors != null && !inspectors.isEmpty()) { + for (DataInspector inspector : inspectors) { + cmp = inspector.inspect(cmp, sourceVer, desiredVersion); + } + } + + return cmp; + } + + @Override + public Schema getSchema(int i) { + return realFixer.getSchema(i); + } + } + + public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp) { + return convert(type.getDFUType(), cmp); + } + + public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { + return convert(type.getDFUType(), cmp, sourceVer); + } + + public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { + return convert(type.getDFUType(), cmp, sourceVer, targetVer); + } + + public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp) { + int i = cmp.contains("DataVersion", 99) ? cmp.getInt("DataVersion") : -1; + return convert(type, cmp, i); + } + + public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { + return convert(type, cmp, sourceVer, DATA_VERSION); + } + + public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { + if (sourceVer >= targetVer) { + return cmp; + } + return (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, cmp), sourceVer, targetVer).getValue(); + } + + + public interface DataInspector { + net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer); + } + + public interface DataConverter { + + int getDataVersion(); + + net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp); + } + + private void registerInspector(LegacyType type, DataInspector inspector) { this.inspectors.computeIfAbsent(type, k -> new ArrayList<>()).add(inspector); } @@ -544,39 +470,146 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo registerEntityItemList(type, "ArmorItems", "HandItems"); } - public enum LegacyType { - LEVEL(References.LEVEL), - PLAYER(References.PLAYER), - CHUNK(References.CHUNK), - BLOCK_ENTITY(References.BLOCK_ENTITY), - ENTITY(References.ENTITY), - ITEM_INSTANCE(References.ITEM_STACK), - OPTIONS(References.OPTIONS), - STRUCTURE(References.STRUCTURE); + private static final Map OLD_ID_TO_KEY_MAP = new HashMap<>(); - private final TypeReference type; + static { + final Map map = OLD_ID_TO_KEY_MAP; + map.put("EntityItem", new ResourceLocation("item")); + map.put("EntityExperienceOrb", new ResourceLocation("xp_orb")); + map.put("EntityAreaEffectCloud", new ResourceLocation("area_effect_cloud")); + map.put("EntityGuardianElder", new ResourceLocation("elder_guardian")); + map.put("EntitySkeletonWither", new ResourceLocation("wither_skeleton")); + map.put("EntitySkeletonStray", new ResourceLocation("stray")); + map.put("EntityEgg", new ResourceLocation("egg")); + map.put("EntityLeash", new ResourceLocation("leash_knot")); + map.put("EntityPainting", new ResourceLocation("painting")); + map.put("EntityTippedArrow", new ResourceLocation("arrow")); + map.put("EntitySnowball", new ResourceLocation("snowball")); + map.put("EntityLargeFireball", new ResourceLocation("fireball")); + map.put("EntitySmallFireball", new ResourceLocation("small_fireball")); + map.put("EntityEnderPearl", new ResourceLocation("ender_pearl")); + map.put("EntityEnderSignal", new ResourceLocation("eye_of_ender_signal")); + map.put("EntityPotion", new ResourceLocation("potion")); + map.put("EntityThrownExpBottle", new ResourceLocation("xp_bottle")); + map.put("EntityItemFrame", new ResourceLocation("item_frame")); + map.put("EntityWitherSkull", new ResourceLocation("wither_skull")); + map.put("EntityTNTPrimed", new ResourceLocation("tnt")); + map.put("EntityFallingBlock", new ResourceLocation("falling_block")); + map.put("EntityFireworks", new ResourceLocation("fireworks_rocket")); + map.put("EntityZombieHusk", new ResourceLocation("husk")); + map.put("EntitySpectralArrow", new ResourceLocation("spectral_arrow")); + map.put("EntityShulkerBullet", new ResourceLocation("shulker_bullet")); + map.put("EntityDragonFireball", new ResourceLocation("dragon_fireball")); + map.put("EntityZombieVillager", new ResourceLocation("zombie_villager")); + map.put("EntityHorseSkeleton", new ResourceLocation("skeleton_horse")); + map.put("EntityHorseZombie", new ResourceLocation("zombie_horse")); + map.put("EntityArmorStand", new ResourceLocation("armor_stand")); + map.put("EntityHorseDonkey", new ResourceLocation("donkey")); + map.put("EntityHorseMule", new ResourceLocation("mule")); + map.put("EntityEvokerFangs", new ResourceLocation("evocation_fangs")); + map.put("EntityEvoker", new ResourceLocation("evocation_illager")); + map.put("EntityVex", new ResourceLocation("vex")); + map.put("EntityVindicator", new ResourceLocation("vindication_illager")); + map.put("EntityIllagerIllusioner", new ResourceLocation("illusion_illager")); + map.put("EntityMinecartCommandBlock", new ResourceLocation("commandblock_minecart")); + map.put("EntityBoat", new ResourceLocation("boat")); + map.put("EntityMinecartRideable", new ResourceLocation("minecart")); + map.put("EntityMinecartChest", new ResourceLocation("chest_minecart")); + map.put("EntityMinecartFurnace", new ResourceLocation("furnace_minecart")); + map.put("EntityMinecartTNT", new ResourceLocation("tnt_minecart")); + map.put("EntityMinecartHopper", new ResourceLocation("hopper_minecart")); + map.put("EntityMinecartMobSpawner", new ResourceLocation("spawner_minecart")); + map.put("EntityCreeper", new ResourceLocation("creeper")); + map.put("EntitySkeleton", new ResourceLocation("skeleton")); + map.put("EntitySpider", new ResourceLocation("spider")); + map.put("EntityGiantZombie", new ResourceLocation("giant")); + map.put("EntityZombie", new ResourceLocation("zombie")); + map.put("EntitySlime", new ResourceLocation("slime")); + map.put("EntityGhast", new ResourceLocation("ghast")); + map.put("EntityPigZombie", new ResourceLocation("zombie_pigman")); + map.put("EntityEnderman", new ResourceLocation("enderman")); + map.put("EntityCaveSpider", new ResourceLocation("cave_spider")); + map.put("EntitySilverfish", new ResourceLocation("silverfish")); + map.put("EntityBlaze", new ResourceLocation("blaze")); + map.put("EntityMagmaCube", new ResourceLocation("magma_cube")); + map.put("EntityEnderDragon", new ResourceLocation("ender_dragon")); + map.put("EntityWither", new ResourceLocation("wither")); + map.put("EntityBat", new ResourceLocation("bat")); + map.put("EntityWitch", new ResourceLocation("witch")); + map.put("EntityEndermite", new ResourceLocation("endermite")); + map.put("EntityGuardian", new ResourceLocation("guardian")); + map.put("EntityShulker", new ResourceLocation("shulker")); + map.put("EntityPig", new ResourceLocation("pig")); + map.put("EntitySheep", new ResourceLocation("sheep")); + map.put("EntityCow", new ResourceLocation("cow")); + map.put("EntityChicken", new ResourceLocation("chicken")); + map.put("EntitySquid", new ResourceLocation("squid")); + map.put("EntityWolf", new ResourceLocation("wolf")); + map.put("EntityMushroomCow", new ResourceLocation("mooshroom")); + map.put("EntitySnowman", new ResourceLocation("snowman")); + map.put("EntityOcelot", new ResourceLocation("ocelot")); + map.put("EntityIronGolem", new ResourceLocation("villager_golem")); + map.put("EntityHorse", new ResourceLocation("horse")); + map.put("EntityRabbit", new ResourceLocation("rabbit")); + map.put("EntityPolarBear", new ResourceLocation("polar_bear")); + map.put("EntityLlama", new ResourceLocation("llama")); + map.put("EntityLlamaSpit", new ResourceLocation("llama_spit")); + map.put("EntityParrot", new ResourceLocation("parrot")); + map.put("EntityVillager", new ResourceLocation("villager")); + map.put("EntityEnderCrystal", new ResourceLocation("ender_crystal")); + map.put("TileEntityFurnace", new ResourceLocation("furnace")); + map.put("TileEntityChest", new ResourceLocation("chest")); + map.put("TileEntityEnderChest", new ResourceLocation("ender_chest")); + map.put("TileEntityRecordPlayer", new ResourceLocation("jukebox")); + map.put("TileEntityDispenser", new ResourceLocation("dispenser")); + map.put("TileEntityDropper", new ResourceLocation("dropper")); + map.put("TileEntitySign", new ResourceLocation("sign")); + map.put("TileEntityMobSpawner", new ResourceLocation("mob_spawner")); + map.put("TileEntityNote", new ResourceLocation("noteblock")); + map.put("TileEntityPiston", new ResourceLocation("piston")); + map.put("TileEntityBrewingStand", new ResourceLocation("brewing_stand")); + map.put("TileEntityEnchantTable", new ResourceLocation("enchanting_table")); + map.put("TileEntityEnderPortal", new ResourceLocation("end_portal")); + map.put("TileEntityBeacon", new ResourceLocation("beacon")); + map.put("TileEntitySkull", new ResourceLocation("skull")); + map.put("TileEntityLightDetector", new ResourceLocation("daylight_detector")); + map.put("TileEntityHopper", new ResourceLocation("hopper")); + map.put("TileEntityComparator", new ResourceLocation("comparator")); + map.put("TileEntityFlowerPot", new ResourceLocation("flower_pot")); + map.put("TileEntityBanner", new ResourceLocation("banner")); + map.put("TileEntityStructure", new ResourceLocation("structure_block")); + map.put("TileEntityEndGateway", new ResourceLocation("end_gateway")); + map.put("TileEntityCommand", new ResourceLocation("command_block")); + map.put("TileEntityShulkerBox", new ResourceLocation("shulker_box")); + map.put("TileEntityBed", new ResourceLocation("bed")); + } - LegacyType(TypeReference type) { - this.type = type; - DFU_TO_LEGACY.put(type.typeName(), this); + private static ResourceLocation getKey(String type) { + final ResourceLocation key = OLD_ID_TO_KEY_MAP.get(type); + if (key == null) { + throw new IllegalArgumentException("Unknown mapping for " + type); } + return key; + } - public TypeReference getDFUType() { - return type; + private static void convertCompound(LegacyType type, net.minecraft.nbt.CompoundTag cmp, String key, int sourceVer, int targetVer) { + cmp.put(key, convert(type, cmp.getCompound(key), sourceVer, targetVer)); + } + + private static void convertItem(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { + if (nbttagcompound.contains(key, 10)) { + convertCompound(LegacyType.ITEM_INSTANCE, nbttagcompound, key, sourceVer, targetVer); } } - public interface DataInspector { + private static void convertItems(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { + if (nbttagcompound.contains(key, 9)) { + net.minecraft.nbt.ListTag nbttaglist = nbttagcompound.getList(key, 10); - net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer); - - } - - public interface DataConverter { - - int getDataVersion(); - - net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp); + for (int j = 0; j < nbttaglist.size(); ++j) { + nbttaglist.set(j, convert(LegacyType.ITEM_INSTANCE, nbttaglist.getCompound(j), sourceVer, targetVer)); + } + } } @@ -635,7 +668,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataInspectorBlockEntity implements DataInspector { @@ -643,6 +675,50 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo private static final Map b = Maps.newHashMap(); private static final Map c = Maps.newHashMap(); + DataInspectorBlockEntity() { + } + + @Nullable + private static String convertEntityId(int i, String s) { + String key = new ResourceLocation(s).toString(); + if (i < 515 && DataInspectorBlockEntity.b.containsKey(key)) { + return DataInspectorBlockEntity.b.get(key); + } else { + return DataInspectorBlockEntity.c.get(key); + } + } + + public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { + if (!cmp.contains("tag", 10)) { + return cmp; + } else { + net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); + + if (nbttagcompound1.contains("BlockEntityTag", 10)) { + net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); + String s = cmp.getString("id"); + String s1 = convertEntityId(sourceVer, s); + boolean flag; + + if (s1 == null) { + // CraftBukkit - Remove unnecessary warning (occurs when deserializing a Shulker Box item) + // DataInspectorBlockEntity.a.warn("Unable to resolve BlockEntity for ItemInstance: {}", s); + flag = false; + } else { + flag = !nbttagcompound2.contains("id"); + nbttagcompound2.putString("id", s1); + } + + convert(LegacyType.BLOCK_ENTITY, nbttagcompound2, sourceVer, targetVer); + if (flag) { + nbttagcompound2.remove("id"); + } + } + + return cmp; + } + } + static { Map map = DataInspectorBlockEntity.b; @@ -734,56 +810,10 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo map.put("minecraft:end_gateway", "minecraft:end_gateway"); map.put("minecraft:shield", "minecraft:shield"); } - - DataInspectorBlockEntity() { - } - - @Nullable - private static String convertEntityId(int i, String s) { - String key = new ResourceLocation(s).toString(); - if (i < 515 && DataInspectorBlockEntity.b.containsKey(key)) { - return DataInspectorBlockEntity.b.get(key); - } else { - return DataInspectorBlockEntity.c.get(key); - } - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (!cmp.contains("tag", 10)) { - return cmp; - } else { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - String s = cmp.getString("id"); - String s1 = convertEntityId(sourceVer, s); - boolean flag; - - if (s1 == null) { - // CraftBukkit - Remove unnecessary warning (occurs when deserializing a Shulker Box item) - // DataInspectorBlockEntity.a.warn("Unable to resolve BlockEntity for ItemInstance: {}", s); - flag = false; - } else { - flag = !nbttagcompound2.contains("id"); - nbttagcompound2.putString("id", s1); - } - - convert(LegacyType.BLOCK_ENTITY, nbttagcompound2, sourceVer, targetVer); - if (flag) { - nbttagcompound2.remove("id"); - } - } - - return cmp; - } - } } private static class DataInspectorEntity implements DataInspector { - private static final Logger a = LogManager.getLogger(PaperweightDataConverters.class); - DataInspectorEntity() { } @@ -818,9 +848,9 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } + private abstract static class DataInspectorTagged implements DataInspector { private final ResourceLocation key; @@ -837,12 +867,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - abstract net.minecraft.nbt.CompoundTag inspectChecked( - net.minecraft.nbt.CompoundTag nbttagcompound, - int sourceVer, - int targetVer - ); - + abstract net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer); } private static class DataInspectorItemList extends DataInspectorTagged { @@ -861,7 +886,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return nbttagcompound; } - } private static class DataInspectorItem extends DataInspectorTagged { @@ -880,13 +904,31 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return nbttagcompound; } - } private static class DataConverterMaterialId implements DataConverter { private static final String[] materials = new String[2268]; + DataConverterMaterialId() { + } + + public int getDataVersion() { + return 102; + } + + public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { + if (cmp.contains("id", 99)) { + short short0 = cmp.getShort("id"); + + if (short0 > 0 && short0 < materials.length && materials[short0] != null) { + cmp.putString("id", materials[short0]); + } + } + + return cmp; + } + static { materials[1] = "minecraft:stone"; materials[2] = "minecraft:grass"; @@ -1244,25 +1286,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo materials[453] = "minecraft:knowledge_book"; // Paper end } - - DataConverterMaterialId() { - } - - public int getDataVersion() { - return 102; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("id", 99)) { - short short0 = cmp.getShort("id"); - - if (short0 > 0 && short0 < materials.length && materials[short0] != null) { - cmp.putString("id", materials[short0]); - } - } - - return cmp; - } } private static class DataConverterArmorStand implements DataConverter { @@ -1281,7 +1304,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterBanner implements DataConverter { @@ -1328,13 +1350,42 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterPotionId implements DataConverter { private static final String[] potions = new String[128]; + DataConverterPotionId() { + } + + public int getDataVersion() { + return 102; + } + + public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { + if ("minecraft:potion".equals(cmp.getString("id"))) { + net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); + short short0 = cmp.getShort("Damage"); + + if (!nbttagcompound1.contains("Potion", 8)) { + String s = DataConverterPotionId.potions[short0 & 127]; + + nbttagcompound1.putString("Potion", s == null ? "minecraft:water" : s); + cmp.put("tag", nbttagcompound1); + if ((short0 & 16384) == 16384) { + cmp.putString("id", "minecraft:splash_potion"); + } + } + + if (short0 != 0) { + cmp.putShort("Damage", (short) 0); + } + } + + return cmp; + } + static { DataConverterPotionId.potions[0] = "minecraft:water"; DataConverterPotionId.potions[1] = "minecraft:regeneration"; @@ -1465,26 +1516,32 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo DataConverterPotionId.potions[126] = "minecraft:long_invisibility"; DataConverterPotionId.potions[127] = null; } + } - DataConverterPotionId() { + private static class DataConverterSpawnEgg implements DataConverter { + + private static final String[] eggs = new String[256]; + + DataConverterSpawnEgg() { } public int getDataVersion() { - return 102; + return 105; } public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:potion".equals(cmp.getString("id"))) { + if ("minecraft:spawn_egg".equals(cmp.getString("id"))) { net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); + net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); short short0 = cmp.getShort("Damage"); - if (!nbttagcompound1.contains("Potion", 8)) { - String s = DataConverterPotionId.potions[short0 & 127]; + if (!nbttagcompound2.contains("id", 8)) { + String s = DataConverterSpawnEgg.eggs[short0 & 255]; - nbttagcompound1.putString("Potion", s == null ? "minecraft:water" : s); - cmp.put("tag", nbttagcompound1); - if ((short0 & 16384) == 16384) { - cmp.putString("id", "minecraft:splash_potion"); + if (s != null) { + nbttagcompound2.putString("id", s); + nbttagcompound1.put("EntityTag", nbttagcompound2); + cmp.put("tag", nbttagcompound1); } } @@ -1495,11 +1552,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } - - private static class DataConverterSpawnEgg implements DataConverter { - - private static final String[] eggs = new String[256]; static { @@ -1571,50 +1623,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo DataConverterSpawnEgg.eggs[120] = "Villager"; DataConverterSpawnEgg.eggs[200] = "EnderCrystal"; } - - DataConverterSpawnEgg() { - } - - public int getDataVersion() { - return 105; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:spawn_egg".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); - short short0 = cmp.getShort("Damage"); - - if (!nbttagcompound2.contains("id", 8)) { - String s = DataConverterSpawnEgg.eggs[short0 & 255]; - - if (s != null) { - nbttagcompound2.putString("id", s); - nbttagcompound1.put("EntityTag", nbttagcompound2); - cmp.put("tag", nbttagcompound1); - } - } - - if (short0 != 0) { - cmp.putShort("Damage", (short) 0); - } - } - - return cmp; - } } private static class DataConverterMinecart implements DataConverter { - private static final List a = Lists.newArrayList( - "MinecartRideable", - "MinecartChest", - "MinecartFurnace", - "MinecartTNT", - "MinecartSpawner", - "MinecartHopper", - "MinecartCommandBlock" - ); + private static final List a = Lists.newArrayList("MinecartRideable", "MinecartChest", "MinecartFurnace", "MinecartTNT", "MinecartSpawner", "MinecartHopper", "MinecartCommandBlock"); DataConverterMinecart() { } @@ -1638,7 +1651,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterMobSpawner implements DataConverter { @@ -1683,7 +1695,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } } - } private static class DataConverterUUID implements DataConverter { @@ -1702,47 +1713,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterHealth implements DataConverter { - private static final Set a = Sets.newHashSet( - "ArmorStand", - "Bat", - "Blaze", - "CaveSpider", - "Chicken", - "Cow", - "Creeper", - "EnderDragon", - "Enderman", - "Endermite", - "EntityHorse", - "Ghast", - "Giant", - "Guardian", - "LavaSlime", - "MushroomCow", - "Ozelot", - "Pig", - "PigZombie", - "Rabbit", - "Sheep", - "Shulker", - "Silverfish", - "Skeleton", - "Slime", - "SnowMan", - "Spider", - "Squid", - "Villager", - "VillagerGolem", - "Witch", - "WitherBoss", - "Wolf", - "Zombie" - ); + private static final Set a = Sets.newHashSet("ArmorStand", "Bat", "Blaze", "CaveSpider", "Chicken", "Cow", "Creeper", "EnderDragon", "Enderman", "Endermite", "EntityHorse", "Ghast", "Giant", "Guardian", "LavaSlime", "MushroomCow", "Ozelot", "Pig", "PigZombie", "Rabbit", "Sheep", "Shulker", "Silverfish", "Skeleton", "Slime", "SnowMan", "Spider", "Squid", "Villager", "VillagerGolem", "Witch", "WitherBoss", "Wolf", "Zombie"); DataConverterHealth() { } @@ -1771,7 +1746,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterSaddle implements DataConverter { @@ -1796,7 +1770,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterHanging implements DataConverter { @@ -1835,7 +1808,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterDropChances implements DataConverter { @@ -1859,15 +1831,13 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo if (cmp.contains("ArmorDropChances", 9)) { nbttaglist = cmp.getList("ArmorDropChances", 5); - if (nbttaglist.size() == 4 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F && nbttaglist.getFloat( - 2) == 0.0F && nbttaglist.getFloat(3) == 0.0F) { + if (nbttaglist.size() == 4 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F && nbttaglist.getFloat(2) == 0.0F && nbttaglist.getFloat(3) == 0.0F) { cmp.remove("ArmorDropChances"); } } return cmp; } - } private static class DataConverterRiding implements DataConverter { @@ -1903,7 +1873,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo nbttagcompound.remove("Riding"); return nbttagcompound1; } - } private static class DataConverterBook implements DataConverter { @@ -1928,39 +1897,42 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo if (!"null".equals(s) && !StringUtil.isNullOrEmpty(s)) { if ((s.charAt(0) != 34 || s.charAt(s.length() - 1) != 34) && (s.charAt(0) != 123 || s.charAt(s.length() - 1) != 125)) { - object = new TextComponent(s); + object = Component.literal(s); } else { try { object = GsonHelper.fromJson(DataConverterSignText.a, s, Component.class, true); if (object == null) { - object = new TextComponent(""); + object = Component.literal(""); } - } catch (JsonParseException ignored) { + } catch (JsonParseException jsonparseexception) { + ; } if (object == null) { try { - object = Component.Serializer.fromJson(s); - } catch (JsonParseException ignored) { + object = Component.Serializer.fromJson(s, MinecraftServer.getServer().registryAccess()); + } catch (JsonParseException jsonparseexception1) { + ; } } if (object == null) { try { - object = Component.Serializer.fromJsonLenient(s); - } catch (JsonParseException ignored) { + object = Component.Serializer.fromJsonLenient(s, MinecraftServer.getServer().registryAccess()); + } catch (JsonParseException jsonparseexception2) { + ; } } if (object == null) { - object = new TextComponent(s); + object = Component.literal(s); } } } else { - object = new TextComponent(""); + object = Component.literal(""); } - nbttaglist.set(i, net.minecraft.nbt.StringTag.valueOf(Component.Serializer.toJson(object))); + nbttaglist.set(i, StringTag.valueOf(Component.Serializer.toJson(object, MinecraftServer.getServer().registryAccess()))); } nbttagcompound1.put("pages", nbttaglist); @@ -1969,7 +1941,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterCookedFish implements DataConverter { @@ -1990,7 +1961,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterZombie implements DataConverter { @@ -2012,7 +1982,8 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo if (cmp.contains("VillagerProfession", 99)) { try { i = this.convert(cmp.getInt("VillagerProfession")); - } catch (RuntimeException ignored) { + } catch (RuntimeException runtimeexception) { + ; } } @@ -2032,7 +2003,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo private int convert(int i) { return i >= 0 && i < 6 ? i : -1; } - } private static class DataConverterVBO implements DataConverter { @@ -2048,7 +2018,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo cmp.putString("useVbo", "true"); return cmp; } - } private static class DataConverterGuardian implements DataConverter { @@ -2071,7 +2040,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterSkeleton implements DataConverter { @@ -2100,7 +2068,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterZombieType implements DataConverter { @@ -2139,7 +2106,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterHorse implements DataConverter { @@ -2182,13 +2148,29 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterTileEntity implements DataConverter { private static final Map a = Maps.newHashMap(); + DataConverterTileEntity() { + } + + public int getDataVersion() { + return 704; + } + + public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { + String s = DataConverterTileEntity.a.get(cmp.getString("id")); + + if (s != null) { + cmp.putString("id", s); + } + + return cmp; + } + static { DataConverterTileEntity.a.put("Airportal", "minecraft:end_portal"); DataConverterTileEntity.a.put("Banner", "minecraft:banner"); @@ -2214,8 +2196,13 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo DataConverterTileEntity.a.put("Structure", "minecraft:structure_block"); DataConverterTileEntity.a.put("Trap", "minecraft:dispenser"); } + } - DataConverterTileEntity() { + private static class DataConverterEntity implements DataConverter { + + private static final Map a = Maps.newHashMap(); + + DataConverterEntity() { } public int getDataVersion() { @@ -2223,7 +2210,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo } public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = DataConverterTileEntity.a.get(cmp.getString("id")); + String s = DataConverterEntity.a.get(cmp.getString("id")); if (s != null) { cmp.putString("id", s); @@ -2231,11 +2218,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } - - private static class DataConverterEntity implements DataConverter { - - private static final Map a = Maps.newHashMap(); static { DataConverterEntity.a.put("AreaEffectCloud", "minecraft:area_effect_cloud"); @@ -2314,23 +2296,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo DataConverterEntity.a.put("ZombieHorse", "minecraft:zombie_horse"); DataConverterEntity.a.put("ZombieVillager", "minecraft:zombie_villager"); } - - DataConverterEntity() { - } - - public int getDataVersion() { - return 704; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = DataConverterEntity.a.get(cmp.getString("id")); - - if (s != null) { - cmp.putString("id", s); - } - - return cmp; - } } private static class DataConverterPotionWater implements DataConverter { @@ -2345,8 +2310,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { String s = cmp.getString("id"); - if ("minecraft:potion".equals(s) || "minecraft:splash_potion".equals(s) || "minecraft:lingering_potion".equals(s) || "minecraft:tipped_arrow".equals( - s)) { + if ("minecraft:potion".equals(s) || "minecraft:splash_potion".equals(s) || "minecraft:lingering_potion".equals(s) || "minecraft:tipped_arrow".equals(s)) { net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); if (!nbttagcompound1.contains("Potion", 8)) { @@ -2360,7 +2324,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterShulker implements DataConverter { @@ -2379,12 +2342,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterShulkerBoxItem implements DataConverter { - public static final String[] a = new String[]{"minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box"}; + public static final String[] a = new String[] { "minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box" }; DataConverterShulkerBoxItem() { } @@ -2421,7 +2383,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterShulkerBoxBlock implements DataConverter { @@ -2440,7 +2401,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterLang implements DataConverter { @@ -2459,7 +2419,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterTotem implements DataConverter { @@ -2478,7 +2437,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterBedBlock implements DataConverter { @@ -2526,7 +2484,6 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterBedItem implements DataConverter { @@ -2545,26 +2502,22 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataConverterSignText implements DataConverter { public static final Gson a = new GsonBuilder().registerTypeAdapter(Component.class, new JsonDeserializer() { - MutableComponent a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws - JsonParseException { + MutableComponent a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { if (jsonelement.isJsonPrimitive()) { - return new TextComponent(jsonelement.getAsString()); + return Component.literal(jsonelement.getAsString()); } else if (jsonelement.isJsonArray()) { JsonArray jsonarray = jsonelement.getAsJsonArray(); MutableComponent ichatbasecomponent = null; + Iterator iterator = jsonarray.iterator(); - for (final JsonElement jsonelement1 : jsonarray) { - MutableComponent ichatbasecomponent1 = this.a( - jsonelement1, - jsonelement1.getClass(), - jsondeserializationcontext - ); + while (iterator.hasNext()) { + JsonElement jsonelement1 = (JsonElement) iterator.next(); + MutableComponent ichatbasecomponent1 = this.a(jsonelement1, jsonelement1.getClass(), jsondeserializationcontext); if (ichatbasecomponent == null) { ichatbasecomponent = ichatbasecomponent1; @@ -2579,11 +2532,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo } } - public Object deserialize( - JsonElement jsonelement, - Type type, - JsonDeserializationContext jsondeserializationcontext - ) throws JsonParseException { + public Object deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { return this.a(jsonelement, type, jsondeserializationcontext); } }).create(); @@ -2612,45 +2561,46 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo if (!"null".equals(s1) && !StringUtil.isNullOrEmpty(s1)) { if ((s1.charAt(0) != 34 || s1.charAt(s1.length() - 1) != 34) && (s1.charAt(0) != 123 || s1.charAt(s1.length() - 1) != 125)) { - object = new TextComponent(s1); + object = Component.literal(s1); } else { try { object = GsonHelper.fromJson(DataConverterSignText.a, s1, Component.class, true); if (object == null) { - object = new TextComponent(""); + object = Component.literal(""); } - } catch (JsonParseException ignored) { + } catch (JsonParseException jsonparseexception) { + ; } if (object == null) { try { - object = Component.Serializer.fromJson(s1); - } catch (JsonParseException ignored) { + object = Component.Serializer.fromJson(s1, MinecraftServer.getServer().registryAccess()); + } catch (JsonParseException jsonparseexception1) { + ; } } if (object == null) { try { - object = Component.Serializer.fromJsonLenient(s1); - } catch (JsonParseException ignored) { + object = Component.Serializer.fromJsonLenient(s1, MinecraftServer.getServer().registryAccess()); + } catch (JsonParseException jsonparseexception2) { + ; } } if (object == null) { - object = new TextComponent(s1); + object = Component.literal(s1); } } } else { - object = new TextComponent(""); + object = Component.literal(""); } - nbttagcompound.putString(s, Component.Serializer.toJson(object)); + nbttagcompound.putString(s, Component.Serializer.toJson(object, MinecraftServer.getServer().registryAccess())); } - } private static class DataInspectorPlayerVehicle implements DataInspector { - @Override public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { if (cmp.contains("RootVehicle", 10)) { @@ -2663,11 +2613,9 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataInspectorLevelPlayer implements DataInspector { - @Override public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { if (cmp.contains("Player", 10)) { @@ -2676,11 +2624,9 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataInspectorStructure implements DataInspector { - @Override public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { net.minecraft.nbt.ListTag nbttaglist; @@ -2711,11 +2657,9 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataInspectorChunks implements DataInspector { - @Override public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { if (cmp.contains("Level", 10)) { @@ -2727,14 +2671,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo nbttaglist = nbttagcompound1.getList("Entities", 10); for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set( - j, - convert(LegacyType.ENTITY, - (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), - sourceVer, - targetVer - ) - ); + nbttaglist.set(j, convert(LegacyType.ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); } } @@ -2742,25 +2679,16 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo nbttaglist = nbttagcompound1.getList("TileEntities", 10); for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set( - j, - convert(LegacyType.BLOCK_ENTITY, - (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), - sourceVer, - targetVer - ) - ); + nbttaglist.set(j, convert(LegacyType.BLOCK_ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); } } } return cmp; } - } private static class DataInspectorEntityPassengers implements DataInspector { - @Override public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { if (cmp.contains("Passengers", 9)) { @@ -2773,11 +2701,9 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataInspectorPlayer implements DataInspector { - @Override public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { convertItems(cmp, "Inventory", sourceVer, targetVer); @@ -2792,11 +2718,9 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataInspectorVillagers implements DataInspector { - ResourceLocation entityVillager = getKey("EntityVillager"); @Override @@ -2820,11 +2744,9 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataInspectorMobSpawnerMinecart implements DataInspector { - ResourceLocation entityMinecartMobSpawner = getKey("EntityMinecartMobSpawner"); ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); @@ -2839,11 +2761,9 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataInspectorMobSpawnerMobs implements DataInspector { - ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); @Override @@ -2864,11 +2784,9 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } private static class DataInspectorCommandBlock implements DataInspector { - ResourceLocation tileEntityCommand = getKey("TileEntityCommand"); @Override @@ -2881,63 +2799,5 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - } - - @SuppressWarnings("unchecked") - private class WrappedDataFixer implements DataFixer { - - private final DataFixer realFixer; - - WrappedDataFixer(DataFixer realFixer) { - this.realFixer = realFixer; - } - - @Override - public Dynamic update(TypeReference type, Dynamic dynamic, int sourceVer, int targetVer) { - LegacyType legacyType = DFU_TO_LEGACY.get(type.typeName()); - if (sourceVer < LEGACY_VERSION && legacyType != null) { - net.minecraft.nbt.CompoundTag cmp = (net.minecraft.nbt.CompoundTag) dynamic.getValue(); - int desiredVersion = Math.min(targetVer, LEGACY_VERSION); - - cmp = convert(legacyType, cmp, sourceVer, desiredVersion); - sourceVer = desiredVersion; - dynamic = new Dynamic(OPS_NBT, cmp); - } - return realFixer.update(type, dynamic, sourceVer, targetVer); - } - - private net.minecraft.nbt.CompoundTag convert( - LegacyType type, - net.minecraft.nbt.CompoundTag cmp, - int sourceVer, - int desiredVersion - ) { - List converters = PaperweightDataConverters.this.converters.get(type); - if (converters != null && !converters.isEmpty()) { - for (DataConverter converter : converters) { - int dataVersion = converter.getDataVersion(); - if (dataVersion > sourceVer && dataVersion <= desiredVersion) { - cmp = converter.convert(cmp); - } - } - } - - List inspectors = PaperweightDataConverters.this.inspectors.get(type); - if (inspectors != null && !inspectors.isEmpty()) { - for (DataInspector inspector : inspectors) { - cmp = inspector.inspect(cmp, sourceVer, desiredVersion); - } - } - - return cmp; - } - - @Override - public Schema getSchema(int i) { - return realFixer.getSchema(i); - } - - } - } diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R2/PaperweightFakePlayer.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightFakePlayer.java similarity index 78% rename from worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R2/PaperweightFakePlayer.java rename to worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightFakePlayer.java index e5ff26672..792942843 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R2/PaperweightFakePlayer.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightFakePlayer.java @@ -17,18 +17,19 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2; +package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4; import com.mojang.authlib.GameProfile; -import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ServerboundClientInformationPacket; +import net.minecraft.server.level.ClientInformation; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.stats.Stat; import net.minecraft.world.MenuProvider; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.HumanoidArm; +import net.minecraft.world.entity.player.ChatVisiblity; import net.minecraft.world.level.block.entity.SignBlockEntity; import net.minecraft.world.phys.Vec3; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; @@ -37,15 +38,14 @@ import java.util.OptionalInt; import java.util.UUID; class PaperweightFakePlayer extends ServerPlayer { - - private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile( - UUID.nameUUIDFromBytes("worldedit".getBytes()), - "[WorldEdit]" - ); + private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]"); private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D); + private static final ClientInformation FAKE_CLIENT_INFO = new ClientInformation( + "en_US", 16, ChatVisiblity.FULL, true, 0, HumanoidArm.LEFT, false, false + ); PaperweightFakePlayer(ServerLevel world) { - super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE); + super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE, FAKE_CLIENT_INFO); } @Override @@ -72,17 +72,13 @@ class PaperweightFakePlayer extends ServerPlayer { } @Override - public void updateOptions(ServerboundClientInformationPacket packet) { + public void updateOptions(ClientInformation clientOptions) { } @Override public void displayClientMessage(Component message, boolean actionBar) { } - @Override - public void sendMessage(Component message, ChatType type, UUID sender) { - } - @Override public void awardStat(Stat stat, int amount) { } @@ -97,7 +93,6 @@ class PaperweightFakePlayer extends ServerPlayer { } @Override - public void openTextEdit(SignBlockEntity sign) { + public void openTextEdit(SignBlockEntity sign, boolean front) { } - } diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R2/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightWorldNativeAccess.java similarity index 74% rename from worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R2/PaperweightWorldNativeAccess.java rename to worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightWorldNativeAccess.java index e9656539a..f7e5cee3f 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R2/PaperweightWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightWorldNativeAccess.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2; +package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.internal.block.BlockStateIdAccess; @@ -27,21 +27,19 @@ import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.block.BlockState; import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.FullChunkStatus; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.event.block.BlockPhysicsEvent; import java.lang.ref.WeakReference; import java.util.Objects; import javax.annotation.Nullable; -public class PaperweightWorldNativeAccess implements - WorldNativeAccess { - +public class PaperweightWorldNativeAccess implements WorldNativeAccess { private static final int UPDATE = 1; private static final int NOTIFY = 2; @@ -83,19 +81,12 @@ public class PaperweightWorldNativeAccess implements @Nullable @Override - public net.minecraft.world.level.block.state.BlockState setBlockState( - LevelChunk chunk, - BlockPos position, - net.minecraft.world.level.block.state.BlockState state - ) { + public net.minecraft.world.level.block.state.BlockState setBlockState(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState state) { return chunk.setBlockState(position, state, false, this.sideEffectSet.shouldApply(SideEffect.UPDATE)); } @Override - public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition( - net.minecraft.world.level.block.state.BlockState block, - BlockPos position - ) { + public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition(net.minecraft.world.level.block.state.BlockState block, BlockPos position) { return Block.updateFromNeighbourShapes(block, getWorld(), position); } @@ -115,12 +106,7 @@ public class PaperweightWorldNativeAccess implements } @Override - public void notifyBlockUpdate( - LevelChunk chunk, - BlockPos position, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { + public void notifyBlockUpdate(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY); } @@ -128,7 +114,7 @@ public class PaperweightWorldNativeAccess implements @Override public boolean isChunkTicking(LevelChunk chunk) { - return chunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING); + return chunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING); } @Override @@ -139,11 +125,7 @@ public class PaperweightWorldNativeAccess implements } @Override - public void notifyNeighbors( - BlockPos pos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { + public void notifyNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { ServerLevel world = getWorld(); if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { world.updateNeighborsAt(pos, oldState.getBlock()); @@ -162,27 +144,20 @@ public class PaperweightWorldNativeAccess implements } } + // Not sure why neighborChanged is deprecated private void fireNeighborChanged(BlockPos pos, ServerLevel world, Block block, BlockPos neighborPos) { - world.getBlockState(neighborPos).neighborChanged(world, neighborPos, block, pos, false); + world.getBlockState(neighborPos).handleNeighborChanged(world, neighborPos, block, pos, false); } @Override - public void updateNeighbors( - BlockPos pos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState, - int recursionLimit - ) { + public void updateNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState, int recursionLimit) { ServerLevel world = getWorld(); // a == updateNeighbors // b == updateDiagonalNeighbors oldState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { CraftWorld craftWorld = world.getWorld(); - BlockPhysicsEvent event = new BlockPhysicsEvent( - craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), - CraftBlockData.fromData(newState) - ); + BlockPhysicsEvent event = new BlockPhysicsEvent(craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), CraftBlockData.fromData(newState)); world.getCraftServer().getPluginManager().callEvent(event); if (event.isCancelled()) { return; @@ -193,19 +168,13 @@ public class PaperweightWorldNativeAccess implements } @Override - public void onBlockStateChange( - BlockPos pos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { + public void onBlockStateChange(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { getWorld().onBlockStateChange(pos, oldState, newState); } - //FAWE start @Override public void flush() { } - //FAWE end } diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightBlockMaterial.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightBlockMaterial.java similarity index 69% rename from worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightBlockMaterial.java rename to worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightBlockMaterial.java index b5da62e0f..9c2292451 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightBlockMaterial.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightBlockMaterial.java @@ -1,28 +1,24 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4; import com.google.common.base.Suppliers; import com.sk89q.jnbt.CompoundTag; -import com.sk89q.util.ReflectionUtil; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag; +import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag; import com.sk89q.worldedit.world.registry.BlockMaterial; import net.minecraft.core.BlockPos; +import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.world.level.EmptyBlockGetter; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.material.Fluids; import net.minecraft.world.level.material.PushReaction; -import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData; +import org.bukkit.craftbukkit.block.data.CraftBlockData; public class PaperweightBlockMaterial implements BlockMaterial { private final Block block; private final BlockState blockState; - private final Material material; - private final boolean isTranslucent; private final CraftBlockData craftBlockData; private final org.bukkit.Material craftMaterial; private final int opacity; @@ -35,22 +31,16 @@ public class PaperweightBlockMaterial implements BlockMaterial { public PaperweightBlockMaterial(Block block, BlockState blockState) { this.block = block; this.blockState = blockState; - this.material = blockState.getMaterial(); this.craftBlockData = CraftBlockData.fromData(blockState); this.craftMaterial = craftBlockData.getMaterial(); - BlockBehaviour.Properties blockInfo = ReflectionUtil.getField(BlockBehaviour.class, block, Refraction.pickName( - "properties", "aO")); - this.isTranslucent = !(boolean) ReflectionUtil.getField(BlockBehaviour.Properties.class, blockInfo, - Refraction.pickName("canOcclude", "n") - ); opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity( BlockPos.ZERO, blockState ); - tile = tileEntity == null - ? null - : new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); + tile = tileEntity == null ? null : new PaperweightLazyCompoundTag( + Suppliers.memoize(() -> tileEntity.saveWithId(DedicatedServer.getServer().registryAccess())) + ); } public Block getBlock() { @@ -65,10 +55,6 @@ public class PaperweightBlockMaterial implements BlockMaterial { return craftBlockData; } - public Material getMaterial() { - return material; - } - @Override public boolean isAir() { return blockState.isAir(); @@ -81,7 +67,7 @@ public class PaperweightBlockMaterial implements BlockMaterial { @Override public boolean isOpaque() { - return material.isSolidBlocking(); + return blockState.canOcclude(); } @Override @@ -91,12 +77,13 @@ public class PaperweightBlockMaterial implements BlockMaterial { @Override public boolean isLiquid() { - return material.isLiquid(); + return !blockState.getFluidState().is(Fluids.EMPTY); } @Override public boolean isSolid() { - return material.isSolid(); + // No access to world -> EmptyBlockGetter + return blockState.isSolidRender(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); } @Override @@ -126,27 +113,27 @@ public class PaperweightBlockMaterial implements BlockMaterial { @Override public boolean isFragileWhenPushed() { - return material.getPushReaction() == PushReaction.DESTROY; + return blockState.getPistonPushReaction() == PushReaction.DESTROY; } @Override public boolean isUnpushable() { - return material.getPushReaction() == PushReaction.BLOCK; + return blockState.getPistonPushReaction() == PushReaction.BLOCK; } @Override public boolean isTicksRandomly() { - return block.isRandomlyTicking(blockState); + return blockState.isRandomlyTicking(); } @Override public boolean isMovementBlocker() { - return material.isSolid(); + return craftMaterial.isSolid(); } @Override public boolean isBurnable() { - return material.isFlammable(); + return craftMaterial.isBurnable(); } @Override @@ -157,12 +144,12 @@ public class PaperweightBlockMaterial implements BlockMaterial { @Override public boolean isReplacedDuringPlacement() { - return material.isReplaceable(); + return blockState.canBeReplaced(); } @Override public boolean isTranslucent() { - return isTranslucent; + return !blockState.canOcclude(); } @Override @@ -183,7 +170,7 @@ public class PaperweightBlockMaterial implements BlockMaterial { @Override public int getMapColor() { // rgb field - return material.getColor().col; + return block.defaultMapColor().col; } } diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java similarity index 82% rename from worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightFaweAdapter.java rename to worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java index 8b96e2ea6..b263c9ced 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java @@ -1,4 +1,4 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4; import com.fastasyncworldedit.bukkit.adapter.FaweAdapter; import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory; @@ -12,14 +12,13 @@ import com.fastasyncworldedit.core.util.NbtUtils; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.mojang.serialization.Codec; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.blocks.TileEntityBlock; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2.PaperweightAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.regen.PaperweightRegen; +import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag; +import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.regen.PaperweightRegen; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.internal.block.BlockStateIdAccess; @@ -35,6 +34,7 @@ import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.SideEffectSet; +import com.sk89q.worldedit.util.concurrency.LazyReference; import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.nbt.BinaryTag; import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; @@ -45,7 +45,6 @@ import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; -import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.item.ItemType; @@ -53,44 +52,48 @@ import com.sk89q.worldedit.world.registry.BlockMaterial; import io.papermc.lib.PaperLib; import net.minecraft.core.BlockPos; import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.WritableRegistry; -import net.minecraft.nbt.IntTag; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.util.StringRepresentable; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.DirectionProperty; import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.NamespacedKey; import org.bukkit.World; import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.v1_18_R2.CraftChunk; -import org.bukkit.craftbukkit.v1_18_R2.CraftServer; -import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_18_R2.util.CraftNamespacedKey; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.block.data.CraftBlockData; +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; import org.bukkit.entity.Player; import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -104,11 +107,24 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; +import static net.minecraft.core.registries.Registries.BIOME; + public final class PaperweightFaweAdapter extends FaweAdapter { private static final Logger LOGGER = LogManagerCompat.getLogger(); + private static Method CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE; + private static final Codec COMPONENTS_CODEC = DataComponentPatch.CODEC.optionalFieldOf( + "components", DataComponentPatch.EMPTY + ).codec(); - private final PaperweightAdapter parent; + static { + try { + CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE = ChunkHolder.class.getDeclaredMethod("wasAccessibleSinceLastSave"); + } catch (NoSuchMethodException ignored) { // may not be present in newer paper versions + } + } + + private final com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4.PaperweightAdapter parent; // ------------------------------------------------------------------------ // Code that may break between versions of Minecraft // ------------------------------------------------------------------------ @@ -119,7 +135,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter>> allBlockProperties = null; public PaperweightFaweAdapter() throws NoSuchFieldException, NoSuchMethodException { - this.parent = new PaperweightAdapter(); + this.parent = new com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4.PaperweightAdapter(); } @Nullable @@ -128,6 +144,10 @@ public final class PaperweightFaweAdapter extends FaweAdapter getParent() { return parent; @@ -219,7 +239,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter> 4; - LevelChunkSection section = levelChunkSections[y4]; - - net.minecraft.world.level.block.state.BlockState existing; - if (section == null) { - existing = ((PaperweightBlockMaterial) BlockTypes.AIR.getDefaultState().getMaterial()).getState(); - } else { - existing = section.getBlockState(x & 15, y & 15, z & 15); - } - - levelChunk.removeBlockEntity(blockPos); // Force delete the old tile entity - - CompoundBinaryTag compoundTag = state instanceof BaseBlock ? state.getNbt() : null; - if (compoundTag != null || existing instanceof TileEntityBlock) { - level.setBlock(blockPos, blockState, 0); - // remove tile - if (compoundTag != null) { - // We will assume that the tile entity was created for us, - // though we do not do this on the Forge version - BlockEntity blockEntity = level.getBlockEntity(blockPos); - if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeBinary(compoundTag); - tag.put("x", IntTag.valueOf(x)); - tag.put("y", IntTag.valueOf(y)); - tag.put("z", IntTag.valueOf(z)); - blockEntity.load(tag); // readTagIntoTileEntity - load data - } - } - } else { - if (existing == blockState) { - return true; - } - levelChunk.setBlockState(blockPos, blockState, false); - } - if (update) { - level.getMinecraftWorld().sendBlockUpdated(blockPos, existing, blockState, 0); - } - return true; - } - @Override public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { return new PaperweightFaweWorldNativeAccess(this, new WeakReference<>(getServerLevel(world))); @@ -343,7 +316,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter saveTag = () -> { final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag); + readEntityIntoTag(mcEntity, minecraftTag); //add Id for AbstractChangeSet to work final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag); final Map tags = NbtUtils.getCompoundBinaryTagValues(tag); @@ -474,7 +447,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag) */ Stream.empty(); @@ -516,11 +490,18 @@ public final class PaperweightFaweAdapter extends FaweAdapter getEntities(org.bukkit.World world) { - // Quickly add each entity to a list copy. - List mcEntities = new ArrayList<>(); - getServerLevel(world).entityManager.getEntityGetter().getAll().forEach(mcEntities::add); - - List list = new ArrayList<>(); - mcEntities.forEach((mcEnt) -> { - org.bukkit.entity.Entity bukkitEntity = mcEnt.getBukkitEntity(); - if (bukkitEntity.isValid()) { - list.add(bukkitEntity); - } - - }); - return list; - } - @Override public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { + final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess(); final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); - weStack.setNbt(((CompoundBinaryTag) toNativeBinary(nmsStack.getTag()))); - return weStack; + final net.minecraft.nbt.Tag tag = COMPONENTS_CODEC.encodeStart( + registryAccess.createSerializationContext(NbtOps.INSTANCE), + nmsStack.getComponentsPatch() + ).getOrThrow(); + return new BaseItemStack( + BukkitAdapter.asItemType(itemStack.getType()), + LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag)), + itemStack.getAmount() + ); } @Override @@ -577,17 +548,12 @@ public final class PaperweightFaweAdapter extends FaweAdapter registry = MinecraftServer .getServer() .registryAccess() - .ownedRegistryOrThrow(Registry.BIOME_REGISTRY); + .registryOrThrow(BIOME); ResourceLocation resourceLocation = ResourceLocation.tryParse(biomeType.getId()); Biome biome = registry.get(resourceLocation); return registry.getId(biome); @@ -616,8 +582,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter biomeRegistry = (WritableRegistry) ((CraftServer) Bukkit.getServer()) .getServer() .registryAccess() - .ownedRegistryOrThrow( - Registry.BIOME_REGISTRY); + .registryOrThrow(BIOME); List keys = biomeRegistry.stream() .map(biomeRegistry::getKey).filter(Objects::nonNull).toList(); List namespacedKeys = new ArrayList<>(); @@ -659,4 +624,16 @@ public final class PaperweightFaweAdapter extends FaweAdapter currentTick; if (nextTick || cachedChanges.size() >= 1024) { if (nextTick) { @@ -140,7 +141,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ()); - private static final Function nmsTile2We = - tileEntity -> new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); + private static final Function nmsTile2We = tileEntity -> new PaperweightLazyCompoundTag( + Suppliers.memoize(() -> tileEntity.saveWithId(DedicatedServer.getServer().registryAccess())) + ); private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin .getInstance() .getBukkitImplAdapter()); @@ -130,7 +114,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc this.maxSectionPosition = maxHeight >> 4; this.skyLight = new DataLayer[getSectionCount()]; this.blockLight = new DataLayer[getSectionCount()]; - this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY); + this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(BIOME); this.biomeHolderIdMap = biomeRegistry.asHolderIdMap(); } @@ -260,7 +244,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (blockEntity == null) { return null; } - return new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)); + return new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.saveWithId(DedicatedServer.getServer().registryAccess()))); } @Override @@ -289,8 +273,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( LightLayer.BLOCK, sectionPos, - dataLayer, - true + dataLayer ); } skyLight[alayer] = dataLayer; @@ -317,7 +300,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc Arrays.fill(LAYER_COUNT, (byte) 15); dataLayer = new DataLayer(LAYER_COUNT); ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(LightLayer.BLOCK, sectionPos, - dataLayer, true + dataLayer ); } blockLight[alayer] = dataLayer; @@ -334,7 +317,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc @Override public CompoundTag getEntity(UUID uuid) { - Entity entity = serverLevel.getEntity(uuid); + ensureLoaded(serverLevel, chunkX, chunkZ); + List entities = PaperweightPlatformAdapter.getEntities(getChunk()); + Entity entity = null; + for (Entity e : entities) { + if (e.getUUID().equals(uuid)) { + entity = e; + break; + } + } if (entity != null) { org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity(); return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); @@ -349,6 +340,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc @Override public Set getEntities() { + ensureLoaded(serverLevel, chunkX, chunkZ); List entities = PaperweightPlatformAdapter.getEntities(getChunk()); if (entities.isEmpty()) { return Collections.emptySet(); @@ -385,7 +377,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc public Iterator iterator() { Iterable result = entities.stream().map(input -> { net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(input, tag); + input.save(tag); return (CompoundTag) adapter.toNative(tag); }).collect(Collectors.toList()); return result.iterator(); @@ -474,7 +466,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc synchronized (super.sectionLocks[getSectionIndex]) { LevelChunkSection existingSection = levelChunkSections[getSectionIndex]; if (createCopy && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes().copy()); + copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); } if (existingSection == null) { @@ -507,8 +499,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } } } else { - PalettedContainer> biomeData = existingSection.getBiomes(); - setBiomesToPalettedContainer(biomes[setSectionIndex], biomeData); + setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes()); } } } @@ -543,7 +534,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); copy.storeSection(getSectionIndex, copyArr); if (biomes != null && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes().copy()); + copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); } } @@ -555,8 +546,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc .getBukkitImplAdapter() .getInternalBiomeId( BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES, - null + PalettedContainer.Strategy.SECTION_BIOMES ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); newSection = PaperweightPlatformAdapter.newChunkSection( layerNo, @@ -616,11 +606,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc sectionLock.writeLock().unlock(); } - PalettedContainer> biomeData = existingSection.getBiomes(); - - if (biomes != null && biomes[setSectionIndex] != null) { - setBiomesToPalettedContainer(biomes[setSectionIndex], biomeData); - } + PalettedContainer> biomeData = setBiomesToPalettedContainer( + biomes, + setSectionIndex, + existingSection.getBiomes() + ); newSection = PaperweightPlatformAdapter.newChunkSection( @@ -705,7 +695,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) { for (UUID uuid : entityRemoves) { - Entity entity = nmsWorld.entityManager.getEntityGetter().get(uuid); + Entity entity = nmsWorld.getEntities().get(uuid); if (entity != null) { removeEntity(entity); } @@ -800,7 +790,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc tag.put("x", IntTag.valueOf(x)); tag.put("y", IntTag.valueOf(y)); tag.put("z", IntTag.valueOf(z)); - tileEntity.load(tag); + tileEntity.loadWithComponents(tag, DedicatedServer.getServer().registryAccess()); } } } @@ -1076,8 +1066,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( lightLayer, sectionPos, - dataLayer, - true + dataLayer ); } synchronized (dataLayer) { @@ -1095,22 +1084,35 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } } - private void setBiomesToPalettedContainer( - final BiomeType[] biomes, - PalettedContainer> data + private PalettedContainer> setBiomesToPalettedContainer( + final BiomeType[][] biomes, + final int sectionIndex, + final PalettedContainerRO> data ) { - int index = 0; - if (biomes == null) { - return; + PalettedContainer> biomeData; + if (data instanceof PalettedContainer> palettedContainer) { + biomeData = palettedContainer; + } else { + LOGGER.warn( + "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + + "type {} but got {}", + PalettedContainer.class.getSimpleName(), + data.getClass().getSimpleName() + ); + biomeData = data.recreate(); } - for (int y = 0; y < 4; y++) { + BiomeType[] sectionBiomes; + if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { + return biomeData; + } + for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { - BiomeType biomeType = biomes[index]; + BiomeType biomeType = sectionBiomes[index]; if (biomeType == null) { continue; } - data.set( + biomeData.set( x, y, z, @@ -1122,6 +1124,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } } } + return biomeData; } @Override diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java similarity index 86% rename from worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks_Copy.java rename to worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java index b007ea3b4..c0a7bda52 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java @@ -1,4 +1,4 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4; import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; import com.fastasyncworldedit.core.queue.IBlocks; @@ -8,19 +8,23 @@ import com.google.common.base.Suppliers; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag; +import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag; +import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; import net.minecraft.core.Holder; +import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.PalettedContainer; +import net.minecraft.world.level.chunk.PalettedContainerRO; +import org.apache.logging.log4j.Logger; import javax.annotation.Nullable; import java.util.Arrays; @@ -33,6 +37,8 @@ import java.util.concurrent.Future; public class PaperweightGetBlocks_Copy implements IChunkGet { + private static final Logger LOGGER = LogManagerCompat.getLogger(); + private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); private final char[][] blocks; @@ -57,7 +63,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { blockEntity.getBlockPos().getY(), blockEntity.getBlockPos().getZ() ), - new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)) + new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.saveWithId(DedicatedServer.getServer().registryAccess()))) ); } @@ -76,7 +82,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeEntity(Entity entity) { BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(entity, compoundTag); + entity.save(compoundTag); entities.add((CompoundTag) adapter.toNative(compoundTag)); } @@ -166,11 +172,19 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { blocks[layer] = data; } - protected void storeBiomes(int layer, PalettedContainer> biomeData) { + protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { if (biomes == null) { biomes = new PalettedContainer[getSectionCount()]; } - biomes[layer] = biomeData; + if (biomeData instanceof PalettedContainer> palettedContainer) { + biomes[layer] = palettedContainer.copy(); + } else { + LOGGER.error( + "Cannot correctly save biomes to history. Expected class type {} but got {}", + PalettedContainer.class.getSimpleName(), + biomeData.getClass().getSimpleName() + ); + } } @Override diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightMapChunkUtil.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightMapChunkUtil.java similarity index 88% rename from worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightMapChunkUtil.java rename to worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightMapChunkUtil.java index 9189ca251..9e226b088 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightMapChunkUtil.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightMapChunkUtil.java @@ -1,4 +1,4 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4; import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil; import com.sk89q.worldedit.bukkit.adapter.Refraction; @@ -10,10 +10,10 @@ public class PaperweightMapChunkUtil extends MapChunkUtil serverLevel + io.papermc.paper.util.MCUtil.MAIN_EXECUTOR.execute(() -> serverLevel .getChunkSource() - .addRegionTicket(TicketType.PLUGIN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE)); + .addRegionTicket(TicketType.UNLOAD_COOLDOWN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE)); } public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) { @@ -286,20 +338,21 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return; } ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ); - // UNLOADED_CHUNK - Optional optional = ((Either) chunkHolder - .getTickingChunkFuture() - .getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left(); + LevelChunk levelChunk; if (PaperLib.isPaper()) { // getChunkAtIfLoadedImmediately is paper only - optional = optional.or(() -> Optional.ofNullable(nmsWorld + levelChunk = nmsWorld .getChunkSource() - .getChunkAtIfLoadedImmediately(chunkX, chunkZ))); + .getChunkAtIfLoadedImmediately(chunkX, chunkZ); + } else { + levelChunk = ((Optional) ((Either) chunkHolder + .getTickingChunkFuture() // method is not present with new paper chunk system + .getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left()) + .orElse(null); } - if (optional.isEmpty()) { + if (levelChunk == null) { return; } - LevelChunk levelChunk = optional.get(); TaskManager.taskManager().task(() -> { ClientboundLevelChunkWithLightPacket packet; if (PaperLib.isPaper()) { @@ -307,9 +360,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { levelChunk, nmsWorld.getChunkSource().getLightEngine(), null, - null, - true, - false // last false is to not bother with x-ray + null + // last false is to not bother with x-ray ); } else { // deprecated on paper - deprecation suppressed @@ -317,8 +369,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { levelChunk, nmsWorld.getChunkSource().getLightEngine(), null, - null, - true + null ); } nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); @@ -424,12 +475,11 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { .getBukkitImplAdapter() .getInternalBiomeId( BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES, - null + PalettedContainer.Strategy.SECTION_BIOMES ); } - return new LevelChunkSection(layer, blockStatePalettedContainer, biomes); + return new LevelChunkSection(blockStatePalettedContainer, biomes); } catch (final Throwable e) { throw e; } finally { @@ -447,15 +497,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @Nullable PalettedContainer> biomes ) { if (biomes == null) { - return new LevelChunkSection(layer, biomeRegistry); + return new LevelChunkSection(biomeRegistry); } PalettedContainer dataPaletteBlocks = new PalettedContainer<>( Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), - PalettedContainer.Strategy.SECTION_STATES, - null + PalettedContainer.Strategy.SECTION_STATES ); - return new LevelChunkSection(layer, dataPaletteBlocks, biomes); + return new LevelChunkSection(dataPaletteBlocks, biomes); } /** @@ -492,8 +541,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { PalettedContainer> biomePalettedContainer = new PalettedContainer<>( biomeRegistry, biomeRegistry.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES, - null + PalettedContainer.Strategy.SECTION_BIOMES ); final Palette> biomePalette; @@ -571,7 +619,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } public static BiomeType adapt(Holder biome, LevelAccessor levelAccessor) { - final Registry biomeRegistry = levelAccessor.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY); + final Registry biomeRegistry = levelAccessor.registryAccess().registryOrThrow(BIOME); if (biomeRegistry.getKey(biome.value()) == null) { return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN : null; @@ -581,13 +629,11 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { try { - // Do the method ourselves to avoid trying to reflect generic method parameters - // similar to removeGameEventListener if (levelChunk.loaded || levelChunk.level.isClientSide()) { BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos()); if (blockEntity != null) { if (!levelChunk.level.isClientSide) { - methodRemoveGameEventListener.invoke(levelChunk, beacon); + methodRemoveGameEventListener.invoke(levelChunk, beacon, levelChunk.level); } fieldRemove.set(beacon, true); } @@ -599,30 +645,32 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } static List getEntities(LevelChunk chunk) { - return chunk.level.entityManager.getEntities(chunk.getPos()); - } - - public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) { - boolean isVillager = entity instanceof AbstractVillager && !Fawe.isMainThread(); - boolean unset = false; - if (isVillager) { - try { - if (fieldOffers.get(entity) != null) { - fieldOffers.set(entity, OFFERS); - unset = true; + ExceptionCollector collector = new ExceptionCollector<>(); + if (PaperLib.isPaper()) { + if (POST_CHUNK_REWRITE) { + try { + //noinspection unchecked + return (List) PAPER_CHUNK_GEN_ALL_ENTITIES.invoke(chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ)); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=true]", e); } - } catch (IllegalAccessException e) { - throw new RuntimeException("Failed to set offers field to villager to avoid async catcher.", e); } - } - entity.save(compoundTag); - if (unset) { try { - fieldOffers.set(entity, null); + EntityList entityList = (EntityList) LEVEL_CHUNK_ENTITIES.get(chunk); + return List.of(entityList.getRawData()); } catch (IllegalAccessException e) { - throw new RuntimeException("Failed to set offers field to null again on villager.", e); + collector.add(new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=false]", e)); + // fall through } } + try { + //noinspection unchecked + return ((PersistentEntitySectionManager) (SERVER_LEVEL_ENTITY_MANAGER.get(chunk.level))).getEntities(chunk.getPos()); + } catch (IllegalAccessException e) { + collector.add(new RuntimeException("Failed to lookup entities [PAPER=false]", e)); + } + collector.throwIfPresent(); + return List.of(); } record FakeIdMapBlock(int size) implements IdMap { diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPostProcessor.java similarity index 99% rename from worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightPostProcessor.java rename to worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPostProcessor.java index abc8d6150..bc094a916 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightPostProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPostProcessor.java @@ -1,4 +1,4 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4; import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.extent.processor.ProcessorScope; diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightStarlightRelighter.java similarity index 90% rename from worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightStarlightRelighter.java rename to worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightStarlightRelighter.java index c832fc98a..476978b57 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightStarlightRelighter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightStarlightRelighter.java @@ -1,14 +1,14 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4; import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter; import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.queue.IQueueExtent; -import net.minecraft.server.MCUtil; +import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.TicketType; import net.minecraft.util.Unit; import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.chunk.status.ChunkStatus; import java.util.Set; import java.util.concurrent.CompletableFuture; @@ -18,7 +18,7 @@ import java.util.function.IntConsumer; public class PaperweightStarlightRelighter extends StarlightRelighter { private static final TicketType FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0); - private static final int LIGHT_LEVEL = MCUtil.getTicketLevelFor(ChunkStatus.LIGHT); + private static final int LIGHT_LEVEL = ChunkMap.MAX_VIEW_DISTANCE + ChunkStatus.getDistance(ChunkStatus.LIGHT); public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent queue) { super(serverLevel, queue); diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightStarlightRelighterFactory.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightStarlightRelighterFactory.java similarity index 88% rename from worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightStarlightRelighterFactory.java rename to worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightStarlightRelighterFactory.java index 735bcc677..1425088b8 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/PaperweightStarlightRelighterFactory.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightStarlightRelighterFactory.java @@ -1,4 +1,4 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4; import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter; import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode; @@ -7,7 +7,7 @@ import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; import com.fastasyncworldedit.core.queue.IQueueExtent; import com.sk89q.worldedit.world.World; import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; +import org.bukkit.craftbukkit.CraftWorld; import javax.annotation.Nonnull; diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/nbt/PaperweightLazyCompoundTag.java similarity index 98% rename from worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/nbt/PaperweightLazyCompoundTag.java rename to worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/nbt/PaperweightLazyCompoundTag.java index a890d66a4..11d3c940a 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/nbt/PaperweightLazyCompoundTag.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/nbt/PaperweightLazyCompoundTag.java @@ -1,4 +1,4 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt; +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.LazyCompoundTag; diff --git a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/regen/PaperweightRegen.java similarity index 69% rename from worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/regen/PaperweightRegen.java rename to worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/regen/PaperweightRegen.java index 8403d531d..e21e7eef7 100644 --- a/worldedit-bukkit/adapters/adapter-1_18_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R2/regen/PaperweightRegen.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/regen/PaperweightRegen.java @@ -1,17 +1,15 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.regen; +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.regen; import com.fastasyncworldedit.bukkit.adapter.Regenerator; import com.fastasyncworldedit.core.Fawe; import com.fastasyncworldedit.core.queue.IChunkCache; import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.util.ReflectionUtils; import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.collect.ImmutableList; -import com.mojang.datafixers.util.Either; import com.mojang.serialization.Lifecycle; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.PaperweightGetBlocks; +import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.PaperweightGetBlocks; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.regions.Region; @@ -20,14 +18,19 @@ import com.sk89q.worldedit.world.RegenOptions; import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; import net.minecraft.core.Holder; import net.minecraft.core.Registry; -import net.minecraft.data.BuiltinRegistries; +import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.server.level.ChunkMap; +import net.minecraft.server.level.ChunkTaskPriorityQueueSorter.Message; import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ThreadedLevelLightEngine; import net.minecraft.server.level.progress.ChunkProgressListener; +import net.minecraft.util.thread.ProcessorHandle; +import net.minecraft.util.thread.ProcessorMailbox; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelHeightAccessor; @@ -37,31 +40,34 @@ import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.biome.FixedBiomeSource; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.chunk.ChunkStatus; +import net.minecraft.world.level.chunk.ChunkGeneratorStructureState; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.ProtoChunk; import net.minecraft.world.level.chunk.UpgradeData; +import net.minecraft.world.level.chunk.status.ChunkStatus; +import net.minecraft.world.level.chunk.status.WorldGenContext; import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.levelgen.FlatLevelSource; import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; -import net.minecraft.world.level.levelgen.WorldGenSettings; +import net.minecraft.world.level.levelgen.WorldOptions; import net.minecraft.world.level.levelgen.blending.BlendingData; import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_18_R2.CraftServer; -import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_18_R2.generator.CustomChunkGenerator; +import org.bukkit.Chunk; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.generator.CustomChunkGenerator; import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.BlockPopulator; +import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; -import java.io.IOException; import java.lang.reflect.Field; import java.nio.file.Path; import java.util.Collections; @@ -74,6 +80,8 @@ import java.util.concurrent.CompletableFuture; import java.util.function.BooleanSupplier; import java.util.function.Supplier; +import static net.minecraft.core.registries.Registries.BIOME; + public class PaperweightRegen extends Regenerator { private static final Logger LOGGER = LogManagerCompat.getLogger(); @@ -85,6 +93,7 @@ public class PaperweightRegen extends Regenerator) () -> new ServerLevel( @@ -232,66 +254,70 @@ public class PaperweightRegen extends Regenerator singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.asHolderIdMap().byId( - WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) - ) : null; + + private final Holder singleBiome = options.hasBiomeType() ? DedicatedServer.getServer().registryAccess() + .registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow( + WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) + ) : null; @Override - public void tick(BooleanSupplier shouldKeepTicking) { //no ticking + public void tick(@NotNull BooleanSupplier shouldKeepTicking) { //no ticking } @Override - public Holder getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) { + public @NotNull Holder getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) { if (options.hasBiomeType()) { return singleBiome; } - return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome(biomeX, biomeY, biomeZ, - PaperweightRegen.this.chunkGenerator.climateSampler() + return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome( + biomeX, biomeY, biomeZ, getChunkSource().randomState().sampler() ); } + }).get(); freshWorld.noSave = true; removeWorldFromWorldsMap(); newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name if (paperConfigField != null) { - paperConfigField.set(freshWorld, originalServerWorld.paperConfig); + paperConfigField.set(freshWorld, originalServerWorld.paperConfig()); } - //generator ChunkGenerator originalGenerator = originalChunkProvider.getGenerator(); if (originalGenerator instanceof FlatLevelSource flatLevelSource) { FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings(); - chunkGenerator = new FlatLevelSource(originalGenerator.structureSets, generatorSettingFlat); + chunkGenerator = new FlatLevelSource(generatorSettingFlat); } else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) { - Holder generatorSettingBaseSupplier = - (Holder) generatorSettingBaseSupplierField - .get(originalGenerator); + Holder generatorSettingBaseSupplier = (Holder) + generatorSettingBaseSupplierField.get(noiseBasedChunkGenerator); BiomeSource biomeSource; if (options.hasBiomeType()) { - biomeSource = new FixedBiomeSource(BuiltinRegistries.BIOME - .asHolderIdMap() - .byId(WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()))); + biomeSource = new FixedBiomeSource( + DedicatedServer.getServer().registryAccess() + .registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow( + WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) + ) + ); } else { biomeSource = originalGenerator.getBiomeSource(); } - chunkGenerator = new NoiseBasedChunkGenerator(originalGenerator.structureSets, noiseBasedChunkGenerator.noises, - biomeSource, seed, + chunkGenerator = new NoiseBasedChunkGenerator( + biomeSource, generatorSettingBaseSupplier ); } else if (originalGenerator instanceof CustomChunkGenerator customChunkGenerator) { - chunkGenerator = customChunkGenerator.delegate; + chunkGenerator = customChunkGenerator.getDelegate(); } else { LOGGER.error("Unsupported generator type {}", originalGenerator.getClass().getName()); return false; @@ -300,22 +326,8 @@ public class PaperweightRegen extends Regenerator>> ringPositions = - (Map>>) ringPositionsField.get( - originalGenerator); - Map>> copy = new Object2ObjectArrayMap<>(ringPositions); - ringPositionsField.set(chunkGenerator, copy); - hasGeneratedPositionsField.setBoolean(chunkGenerator, true); - } - } - - - chunkGenerator.conf = originalServerWorld.spigotConfig; freshChunkProvider = new ServerChunkCache( freshWorld, session, @@ -333,7 +345,7 @@ public class PaperweightRegen extends Regenerator>> origPositions = + (Map>>) ringPositionsField.get(state); + Map>> copy = new Object2ObjectArrayMap<>( + origPositions); + ChunkGeneratorStructureState newState = (ChunkGeneratorStructureState) generatorStructureStateField.get( + freshChunkProvider.chunkMap); + ringPositionsField.set(newState, copy); + hasGeneratedPositionsField.setBoolean(newState, true); + } + } + + chunkSourceField.set(freshWorld, freshChunkProvider); //let's start then - structureManager = server.getStructureManager(); - threadedLevelLightEngine = freshChunkProvider.getLightEngine(); + structureTemplateManager = server.getStructureManager(); + threadedLevelLightEngine = new NoOpLightEngine(freshChunkProvider); + this.worldGenContext = new WorldGenContext(freshWorld, chunkGenerator, structureTemplateManager, + threadedLevelLightEngine + ); return true; } @@ -362,7 +395,7 @@ public class PaperweightRegen extends Regenerator { try { freshChunkProvider.close(false); - } catch (IOException e) { + } catch (Exception e) { throw new RuntimeException(e); } }); @@ -385,7 +418,7 @@ public class PaperweightRegen extends Regenerator blockPopulator.populate(freshWorld.getWorld(), random, levelChunk.getBukkitChunk())); + TaskManager.taskManager().task(() -> { + final CraftWorld world = freshWorld.getWorld(); + final Chunk chunk = world.getChunkAt(levelChunk.locX, levelChunk.locZ); + blockPopulator.populate(world, random, chunk); + }); } @Override @@ -427,14 +464,12 @@ public class PaperweightRegen extends Regenerator { - try { - Map map = (Map) serverWorldsField.get(Bukkit.getServer()); - map.remove("faweregentempworld"); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - }); + try { + Map map = (Map) serverWorldsField.get(Bukkit.getServer()); + map.remove("faweregentempworld"); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } } private ResourceKey getWorldDimKey(org.bukkit.World.Environment env) { @@ -451,11 +486,15 @@ public class PaperweightRegen extends Regenerator getEntities() { + public @NotNull List getEntities() { return Collections.emptyList(); } @@ -516,23 +554,41 @@ public class PaperweightRegen extends Regenerator processChunk(List accessibleChunks) { return chunkStatus.generate( - Runnable::run, // TODO revisit, we might profit from this somehow? - freshWorld, - chunkGenerator, - structureManager, - threadedLevelLightEngine, - c -> CompletableFuture.completedFuture(Either.left(c)), - accessibleChunks, - true + worldGenContext, + Runnable::run, + CompletableFuture::completedFuture, + accessibleChunks ); } } + /** + * A light engine that does nothing. As light is calculated after pasting anyway, we can avoid + * work this way. + */ + static class NoOpLightEngine extends ThreadedLevelLightEngine { + + private static final ProcessorMailbox MAILBOX = ProcessorMailbox.create(task -> { + }, "fawe-no-op"); + private static final ProcessorHandle> HANDLE = ProcessorHandle.of("fawe-no-op", m -> { + }); + + public NoOpLightEngine(final ServerChunkCache chunkProvider) { + super(chunkProvider, chunkProvider.chunkMap, false, MAILBOX, HANDLE); + } + + @Override + public @NotNull CompletableFuture lightChunk(final @NotNull ChunkAccess chunk, final boolean excludeBlocks) { + return CompletableFuture.completedFuture(chunk); + } + + } + } diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index 8705c931c..3af5fa04e 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -36,6 +36,7 @@ repositories { name = "Glaremasters" url = uri("https://repo.glaremasters.me/repository/towny/") } + maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") // TODO Remove when 4.17.0 is released flatDir { dir(File("src/main/resources")) } } @@ -210,7 +211,7 @@ tasks { versionNumber.set("${project.version}") versionType.set("release") uploadFile.set(file("build/libs/${rootProject.name}-Bukkit-${project.version}.jar")) - gameVersions.addAll(listOf("1.20.4", "1.20.3", "1.20.2", "1.20.1", "1.20", "1.19.4", "1.18.2")) + gameVersions.addAll(listOf("1.20.6", "1.20.5", "1.20.3", "1.20.2", "1.20.1", "1.20", "1.19.4")) loaders.addAll(listOf("paper", "spigot")) changelog.set("The changelog is available on GitHub: https://github.com/IntellectualSites/" + "FastAsyncWorldEdit/releases/tag/${project.version}") diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/Regenerator.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/Regenerator.java index 607bc75bf..2a006d141 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/Regenerator.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/Regenerator.java @@ -5,6 +5,7 @@ import com.fastasyncworldedit.core.queue.IChunkCache; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.implementation.SingleThreadQueueExtent; import com.fastasyncworldedit.core.util.MathMan; +import com.google.common.collect.Lists; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.bukkit.BukkitAdapter; @@ -24,11 +25,16 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.LongArrayList; import it.unimi.dsi.fastutil.longs.LongList; +import jdk.jfr.Category; +import jdk.jfr.Event; +import jdk.jfr.Label; +import jdk.jfr.Name; import org.apache.logging.log4j.Logger; import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.WorldInfo; +import java.util.AbstractList; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -36,6 +42,7 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Random; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; @@ -62,7 +69,7 @@ public abstract class Regenerator chunkStatuses = new LinkedHashMap<>(); + protected final LinkedHashMap chunkStatuses = new LinkedHashMap<>(); // TODO (j21): use SequencedMap private final Long2ObjectLinkedOpenHashMap protoChunks = new Long2ObjectLinkedOpenHashMap<>(); private final Long2ObjectOpenHashMap chunks = new Long2ObjectOpenHashMap<>(); protected boolean generateConcurrent = true; @@ -172,51 +179,70 @@ public abstract class Regenerator chunkCoordsForRadius = new Int2ObjectOpenHashMap<>(); - chunkStatuses.keySet().stream().mapToInt(ChunkStatusWrapper::requiredNeighborChunkRadius0).distinct().forEach(radius -> { - if (radius == -1) { //ignore ChunkStatus.EMPTY - return; - } - int border = 10 - radius; //9 = 8 + 1, 8: max border radius used in chunk stages, 1: need 1 extra chunk for chunk - // features to generate at the border of the region - chunkCoordsForRadius.put(radius, getChunkCoordsRegen(region, border)); - }); + // to get the chunks we need to generate in the nth chunk status, we need to know how many chunks + // we need to generate in the n + 1 th chunk status. Summing up the margin solves that + LinkedHashMap chunkCoordsForChunkStatus = new LinkedHashMap<>(); + int borderSum = 1; + // TODO (j21): use SequencedMap#sequencedKeySet().reversed() + final List reversedKeys = Lists.reverse(new ArrayList<>(chunkStatuses.keySet())); + for (final ChunkStatus status : reversedKeys) { + chunkCoordsForChunkStatus.put(status, getChunkCoordsRegen(region, borderSum)); + borderSum += status.requiredNeighborChunkRadius(); + } //create chunks - for (long xz : chunkCoordsForRadius.get(0)) { + // TODO (j21): use SequencedMap#firstEntry().getKey() + for (long xz : chunkCoordsForChunkStatus.get(chunkStatuses.keySet().iterator().next())) { ProtoChunk chunk = createProtoChunk(MathMan.unpairIntX(xz), MathMan.unpairIntY(xz)); protoChunks.put(xz, chunk); } - //generate lists for RegionLimitedWorldAccess, need to be square with odd length (e.g. 17x17), 17 = 1 middle chunk + 8 border chunks * 2 - Int2ObjectOpenHashMap>> worldLimits = new Int2ObjectOpenHashMap<>(); - chunkStatuses.keySet().stream().mapToInt(ChunkStatusWrapper::requiredNeighborChunkRadius0).distinct().forEach(radius -> { - if (radius == -1) { //ignore ChunkStatus.EMPTY - return; + // a memory-efficient, lightweight "list" that calculates index -> ChunkAccess + // as needed when accessed + class LazyChunkList extends AbstractList { + private final int size; + private final int minX; + private final int minZ; + private final int sizeSqrt; + + LazyChunkList(int radius, int centerX, int centerZ) { + this.sizeSqrt = radius + 1 + radius; // length of one side + this.size = this.sizeSqrt * this.sizeSqrt; + this.minX = centerX - radius; + this.minZ = centerZ - radius; } - Long2ObjectOpenHashMap> map = new Long2ObjectOpenHashMap<>(); - for (long xz : chunkCoordsForRadius.get(radius)) { - int x = MathMan.unpairIntX(xz); - int z = MathMan.unpairIntY(xz); - List l = new ArrayList<>((radius + 1 + radius) * (radius + 1 + radius)); - for (int zz = z - radius; zz <= z + radius; zz++) { //order is important, first z then x - for (int xx = x - radius; xx <= x + radius; xx++) { - l.add(protoChunks.get(MathMan.pairInt(xx, zz))); - } - } - map.put(xz, l); + @Override + public IChunkAccess get(final int index) { + Objects.checkIndex(index, size); + int absX = (index % sizeSqrt) + minX; + int absZ = (index / sizeSqrt) + minZ; + return protoChunks.get(MathMan.pairInt(absX, absZ)); } - worldLimits.put(radius, map); - }); + + @Override + public int size() { + return size; + } + + } + @Label("Regeneration") + @Category("FAWE") + @Name("fawe.regen") + class RegenerationEvent extends Event { + private String chunkStatus; + private int chunksToProcess; + } //run generation tasks excluding FULL chunk status for (Map.Entry entry : chunkStatuses.entrySet()) { ChunkStatus chunkStatus = entry.getKey(); - int radius = chunkStatus.requiredNeighborChunkRadius0(); + final RegenerationEvent event = new RegenerationEvent(); + event.begin(); + event.chunkStatus = chunkStatus.name(); + int radius = Math.max(1, chunkStatus.requiredNeighborChunkRadius0()); - long[] coords = chunkCoordsForRadius.get(radius); - Long2ObjectOpenHashMap> limitsForRadius = worldLimits.get(radius); + long[] coords = chunkCoordsForChunkStatus.get(chunkStatus); + event.chunksToProcess = coords.length; if (this.generateConcurrent && entry.getValue() == Concurrency.RADIUS) { SequentialTasks> tasks = getChunkStatusTaskRows(coords, radius); for (ConcurrentTasks para : tasks) { @@ -224,7 +250,8 @@ public abstract class Regenerator { for (long xz : row) { - chunkStatus.processChunkSave(xz, limitsForRadius.get(xz)); + chunkStatus.processChunkSave(xz, new LazyChunkList(radius, MathMan.unpairIntX(xz), + MathMan.unpairIntY(xz))); } }); } @@ -234,7 +261,8 @@ public abstract class Regenerator scheduled = new ArrayList<>(coords.length); for (long xz : coords) { - scheduled.add(() -> chunkStatus.processChunkSave(xz, limitsForRadius.get(xz))); + scheduled.add(() -> chunkStatus.processChunkSave(xz, new LazyChunkList(radius, MathMan.unpairIntX(xz), + MathMan.unpairIntY(xz)))); } runAndWait(scheduled); } else { // Concurrency.NONE or generateConcurrent == false @@ -242,28 +270,33 @@ public abstract class Regenerator { for (long xz : coords) { - chunkStatus.processChunkSave(xz, limitsForRadius.get(xz)); + chunkStatus.processChunkSave(xz, new LazyChunkList(radius, MathMan.unpairIntX(xz), + MathMan.unpairIntY(xz))); } }).get(); // wait until finished this step } + event.commit(); } //convert to proper chunks - for (long xz : chunkCoordsForRadius.get(0)) { + // TODO (j21): use SequencedMap#firstEntry().getValue() + for (long xz : chunkCoordsForChunkStatus.values().iterator().next()) { ProtoChunk proto = protoChunks.get(xz); chunks.put(xz, createChunk(proto)); } //final chunkstatus ChunkStatus FULL = getFullChunkStatus(); - for (long xz : chunkCoordsForRadius.get(0)) { //FULL.requiredNeighbourChunkRadius() == 0! + // TODO (j21): use SequencedMap#firstEntry().getValue() + for (long xz : chunkCoordsForChunkStatus.values().iterator().next()) { //FULL.requiredNeighbourChunkRadius() == 0! Chunk chunk = chunks.get(xz); FULL.processChunkSave(xz, List.of(chunk)); } //populate List populators = getBlockPopulators(); - for (long xz : chunkCoordsForRadius.get(0)) { + // TODO (j21): use SequencedMap#firstEntry().getValue() + for (long xz : chunkCoordsForChunkStatus.values().iterator().next()) { int x = MathMan.unpairIntX(xz); int z = MathMan.unpairIntY(xz); @@ -277,8 +310,10 @@ public abstract class Regenerator byZ = new Int2ObjectOpenHashMap<>(); - int expectedListLength = (coordsCount + 1) / (maxZ - minZ); + int expectedListLength = (coordsCount + 1) / (maxZ - minZ + 2); //init lists for (int i = minZ; i <= maxZ; i++) { @@ -581,13 +616,16 @@ public abstract class Regenerator extends Tasks { diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/listener/ChunkListener.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/listener/ChunkListener.java index 7b9599084..91ec973bb 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/listener/ChunkListener.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/listener/ChunkListener.java @@ -135,7 +135,7 @@ public abstract class ChunkListener implements Listener { @Deprecated(since = "2.0.0") public void cleanup(Chunk chunk) { for (Entity entity : chunk.getEntities()) { - if (entity.getType() == EntityType.DROPPED_ITEM) { + if (entity.getType() == EntityType.ITEM) { entity.remove(); } } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/bukkit/util/CommandRegistration.java b/worldedit-bukkit/src/main/java/com/sk89q/bukkit/util/CommandRegistration.java index 424325127..c650975c3 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/bukkit/util/CommandRegistration.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/bukkit/util/CommandRegistration.java @@ -20,6 +20,7 @@ package com.sk89q.bukkit.util; import com.sk89q.util.ReflectionUtil; +import io.papermc.lib.PaperLib; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -96,12 +97,11 @@ public class CommandRegistration { return fallbackCommands; } - CommandMap commandMap = ReflectionUtil.getField(plugin.getServer().getPluginManager(), "commandMap"); + CommandMap commandMap = PaperLib.isPaper() ? Bukkit.getCommandMap() : ReflectionUtil.getField(plugin.getServer().getPluginManager(), "commandMap"); if (commandMap == null) { Bukkit.getServer().getLogger().severe(plugin.getDescription().getName() - + ": Could not retrieve server CommandMap, using fallback instead!"); - fallbackCommands = commandMap = new SimpleCommandMap(Bukkit.getServer()); - Bukkit.getServer().getPluginManager().registerEvents(new FallbackRegistrationListener(fallbackCommands), plugin); + + ": Could not retrieve server CommandMap"); + throw new IllegalStateException("Failed to retrieve command map, make sure you are running supported server software"); } else { serverCommandMap = commandMap; } diff --git a/worldedit-core/doctools/build.gradle.kts b/worldedit-core/doctools/build.gradle.kts index 6f2123f20..cf1cf33de 100644 --- a/worldedit-core/doctools/build.gradle.kts +++ b/worldedit-core/doctools/build.gradle.kts @@ -1,16 +1,12 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - kotlin("jvm") version "1.8.20" + kotlin("jvm") version "1.9.23" application } applyCommonConfiguration() -tasks.withType { - kotlinOptions.jvmTarget = "17" -} - application.mainClass.set("com.sk89q.worldedit.internal.util.DocumentationPrinter") tasks.named("run") { workingDir = rootProject.projectDir diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEditManifest.java b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEditManifest.java index 9ce5c24f0..449e08db3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEditManifest.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEditManifest.java @@ -23,7 +23,7 @@ import javax.annotation.Nullable; import java.io.IOException; import java.io.UncheckedIOException; import java.net.JarURLConnection; -import java.net.URL; +import java.net.URI; import java.util.function.Supplier; import java.util.jar.Attributes; import java.util.jar.Manifest; @@ -73,8 +73,7 @@ public class WorldEditManifest { } try { - URL url = new URL(classPath); - JarURLConnection jarConnection = (JarURLConnection) url.openConnection(); + JarURLConnection jarConnection = (JarURLConnection) URI.create(classPath).toURL().openConnection(); Manifest manifest = jarConnection.getManifest(); return manifest.getMainAttributes(); } catch (IOException e) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java index ceb07a71e..235cdf761 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java @@ -56,6 +56,7 @@ public class BaseEntity implements NbtValued { * @param nbtData NBT data * @deprecated Use {@link BaseEntity#BaseEntity(EntityType, LazyReference)} */ + @SuppressWarnings("this-escape") @Deprecated public BaseEntity(EntityType type, CompoundTag nbtData) { this(type); @@ -87,6 +88,7 @@ public class BaseEntity implements NbtValued { * * @param other the object to clone */ + @SuppressWarnings("this-escape") public BaseEntity(BaseEntity other) { checkNotNull(other); this.type = other.getType(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/BlockChangeLimiter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/BlockChangeLimiter.java index 498e5ce9f..38b79dc34 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/BlockChangeLimiter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/BlockChangeLimiter.java @@ -62,6 +62,7 @@ public class BlockChangeLimiter extends AbstractDelegateExtent { * * @param limit the limit (>= 0) or -1 for no limit */ + @SuppressWarnings("this-escape") // Unlikely anyone is extending this in practice public void setLimit(int limit) { checkArgument(limit >= -1, "limit >= -1 required"); this.limit = limit; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/io/ForwardSeekableInputStream.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/io/ForwardSeekableInputStream.java index 585eaa00e..47f17781f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/io/ForwardSeekableInputStream.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/io/ForwardSeekableInputStream.java @@ -19,11 +19,16 @@ package com.sk89q.worldedit.util.io; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import java.io.IOException; import java.io.InputStream; public class ForwardSeekableInputStream extends InputStream { + private static final Logger LOGGER = LogManager.getLogger(); + protected InputStream parent; protected long position = 0; @@ -60,7 +65,7 @@ public class ForwardSeekableInputStream extends InputStream { @Override public int read(byte[] b, int off, int len) throws IOException { - int read = super.read(b, off, len); + int read = parent.read(b, off, len); position += read; return read; } @@ -86,6 +91,7 @@ public class ForwardSeekableInputStream extends InputStream { public void seek(long n) throws IOException { long diff = n - position; + LOGGER.error("Seek to {} from {} using {}", n, position, diff); if (diff < 0) { throw new IOException("Can't seek backwards"); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/net/HttpRequest.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/net/HttpRequest.java index a5c9fdced..d133eb54e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/net/HttpRequest.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/net/HttpRequest.java @@ -357,7 +357,7 @@ public class HttpRequest implements Closeable { */ public static URL url(String url) { try { - return new URL(url); + return URI.create(url).toURL(); } catch (MalformedURLException e) { throw new RuntimeException(e); } @@ -371,13 +371,7 @@ public class HttpRequest implements Closeable { */ private static URL reformat(URL existing) { try { - URL url = new URL(existing.toString()); - URI uri = new URI( - url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), - url.getPath(), url.getQuery(), url.getRef() - ); - url = uri.toURL(); - return url; + return existing.toURI().toURL(); } catch (MalformedURLException | URISyntaxException e) { return existing; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/EngineHubPaste.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/EngineHubPaste.java index 037cea727..1decfd384 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/EngineHubPaste.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/paste/EngineHubPaste.java @@ -24,6 +24,7 @@ import com.google.gson.reflect.TypeToken; import com.sk89q.worldedit.util.net.HttpRequest; import java.io.IOException; +import java.net.URI; import java.net.URL; import java.util.Map; import java.util.concurrent.Callable; @@ -83,7 +84,7 @@ public class EngineHubPaste implements Paster { .execute() .expectResponseCode(200, 204); - return new URL(response.viewUrl); + return URI.create(response.viewUrl).toURL(); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/task/FutureForwardingTask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/task/FutureForwardingTask.java index fcf0bd661..515d4d53b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/task/FutureForwardingTask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/task/FutureForwardingTask.java @@ -82,21 +82,22 @@ public class FutureForwardingTask extends AbstractTask { return future.get(timeout, unit); } + // TODO: consider deprecating in favor of Future.State? @Override - public State getState() { + public Task.State getState() { if (isCancelled()) { - return State.CANCELLED; + return Task.State.CANCELLED; } else if (isDone()) { try { get(); - return State.SUCCEEDED; + return Task.State.SUCCEEDED; } catch (InterruptedException e) { - return State.CANCELLED; + return Task.State.CANCELLED; } catch (ExecutionException e) { - return State.FAILED; + return Task.State.FAILED; } } else { - return State.RUNNING; + return Task.State.RUNNING; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockCategories.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockCategories.java index 4d1bde5f8..7d09d509e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockCategories.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockCategories.java @@ -33,8 +33,10 @@ public final class BlockCategories { public static final BlockCategory ANCIENT_CITY_REPLACEABLE = get("minecraft:ancient_city_replaceable"); public static final BlockCategory ANIMALS_SPAWNABLE_ON = get("minecraft:animals_spawnable_on"); public static final BlockCategory ANVIL = get("minecraft:anvil"); + public static final BlockCategory ARMADILLO_SPAWNABLE_ON = get("minecraft:armadillo_spawnable_on"); public static final BlockCategory AXOLOTLS_SPAWNABLE_ON = get("minecraft:axolotls_spawnable_on"); public static final BlockCategory AZALEA_GROWS_ON = get("minecraft:azalea_grows_on"); + public static final BlockCategory BADLANDS_TERRACOTTA = get("minecraft:badlands_terracotta"); public static final BlockCategory AZALEA_ROOT_REPLACEABLE = get("minecraft:azalea_root_replaceable"); public static final BlockCategory BAMBOO_BLOCKS = get("minecraft:bamboo_blocks"); public static final BlockCategory BAMBOO_PLANTABLE_ON = get("minecraft:bamboo_plantable_on"); @@ -78,6 +80,7 @@ public final class BlockCategories { public static final BlockCategory DIRT = get("minecraft:dirt"); @Deprecated public static final BlockCategory DIRT_LIKE = get("minecraft:dirt_like"); + public static final BlockCategory DOES_NOT_BLOCK_HOPPERS = get("minecraft:does_not_block_hoppers"); public static final BlockCategory DOORS = get("minecraft:doors"); public static final BlockCategory DRAGON_IMMUNE = get("minecraft:dragon_immune"); public static final BlockCategory DRAGON_TRANSPARENT = get("minecraft:dragon_transparent"); @@ -103,6 +106,12 @@ public final class BlockCategories { public static final BlockCategory HOGLIN_REPELLENTS = get("minecraft:hoglin_repellents"); public static final BlockCategory ICE = get("minecraft:ice"); public static final BlockCategory IMPERMEABLE = get("minecraft:impermeable"); + public static final BlockCategory INCORRECT_FOR_DIAMOND_TOOL = get("minecraft:incorrect_for_diamond_tool"); + public static final BlockCategory INCORRECT_FOR_GOLD_TOOL = get("minecraft:incorrect_for_gold_tool"); + public static final BlockCategory INCORRECT_FOR_IRON_TOOL = get("minecraft:incorrect_for_iron_tool"); + public static final BlockCategory INCORRECT_FOR_NETHERITE_TOOL = get("minecraft:incorrect_for_netherite_tool"); + public static final BlockCategory INCORRECT_FOR_STONE_TOOL = get("minecraft:incorrect_for_stone_tool"); + public static final BlockCategory INCORRECT_FOR_WOODEN_TOOL = get("minecraft:incorrect_for_wooden_tool"); public static final BlockCategory INFINIBURN_END = get("minecraft:infiniburn_end"); public static final BlockCategory INFINIBURN_NETHER = get("minecraft:infiniburn_nether"); public static final BlockCategory INFINIBURN_OVERWORLD = get("minecraft:infiniburn_overworld"); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java index 7762ee532..a2e58a97c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java @@ -60,6 +60,7 @@ public class BlockType implements Keyed, Pattern { private static final Logger LOGGER = LogManagerCompat.getLogger(); private final String id; + @SuppressWarnings("this-escape") private final LazyReference emptyFuzzy = LazyReference.from(() -> new FuzzyBlockState(this)); //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java index 513a00557..0206cdf92 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java @@ -908,6 +908,8 @@ public final class BlockTypes { @Nullable public static final BlockType HAY_BLOCK = init(); @Nullable + public static final BlockType HEAVY_CORE = init(); + @Nullable public static final BlockType HEAVY_WEIGHTED_PRESSURE_PLATE = init(); @Nullable public static final BlockType HONEYCOMB_BLOCK = init(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java index e1cb08bc8..9b0d764f1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java @@ -163,7 +163,7 @@ public class AnvilChunk13 implements Chunk { throw new InvalidFormatException("Too short block state table"); } currentSerializedValue = blockStatesSerialized[nextSerializedItem++]; - localBlockId |= (currentSerializedValue & ((1 << bitsNextLong) - 1)) << remainingBits; + localBlockId |= (int) ((currentSerializedValue & ((1 << bitsNextLong) - 1)) << remainingBits); currentSerializedValue >>>= bitsNextLong; remainingBits = 64 - bitsNextLong; } else { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityTypes.java index f981593fe..52044abdf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityTypes.java @@ -35,6 +35,8 @@ public final class EntityTypes { @Nullable public static final EntityType AREA_EFFECT_CLOUD = get("minecraft:area_effect_cloud"); @Nullable + public static final EntityType ARMADILLO = get("minecraft:armadillo"); + @Nullable public static final EntityType ARMOR_STAND = get("minecraft:armor_stand"); @Nullable public static final EntityType ARROW = get("minecraft:arrow"); @@ -51,8 +53,12 @@ public final class EntityTypes { @Nullable public static final EntityType BOAT = get("minecraft:boat"); @Nullable + public static final EntityType BOGGED = get("minecraft:bogged"); + @Nullable public static final EntityType BREEZE = get("minecraft:breeze"); @Nullable + public static final EntityType BREEZE_WIND_CHARGE = get("minecraft:breeze_wind_charge"); + @Nullable public static final EntityType CAMEL = get("minecraft:camel"); @Nullable public static final EntityType CAT = get("minecraft:cat"); @@ -171,6 +177,8 @@ public final class EntityTypes { @Nullable public static final EntityType OCELOT = get("minecraft:ocelot"); @Nullable + public static final EntityType OMINOUS_ITEM_SPAWNER = get("minecraft:ominous_item_spawner"); + @Nullable public static final EntityType PAINTING = get("minecraft:painting"); @Nullable public static final EntityType PANDA = get("minecraft:panda"); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemCategories.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemCategories.java index 3b6bdc6b6..466db6fdd 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemCategories.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemCategories.java @@ -29,28 +29,36 @@ public final class ItemCategories { public static final ItemCategory ACACIA_LOGS = get("minecraft:acacia_logs"); public static final ItemCategory ANVIL = get("minecraft:anvil"); + public static final ItemCategory ARMADILLO_FOOD = get("minecraft:armadillo_food"); public static final ItemCategory ARROWS = get("minecraft:arrows"); public static final ItemCategory AXES = get("minecraft:axes"); - public static final ItemCategory AXOLOTL_TEMPT_ITEMS = get("minecraft:axolotl_tempt_items"); + public static final ItemCategory AXOLOTL_FOOD = get("minecraft:axolotl_food"); + @Deprecated public static final ItemCategory AXOLOTL_TEMPT_ITEMS = get("minecraft:axolotl_tempt_items"); public static final ItemCategory BAMBOO_BLOCKS = get("minecraft:bamboo_blocks"); public static final ItemCategory BANNERS = get("minecraft:banners"); public static final ItemCategory BEACON_PAYMENT_ITEMS = get("minecraft:beacon_payment_items"); public static final ItemCategory BEDS = get("minecraft:beds"); + public static final ItemCategory BEE_FOOD = get("minecraft:bee_food"); public static final ItemCategory BIRCH_LOGS = get("minecraft:birch_logs"); public static final ItemCategory BOATS = get("minecraft:boats"); public static final ItemCategory BOOKSHELF_BOOKS = get("minecraft:bookshelf_books"); public static final ItemCategory BREAKS_DECORATED_POTS = get("minecraft:breaks_decorated_pots"); public static final ItemCategory BUTTONS = get("minecraft:buttons"); + public static final ItemCategory CAMEL_FOOD = get("minecraft:camel_food"); public static final ItemCategory CANDLES = get("minecraft:candles"); @Deprecated public static final ItemCategory CARPETS = get("minecraft:carpets"); + public static final ItemCategory CAT_FOOD = get("minecraft:cat_food"); public static final ItemCategory CHERRY_LOGS = get("minecraft:cherry_logs"); + public static final ItemCategory CHEST_ARMOR = get("minecraft:chest_armor"); public static final ItemCategory CHEST_BOATS = get("minecraft:chest_boats"); + public static final ItemCategory CHICKEN_FOOD = get("minecraft:chicken_food"); public static final ItemCategory CLUSTER_MAX_HARVESTABLES = get("minecraft:cluster_max_harvestables"); public static final ItemCategory COAL_ORES = get("minecraft:coal_ores"); public static final ItemCategory COALS = get("minecraft:coals"); public static final ItemCategory COMPASSES = get("minecraft:compasses"); public static final ItemCategory COMPLETES_FIND_TREE_TUTORIAL = get("minecraft:completes_find_tree_tutorial"); public static final ItemCategory COPPER_ORES = get("minecraft:copper_ores"); + public static final ItemCategory COW_FOOD = get("minecraft:cow_food"); public static final ItemCategory CREEPER_DROP_MUSIC_DISCS = get("minecraft:creeper_drop_music_discs"); public static final ItemCategory CREEPER_IGNITERS = get("minecraft:creeper_igniters"); public static final ItemCategory CRIMSON_STEMS = get("minecraft:crimson_stems"); @@ -61,44 +69,82 @@ public final class ItemCategories { public static final ItemCategory DIAMOND_ORES = get("minecraft:diamond_ores"); public static final ItemCategory DIRT = get("minecraft:dirt"); public static final ItemCategory DOORS = get("minecraft:doors"); + public static final ItemCategory DYEABLE = get("minecraft:dyeable"); public static final ItemCategory EMERALD_ORES = get("minecraft:emerald_ores"); + public static final ItemCategory ENCHANTABLE_ARMOR = get("minecraft:enchantable/armor"); + public static final ItemCategory ENCHANTABLE_BOW = get("minecraft:enchantable/bow"); + public static final ItemCategory ENCHANTABLE_CHEST_ARMOR = get("minecraft:enchantable/chest_armor"); + public static final ItemCategory ENCHANTABLE_CROSSBOW = get("minecraft:enchantable/crossbow"); + public static final ItemCategory ENCHANTABLE_DURABILITY = get("minecraft:enchantable/durability"); + public static final ItemCategory ENCHANTABLE_EQUIPPABLE = get("minecraft:enchantable/equippable"); + public static final ItemCategory ENCHANTABLE_FIRE_ASPECT = get("minecraft:enchantable/fire_aspect"); + public static final ItemCategory ENCHANTABLE_FISHING = get("minecraft:enchantable/fishing"); + public static final ItemCategory ENCHANTABLE_FOOT_ARMOR = get("minecraft:enchantable/foot_armor"); + public static final ItemCategory ENCHANTABLE_HEAD_ARMOR = get("minecraft:enchantable/head_armor"); + public static final ItemCategory ENCHANTABLE_LEG_ARMOR = get("minecraft:enchantable/leg_armor"); + public static final ItemCategory ENCHANTABLE_MINING = get("minecraft:enchantable/mining"); + public static final ItemCategory ENCHANTABLE_MINING_LOOT = get("minecraft:enchantable/mining_loot"); + public static final ItemCategory ENCHANTABLE_SHARP_WEAPON = get("minecraft:enchantable/sharp_weapon"); + public static final ItemCategory ENCHANTABLE_SWORD = get("minecraft:enchantable/sword"); + public static final ItemCategory ENCHANTABLE_TRIDENT = get("minecraft:enchantable/trident"); + public static final ItemCategory ENCHANTABLE_VANISHING = get("minecraft:enchantable/vanishing"); + public static final ItemCategory ENCHANTABLE_WEAPON = get("minecraft:enchantable/weapon"); public static final ItemCategory FENCE_GATES = get("minecraft:fence_gates"); public static final ItemCategory FENCES = get("minecraft:fences"); public static final ItemCategory FISHES = get("minecraft:fishes"); public static final ItemCategory FLOWERS = get("minecraft:flowers"); + public static final ItemCategory FOOT_ARMOR = get("minecraft:foot_armor"); public static final ItemCategory FOX_FOOD = get("minecraft:fox_food"); public static final ItemCategory FREEZE_IMMUNE_WEARABLES = get("minecraft:freeze_immune_wearables"); + public static final ItemCategory FROG_FOOD = get("minecraft:frog_food"); @Deprecated public static final ItemCategory FURNACE_MATERIALS = get("minecraft:furnace_materials"); + public static final ItemCategory GOAT_FOOD = get("minecraft:goat_food"); public static final ItemCategory GOLD_ORES = get("minecraft:gold_ores"); public static final ItemCategory HANGING_SIGNS = get("minecraft:hanging_signs"); + public static final ItemCategory HEAD_ARMOR = get("minecraft:head_armor"); public static final ItemCategory HOES = get("minecraft:hoes"); + public static final ItemCategory HOGLIN_FOOD = get("minecraft:hoglin_food"); + public static final ItemCategory HORSE_FOOD = get("minecraft:horse_food"); + public static final ItemCategory HORSE_TEMPT_ITEMS = get("minecraft:horse_tempt_items"); public static final ItemCategory IGNORED_BY_PIGLIN_BABIES = get("minecraft:ignored_by_piglin_babies"); public static final ItemCategory IRON_ORES = get("minecraft:iron_ores"); public static final ItemCategory JUNGLE_LOGS = get("minecraft:jungle_logs"); public static final ItemCategory LAPIS_ORES = get("minecraft:lapis_ores"); public static final ItemCategory LEAVES = get("minecraft:leaves"); public static final ItemCategory LECTERN_BOOKS = get("minecraft:lectern_books"); + public static final ItemCategory LEG_ARMOR = get("minecraft:leg_armor"); + public static final ItemCategory LLAMA_FOOD = get("minecraft:llama_food"); + public static final ItemCategory LLAMA_TEMPT_ITEMS = get("minecraft:llama_tempt_items"); public static final ItemCategory LOGS = get("minecraft:logs"); public static final ItemCategory LOGS_THAT_BURN = get("minecraft:logs_that_burn"); public static final ItemCategory MANGROVE_LOGS = get("minecraft:mangrove_logs"); + public static final ItemCategory MEAT = get("minecraft:meat"); public static final ItemCategory MUSIC_DISCS = get("minecraft:music_discs"); public static final ItemCategory NON_FLAMMABLE_WOOD = get("minecraft:non_flammable_wood"); public static final ItemCategory NOTEBLOCK_TOP_INSTRUMENTS = get("minecraft:noteblock_top_instruments"); public static final ItemCategory OAK_LOGS = get("minecraft:oak_logs"); @Deprecated public static final ItemCategory OCCLUDES_VIBRATION_SIGNALS = get("minecraft:occludes_vibration_signals"); + public static final ItemCategory OCELOT_FOOD = get("minecraft:ocelot_food"); @Deprecated public static final ItemCategory OVERWORLD_NATURAL_LOGS = get("minecraft:overworld_natural_logs"); + public static final ItemCategory PANDA_FOOD = get("minecraft:panda_food"); + public static final ItemCategory PARROT_FOOD = get("minecraft:parrot_food"); + public static final ItemCategory PARROT_POISONOUS_FOOD = get("minecraft:parrot_poisonous_food"); public static final ItemCategory PICKAXES = get("minecraft:pickaxes"); + public static final ItemCategory PIG_FOOD = get("minecraft:pig_food"); public static final ItemCategory PIGLIN_FOOD = get("minecraft:piglin_food"); public static final ItemCategory PIGLIN_LOVED = get("minecraft:piglin_loved"); public static final ItemCategory PIGLIN_REPELLENTS = get("minecraft:piglin_repellents"); public static final ItemCategory PLANKS = get("minecraft:planks"); + public static final ItemCategory RABBIT_FOOD = get("minecraft:rabbit_food"); public static final ItemCategory RAILS = get("minecraft:rails"); public static final ItemCategory REDSTONE_ORES = get("minecraft:redstone_ores"); public static final ItemCategory SAND = get("minecraft:sand"); public static final ItemCategory SAPLINGS = get("minecraft:saplings"); + public static final ItemCategory SHEEP_FOOD = get("minecraft:sheep_food"); public static final ItemCategory SHOVELS = get("minecraft:shovels"); public static final ItemCategory SIGNS = get("minecraft:signs"); + public static final ItemCategory SKULLS = get("minecraft:skulls"); public static final ItemCategory SLABS = get("minecraft:slabs"); public static final ItemCategory SMALL_FLOWERS = get("minecraft:small_flowers"); public static final ItemCategory SMELTS_TO_GLASS = get("minecraft:smelts_to_glass"); @@ -110,18 +156,22 @@ public final class ItemCategories { public static final ItemCategory STONE_BUTTONS = get("minecraft:stone_buttons"); public static final ItemCategory STONE_CRAFTING_MATERIALS = get("minecraft:stone_crafting_materials"); public static final ItemCategory STONE_TOOL_MATERIALS = get("minecraft:stone_tool_materials"); + public static final ItemCategory STRIDER_FOOD = get("minecraft:strider_food"); + public static final ItemCategory STRIDER_TEMPT_ITEMS = get("minecraft:strider_tempt_items"); public static final ItemCategory SWORDS = get("minecraft:swords"); public static final ItemCategory TALL_FLOWERS = get("minecraft:tall_flowers"); public static final ItemCategory TERRACOTTA = get("minecraft:terracotta"); - public static final ItemCategory TOOLS = get("minecraft:tools"); + @Deprecated public static final ItemCategory TOOLS = get("minecraft:tools"); public static final ItemCategory TRAPDOORS = get("minecraft:trapdoors"); public static final ItemCategory TRIM_MATERIALS = get("minecraft:trim_materials"); public static final ItemCategory TRIM_TEMPLATES = get("minecraft:trim_templates"); public static final ItemCategory TRIMMABLE_ARMOR = get("minecraft:trimmable_armor"); + public static final ItemCategory TURTLE_FOOD = get("minecraft:turtle_food"); public static final ItemCategory VILLAGER_PLANTABLE_SEEDS = get("minecraft:villager_plantable_seeds"); public static final ItemCategory WALLS = get("minecraft:walls"); public static final ItemCategory WARPED_STEMS = get("minecraft:warped_stems"); public static final ItemCategory WART_BLOCKS = get("minecraft:wart_blocks"); + public static final ItemCategory WOLF_FOOD = get("minecraft:wolf_food"); public static final ItemCategory WOODEN_BUTTONS = get("minecraft:wooden_buttons"); public static final ItemCategory WOODEN_DOORS = get("minecraft:wooden_doors"); public static final ItemCategory WOODEN_FENCES = get("minecraft:wooden_fences"); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java index 16a65c308..5dc7f9277 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java @@ -42,7 +42,7 @@ public class ItemType implements RegistryItem, Keyed { public static final NamespacedRegistry REGISTRY = new NamespacedRegistry<>("item type", true); private final String id; - @SuppressWarnings("deprecation") + @SuppressWarnings({"deprecation", "this-escape"}) private transient final LazyReference name = LazyReference.from(() -> { String name = GuavaUtil.firstNonNull( WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS) @@ -51,10 +51,12 @@ public class ItemType implements RegistryItem, Keyed { ); return name.isEmpty() ? getId() : name; }); + @SuppressWarnings("this-escape") private transient final LazyReference richName = LazyReference.from(() -> WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS) .getRegistries().getItemRegistry().getRichName(this) ); + @SuppressWarnings("this-escape") private transient final LazyReference itemMaterial = LazyReference.from(() -> WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS) .getRegistries().getItemRegistry().getMaterial(this) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemTypes.java index b8064bb94..f3cd6d0cc 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemTypes.java @@ -105,6 +105,10 @@ public final class ItemTypes { @Nullable public static final ItemType ARMOR_STAND = init(); @Nullable + public static final ItemType ARMADILLO_SCUTE = init(); + @Nullable + public static final ItemType ARMADILLO_SPAWN_EGG = init(); + @Nullable public static final ItemType ARMS_UP_POTTERY_SHERD = init(); @Nullable public static final ItemType ARROW = init(); @@ -297,6 +301,10 @@ public final class ItemTypes { @Nullable public static final ItemType BLUE_WOOL = init(); @Nullable + public static final ItemType BOGGED_SPAWN_EGG = init(); + @Nullable + public static final ItemType BOLT_ARMOR_TRIM_SMITHING_TEMPLATE = init(); + @Nullable public static final ItemType BONE = init(); @Nullable public static final ItemType BONE_BLOCK = init(); @@ -319,6 +327,8 @@ public final class ItemTypes { @Nullable public static final ItemType BREAD = init(); @Nullable + public static final ItemType BREEZE_ROD = init(); + @Nullable public static final ItemType BREEZE_SPAWN_EGG = init(); @Nullable public static final ItemType BREWER_POTTERY_SHERD = init(); @@ -971,6 +981,12 @@ public final class ItemTypes { @Nullable public static final ItemType FLINT_AND_STEEL = init(); @Nullable + public static final ItemType FLOW_ARMOR_TRIM_SMITHING_TEMPLATE = init(); + @Nullable + public static final ItemType FLOW_BANNER_PATTERN = init(); + @Nullable + public static final ItemType FLOW_POTTERY_SHERD = init(); + @Nullable public static final ItemType FLOWER_BANNER_PATTERN = init(); @Nullable public static final ItemType FLOWER_POT = init(); @@ -1132,6 +1148,10 @@ public final class ItemTypes { @Nullable public static final ItemType GUNPOWDER = init(); @Nullable + public static final ItemType GUSTER_BANNER_PATTERN = init(); + @Nullable + public static final ItemType GUSTER_POTTERY_SHERD = init(); + @Nullable public static final ItemType HANGING_ROOTS = init(); @Nullable public static final ItemType HAY_BLOCK = init(); @@ -1142,6 +1162,8 @@ public final class ItemTypes { @Nullable public static final ItemType HEARTBREAK_POTTERY_SHERD = init(); @Nullable + public static final ItemType HEAVY_CORE = init(); + @Nullable public static final ItemType HEAVY_WEIGHTED_PRESSURE_PLATE = init(); @Nullable public static final ItemType HOGLIN_SPAWN_EGG = init(); @@ -1404,6 +1426,8 @@ public final class ItemTypes { @Nullable public static final ItemType LOOM = init(); @Nullable + public static final ItemType MACE = init(); + @Nullable public static final ItemType MAGENTA_BANNER = init(); @Nullable public static final ItemType MAGENTA_BED = init(); @@ -1668,6 +1692,10 @@ public final class ItemTypes { @Nullable public static final ItemType OCHRE_FROGLIGHT = init(); @Nullable + public static final ItemType OMINOUS_BOTTLE = init(); + @Nullable + public static final ItemType OMINOUS_TRIAL_KEY = init(); + @Nullable public static final ItemType ORANGE_BANNER = init(); @Nullable public static final ItemType ORANGE_BED = init(); @@ -2075,6 +2103,8 @@ public final class ItemTypes { @Nullable public static final ItemType SCAFFOLDING = init(); @Nullable + public static final ItemType SCRAPE_POTTERY_SHERD = init(); + @Nullable public static final ItemType SCULK = init(); @Nullable public static final ItemType SCULK_CATALYST = init(); @@ -2085,6 +2115,7 @@ public final class ItemTypes { @Nullable public static final ItemType SCULK_VEIN = init(); @Nullable + @Deprecated public static final ItemType SCUTE = init(); @Nullable public static final ItemType SEA_LANTERN = init(); @@ -2424,10 +2455,14 @@ public final class ItemTypes { @Nullable public static final ItemType TURTLE_HELMET = init(); @Nullable + public static final ItemType TURTLE_SCUTE = init(); + @Nullable public static final ItemType TURTLE_SPAWN_EGG = init(); @Nullable public static final ItemType TWISTING_VINES = init(); @Nullable + public static final ItemType VAULT = init(); + @Nullable public static final ItemType VERDANT_FROGLIGHT = init(); @Nullable public static final ItemType VEX_ARMOR_TRIM_SMITHING_TEMPLATE = init(); @@ -2614,6 +2649,8 @@ public final class ItemTypes { @Nullable public static final ItemType WILD_ARMOR_TRIM_SMITHING_TEMPLATE = init(); @Nullable + public static final ItemType WIND_CHARGE = init(); + @Nullable public static final ItemType WITCH_SPAWN_EGG = init(); @Nullable public static final ItemType WITHER_ROSE = init(); @@ -2624,6 +2661,8 @@ public final class ItemTypes { @Nullable public static final ItemType WITHER_SPAWN_EGG = init(); @Nullable + public static final ItemType WOLF_ARMOR = init(); + @Nullable public static final ItemType WOLF_SPAWN_EGG = init(); @Nullable public static final ItemType WOODEN_AXE = init(); From 9a6aa78ae8c6afd947d8c1a68c43d7f633fa167a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 May 2024 14:46:31 +0200 Subject: [PATCH 124/220] Update dependency com.sk89q.worldguard:worldguard-bukkit to v7.0.10 (#2731) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c02ba9098..ec09586f1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,7 +9,7 @@ snakeyaml = "2.0" # Plugins dummypermscompat = "1.10" -worldguard-bukkit = "7.0.9" +worldguard-bukkit = "7.0.10" mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" From 49ea04574dd6b49dafb58d649be6697cba23dcd0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 May 2024 14:46:38 +0200 Subject: [PATCH 125/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.2.9 (#2730) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ec09586f1..c793b1a49 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.2.8" +towny = "0.100.2.9" plotsquared = "7.3.8" # Third party From 96c324a0acb32ebafd0e54d1bf85e58d29a088de Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 May 2024 14:20:04 +0000 Subject: [PATCH 126/220] Update eps1lon/actions-label-merge-conflict action to v3.0.1 --- .github/workflows/label-merge-conflicts.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/label-merge-conflicts.yaml b/.github/workflows/label-merge-conflicts.yaml index fa6f3d72d..551b39417 100644 --- a/.github/workflows/label-merge-conflicts.yaml +++ b/.github/workflows/label-merge-conflicts.yaml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Label conflicting PRs - uses: eps1lon/actions-label-merge-conflict@v3.0.0 + uses: eps1lon/actions-label-merge-conflict@v3.0.1 with: dirtyLabel: "unresolved-merge-conflict" repoToken: "${{ secrets.GITHUB_TOKEN }}" From 2285b1dc34452cf891f5d60a856e04601ebd0693 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 May 2024 14:20:09 +0000 Subject: [PATCH 127/220] Update adventure to v4.17.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c793b1a49..dfa177187 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,7 +21,7 @@ plotsquared = "7.3.8" bstats = "3.0.2" sparsebitset = "1.3" parallelgzip = "1.0.5" -adventure = "4.16.0" +adventure = "4.17.0" adventure-bukkit = "4.3.2" checkerqual = "3.43.0" truezip = "6.8.4" From adb045be6a034d7a2e87cac5c3b48e66d74f43b4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 May 2024 14:20:15 +0000 Subject: [PATCH 128/220] Update dependency net.kyori:adventure-nbt to v4.17.0 --- worldedit-bukkit/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index 3af5fa04e..ce6c9d1b1 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -179,7 +179,7 @@ tasks.named("shadowJar") { include(dependency("org.lz4:lz4-java:1.8.0")) } relocate("net.kyori", "com.fastasyncworldedit.core.adventure") { - include(dependency("net.kyori:adventure-nbt:4.16.0")) + include(dependency("net.kyori:adventure-nbt:4.17.0")) } relocate("com.zaxxer", "com.fastasyncworldedit.core.math") { include(dependency("com.zaxxer:SparseBitSet:1.3")) From d17beba7bb76eb0711fbd4701155753a52fbc38e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 May 2024 14:19:58 +0000 Subject: [PATCH 129/220] Update dependency paperweight-userdev to v1.20.6-R0.1-20240518.202723-58 --- worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts index e1a518cbb..abac5e94c 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/ - the().paperDevBundle("1.20.6-R0.1-20240516.001739-55") + the().paperDevBundle("1.20.6-R0.1-20240518.202723-58") compileOnly(libs.paperlib) } From 361baef13dfdc7450459f3808248376007010bfd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 May 2024 14:20:21 +0000 Subject: [PATCH 130/220] Update dependency org.mockito:mockito-core to v5.12.0 --- gradle/libs.versions.toml | 2 +- worldedit-sponge/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index dfa177187..639b7b010 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -46,7 +46,7 @@ text = "3.0.4" piston = "0.5.10" # Tests -mockito = "5.11.0" +mockito = "5.12.0" # Gradle plugins pluginyml = "0.6.0" diff --git a/worldedit-sponge/build.gradle.kts b/worldedit-sponge/build.gradle.kts index 6498cca7e..1c3ad6b68 100644 --- a/worldedit-sponge/build.gradle.kts +++ b/worldedit-sponge/build.gradle.kts @@ -28,7 +28,7 @@ dependencies { }) api("org.apache.logging.log4j:log4j-api") api("org.bstats:bstats-sponge:1.7") - testImplementation("org.mockito:mockito-core:5.11.0") + testImplementation("org.mockito:mockito-core:5.12.0") } <<<<<<< HEAD From db6442ad35750e933b1855ca6c4ad67d521adfdb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 May 2024 14:20:28 +0000 Subject: [PATCH 131/220] Update plugin xyz.jpenilla.run-paper to v2.3.0 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index aed748cdb..a57667e8d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ import xyz.jpenilla.runpaper.task.RunServer plugins { id("io.github.gradle-nexus.publish-plugin") version "2.0.0" - id("xyz.jpenilla.run-paper") version "2.2.4" + id("xyz.jpenilla.run-paper") version "2.3.0" } if (!File("$rootDir/.git").exists()) { From d8eb03f4c1f000cbb496cd3df7e356fcc23be0ab Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Sun, 19 May 2024 17:31:14 +0200 Subject: [PATCH 132/220] Release 2.10.0 Signed-off-by: Alexander Brandes --- build.gradle.kts | 4 ++-- buildSrc/src/main/kotlin/CommonJavaConfig.kt | 2 +- .../com/fastasyncworldedit/core/configuration/Config.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index a57667e8d..7c99f1678 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,7 +34,7 @@ logger.lifecycle(""" ******************************************* """) -var rootVersion by extra("2.9.3") +var rootVersion by extra("2.10.0") var snapshot by extra("SNAPSHOT") var revision: String by extra("") var buildNumber by extra("") @@ -52,7 +52,7 @@ ext { } } -version = String.format("%s-%s", rootVersion, buildNumber) +version = String.format("%s", rootVersion) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") diff --git a/buildSrc/src/main/kotlin/CommonJavaConfig.kt b/buildSrc/src/main/kotlin/CommonJavaConfig.kt index f915c2e0c..fec02d1a0 100644 --- a/buildSrc/src/main/kotlin/CommonJavaConfig.kt +++ b/buildSrc/src/main/kotlin/CommonJavaConfig.kt @@ -61,7 +61,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean "https://jd.advntr.dev/api/latest/", "https://logging.apache.org/log4j/2.x/javadoc/log4j-api/", "https://www.antlr.org/api/Java/", - "https://jd.papermc.io/paper/1.20/", + "https://jd.papermc.io/paper/1.20.6/", "https://intellectualsites.github.io/fastasyncworldedit-javadocs/worldedit-core/" ) docTitle = "${rootProject.name}-${project.description}" + " " + "${rootProject.version}" diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java index c3f223dc2..e5185e6d8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java @@ -189,7 +189,7 @@ public class Config { /** * Indicates that a field should be instantiated / created. * - * @since TODO + * @since 2.10.0 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) From 657dbe214607b6ea620f1f357180aa179d60ed18 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Sun, 19 May 2024 17:47:26 +0200 Subject: [PATCH 133/220] [ci skip] Back to snapshot for development Signed-off-by: Alexander Brandes --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7c99f1678..8fdea3200 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,7 +34,7 @@ logger.lifecycle(""" ******************************************* """) -var rootVersion by extra("2.10.0") +var rootVersion by extra("2.10.1") var snapshot by extra("SNAPSHOT") var revision: String by extra("") var buildNumber by extra("") @@ -52,7 +52,7 @@ ext { } } -version = String.format("%s", rootVersion) +version = String.format("%s-%s", rootVersion, buildNumber) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") From 3dc949e38394dd0599904bf9c55c101cbce69fd0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 03:33:56 +0000 Subject: [PATCH 134/220] Update dependency paperweight-userdev to v1.20.6-R0.1-20240520.005421-60 --- worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts index abac5e94c..a0ee57dc2 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/ - the().paperDevBundle("1.20.6-R0.1-20240518.202723-58") + the().paperDevBundle("1.20.6-R0.1-20240520.005421-60") compileOnly(libs.paperlib) } From f9c523c1738d9039e49ec1ff86f11bd95098221a Mon Sep 17 00:00:00 2001 From: Jordan Date: Fri, 24 May 2024 15:09:57 +0200 Subject: [PATCH 135/220] feat: move limits for (brush, superpickaxe and normal) radii to fawe (#2635) - closes #2587 --- .../worldedit/bukkit/WorldEditPlugin.java | 19 +- .../resources/defaults/worldedit-config.yml | 2 + .../core/command/tool/scroll/ScrollRange.java | 2 +- .../core/command/tool/scroll/ScrollSize.java | 2 +- .../core/configuration/Settings.java | 27 ++- .../exception/BrushRadiusLimitException.java | 30 +++ .../core/exception/RadiusLimitException.java | 41 +++++ .../core/limit/FaweLimit.java | 23 ++- .../sk89q/worldedit/LocalConfiguration.java | 30 +++ .../worldedit/MaxBrushRadiusException.java | 15 ++ .../sk89q/worldedit/MaxRadiusException.java | 14 ++ .../java/com/sk89q/worldedit/WorldEdit.java | 57 ++++++ .../worldedit/command/BrushCommands.java | 172 ++++++++++++++---- .../worldedit/command/GenerationCommands.java | 32 ++-- .../command/SuperPickaxeCommands.java | 18 +- .../sk89q/worldedit/command/ToolCommands.java | 9 +- .../worldedit/command/ToolUtilCommands.java | 2 +- .../worldedit/command/UtilityCommands.java | 41 ++--- .../worldedit/command/tool/BrushTool.java | 2 +- .../command/util/annotation/Confirm.java | 2 +- .../WorldEditExceptionConverter.java | 14 ++ .../util/PropertiesConfiguration.java | 8 + .../worldedit/util/YAMLConfiguration.java | 7 + .../src/main/resources/lang/strings.json | 2 + 24 files changed, 470 insertions(+), 101 deletions(-) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/BrushRadiusLimitException.java create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/RadiusLimitException.java diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index e881416c5..b4556409c 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -120,7 +120,6 @@ public class WorldEditPlugin extends JavaPlugin { public void onLoad() { //FAWE start - this.bukkitConsoleCommandSender = new BukkitCommandSender(this, Bukkit.getConsoleSender()); // This is already covered by Spigot, however, a more pesky warning with a proper explanation over "Ambiguous plugin name..." can't hurt. Plugin[] plugins = Bukkit.getServer().getPluginManager().getPlugins(); for (Plugin p : plugins) { @@ -138,6 +137,14 @@ public class WorldEditPlugin extends JavaPlugin { //noinspection ResultOfMethodCallIgnored getDataFolder().mkdirs(); + //FAWE start - Modify WorldEdit config name + config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "worldedit-config.yml"), true), this); + // Load config before we say we've loaded platforms as it is used in listeners of the event + // Load config in onLoad to ensure it is loaded before FAWE settings to allow (inelegant) copying of values across + // where needed + config.load(); + //FAWE end + WorldEdit worldEdit = WorldEdit.getInstance(); // Setup platform @@ -148,14 +155,14 @@ public class WorldEditPlugin extends JavaPlugin { migrateLegacyConfig(); //FAWE end - //FAWE start - Modify WorldEdit config name - config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "worldedit-config.yml"), true), this); - //FAWE end - //FAWE start - Setup permission attachments permissionAttachmentManager = new BukkitPermissionAttachmentManager(this); //FAWE end + //FAWE start - initialise bukkitConsoleCommandSender later + this.bukkitConsoleCommandSender = new BukkitCommandSender(this, Bukkit.getConsoleSender()); + //FAWE end + Path delChunks = Paths.get(getDataFolder().getPath(), DELCHUNKS_FILE_NAME); if (Files.exists(delChunks)) { ChunkDeleter.runFromFile(delChunks, true); @@ -189,8 +196,6 @@ public class WorldEditPlugin extends JavaPlugin { new FaweBukkit(this); //FAWE end - config.load(); // Load config before we say we've loaded platforms as it is used in listeners of the event - WorldEdit.getInstance().getEventBus().post(new PlatformsRegisteredEvent()); PermissionsResolverManager.initialize(this); // Setup permission resolver diff --git a/worldedit-bukkit/src/main/resources/defaults/worldedit-config.yml b/worldedit-bukkit/src/main/resources/defaults/worldedit-config.yml index 8140cade6..b74eaa091 100644 --- a/worldedit-bukkit/src/main/resources/defaults/worldedit-config.yml +++ b/worldedit-bukkit/src/main/resources/defaults/worldedit-config.yml @@ -24,11 +24,13 @@ limits: max-polygonal-points: default: -1 maximum: 20 + # radius, superpickaxe, brush radius are ignored, use FAWE config limits max-radius: -1 max-super-pickaxe-size: 5 max-brush-radius: 100 butcher-radius: default: -1 + # Ignored, use FAWE config limits maximum: -1 disallowed-blocks: - "minecraft:wheat" diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/scroll/ScrollRange.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/scroll/ScrollRange.java index 405b62b81..db33a526f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/scroll/ScrollRange.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/scroll/ScrollRange.java @@ -13,7 +13,7 @@ public class ScrollRange extends Scroll { @Override public boolean increment(Player player, int amount) { - int max = WorldEdit.getInstance().getConfiguration().maxBrushRadius; + int max = player.getLimit().MAX_BRUSH_RADIUS; int newSize = MathMan.wrap(getTool().getRange() + amount, (int) (getTool().getSize() + 1), max); getTool().setRange(newSize); return true; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/scroll/ScrollSize.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/scroll/ScrollSize.java index cf60639f5..ac34226f2 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/scroll/ScrollSize.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/scroll/ScrollSize.java @@ -12,7 +12,7 @@ public class ScrollSize extends Scroll { @Override public boolean increment(Player player, int amount) { - int max = WorldEdit.getInstance().getConfiguration().maxRadius; + int max = player.getLimit().MAX_RADIUS; double newSize = Math.max(0, Math.min(max == -1 ? 4095 : max, getTool().getSize() + amount)); getTool().setSize(newSize); return true; 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 63f37fd6b..33c8c94f0 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 @@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.configuration; import com.fastasyncworldedit.core.limit.FaweLimit; import com.fastasyncworldedit.core.limit.PropertyRemap; +import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -140,8 +141,22 @@ public class Settings extends Config { ); limit.MAX_FAILS = Math.max(limit.MAX_FAILS, newLimit.MAX_FAILS != -1 ? newLimit.MAX_FAILS : Integer.MAX_VALUE); limit.MAX_ITERATIONS = Math.max( - limit.MAX_ITERATIONS, - newLimit.MAX_ITERATIONS != -1 ? newLimit.MAX_ITERATIONS : Integer.MAX_VALUE + limit.MAX_ITERATIONS, newLimit.MAX_ITERATIONS != -1 ? newLimit.MAX_ITERATIONS : Integer.MAX_VALUE); + limit.MAX_RADIUS = Math.max( + limit.MAX_RADIUS, + newLimit.MAX_RADIUS != -1 ? newLimit.MAX_RADIUS : Integer.MAX_VALUE + ); + limit.MAX_SUPER_PICKAXE_SIZE = Math.max( + limit.MAX_SUPER_PICKAXE_SIZE, + newLimit.MAX_SUPER_PICKAXE_SIZE != -1 ? newLimit.MAX_SUPER_PICKAXE_SIZE : Integer.MAX_VALUE + ); + limit.MAX_BRUSH_RADIUS = Math.max( + limit.MAX_BRUSH_RADIUS, + newLimit.MAX_BRUSH_RADIUS != -1 ? newLimit.MAX_BRUSH_RADIUS : Integer.MAX_VALUE + ); + limit.MAX_BUTCHER_RADIUS = Math.max( + limit.MAX_BUTCHER_RADIUS, + newLimit.MAX_BUTCHER_RADIUS != -1 ? newLimit.MAX_BUTCHER_RADIUS : Integer.MAX_VALUE ); limit.MAX_HISTORY = Math.max( limit.MAX_HISTORY, @@ -352,6 +367,14 @@ public class Settings extends Config { public int MAX_ITERATIONS = 1000; @Comment("Max allowed entities (e.g. cows)") public int MAX_ENTITIES = 1337; + @Comment("Max allowed radius (e.g. for //sphere)") + public int MAX_RADIUS = LocalConfiguration.MAX_RADIUS; + @Comment("Max allowed superpickaxe size") + public int MAX_SUPER_PICKAXE_SIZE = LocalConfiguration.MAX_SUPER_RADIUS; + @Comment("Max allowed brush radius") + public int MAX_BRUSH_RADIUS = LocalConfiguration.MAX_BRUSH_RADIUS; + @Comment("Max allowed butcher radius") + public int MAX_BUTCHER_RADIUS = LocalConfiguration.MAX_BUTCHER_RADIUS; @Comment({ "Blockstates include Banner, Beacon, BrewingStand, Chest, CommandBlock, ", "CreatureSpawner, Dispenser, Dropper, EndGateway, Furnace, Hopper, Jukebox, ", diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/BrushRadiusLimitException.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/BrushRadiusLimitException.java new file mode 100644 index 000000000..838845bd0 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/BrushRadiusLimitException.java @@ -0,0 +1,30 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.fastasyncworldedit.core.exception; + +/** + * Thrown when a maximum radius for a brush is reached. + */ +public class BrushRadiusLimitException extends RadiusLimitException { + + public BrushRadiusLimitException(int maxBrushRadius) { + super(maxBrushRadius); + } +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/RadiusLimitException.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/RadiusLimitException.java new file mode 100644 index 000000000..c7f72af3a --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/RadiusLimitException.java @@ -0,0 +1,41 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.fastasyncworldedit.core.exception; + +import com.sk89q.worldedit.WorldEditException; + +/** + * Thrown when a maximum radius is reached, such as, for example, + * in the case of a sphere command. + */ +public class RadiusLimitException extends WorldEditException { + + private final int maxRadius; + + public RadiusLimitException(int maxRadius) { + this.maxRadius = maxRadius; + } + + public int getMaxRadius() { + return maxRadius; + } + //FAWE end + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java index e02e3abc9..5ecc89d44 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java @@ -18,6 +18,10 @@ public class FaweLimit { public int SCHEM_FILE_SIZE_LIMIT = 0; public int SCHEM_FILE_NUM_LIMIT = 0; public int MAX_EXPRESSION_MS = 0; + public int MAX_RADIUS = 0; + public int MAX_SUPER_PICKAXE_SIZE = 0; + public int MAX_BRUSH_RADIUS = 0; + public int MAX_BUTCHER_RADIUS = 0; public int INVENTORY_MODE = Integer.MAX_VALUE; public int SPEED_REDUCTION = Integer.MAX_VALUE; public boolean FAST_PLACEMENT = false; @@ -123,6 +127,10 @@ public class FaweLimit { MAX.UNIVERSAL_DISALLOWED_BLOCKS = false; MAX.DISALLOWED_BLOCKS = Collections.emptySet(); MAX.REMAP_PROPERTIES = Collections.emptySet(); + MAX.MAX_RADIUS = Integer.MAX_VALUE; + MAX.MAX_SUPER_PICKAXE_SIZE = Integer.MAX_VALUE; + MAX.MAX_BRUSH_RADIUS = Integer.MAX_VALUE; + MAX.MAX_BUTCHER_RADIUS = Integer.MAX_VALUE; } public boolean MAX_CHANGES() { @@ -250,7 +258,12 @@ public class FaweLimit { && (STRIP_NBT == null || STRIP_NBT.isEmpty()) // && !UNIVERSAL_DISALLOWED_BLOCKS --> do not include this, it effectively has no relevance && (DISALLOWED_BLOCKS == null || DISALLOWED_BLOCKS.isEmpty()) - && (REMAP_PROPERTIES == null || REMAP_PROPERTIES.isEmpty()); + && (REMAP_PROPERTIES == null || REMAP_PROPERTIES.isEmpty()) + && MAX_RADIUS == Integer.MAX_VALUE + && MAX_SUPER_PICKAXE_SIZE == Integer.MAX_VALUE + && MAX_BRUSH_RADIUS == Integer.MAX_VALUE + && MAX_BUTCHER_RADIUS == Integer.MAX_VALUE; + } public void set(FaweLimit limit) { @@ -273,6 +286,10 @@ public class FaweLimit { UNIVERSAL_DISALLOWED_BLOCKS = limit.UNIVERSAL_DISALLOWED_BLOCKS; DISALLOWED_BLOCKS = limit.DISALLOWED_BLOCKS; REMAP_PROPERTIES = limit.REMAP_PROPERTIES; + MAX_RADIUS = limit.MAX_RADIUS; + MAX_SUPER_PICKAXE_SIZE = limit.MAX_SUPER_PICKAXE_SIZE; + MAX_BRUSH_RADIUS = limit.MAX_BRUSH_RADIUS; + MAX_BUTCHER_RADIUS = limit.MAX_BUTCHER_RADIUS; } public FaweLimit copy() { @@ -296,6 +313,10 @@ public class FaweLimit { limit.UNIVERSAL_DISALLOWED_BLOCKS = UNIVERSAL_DISALLOWED_BLOCKS; limit.DISALLOWED_BLOCKS = DISALLOWED_BLOCKS; limit.REMAP_PROPERTIES = REMAP_PROPERTIES; + limit.MAX_RADIUS = MAX_RADIUS; + limit.MAX_SUPER_PICKAXE_SIZE = MAX_SUPER_PICKAXE_SIZE; + limit.MAX_BRUSH_RADIUS = MAX_BRUSH_RADIUS; + limit.MAX_BUTCHER_RADIUS = MAX_BUTCHER_RADIUS; return limit; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java index 57ec6f186..7e2ba4549 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java @@ -52,12 +52,26 @@ import java.util.Set; public abstract class LocalConfiguration { private static final Logger LOGGER = LogManagerCompat.getLogger(); + //FAWE start - inelegant but required to transfer to FAWE limits as defaults + public static int MAX_RADIUS; + public static int MAX_SUPER_RADIUS; + public static int MAX_BRUSH_RADIUS; + public static int MAX_BUTCHER_RADIUS; + //FAWE end public boolean profile = false; public boolean traceUnflushedSessions = true; public Set disallowedBlocks = new HashSet<>(); protected BlockMask disallowedBlocksMask; + /** + * @deprecated Use actor's limit {@link com.fastasyncworldedit.core.limit.FaweLimit#MAX_CHANGES} + */ + @Deprecated public int defaultChangeLimit = -1; + /** + * @deprecated Use actor's limit {@link com.fastasyncworldedit.core.limit.FaweLimit#MAX_CHANGES} + */ + @Deprecated public int maxChangeLimit = -1; public int defaultVerticalHeight = 256; public int defaultMaxPolygonalPoints = -1; @@ -68,8 +82,20 @@ public abstract class LocalConfiguration { public boolean snapshotsConfigured = false; public SnapshotRepository snapshotRepo = null; public SnapshotDatabase snapshotDatabase = null; + /** + * @deprecated Use actor's limit {@link com.fastasyncworldedit.core.limit.FaweLimit#MAX_RADIUS} + */ + @Deprecated public int maxRadius = -1; + /** + * @deprecated Use actor's limit {@link com.fastasyncworldedit.core.limit.FaweLimit#MAX_SUPER_PICKAXE_SIZE} + */ + @Deprecated public int maxSuperPickaxeSize = 5; + /** + * @deprecated Use actor's limit {@link com.fastasyncworldedit.core.limit.FaweLimit#MAX_BRUSH_RADIUS} + */ + @Deprecated public int maxBrushRadius = 6; public boolean logCommands = false; public String logFile = ""; @@ -92,6 +118,10 @@ public abstract class LocalConfiguration { public String scriptsDir = "craftscripts"; public boolean showHelpInfo = true; // unused public int butcherDefaultRadius = -1; + /** + * @deprecated Use actor's limit {@link com.fastasyncworldedit.core.limit.FaweLimit#MAX_BUTCHER_RADIUS} + */ + @Deprecated public int butcherMaxRadius = -1; public boolean allowSymlinks = false; public boolean serverSideCUI = true; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/MaxBrushRadiusException.java b/worldedit-core/src/main/java/com/sk89q/worldedit/MaxBrushRadiusException.java index 76a640c66..cb1371451 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/MaxBrushRadiusException.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/MaxBrushRadiusException.java @@ -19,9 +19,24 @@ package com.sk89q.worldedit; +import com.fastasyncworldedit.core.exception.BrushRadiusLimitException; +import com.fastasyncworldedit.core.exception.RadiusLimitException; + /** * Thrown when a maximum radius for a brush is reached. + * + * @deprecated Use {@link RadiusLimitException} */ +@Deprecated public class MaxBrushRadiusException extends MaxRadiusException { + //FAWE start + + /** + * @deprecated Use {@link BrushRadiusLimitException} + */ + @Deprecated + public MaxBrushRadiusException() { + } + //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/MaxRadiusException.java b/worldedit-core/src/main/java/com/sk89q/worldedit/MaxRadiusException.java index 6641c063c..1e5da912f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/MaxRadiusException.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/MaxRadiusException.java @@ -19,10 +19,24 @@ package com.sk89q.worldedit; +import com.fastasyncworldedit.core.exception.RadiusLimitException; + /** * Thrown when a maximum radius is reached, such as, for example, * in the case of a sphere command. + * + * @deprecated Use {@link RadiusLimitException} */ +@Deprecated public class MaxRadiusException extends WorldEditException { + //FAWE start + /** + * @deprecated Use {@link RadiusLimitException} + */ + @Deprecated + public MaxRadiusException() { + } + //FAWE end + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java index 2c62e08ec..be4c9af8c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java @@ -20,6 +20,8 @@ package com.sk89q.worldedit; import com.fastasyncworldedit.core.configuration.Caption; +import com.fastasyncworldedit.core.exception.BrushRadiusLimitException; +import com.fastasyncworldedit.core.exception.RadiusLimitException; import com.fastasyncworldedit.core.extension.factory.TransformFactory; import com.fastasyncworldedit.core.extent.ResettableExtent; import com.google.common.base.Throwables; @@ -437,7 +439,9 @@ public final class WorldEdit { * * @param radius the radius * @throws MaxRadiusException if the radius is bigger than the configured radius + * @deprecated Use {@link WorldEdit#checkMaxRadius(double, Actor)} */ + @Deprecated public void checkMaxRadius(double radius) throws MaxRadiusException { if (getConfiguration().maxRadius > 0 && radius > getConfiguration().maxRadius) { throw new MaxRadiusException(); @@ -449,7 +453,9 @@ public final class WorldEdit { * * @param radius the radius * @throws MaxBrushRadiusException if the radius is bigger than the configured radius + * @deprecated Use {@link WorldEdit#checkMaxBrushRadius(double, Actor)} */ + @Deprecated public void checkMaxBrushRadius(double radius) throws MaxBrushRadiusException { if (getConfiguration().maxBrushRadius > 0 && radius > getConfiguration().maxBrushRadius) { throw new MaxBrushRadiusException(); @@ -457,6 +463,10 @@ public final class WorldEdit { } //FAWE start + /** + * @deprecated Use {@link WorldEdit#checkMaxBrushRadius(Expression, Actor)} + */ + @Deprecated(forRemoval = true, since = "TODO") public void checkMaxBrushRadius(Expression radius) throws MaxBrushRadiusException { double val = radius.evaluate(); checkArgument(val >= 0, "Radius must be a positive number."); @@ -466,6 +476,53 @@ public final class WorldEdit { } } } + + /** + * Check the given radius against the give actor's limit. + * + * @param radius Radius to check + * @param actor Actor to check for + * @throws MaxRadiusException If given radius larger than allowed + * @since TODO + */ + public void checkMaxRadius(double radius, Actor actor) { + int max = actor.getLimit().MAX_RADIUS; + if (max > 0 && radius > max) { + throw new RadiusLimitException(max); + } + } + + /** + * Check the given radius against the give actor's limit. + * + * @param radius Radius to check + * @param actor Actor to check for + * @throws MaxRadiusException If given radius larger than allowed + * @since TODO + */ + public void checkMaxBrushRadius(double radius, Actor actor) { + int max = actor.getLimit().MAX_BRUSH_RADIUS; + if (max > 0 && radius > max) { + throw new RadiusLimitException(max); + } + } + + /** + * Check the given radius against the give actor's limit. + * + * @param expression Radius to check + * @param actor Actor to check for + * @throws BrushRadiusLimitException If given radius larger than allowed + * @since TODO + */ + public void checkMaxBrushRadius(Expression expression, Actor actor) { + double radius = expression.evaluate(); + checkArgument(radius >= 0, "Radius must be a positive number."); + int max = actor.getLimit().MAX_BRUSH_RADIUS; + if (max > 0 && radius > max) { + throw new BrushRadiusLimitException(max); + } + } //FAWE end /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index 76cb60c64..bdd6a4ed4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -186,7 +186,10 @@ public class BrushCommands { @ArgFlag(name = 'm', desc = "Mask to limit blocks being considered", def = "") Mask mask ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); checkCommandArgument(minFreqDiff >= 0 && minFreqDiff <= 26, "minFreqDiff not in range 0 <= value <= 26"); if (mask != null && !(mask instanceof CachedMask)) { mask = new CachedMask(mask, false); @@ -212,7 +215,10 @@ public class BrushCommands { @Arg(desc = "fillRec", def = "1") int fillRec ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set(context, new ErodeBrush(erodefaces, erodeRec, fillFaces, fillRec), "worldedit.brush.erode").setSize(radius); } @@ -234,7 +240,10 @@ public class BrushCommands { @Arg(desc = "fillRec", def = "1") int fillRec ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set(context, new RaiseBrush(erodefaces, erodeRec, fillFaces, fillRec), "worldedit.brush.pull").setSize(radius); } @@ -252,7 +261,10 @@ public class BrushCommands { @Arg(name = "filled", desc = "Whether the circle should be filled", def = "false") boolean filled ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set(context, new CircleBrush(filled), "worldedit.brush.sphere").setSize(radius).setFill(fill); } @@ -276,7 +288,10 @@ public class BrushCommands { @Switch(name = 'd', desc = "Apply in depth first order") boolean depthFirst ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set(context, new RecurseBrush(depthFirst), "worldedit.brush.recursive").setSize(radius).setFill(fill) .setMask(new IdMask(editSession)); } @@ -299,7 +314,10 @@ public class BrushCommands { @Switch(name = 'f', desc = "Create a flat line") boolean flat ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set(context, new LineBrush(shell, select, flat), "worldedit.brush.line").setSize(radius).setFill(fill); } @@ -326,7 +344,10 @@ public class BrushCommands { Expression radius ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); player.print(Caption.of("fawe.worldedit.brush.brush.spline", (radius))); set(context, new SplineBrush(player), "worldedit.brush.spline").setSize(radius).setFill(fill); } @@ -379,7 +400,10 @@ public class BrushCommands { @Switch(name = 'd', desc = "sags the catenary toward the facing direction") boolean facingDirection ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set(context, new CatenaryBrush(shell, select, facingDirection, lengthFactor), "worldedit.brush.spline") .setSize(radius).setFill(fill); } @@ -411,7 +435,10 @@ public class BrushCommands { double quality ) throws WorldEditException { player.print(Caption.of("fawe.worldedit.brush.brush.spline", (radius))); - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set(context, new SurfaceSpline(tension, bias, continuity, quality), "surfacespline").setSize(radius) .setFill(fill); } @@ -436,9 +463,11 @@ public class BrushCommands { double amplitude ) throws WorldEditException { double max = MathMan.max(radius.getX(), radius.getY(), radius.getZ()); - worldEdit.checkMaxBrushRadius(max); - Brush brush = - new BlobBrush(radius.divide(max), frequency / 100, amplitude / 100, sphericity / 100); + worldEdit.checkMaxBrushRadius( + max, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); + Brush brush = new BlobBrush(radius.divide(max), frequency / 100, amplitude / 100, sphericity / 100); set(context, brush, "worldedit.brush.rock").setSize(max).setFill(fill); } @@ -459,7 +488,10 @@ public class BrushCommands { @Arg(desc = "Lines", def = "10") int count ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set(context, new ShatterBrush(count), "worldedit.brush.shatter").setSize(radius).setFill(fill) .setMask(new ExistingBlockMask(editSession)); } @@ -490,7 +522,10 @@ public class BrushCommands { boolean randomRotate ) throws WorldEditException, FileNotFoundException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); InputStream stream = getHeightmapStream(image); HeightBrush brush; int minY = player.getWorld().getMinY(); @@ -526,7 +561,10 @@ public class BrushCommands { URL url = new URL(imageURL); MainUtil.checkImageHost(url.toURI()); BufferedImage image = MainUtil.readImage(url); - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); if (yscale != 1) { ImageUtil.scaleAlpha(image, yscale); alpha = true; @@ -553,7 +591,10 @@ public class BrushCommands { @Arg(desc = "Expression", def = "5") Expression radius ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set(context, new SurfaceSphereBrush(), "worldedit.brush.surface").setFill(fill).setSize(radius); } @@ -578,7 +619,10 @@ public class BrushCommands { @Switch(name = 'o', desc = "Overlay the block") boolean overlay ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); Brush brush; if (overlay) { brush = new ScatterOverlayBrush((int) points, (int) distance); @@ -612,7 +656,10 @@ public class BrushCommands { @Switch(name = 'r', desc = "Apply random rotation") boolean rotate ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); try { MultiClipboardHolder clipboards = ClipboardFormats.loadAllFromInput(player, clipboardStr, null, true); @@ -651,7 +698,10 @@ public class BrushCommands { List patternLayers ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set(context, new LayerBrush(patternLayers.toArray(new Pattern[0])), "worldedit.brush.layer").setSize(radius); } @@ -678,7 +728,10 @@ public class BrushCommands { @Arg(desc = "boolean", def = "true") boolean solid ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set(context, new SplatterBrush((int) points, (int) recursion, solid), "worldedit.brush.splatter").setSize(radius) .setFill(fill); } @@ -711,7 +764,10 @@ public class BrushCommands { boolean print ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set( context, new ScatterCommand((int) points, (int) distance, StringMan.join(commandStr, " "), print), @@ -838,7 +894,10 @@ public class BrushCommands { InjectedValueAccess context ) throws WorldEditException, FileNotFoundException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); InputStream stream = getHeightmapStream(image); HeightBrush brush; int minY = player.getWorld().getMinY(); @@ -908,7 +967,10 @@ public class BrushCommands { @Switch(name = 'a', desc = "Apply auto view based rotation on paste") boolean autoRotate ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); player.print(Caption.of("fawe.worldedit.brush.brush.copy", (radius))); set(context, new CopyPastaBrush(player, session, randomRotate, autoRotate), "worldedit.brush.copy").setSize(radius); @@ -933,7 +995,10 @@ public class BrushCommands { @Switch(name = 'p', desc = "Show any printed output") boolean print ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); String cmd = StringMan.join(input, " "); set(context, new CommandBrush(cmd, print), "worldedit.brush.command").setSize(radius); } @@ -1042,7 +1107,7 @@ public class BrushCommands { String permission ) throws WorldEditException { - WorldEdit.getInstance().checkMaxBrushRadius(radius); + WorldEdit.getInstance().checkMaxBrushRadius(radius, player); BrushTool tool = session.getBrushTool(player); tool.setSize(radius); tool.setFill(null); @@ -1197,7 +1262,10 @@ public class BrushCommands { @Switch(name = 'f', desc = "Create falling spheres instead") boolean falling ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); Brush brush; if (hollow) { brush = new HollowSphereBrush(); @@ -1244,8 +1312,14 @@ public class BrushCommands { @Switch(name = 'h', desc = "Create hollow cylinders instead") boolean hollow ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); - worldEdit.checkMaxBrushRadius(height); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); + worldEdit.checkMaxBrushRadius( + height, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); BrushSettings settings; if (hollow) { @@ -1293,9 +1367,18 @@ public class BrushCommands { BlockVector3 size = clipboard.getDimensions(); - worldEdit.checkMaxBrushRadius(size.getBlockX() / 2D - 1); - worldEdit.checkMaxBrushRadius(size.getBlockY() / 2D - 1); - worldEdit.checkMaxBrushRadius(size.getBlockZ() / 2D - 1); + worldEdit.checkMaxBrushRadius( + size.getBlockX() / 2D - 1, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); + worldEdit.checkMaxBrushRadius( + size.getBlockY() / 2D - 1, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); + worldEdit.checkMaxBrushRadius( + size.getBlockZ() / 2D - 1, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set( context, @@ -1324,7 +1407,10 @@ public class BrushCommands { Mask mask, InjectedValueAccess context ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); //FAWE start FaweLimit limit = Settings.settings().getLimit(player); @@ -1359,7 +1445,10 @@ public class BrushCommands { @ArgFlag(name = 'm', desc = "The mask of blocks to use for the heightmap") Mask mask, InjectedValueAccess context ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); //FAWE start FaweLimit limit = Settings.settings().getLimit(player); @@ -1386,7 +1475,10 @@ public class BrushCommands { @Arg(desc = "The radius to extinguish", def = "5") Expression radius ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set(context, new SphereBrush(), "worldedit.brush.ex").setSize(radius).setFill(BlockTypes.AIR.getDefaultState()) .setMask(new SingleBlockTypeMask(editSession, BlockTypes.FIRE)); @@ -1405,7 +1497,10 @@ public class BrushCommands { @Switch(name = 'h', desc = "Affect blocks starting at max Y, rather than the target location Y + radius") boolean fromMaxY ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); set(context, new GravityBrush(fromMaxY), "worldedit.brush.gravity").setSize(radius); } @@ -1439,7 +1534,10 @@ public class BrushCommands { @Switch(name = 'w', desc = "Also kill water mobs") boolean killWater, InjectedValueAccess context ) throws WorldEditException { - worldEdit.checkMaxBrushRadius(radius); + worldEdit.checkMaxBrushRadius( + radius, + context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) + ); CreatureButcher flags = new CreatureButcher(player); flags.or( @@ -1508,7 +1606,7 @@ public class BrushCommands { RegionFactory shape, String permission ) throws WorldEditException { - WorldEdit.getInstance().checkMaxBrushRadius(radius); + WorldEdit.getInstance().checkMaxBrushRadius(radius, player); BrushTool tool = session.getBrushTool(player.getItemInHand(HandSide.MAIN_HAND).getType()); tool.setSize(radius); tool.setFill(null); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java index d3d456965..90b59cb52 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java @@ -130,9 +130,9 @@ public class GenerationCommands { return 0; } } - worldEdit.checkMaxRadius(radiusX); - worldEdit.checkMaxRadius(radiusZ); - worldEdit.checkMaxRadius(height); + worldEdit.checkMaxRadius(radiusX, actor); + worldEdit.checkMaxRadius(radiusZ, actor); + worldEdit.checkMaxRadius(height, actor); if (thickness > radiusX || thickness > radiusZ) { actor.print(Caption.of("worldedit.hcyl.thickness-too-large")); @@ -178,9 +178,9 @@ public class GenerationCommands { } } - worldEdit.checkMaxRadius(radiusX); - worldEdit.checkMaxRadius(radiusZ); - worldEdit.checkMaxRadius(height); + worldEdit.checkMaxRadius(radiusX, actor); + worldEdit.checkMaxRadius(radiusZ, actor); + worldEdit.checkMaxRadius(height, actor); BlockVector3 pos = session.getPlacementPosition(actor); int affected = editSession.makeCylinder(pos, pattern, radiusX, radiusZ, height, !hollow); @@ -224,9 +224,9 @@ public class GenerationCommands { } } - worldEdit.checkMaxRadius(radiusX); - worldEdit.checkMaxRadius(radiusZ); - worldEdit.checkMaxRadius(height); + worldEdit.checkMaxRadius(radiusX, actor); + worldEdit.checkMaxRadius(radiusZ, actor); + worldEdit.checkMaxRadius(height, actor); BlockVector3 pos = session.getPlacementPosition(actor); int affected = editSession.makeCone(pos, pattern, radiusX, radiusZ, height, !hollow, thickness); @@ -290,9 +290,9 @@ public class GenerationCommands { } } - worldEdit.checkMaxRadius(radiusX); - worldEdit.checkMaxRadius(radiusY); - worldEdit.checkMaxRadius(radiusZ); + worldEdit.checkMaxRadius(radiusX, actor); + worldEdit.checkMaxRadius(radiusY, actor); + worldEdit.checkMaxRadius(radiusZ, actor); BlockVector3 pos = session.getPlacementPosition(actor); if (raised) { pos = pos.add(0, (int) radiusY, 0); @@ -323,7 +323,7 @@ public class GenerationCommands { double density ) throws WorldEditException { checkCommandArgument(0 <= density && density <= 100, "Density must be between 0 and 100"); - worldEdit.checkMaxRadius(size); + worldEdit.checkMaxRadius(size, actor); density /= 100; int affected = editSession.makeForest(session.getPlacementPosition(actor), size, density, type); actor.print(Caption.of("worldedit.forestgen.created", TextComponent.of(affected))); @@ -345,7 +345,7 @@ public class GenerationCommands { double density ) throws WorldEditException { checkCommandArgument(0 <= density && density <= 100, "Density must be between 0 and 100"); - worldEdit.checkMaxRadius(size); + worldEdit.checkMaxRadius(size, actor); int affected = editSession.makePumpkinPatches(session.getPlacementPosition(actor), size, density); actor.print(Caption.of("worldedit.pumpkins.created", TextComponent.of(affected))); return affected; @@ -382,7 +382,7 @@ public class GenerationCommands { @Switch(name = 'h', desc = "Make a hollow pyramid") boolean hollow ) throws WorldEditException { - worldEdit.checkMaxRadius(size); + worldEdit.checkMaxRadius(size, actor); BlockVector3 pos = session.getPlacementPosition(actor); int affected = editSession.makePyramid(pos, pattern, size, !hollow); if (actor instanceof Player && Settings.settings().GENERAL.UNSTUCK_ON_GENERATE) { @@ -736,7 +736,7 @@ public class GenerationCommands { double amplitude ) throws WorldEditException { double max = MathMan.max(radius.getX(), radius.getY(), radius.getZ()); - worldEdit.checkMaxRadius(max); + worldEdit.checkMaxRadius(max, actor); BlockVector3 pos = session.getPlacementPosition(actor); int affected = editSession.makeBlob( pos, diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java index cb24daec5..fdd86498f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SuperPickaxeCommands.java @@ -66,10 +66,11 @@ public class SuperPickaxeCommands { int range ) throws WorldEditException { - LocalConfiguration config = we.getConfiguration(); - - if (range > config.maxSuperPickaxeSize) { - player.print(Caption.of("worldedit.tool.superpickaxe.max-range", TextComponent.of(config.maxSuperPickaxeSize))); + if (range > player.getLimit().MAX_SUPER_PICKAXE_SIZE) { + player.print(Caption.of( + "worldedit.tool.superpickaxe.max-range", + TextComponent.of(player.getLimit().MAX_SUPER_PICKAXE_SIZE) + )); return; } session.setSuperPickaxe(new AreaPickaxe(range)); @@ -89,10 +90,11 @@ public class SuperPickaxeCommands { double range ) throws WorldEditException { - LocalConfiguration config = we.getConfiguration(); - - if (range > config.maxSuperPickaxeSize) { - player.print(Caption.of("worldedit.tool.superpickaxe.max-range", TextComponent.of(config.maxSuperPickaxeSize))); + if (range > player.getLimit().MAX_SUPER_PICKAXE_SIZE) { + player.print(Caption.of( + "worldedit.tool.superpickaxe.max-range", + TextComponent.of(player.getLimit().MAX_SUPER_PICKAXE_SIZE) + )); return; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java index 8395b2e2d..95499372c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java @@ -297,10 +297,11 @@ public class ToolCommands { int range ) throws WorldEditException { - LocalConfiguration config = we.getConfiguration(); - - if (range > config.maxSuperPickaxeSize) { - player.print(Caption.of("worldedit.tool.superpickaxe.max-range", TextComponent.of(config.maxSuperPickaxeSize))); + if (range > player.getLimit().MAX_SUPER_PICKAXE_SIZE) { + player.print(Caption.of( + "worldedit.tool.superpickaxe.max-range", + TextComponent.of(player.getLimit().MAX_SUPER_PICKAXE_SIZE) + )); return; } setTool(player, session, new FloodFillTool(range, pattern), "worldedit.tool.floodfill.equip"); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java index 0694b2af3..48fb76318 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolUtilCommands.java @@ -154,7 +154,7 @@ public class ToolUtilCommands { @Arg(desc = "The size of the brush") int size ) throws WorldEditException { - we.checkMaxBrushRadius(size); + we.checkMaxBrushRadius(size, player); session.getBrushTool(player).setSize(size); player.print(Caption.of("worldedit.tool.size.set")); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index aca13bc46..a336f4b12 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -246,8 +246,9 @@ public class UtilityCommands { double radius = radiusExp.evaluate(); //FAWE end radius = Math.max(1, radius); - we.checkMaxRadius(radius); + we.checkMaxRadius(radius, actor); depth = Math.max(1, depth); + we.checkMaxRadius(depth, actor); BlockVector3 pos = session.getPlacementPosition(actor); int affected = editSession.fillDirection(pos, pattern, radius, depth, direction); @@ -333,9 +334,9 @@ public class UtilityCommands { double radius = radiusExp.evaluate(); //FAWE end radius = Math.max(1, radius); - we.checkMaxRadius(radius); + we.checkMaxRadius(radius, actor); depth = depth == null ? Integer.MAX_VALUE : Math.max(1, depth); - we.checkMaxRadius(radius); + we.checkMaxRadius(radius, actor); BlockVector3 pos = session.getPlacementPosition(actor); int affected = editSession.fillXZ(pos, pattern, radius, depth, true); @@ -364,7 +365,7 @@ public class UtilityCommands { //FAWE end double radius = radiusExp.evaluate(); radius = Math.max(0, radius); - we.checkMaxRadius(radius); + we.checkMaxRadius(radius, actor); int affected = editSession.drainArea(session.getPlacementPosition(actor), radius, waterlogged, plants); actor.print(Caption.of("worldedit.drain.drained", TextComponent.of(affected))); return affected; @@ -383,7 +384,7 @@ public class UtilityCommands { double radius ) throws WorldEditException { radius = Math.max(0, radius); - we.checkMaxRadius(radius); + we.checkMaxRadius(radius, actor); int affected = editSession.fixLiquid(session.getPlacementPosition(actor), radius, BlockTypes.LAVA); actor.print(Caption.of("worldedit.fixlava.fixed", TextComponent.of(affected))); return affected; @@ -402,7 +403,7 @@ public class UtilityCommands { double radius ) throws WorldEditException { radius = Math.max(0, radius); - we.checkMaxRadius(radius); + we.checkMaxRadius(radius, actor); int affected = editSession.fixLiquid(session.getPlacementPosition(actor), radius, BlockTypes.WATER); actor.print(Caption.of("worldedit.fixwater.fixed", TextComponent.of(affected))); return affected; @@ -423,7 +424,7 @@ public class UtilityCommands { Integer height ) throws WorldEditException { size = Math.max(1, size); - we.checkMaxRadius(size); + we.checkMaxRadius(size, actor); height = height != null ? Math.min((world.getMaxY() - world.getMinY() + 1), height + 1) @@ -448,7 +449,7 @@ public class UtilityCommands { Integer height ) throws WorldEditException { size = Math.max(1, size); - we.checkMaxRadius(size); + we.checkMaxRadius(size, actor); height = height != null ? Math.min((world.getMaxY() - world.getMinY() + 1), height + 1) @@ -476,7 +477,7 @@ public class UtilityCommands { new MaskTraverser(mask).setNewExtent(editSession); //FAWE end radius = Math.max(1, radius); - we.checkMaxRadius(radius); + we.checkMaxRadius(radius, actor); int affected = editSession.removeNear(session.getPlacementPosition(actor), mask, radius); actor.print(Caption.of("worldedit.removenear.removed", TextComponent.of(affected))); @@ -503,7 +504,7 @@ public class UtilityCommands { new MaskTraverser(from).setNewExtent(editSession); //FAWE end radius = Math.max(1, radius); - we.checkMaxRadius(radius); + we.checkMaxRadius(radius, actor); BlockVector3 base = session.getPlacementPosition(actor); BlockVector3 min = base.subtract(radius, radius, radius); @@ -542,7 +543,7 @@ public class UtilityCommands { ) throws WorldEditException { size = Math.max(1, size); height = Math.max(1, height); - we.checkMaxRadius(size); + we.checkMaxRadius(size, actor); BlockVector3 position = session.getPlacementPosition(actor); @@ -579,7 +580,7 @@ public class UtilityCommands { ) throws WorldEditException { size = Math.max(1, size); height = Math.max(1, height); - we.checkMaxRadius(size); + we.checkMaxRadius(size, actor); int affected = editSession.thaw(session.getPlacementPosition(actor), size, height); actor.print(Caption.of( @@ -610,7 +611,7 @@ public class UtilityCommands { ) throws WorldEditException { size = Math.max(1, size); height = Math.max(1, height); - we.checkMaxRadius(size); + we.checkMaxRadius(size, actor); final boolean onlyNormalDirt = !convertCoarse; final int affected = editSession.green( @@ -635,11 +636,9 @@ public class UtilityCommands { Integer radius ) throws WorldEditException { - LocalConfiguration config = we.getConfiguration(); - - int defaultRadius = config.maxRadius != -1 ? Math.min(40, config.maxRadius) : 40; + int defaultRadius = actor.getLimit().MAX_RADIUS != -1 ? Math.min(40, actor.getLimit().MAX_RADIUS) : 40; int size = radius != null ? Math.max(1, radius) : defaultRadius; - we.checkMaxRadius(size); + we.checkMaxRadius(size, actor); Mask mask = new BlockTypeMask(editSession, BlockTypes.FIRE); int affected = editSession.removeNear(session.getPlacementPosition(actor), mask, size); @@ -685,12 +684,12 @@ public class UtilityCommands { actor.print(Caption.of("worldedit.butcher.explain-all")); return 0; } else if (radius == -1) { - if (config.butcherMaxRadius != -1) { - radius = config.butcherMaxRadius; + if (actor.getLimit().MAX_BUTCHER_RADIUS != -1) { + radius = actor.getLimit().MAX_BUTCHER_RADIUS; } } - if (config.butcherMaxRadius != -1) { - radius = Math.min(radius, config.butcherMaxRadius); + if (actor.getLimit().MAX_BUTCHER_RADIUS != -1) { + radius = Math.min(radius, actor.getLimit().MAX_BUTCHER_RADIUS); } CreatureButcher flags = new CreatureButcher(actor); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java index d6c44fa66..c4d45d683 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java @@ -477,7 +477,7 @@ public class BrushTool try { new PatternTraverser(current).reset(editSession); double size = current.getSize(); - WorldEdit.getInstance().checkMaxBrushRadius(size); + WorldEdit.getInstance().checkMaxBrushRadius(size, player); brush.build(editSession, target.toBlockPoint(), current.getMaterial(), size); } catch (MaxChangedBlocksException e) { player.print(Caption.of("worldedit.tool.max-block-changes")); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/Confirm.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/Confirm.java index a2854a8c7..37ea4abeb 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/Confirm.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/Confirm.java @@ -75,7 +75,7 @@ public @interface Confirm { if (checkExisting(context)) { return true; } - int max = WorldEdit.getInstance().getConfiguration().maxRadius; + int max = actor.getLimit().MAX_RADIUS; if (max != -1 && value > max) { actor.print(Caption.of("fawe.cancel.reason.confirm.radius", value, max, getArgs(context) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java index a0c5eb328..b07f3f61d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java @@ -20,6 +20,8 @@ package com.sk89q.worldedit.internal.command.exception; import com.fastasyncworldedit.core.configuration.Caption; +import com.fastasyncworldedit.core.exception.BrushRadiusLimitException; +import com.fastasyncworldedit.core.exception.RadiusLimitException; import com.fastasyncworldedit.core.internal.exception.FaweException; import com.google.common.collect.ImmutableList; import com.sk89q.worldedit.DisallowedItemException; @@ -134,6 +136,18 @@ public class WorldEditExceptionConverter extends ExceptionConverterHelper { ); } + //FAWE start + @ExceptionMatch + public void convert(BrushRadiusLimitException e) throws CommandException { + throw newCommandException(Caption.of("fawe.error.limit.max-brush-radius", TextComponent.of(e.getMaxRadius())), e); + } + + @ExceptionMatch + public void convert(RadiusLimitException e) throws CommandException { + throw newCommandException(Caption.of("fawe.error.limit.max-radius", TextComponent.of(e.getMaxRadius())), e); + } + //FAWE end + @ExceptionMatch public void convert(UnknownDirectionException e) throws CommandException { throw newCommandException(e.getRichMessage(), e); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java index f350af03f..3804be8d3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java @@ -136,6 +136,14 @@ public class PropertiesConfiguration extends LocalConfiguration { scriptsDir = getString("craftscript-dir", scriptsDir); butcherDefaultRadius = getInt("butcher-default-radius", butcherDefaultRadius); butcherMaxRadius = getInt("butcher-max-radius", butcherMaxRadius); + + //FAWE start + MAX_RADIUS = maxRadius; + MAX_BRUSH_RADIUS = maxBrushRadius; + MAX_SUPER_RADIUS = maxSuperPickaxeSize; + MAX_BUTCHER_RADIUS = butcherMaxRadius; + //FAWE end + allowSymlinks = getBool("allow-symbolic-links", allowSymlinks); serverSideCUI = getBool("server-side-cui", serverSideCUI); extendedYLimit = getBool("extended-y-limit", extendedYLimit); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java index 1a8b0667c..7b0cbf4b8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java @@ -95,6 +95,13 @@ public class YAMLConfiguration extends LocalConfiguration { butcherDefaultRadius = Math.max(-1, config.getInt("limits.butcher-radius.default", butcherDefaultRadius)); butcherMaxRadius = Math.max(-1, config.getInt("limits.butcher-radius.maximum", butcherMaxRadius)); + //FAWE start + MAX_RADIUS = maxRadius; + MAX_BRUSH_RADIUS = maxBrushRadius; + MAX_SUPER_RADIUS = maxSuperPickaxeSize; + MAX_BUTCHER_RADIUS = butcherMaxRadius; + //FAWE end + disallowedBlocks = config.getStringList("limits.disallowed-blocks", Lists.newArrayList(getDefaultDisallowedBlocks())) .stream() .map(s -> s.contains(":") ? s.toLowerCase(Locale.ROOT) : ("minecraft:" + s).toLowerCase(Locale.ROOT)) diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index 208de9027..c343dd623 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -137,6 +137,8 @@ "fawe.error.limit.disallowed-property": "Your limit disallows use of property '{0}'", "fawe.error.region-mask-invalid": "Invalid region mask: {0}", "fawe.error.occurred-continuing": "Ignorable error occurred during edit: {0}", + "fawe.error.limit.max-brush-radius": "Maximum brush radius in limit: {0}", + "fawe.error.limit.max-radius": "Maximum radius in limit: {0}", "fawe.cancel.count": "Cancelled {0} edits.", "fawe.cancel.reason.confirm": "Use //confirm to execute {0}", "fawe.cancel.reason.confirm.region": "Your selection is large ({0} -> {1}, containing {3} blocks). Use //confirm to execute {2}", From c77d34156b5f5b460691c74a5573a8a0ba1d7996 Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Sat, 25 May 2024 13:36:37 +0200 Subject: [PATCH 136/220] Fix compatibility with WorldGuard (#2743) * Make the Vector classes into Records (#2477) * Make the Vector classes into Records * Drop custom equals and hashCode methods in Vector/BlockVector classes (cherry picked from commit 0df2b6af4c1ce18b77eedd5c62eeb45011512103) Signed-off-by: Pierre Maurice Schwang * chore: cleanup cherry-pick issues, migrate to new methods * chore: add since attributes to deprecated tags, use MathMan instead of Math std lib for rounding ints * chore: mark custom hashCode + equals implementations diffing from upstream --------- Co-authored-by: Maddy Miller --- .../adapters/adapter-1_20_5/build.gradle.kts | 2 +- .../filter/block/AbstractFilterBlock.java | 20 +- .../extent/filter/block/ArrayFilterBlock.java | 10 +- .../extent/filter/block/CharFilterBlock.java | 16 +- .../core/extent/filter/block/FilterBlock.java | 32 +-- .../filter/block/SingleFilterBlock.java | 6 +- .../core/math/DelegateBlockVector3.java | 27 +- .../core/math/MutableBlockVector3.java | 22 +- .../core/math/MutableVector3.java | 14 +- .../core/math/OffsetBlockVector3.java | 12 +- .../core/math/Vector3Impl.java | 8 +- .../sk89q/worldedit/math/BlockVector2.java | 35 ++- .../sk89q/worldedit/math/BlockVector3.java | 253 ++++++++++------- .../sk89q/worldedit/math/BlockVector3Imp.java | 12 +- .../com/sk89q/worldedit/math/Vector2.java | 59 ++-- .../com/sk89q/worldedit/math/Vector3.java | 266 +++++++++++------- .../com/sk89q/worldedit/util/Location.java | 14 +- 17 files changed, 454 insertions(+), 354 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts index a0ee57dc2..80c044f91 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/ - the().paperDevBundle("1.20.6-R0.1-20240520.005421-60") + the().paperDevBundle("1.20.6-R0.1-20240523.202134-70") compileOnly(libs.paperlib) } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/AbstractFilterBlock.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/AbstractFilterBlock.java index b91ef08b0..4f3db3994 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/AbstractFilterBlock.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/AbstractFilterBlock.java @@ -31,18 +31,18 @@ public abstract class AbstractFilterBlock extends FilterBlock { public abstract Extent getExtent(); @Override - public int getX() { - return getPosition().getX(); + public int x() { + return getPosition().x(); } @Override - public int getY() { - return getPosition().getY(); + public int y() { + return getPosition().y(); } @Override - public int getZ() { - return getPosition().getZ(); + public int z() { + return getPosition().z(); } @Override @@ -72,12 +72,12 @@ public abstract class AbstractFilterBlock extends FilterBlock { @Override public BlockVector3 getMinimumPoint() { - return at(getX(), getY(), getZ()); + return at(x(), y(), z()); } @Override public BlockVector3 getMaximumPoint() { - return at(getX(), getY(), getZ()); + return at(x(), y(), z()); } @Override @@ -88,7 +88,7 @@ public abstract class AbstractFilterBlock extends FilterBlock { @Override public > boolean setBlock(int x, int y, int z, T block) throws WorldEditException { - if (x == this.getX() && y == this.getY() && z == this.getZ()) { + if (x == this.x() && y == this.y() && z == this.z()) { setFullBlock(block.toBaseBlock()); return true; } @@ -97,7 +97,7 @@ public abstract class AbstractFilterBlock extends FilterBlock { @Override public boolean setBiome(int x, int y, int z, BiomeType biome) { - if (x == this.getX() && y == this.getY() && z == this.getZ()) { + if (x == this.x() && y == this.y() && z == this.z()) { setBiome(biome); return true; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/ArrayFilterBlock.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/ArrayFilterBlock.java index 4f73d5fa3..362f869ac 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/ArrayFilterBlock.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/ArrayFilterBlock.java @@ -80,17 +80,17 @@ public class ArrayFilterBlock extends AbstractExtentFilterBlock { } @Override - public int getX() { + public int x() { return x; } @Override - public int getY() { + public int y() { return (heights[index] & 0xFF) + yOffset; } @Override - public int getZ() { + public int z() { return z; } @@ -112,12 +112,12 @@ public class ArrayFilterBlock extends AbstractExtentFilterBlock { @Override public void setBiome(final BiomeType biome) { - getExtent().setBiome(getX(), getY(), getZ(), biome); + getExtent().setBiome(x(), y(), z(), biome); } @Override public BiomeType getBiome() { - return getExtent().getBiomeType(getX(), getY(), getZ()); + return getExtent().getBiomeType(x(), y(), z()); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/CharFilterBlock.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/CharFilterBlock.java index 9a339826a..579f04a9a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/CharFilterBlock.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/CharFilterBlock.java @@ -190,17 +190,17 @@ public class CharFilterBlock extends ChunkFilterBlock { } @Override - public final int getX() { + public final int x() { return xx + x; } @Override - public final int getY() { + public final int y() { return yy + y; } @Override - public final int getZ() { + public final int z() { return zz + z; } @@ -304,7 +304,7 @@ public class CharFilterBlock extends ChunkFilterBlock { if (z > 0) { return states[getArr[index - 16]]; } - return getExtent().getBlock(getX(), getY(), getZ() - 1); + return getExtent().getBlock(x(), y(), z() - 1); } @Override @@ -312,7 +312,7 @@ public class CharFilterBlock extends ChunkFilterBlock { if (x < 15) { return states[getArr[index + 1]]; } - return getExtent().getBlock(getX() + 1, getY(), getZ()); + return getExtent().getBlock(x() + 1, y(), z()); } @Override @@ -320,7 +320,7 @@ public class CharFilterBlock extends ChunkFilterBlock { if (z < 15) { return states[getArr[index + 16]]; } - return getExtent().getBlock(getX(), getY(), getZ() + 1); + return getExtent().getBlock(x(), y(), z() + 1); } @Override @@ -328,7 +328,7 @@ public class CharFilterBlock extends ChunkFilterBlock { if (x > 0) { return states[getArr[index - 1]]; } - return getExtent().getBlock(getX() - 1, getY(), getZ()); + return getExtent().getBlock(x() - 1, y(), z()); } @Override @@ -401,7 +401,7 @@ public class CharFilterBlock extends ChunkFilterBlock { @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { - return setBiome(position.getX(), position.getY(), position.getBlockZ(), biome); + return setBiome(position.x(), position.y(), position.z(), biome); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/FilterBlock.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/FilterBlock.java index c27d3770a..3565c696f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/FilterBlock.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/FilterBlock.java @@ -73,60 +73,60 @@ public abstract class FilterBlock extends BlockVector3 implements Extent, TileEn } public BlockState getBlockBelow() { - return getBlock(getX(), getY() - 1, getZ()); + return getBlock(x(), y() - 1, z()); } public BlockState getBlockAbove() { - return getBlock(getX(), getY() + 1, getZ()); + return getBlock(x(), y() + 1, z()); } public BlockState getBlockNorth() { - return getBlock(getX(), getY(), getZ() - 1); + return getBlock(x(), y(), z() - 1); } public BlockState getBlockEast() { - return getBlock(getX() + 1, getY(), getZ()); + return getBlock(x() + 1, y(), z()); } public BlockState getBlockSouth() { - return getBlock(getX(), getY(), getZ() + 1); + return getBlock(x(), y(), z() + 1); } public BlockState getBlockWest() { - return getBlock(getX() - 1, getY(), getZ()); + return getBlock(x() - 1, y(), z()); } public BlockState getBlockRelativeY(int y) { - return getBlock(getX(), getY() + y, getZ()); + return getBlock(x(), y() + y, z()); } @Override - public abstract int getX(); + public abstract int x(); @Override - public abstract int getY(); + public abstract int y(); @Override - public abstract int getZ(); + public abstract int z(); public int getLocalX() { - return getX() & 15; + return x() & 15; } public int getLocalY() { - return getY() & 15; + return y() & 15; } public int getLocalZ() { - return getZ() & 15; + return z() & 15; } public int getChunkX() { - return getX() >> 4; + return x() >> 4; } public int getChunkZ() { - return getZ() >> 4; + return z() >> 4; } /* @@ -204,7 +204,7 @@ public abstract class FilterBlock extends BlockVector3 implements Extent, TileEn @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { - return setBiome(position.getX(), position.getY(), position.getZ(), biome); + return setBiome(position.x(), position.y(), position.z(), biome); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/SingleFilterBlock.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/SingleFilterBlock.java index 5516ae3bb..83301c4ea 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/SingleFilterBlock.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/SingleFilterBlock.java @@ -17,17 +17,17 @@ public class SingleFilterBlock extends AbstractSingleFilterBlock { } @Override - public int getX() { + public int x() { return x; } @Override - public int getY() { + public int y() { return y; } @Override - public int getZ() { + public int z() { return z; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/DelegateBlockVector3.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/DelegateBlockVector3.java index b75e157b2..b13aece41 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/DelegateBlockVector3.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/DelegateBlockVector3.java @@ -95,13 +95,8 @@ public class DelegateBlockVector3 extends BlockVector3 { } @Override - public int getX() { - return parent.getX(); - } - - @Override - public int getBlockX() { - return parent.getBlockX(); + public int x() { + return parent.x(); } @Override @@ -110,13 +105,8 @@ public class DelegateBlockVector3 extends BlockVector3 { } @Override - public int getY() { - return parent.getY(); - } - - @Override - public int getBlockY() { - return parent.getBlockY(); + public int y() { + return parent.y(); } @Override @@ -125,13 +115,8 @@ public class DelegateBlockVector3 extends BlockVector3 { } @Override - public int getZ() { - return parent.getZ(); - } - - @Override - public int getBlockZ() { - return parent.getBlockZ(); + public int z() { + return parent.z(); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/MutableBlockVector3.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/MutableBlockVector3.java index 6ebabae1d..e4cfda85a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/MutableBlockVector3.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/MutableBlockVector3.java @@ -21,11 +21,11 @@ public class MutableBlockVector3 extends BlockVector3 { } public MutableBlockVector3(BlockVector3 other) { - this(other.getX(), other.getY(), other.getZ()); + this(other.x(), other.y(), other.z()); } public MutableBlockVector3 setComponents(BlockVector3 other) { - return setComponents(other.getBlockX(), other.getBlockY(), other.getBlockZ()); + return setComponents(other.x(), other.y(), other.z()); } private int x; @@ -47,33 +47,33 @@ public class MutableBlockVector3 extends BlockVector3 { } @Override - public final int getX() { + public final int x() { return x; } @Override - public final int getY() { + public final int y() { return y; } @Override - public final int getZ() { + public final int z() { return z; } @Override public BlockVector3 getMinimum(BlockVector3 v2) { - this.x = Math.min(v2.getX(), x); - this.y = Math.min(v2.getY(), y); - this.z = Math.min(v2.getZ(), z); + this.x = Math.min(v2.x(), x); + this.y = Math.min(v2.y(), y); + this.z = Math.min(v2.z(), z); return this; } @Override public BlockVector3 getMaximum(BlockVector3 v2) { - this.x = Math.max(v2.getX(), x); - this.y = Math.max(v2.getY(), y); - this.z = Math.max(v2.getZ(), z); + this.x = Math.max(v2.x(), x); + this.y = Math.max(v2.y(), y); + this.z = Math.max(v2.z(), z); return this; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/MutableVector3.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/MutableVector3.java index 22d85d38a..3c6ad1334 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/MutableVector3.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/MutableVector3.java @@ -23,7 +23,7 @@ public class MutableVector3 extends Vector3 { } public MutableVector3(Vector3 other) { - this(other.getX(), other.getY(), other.getZ()); + this(other.x(), other.y(), other.z()); } public static MutableVector3 get(int x, int y, int z) { @@ -36,9 +36,9 @@ public class MutableVector3 extends Vector3 { @Override public MutableVector3 setComponents(Vector3 other) { - this.x = other.getX(); - this.y = other.getY(); - this.z = other.getZ(); + this.x = other.x(); + this.y = other.y(); + this.z = other.z(); return this; } @@ -95,17 +95,17 @@ public class MutableVector3 extends Vector3 { } @Override - public double getX() { + public double x() { return x; } @Override - public double getY() { + public double y() { return y; } @Override - public double getZ() { + public double z() { return z; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/OffsetBlockVector3.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/OffsetBlockVector3.java index 044a623de..5e0d0ebe0 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/OffsetBlockVector3.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/OffsetBlockVector3.java @@ -11,18 +11,18 @@ public class OffsetBlockVector3 extends DelegateBlockVector3 { } @Override - public int getX() { - return super.getX() + offset.getX(); + public int x() { + return super.x() + offset.x(); } @Override - public int getY() { - return super.getY() + offset.getY(); + public int y() { + return super.y() + offset.y(); } @Override - public int getZ() { - return super.getZ() + offset.getZ(); + public int z() { + return super.z() + offset.z(); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/Vector3Impl.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/Vector3Impl.java index c1092a881..33706aee5 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/Vector3Impl.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/Vector3Impl.java @@ -15,21 +15,21 @@ public class Vector3Impl extends Vector3 { } public Vector3Impl(Vector3 other) { - this(other.getX(), other.getY(), other.getZ()); + this(other.x(), other.y(), other.z()); } @Override - public final double getX() { + public final double x() { return x; } @Override - public final double getY() { + public final double y() { return y; } @Override - public final double getZ() { + public final double z() { return z; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java index fe95ad3ad..cb5784cce 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java @@ -27,7 +27,7 @@ import java.util.Comparator; /** * An immutable 2-dimensional vector. */ -//FAWE start - un-finalize +//FAWE start - not a record public class BlockVector2 { //FAWE end @@ -122,7 +122,19 @@ public class BlockVector2 { * Get the X coordinate. * * @return the x coordinate + * @since TODO */ + public int x() { + return x; + } + + /** + * Get the X coordinate. + * + * @return the x coordinate + * @deprecated use {@link #x()} instead + */ + @Deprecated(forRemoval = true, since = "TODO") public int getX() { return x; } @@ -131,7 +143,9 @@ public class BlockVector2 { * Get the X coordinate. * * @return the x coordinate + * @deprecated use {@link #x()} instead */ + @Deprecated(forRemoval = true, since = "TODO") public int getBlockX() { return x; } @@ -150,7 +164,19 @@ public class BlockVector2 { * Get the Z coordinate. * * @return the z coordinate + * @since TODO */ + public int z() { + return z; + } + + /** + * Get the Z coordinate. + * + * @return the z coordinate + * @deprecated use {@link #z()} instead + */ + @Deprecated(forRemoval = true, since = "TODO") public int getZ() { return z; } @@ -159,7 +185,9 @@ public class BlockVector2 { * Get the Z coordinate. * * @return the z coordinate + * @deprecated use {@link #z()} instead */ + @Deprecated(forRemoval = true, since = "TODO") public int getBlockZ() { return z; } @@ -598,13 +626,13 @@ public class BlockVector2 { return BlockVector3.at(x, y, z); } + //FAWE start - not a record, need own implementations @Override public boolean equals(Object obj) { - if (!(obj instanceof BlockVector2)) { + if (!(obj instanceof BlockVector2 other)) { return false; } - BlockVector2 other = (BlockVector2) obj; return other.x == this.x && other.z == this.z; } @@ -613,6 +641,7 @@ public class BlockVector2 { public int hashCode() { return (x << 16) ^ z; } + //FAWE end @Override public String toString() { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java index 5f1c14842..e48355d63 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java @@ -38,7 +38,9 @@ import static com.sk89q.worldedit.math.BitMath.unpackZ; /** * An immutable 3-dimensional vector. */ +//FAWE start - not a record public abstract class BlockVector3 { +//FAWE end public static final BlockVector3 ZERO = BlockVector3.at(0, 0, 0); public static final BlockVector3 UNIT_X = BlockVector3.at(1, 0, 0); @@ -85,9 +87,9 @@ public abstract class BlockVector3 { } public static boolean isLongPackable(BlockVector3 location) { - return isHorizontallyInBounds(location.getX()) - && isHorizontallyInBounds(location.getZ()) - && WORLD_Y_MIN <= location.getY() && location.getY() <= WORLD_Y_MAX; + return isHorizontallyInBounds(location.x()) + && isHorizontallyInBounds(location.z()) + && WORLD_Y_MIN <= location.y() && location.y() <= WORLD_Y_MAX; } public static void checkLongPackable(BlockVector3 location) { @@ -107,9 +109,9 @@ public abstract class BlockVector3 { private static final class YzxOrderComparator { private static final Comparator YZX_ORDER = - Comparator.comparingInt(BlockVector3::getY) - .thenComparingInt(BlockVector3::getZ) - .thenComparingInt(BlockVector3::getX); + Comparator.comparingInt(BlockVector3::y) + .thenComparingInt(BlockVector3::z) + .thenComparingInt(BlockVector3::x); } @@ -135,57 +137,69 @@ public abstract class BlockVector3 { public long toLongPackedForm() { checkLongPackable(this); - return (getX() & BITS_26) | ((getZ() & BITS_26) << 26) | (((getY() & BITS_12) << (26 + 26))); + return (x() & BITS_26) | ((z() & BITS_26) << 26) | (((y() & BITS_12) << (26 + 26))); } public MutableBlockVector3 mutX(double x) { - return new MutableBlockVector3((int) x, getY(), getZ()); + return new MutableBlockVector3((int) x, y(), z()); } public MutableBlockVector3 mutY(double y) { - return new MutableBlockVector3(getX(), (int) y, getZ()); + return new MutableBlockVector3(x(), (int) y, z()); } public MutableBlockVector3 mutZ(double z) { - return new MutableBlockVector3(getX(), getY(), (int) z); + return new MutableBlockVector3(x(), y(), (int) z); } public MutableBlockVector3 mutX(int x) { - return new MutableBlockVector3(x, getY(), getZ()); + return new MutableBlockVector3(x, y(), z()); } public MutableBlockVector3 mutY(int y) { - return new MutableBlockVector3(getX(), y, getZ()); + return new MutableBlockVector3(x(), y, z()); } public MutableBlockVector3 mutZ(int z) { - return new MutableBlockVector3(getX(), getY(), z); + return new MutableBlockVector3(x(), y(), z); } public BlockVector3 toImmutable() { - return BlockVector3.at(getX(), getY(), getZ()); + return BlockVector3.at(x(), y(), z()); } //FAWE end + //FAWE start - make record getters to abstract methods /** * Get the X coordinate. * * @return the x coordinate + * @since TODO */ - //FAWE start - Made abstract - public abstract int getX(); + public abstract int x(); //FAWE end /** * Get the X coordinate. * * @return the x coordinate + * @deprecated use {@link #x()} instead */ - //FAWE start - getter + @Deprecated(forRemoval = true, since = "TODO") + public int getX() { + return this.x(); //FAWE - access abstract getter instead of local field + } + + /** + * Get the X coordinate. + * + * @return the x coordinate + * @deprecated use {@link #x()} instead + */ + @Deprecated(forRemoval = true, since = "TODO") public int getBlockX() { - return getX(); + return this.x(); //FAWE - access abstract getter instead of local field } - //FAWE end /** * Set the X coordinate. @@ -195,29 +209,42 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 withX(int x) { - return BlockVector3.at(x, getY(), getZ()); + return BlockVector3.at(x, y(), z()); } //FAWE end + + //FAWE start - make record getters to abstract methods /** * Get the Y coordinate. * * @return the y coordinate + * @since TODO */ - //FAWE start - Made abstract - public abstract int getY(); + public abstract int y(); //FAWE end /** * Get the Y coordinate. * * @return the y coordinate + * @deprecated use {@link #y()} instead */ - //FAWE start - getter + @Deprecated(forRemoval = true, since = "TODO") + public int getY() { + return this.y(); //FAWE - access abstract getter instead of local field + } + + /** + * Get the Y coordinate. + * + * @return the y coordinate + * @deprecated use {@link #y()} instead + */ + @Deprecated(forRemoval = true, since = "TODO") public int getBlockY() { - return getY(); + return this.y(); //FAWE - access abstract getter instead of local field } - //FAWE end /** * Set the Y coordinate. @@ -231,25 +258,37 @@ public abstract class BlockVector3 { } //FAWE end + //FAWE start - make record getters to abstract methods /** * Get the Z coordinate. * - * @return the z coordinate + * @return the Z coordinate + * @since TODO */ - //FAWE start - Made abstract - public abstract int getZ(); + public abstract int z(); //FAWE end /** * Get the Z coordinate. * * @return the z coordinate + * @deprecated use {@link #z()} instead */ - //FAWE start - getter - public int getBlockZ() { - return getZ(); + @Deprecated(forRemoval = true, since = "TODO") + public int getZ() { + return this.z(); //FAWE - access abstract getter instead of local field + } + + /** + * Get the Z coordinate. + * + * @return the z coordinate + * @deprecated use {@link #z()} instead + */ + @Deprecated(forRemoval = true, since = "TODO") + public int getBlockZ() { + return this.z(); //FAWE - access abstract getter instead of local field } - //FAWE end /** * Set the Z coordinate. @@ -259,7 +298,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 withZ(int z) { - return BlockVector3.at(getX(), getY(), z); + return BlockVector3.at(x(), y(), z); } //FAWE end @@ -271,7 +310,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 add(BlockVector3 other) { - return add(other.getX(), other.getY(), other.getZ()); + return add(other.x(), other.y(), other.z()); } //FAWE end @@ -285,7 +324,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 add(int x, int y, int z) { - return BlockVector3.at(this.getX() + x, this.getY() + y, this.getZ() + z); + return BlockVector3.at(this.x() + x, this.y() + y, this.z() + z); } //FAWE end @@ -298,14 +337,14 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 add(BlockVector3... others) { - int newX = getX(); - int newY = getY(); - int newZ = getZ(); + int newX = x(); + int newY = y(); + int newZ = z(); for (BlockVector3 other : others) { - newX += other.getX(); - newY += other.getY(); - newZ += other.getZ(); + newX += other.x(); + newY += other.y(); + newZ += other.z(); } return BlockVector3.at(newX, newY, newZ); @@ -321,7 +360,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 subtract(BlockVector3 other) { - return subtract(other.getX(), other.getY(), other.getZ()); + return subtract(other.x(), other.y(), other.z()); } //FAWE end @@ -336,7 +375,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 subtract(int x, int y, int z) { - return BlockVector3.at(this.getX() - x, this.getY() - y, this.getZ() - z); + return BlockVector3.at(this.x() - x, this.y() - y, this.z() - z); } //FAWE end @@ -349,14 +388,14 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 subtract(BlockVector3... others) { - int newX = getX(); - int newY = getY(); - int newZ = getZ(); + int newX = x(); + int newY = y(); + int newZ = z(); for (BlockVector3 other : others) { - newX -= other.getX(); - newY -= other.getY(); - newZ -= other.getZ(); + newX -= other.x(); + newY -= other.y(); + newZ -= other.z(); } return BlockVector3.at(newX, newY, newZ); @@ -371,7 +410,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 multiply(BlockVector3 other) { - return multiply(other.getX(), other.getY(), other.getZ()); + return multiply(other.x(), other.y(), other.z()); } //FAWE end @@ -385,7 +424,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 multiply(int x, int y, int z) { - return BlockVector3.at(this.getX() * x, this.getY() * y, this.getZ() * z); + return BlockVector3.at(this.x() * x, this.y() * y, this.z() * z); } //FAWE end @@ -397,14 +436,14 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 multiply(BlockVector3... others) { - int newX = getX(); - int newY = getY(); - int newZ = getZ(); + int newX = x(); + int newY = y(); + int newZ = z(); for (BlockVector3 other : others) { - newX *= other.getX(); - newY *= other.getY(); - newZ *= other.getZ(); + newX *= other.x(); + newY *= other.y(); + newZ *= other.z(); } return BlockVector3.at(newX, newY, newZ); @@ -429,7 +468,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 divide(BlockVector3 other) { - return divide(other.getX(), other.getY(), other.getZ()); + return divide(other.x(), other.y(), other.z()); } //FAWE end @@ -443,7 +482,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 divide(int x, int y, int z) { - return BlockVector3.at(this.getX() / x, this.getY() / y, this.getZ() / z); + return BlockVector3.at(this.x() / x, this.y() / y, this.z() / z); } //FAWE end @@ -467,7 +506,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 shr(int x, int y, int z) { - return at(this.getX() >> x, this.getY() >> y, this.getZ() >> z); + return at(this.x() >> x, this.y() >> y, this.z() >> z); } //FAWE end @@ -491,7 +530,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 shl(int x, int y, int z) { - return at(this.getX() << x, this.getY() << y, this.getZ() << z); + return at(this.x() << x, this.y() << y, this.z() << z); } //FAWE end @@ -521,7 +560,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public int lengthSq() { - return getX() * getX() + getY() * getY() + getZ() * getZ(); + return x() * x() + y() * y() + z() * z(); } //FAWE end @@ -543,9 +582,9 @@ public abstract class BlockVector3 { */ //FAWE start - getter public int distanceSq(BlockVector3 other) { - int dx = other.getX() - getX(); - int dy = other.getY() - getY(); - int dz = other.getZ() - getZ(); + int dx = other.x() - x(); + int dy = other.y() - y(); + int dz = other.z() - z(); return dx * dx + dy * dy + dz * dz; } //FAWE end @@ -559,9 +598,9 @@ public abstract class BlockVector3 { //FAWE start - getter public BlockVector3 normalize() { double len = length(); - double x = this.getX() / len; - double y = this.getY() / len; - double z = this.getZ() / len; + double x = this.x() / len; + double y = this.y() / len; + double z = this.z() / len; return BlockVector3.at(x, y, z); } //FAWE end @@ -574,7 +613,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public double dot(BlockVector3 other) { - return getX() * other.getX() + getY() * other.getY() + getZ() * other.getZ(); + return x() * other.x() + y() * other.y() + z() * other.z(); } //FAWE end @@ -587,9 +626,9 @@ public abstract class BlockVector3 { //FAWE start - getter public BlockVector3 cross(BlockVector3 other) { return new BlockVector3Imp( - getY() * other.getZ() - getZ() * other.getY(), - getZ() * other.getX() - getX() * other.getZ(), - getX() * other.getY() - getY() * other.getX() + y() * other.z() - z() * other.y(), + z() * other.x() - x() * other.z(), + x() * other.y() - y() * other.x() ); } //FAWE end @@ -603,8 +642,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public boolean containedWithin(BlockVector3 min, BlockVector3 max) { - return getX() >= min.getX() && getX() <= max.getX() && getY() >= min.getY() && getY() <= max - .getY() && getZ() >= min.getZ() && getZ() <= max.getZ(); + return x() >= min.x() && x() <= max.x() && y() >= min.y() && y() <= max.y() && z() >= min.z() && z() <= max.z(); } //FAWE end @@ -618,11 +656,11 @@ public abstract class BlockVector3 { //FAWE start - getter public BlockVector3 clampY(int min, int max) { checkArgument(min <= max, "minimum cannot be greater than maximum"); - if (getY() < min) { - return BlockVector3.at(getX(), min, getZ()); + if (y() < min) { + return BlockVector3.at(x(), min, z()); } - if (getY() > max) { - return BlockVector3.at(getX(), max, getZ()); + if (y() > max) { + return BlockVector3.at(x(), max, z()); } return this; } @@ -668,7 +706,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 abs() { - return BlockVector3.at(Math.abs(getX()), Math.abs(getY()), Math.abs(getZ())); + return BlockVector3.at(Math.abs(x()), Math.abs(y()), Math.abs(z())); } //FAWE end @@ -686,8 +724,8 @@ public abstract class BlockVector3 { //FAWE start - getter public BlockVector3 transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) { angle = Math.toRadians(angle); - double x = this.getX() - aboutX; - double z = this.getZ() - aboutZ; + double x = this.x() - aboutX; + double z = this.z() - aboutZ; double cos = Math.cos(angle); double sin = Math.sin(angle); double x2 = x * cos - z * sin; @@ -695,7 +733,7 @@ public abstract class BlockVector3 { return BlockVector3.at( x2 + aboutX + translateX, - getY(), + y(), z2 + aboutZ + translateZ ); } @@ -707,16 +745,16 @@ public abstract class BlockVector3 { * @return pitch in radians */ public double toPitch() { - double x = getX(); - double z = getZ(); + double x = x(); + double z = z(); if (x == 0 && z == 0) { - return getY() > 0 ? -90 : 90; + return y() > 0 ? -90 : 90; } else { double x2 = x * x; double z2 = z * z; double xz = Math.sqrt(x2 + z2); - return Math.toDegrees(Math.atan(-getY() / xz)); + return Math.toDegrees(Math.atan(-y() / xz)); } } @@ -726,8 +764,8 @@ public abstract class BlockVector3 { * @return yaw in radians */ public double toYaw() { - double x = getX(); - double z = getZ(); + double x = x(); + double z = z(); double t = Math.atan2(-x, z); double tau = 2 * Math.PI; @@ -744,9 +782,9 @@ public abstract class BlockVector3 { //FAWE start - getter public BlockVector3 getMinimum(BlockVector3 v2) { return new BlockVector3Imp( - Math.min(getX(), v2.getX()), - Math.min(getY(), v2.getY()), - Math.min(getZ(), v2.getZ()) + Math.min(x(), v2.x()), + Math.min(y(), v2.y()), + Math.min(z(), v2.z()) ); } //FAWE end @@ -760,9 +798,9 @@ public abstract class BlockVector3 { //FAWE start - getter public BlockVector3 getMaximum(BlockVector3 v2) { return new BlockVector3Imp( - Math.max(getX(), v2.getX()), - Math.max(getY(), v2.getY()), - Math.max(getZ(), v2.getZ()) + Math.max(x(), v2.x()), + Math.max(y(), v2.y()), + Math.max(z(), v2.z()) ); } //FAWE end @@ -815,19 +853,19 @@ public abstract class BlockVector3 { } public CompoundTag getNbtData(Extent orDefault) { - return orDefault.getFullBlock(getX(), getY(), getZ()).getNbtData(); + return orDefault.getFullBlock(x(), y(), z()).getNbtData(); } public BlockState getOrdinalBelow(Extent orDefault) { - return orDefault.getBlock(getX(), getY() - 1, getZ()); + return orDefault.getBlock(x(), y() - 1, z()); } public BlockState getStateAbove(Extent orDefault) { - return orDefault.getBlock(getX(), getY() + 1, getZ()); + return orDefault.getBlock(x(), y() + 1, z()); } public BlockState getStateRelativeY(Extent orDefault, final int y) { - return orDefault.getBlock(getX(), getY() + y, getZ()); + return orDefault.getBlock(x(), y() + y, z()); } /** @@ -836,21 +874,21 @@ public abstract class BlockVector3 { * @return a new {@link BlockVector2} */ public BlockVector2 toBlockVector2() { - return BlockVector2.at(getX(), getZ()); + return BlockVector2.at(x(), z()); } public Vector3 toVector3() { - return Vector3.at(getX(), getY(), getZ()); + return Vector3.at(x(), y(), z()); } + //FAWE start - not a record, need own implementations @Override public boolean equals(Object obj) { - if (!(obj instanceof BlockVector3)) { + if (!(obj instanceof final BlockVector3 other)) { return false; } - BlockVector3 other = (BlockVector3) obj; - return other.getX() == this.getX() && other.getY() == this.getY() && other.getZ() == this.getZ(); + return other.x() == this.x() && other.y() == this.y() && other.z() == this.z(); } public final boolean equals(BlockVector3 other) { @@ -858,17 +896,18 @@ public abstract class BlockVector3 { return false; } - return other.getX() == this.getX() && other.getY() == this.getY() && other.getZ() == this.getZ(); + return other.x() == this.x() && other.y() == this.y() && other.z() == this.z(); } @Override public int hashCode() { - return (getX() ^ (getZ() << 12)) ^ (getY() << 24); + return (x() ^ (z() << 12)) ^ (y() << 24); } + //FAWE end @Override public String toString() { - return "(" + getX() + ", " + getY() + ", " + getZ() + ")"; + return "(" + x() + ", " + y() + ", " + z() + ")"; } /** @@ -877,7 +916,7 @@ public abstract class BlockVector3 { * @return string */ public String toParserString() { - return getX() + "," + getY() + "," + getZ(); + return x() + "," + y() + "," + z(); } //Used by VS fork diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3Imp.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3Imp.java index ab202e83b..5ec2f4fe2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3Imp.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3Imp.java @@ -56,33 +56,33 @@ public final class BlockVector3Imp extends BlockVector3 { } @Override - public final int getX() { + public int x() { return x; } @Override - public final int getY() { + public int y() { return y; } @Override - public final int getZ() { + public int z() { return z; } @Override public int hashCode() { - return (getX() ^ (getZ() << 12)) ^ (getY() << 24); + return (x() ^ (z() << 12)) ^ (y() << 24); } @Override - public final BlockVector3 toImmutable() { + public BlockVector3 toImmutable() { return this; } @Override public String toString() { - return "(" + getX() + ", " + getY() + ", " + getZ() + ")"; + return "(" + x() + ", " + y() + ", " + z() + ")"; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java index d680b0c0d..9d08676f9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java @@ -19,12 +19,13 @@ package com.sk89q.worldedit.math; +import com.fastasyncworldedit.core.util.MathMan; import com.sk89q.worldedit.math.transform.AffineTransform; /** * An immutable 2-dimensional vector. */ -public final class Vector2 { +public record Vector2(double x, double z) { public static final Vector2 ZERO = new Vector2(0, 0); public static final Vector2 UNIT_X = new Vector2(1, 0); @@ -50,29 +51,27 @@ public final class Vector2 { return new Vector2(x, z); } - private final double x; - private final double z; - - /** - * Construct an instance. - * - * @param x the X coordinate - * @param z the Z coordinate - */ - private Vector2(double x, double z) { - this.x = x; - this.z = z; - } - /** * Get the X coordinate. * * @return the x coordinate + * @deprecated use {@link #x()} instead */ + @Deprecated(forRemoval = true, since = "TODO") public double getX() { return x; } + /** + * Get the X coordinate, aligned to the block grid. + * + * @return the block-aligned x coordinate + * @since TODO + */ + public int blockX() { + return MathMan.roundInt(x); + } + /** * Set the X coordinate. * @@ -83,11 +82,23 @@ public final class Vector2 { return Vector2.at(x, z); } + /** + * Get the Z coordinate, aligned to the block grid. + * + * @return the block-aligned z coordinate + * @since TODO + */ + public int blockZ() { + return MathMan.roundInt(z); + } + /** * Get the Z coordinate. * * @return the z coordinate + * @deprecated use {@link #z()} instead */ + @Deprecated(forRemoval = true, since = "TODO") public double getZ() { return z; } @@ -458,24 +469,6 @@ public final class Vector2 { return Vector3.at(x, y, z); } - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Vector2)) { - return false; - } - - Vector2 other = (Vector2) obj; - return other.x == this.x && other.z == this.z; - - } - - @Override - public int hashCode() { - //FAWE start - XOR over x z calc - return (int) x << 16 ^ (int) z; - //FAWE end - } - @Override public String toString() { return "(" + x + ", " + z + ")"; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java index 5a4d550b4..898bb5241 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java @@ -32,7 +32,9 @@ import static com.google.common.base.Preconditions.checkArgument; /** * An immutable 3-dimensional vector. */ +//FAWE start - not a record, make abstract public abstract class Vector3 { +//FAWE end public static final Vector3 ZERO = Vector3.at(0, 0, 0); public static final Vector3 UNIT_X = Vector3.at(1, 0, 0); @@ -69,9 +71,9 @@ public abstract class Vector3 { private static final Comparator YZX_ORDER = (a, b) -> { return ComparisonChain.start() - .compare(a.getY(), b.getY()) - .compare(a.getZ(), b.getZ()) - .compare(a.getX(), b.getX()) + .compare(a.y(), b.y()) + .compare(a.z(), b.z()) + .compare(a.x(), b.x()) .result(); }; @@ -96,7 +98,7 @@ public abstract class Vector3 { * @return the x coordinate */ public int getBlockX() { - return MathMan.roundInt(getX()); + return MathMan.roundInt(x()); } /** @@ -105,7 +107,7 @@ public abstract class Vector3 { * @return the y coordinate */ public int getBlockY() { - return MathMan.roundInt(getY()); + return MathMan.roundInt(y()); } /** @@ -114,7 +116,7 @@ public abstract class Vector3 { * @return the z coordinate */ public int getBlockZ() { - return MathMan.roundInt(getZ()); + return MathMan.roundInt(z()); } public MutableVector3 setComponents(Vector3 other) { @@ -130,27 +132,27 @@ public abstract class Vector3 { } public MutableVector3 mutX(int x) { - return new MutableVector3(x, getY(), getZ()); + return new MutableVector3(x, y(), z()); } public MutableVector3 mutX(double x) { - return new MutableVector3(x, getY(), getZ()); + return new MutableVector3(x, y(), z()); } public MutableVector3 mutY(int y) { - return new MutableVector3(getX(), y, getZ()); + return new MutableVector3(x(), y, z()); } public MutableVector3 mutY(double y) { - return new MutableVector3(getX(), y, getZ()); + return new MutableVector3(x(), y, z()); } public MutableVector3 mutZ(int z) { - return new MutableVector3(getX(), getY(), z); + return new MutableVector3(x(), y(), z); } public MutableVector3 mutZ(double z) { - return new MutableVector3(getX(), getY(), z); + return new MutableVector3(x(), y(), z); } //FAWE end @@ -158,10 +160,29 @@ public abstract class Vector3 { * Get the X coordinate. * * @return the x coordinate + * @since TODO */ - //FAWE start - made abstract - public abstract double getX(); - //FAWE end + public abstract double x(); + + /** + * Get the X coordinate, aligned to the block grid. + * + * @return the block-aligned x coordinate + */ + public int blockX() { + return MathMan.roundInt(this.x()); + } + + /** + * Get the X coordinate. + * + * @return the x coordinate + * @deprecated use {@link #x()} instead + */ + @Deprecated(forRemoval = true, since = "TODO") + public double getX() { + return this.x(); + } /** * Set the X coordinate. @@ -171,18 +192,38 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 withX(double x) { - return Vector3.at(x, getY(), getZ()); + return Vector3.at(x, y(), z()); } //FAWE end + /** * Get the Y coordinate. * * @return the y coordinate + * @since TODO */ - //FAWE start - made abstract - public abstract double getY(); - //FAWE end + public abstract double y(); + + /** + * Get the Y coordinate, aligned to the block grid. + * + * @return the block-aligned y coordinate + */ + public int blockY() { + return MathMan.roundInt(this.y()); + } + + /** + * Get the Y coordinate. + * + * @return the y coordinate + * @deprecated use {@link #y()} instead + */ + @Deprecated(forRemoval = true, since = "TODO") + public double getY() { + return this.y(); + } /** * Set the Y coordinate. @@ -192,7 +233,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 withY(double y) { - return Vector3.at(getX(), y, getZ()); + return Vector3.at(x(), y, z()); } //FAWE end @@ -200,10 +241,29 @@ public abstract class Vector3 { * Get the Z coordinate. * * @return the z coordinate + * @since TODO */ - //FAWE start - made abstract - public abstract double getZ(); - //FAWE end + public abstract double z(); + + /** + * Get the Z coordinate, aligned to the block grid. + * + * @return the block-aligned z coordinate + */ + public int blockZ() { + return MathMan.roundInt(this.z()); + } + + /** + * Get the Z coordinate. + * + * @return the z coordinate + * @deprecated use {@link #z()} instead + */ + @Deprecated(forRemoval = true, since = "TODO") + public double getZ() { + return this.z(); + } /** * Set the Z coordinate. @@ -213,7 +273,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 withZ(double z) { - return Vector3.at(getX(), getY(), z); + return Vector3.at(x(), y(), z); } //FAWE end @@ -225,7 +285,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 add(Vector3 other) { - return add(other.getX(), other.getY(), other.getZ()); + return add(other.x(), other.y(), other.z()); } //FAWE end @@ -239,7 +299,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 add(double x, double y, double z) { - return Vector3.at(this.getX() + x, this.getY() + y, this.getZ() + z); + return Vector3.at(this.x() + x, this.y() + y, this.z() + z); } //FAWE end @@ -252,14 +312,14 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 add(Vector3... others) { - double newX = getX(); - double newY = getY(); - double newZ = getZ(); + double newX = x(); + double newY = y(); + double newZ = z(); for (Vector3 other : others) { - newX += other.getX(); - newY += other.getY(); - newZ += other.getZ(); + newX += other.x(); + newY += other.y(); + newZ += other.z(); } return Vector3.at(newX, newY, newZ); @@ -275,7 +335,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 subtract(Vector3 other) { - return subtract(other.getX(), other.getY(), other.getZ()); + return subtract(other.x(), other.y(), other.z()); } //FAWE end @@ -290,7 +350,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 subtract(double x, double y, double z) { - return Vector3.at(this.getX() - x, this.getY() - y, this.getZ() - z); + return Vector3.at(this.x() - x, this.y() - y, this.z() - z); } //FAWE end @@ -303,14 +363,14 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 subtract(Vector3... others) { - double newX = getX(); - double newY = getY(); - double newZ = getZ(); + double newX = x(); + double newY = y(); + double newZ = z(); for (Vector3 other : others) { - newX -= other.getX(); - newY -= other.getY(); - newZ -= other.getZ(); + newX -= other.x(); + newY -= other.y(); + newZ -= other.z(); } return Vector3.at(newX, newY, newZ); @@ -325,7 +385,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 multiply(Vector3 other) { - return multiply(other.getX(), other.getY(), other.getZ()); + return multiply(other.x(), other.y(), other.z()); } //FAWE end @@ -339,7 +399,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 multiply(double x, double y, double z) { - return Vector3.at(this.getX() * x, this.getY() * y, this.getZ() * z); + return Vector3.at(this.x() * x, this.y() * y, this.z() * z); } //FAWE end @@ -351,14 +411,14 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 multiply(Vector3... others) { - double newX = getX(); - double newY = getY(); - double newZ = getZ(); + double newX = x(); + double newY = y(); + double newZ = z(); for (Vector3 other : others) { - newX *= other.getX(); - newY *= other.getY(); - newZ *= other.getZ(); + newX *= other.x(); + newY *= other.y(); + newZ *= other.z(); } return Vector3.at(newX, newY, newZ); @@ -383,7 +443,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 divide(Vector3 other) { - return divide(other.getX(), other.getY(), other.getZ()); + return divide(other.x(), other.y(), other.z()); } //FAWE end @@ -397,7 +457,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 divide(double x, double y, double z) { - return Vector3.at(this.getX() / x, this.getY() / y, this.getZ() / z); + return Vector3.at(this.x() / x, this.y() / y, this.z() / z); } //FAWE end @@ -427,7 +487,7 @@ public abstract class Vector3 { */ //FAWE start - getter public double lengthSq() { - return getX() * getX() + getY() * getY() + getZ() * getZ(); + return x() * x() + y() * y() + z() * z(); } //FAWE end @@ -449,9 +509,9 @@ public abstract class Vector3 { */ //FAWE start - getter public double distanceSq(Vector3 other) { - double dx = other.getX() - getX(); - double dy = other.getY() - getY(); - double dz = other.getZ() - getZ(); + double dx = other.x() - x(); + double dy = other.y() - y(); + double dz = other.z() - z(); return dx * dx + dy * dy + dz * dz; } //FAWE end @@ -474,7 +534,7 @@ public abstract class Vector3 { */ //FAWE start - getter public double dot(Vector3 other) { - return getX() * other.getX() + getY() * other.getY() + getZ() * other.getZ(); + return x() * other.x() + y() * other.y() + z() * other.z(); } //FAWE end @@ -487,9 +547,9 @@ public abstract class Vector3 { //FAWE start - getter public Vector3 cross(Vector3 other) { return Vector3.at( - getY() * other.getZ() - getZ() * other.getY(), - getZ() * other.getX() - getX() * other.getZ(), - getX() * other.getY() - getY() * other.getX() + y() * other.z() - z() * other.y(), + z() * other.x() - x() * other.z(), + x() * other.y() - y() * other.x() ); } //FAWE end @@ -503,8 +563,7 @@ public abstract class Vector3 { */ //FAWE start - getter public boolean containedWithin(Vector3 min, Vector3 max) { - return getX() >= min.getX() && getX() <= max.getX() && getY() >= min.getY() && getY() <= max.getY() && getZ() >= min.getZ() && getZ() <= max - .getZ(); + return x() >= min.x() && x() <= max.x() && y() >= min.y() && y() <= max.y() && z() >= min.z() && z() <= max.z(); } //FAWE end @@ -518,11 +577,11 @@ public abstract class Vector3 { //FAWE start - getter public Vector3 clampY(int min, int max) { checkArgument(min <= max, "minimum cannot be greater than maximum"); - if (getY() < min) { - return Vector3.at(getX(), min, getZ()); + if (y() < min) { + return Vector3.at(x(), min, z()); } - if (getY() > max) { - return Vector3.at(getX(), max, getZ()); + if (y() > max) { + return Vector3.at(x(), max, z()); } return this; } @@ -535,7 +594,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 floor() { - return Vector3.at(Math.floor(getX()), Math.floor(getY()), Math.floor(getZ())); + return Vector3.at(Math.floor(x()), Math.floor(y()), Math.floor(z())); } //FAWE end @@ -546,7 +605,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 ceil() { - return Vector3.at(Math.ceil(getX()), Math.ceil(getY()), Math.ceil(getZ())); + return Vector3.at(Math.ceil(x()), Math.ceil(y()), Math.ceil(z())); } //FAWE end @@ -559,7 +618,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 round() { - return Vector3.at(Math.floor(getX() + 0.5), Math.floor(getY() + 0.5), Math.floor(getZ() + 0.5)); + return Vector3.at(Math.floor(x() + 0.5), Math.floor(y() + 0.5), Math.floor(z() + 0.5)); } //FAWE end @@ -570,7 +629,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 roundHalfUp() { - return Vector3.at(MathUtils.roundHalfUp(getX()), MathUtils.roundHalfUp(getY()), MathUtils.roundHalfUp(getZ())); + return Vector3.at(MathUtils.roundHalfUp(x()), MathUtils.roundHalfUp(y()), MathUtils.roundHalfUp(z())); } //FAWE end @@ -582,7 +641,7 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector3 abs() { - return Vector3.at(Math.abs(getX()), Math.abs(getY()), Math.abs(getZ())); + return Vector3.at(Math.abs(x()), Math.abs(y()), Math.abs(z())); } //FAWE end @@ -600,8 +659,8 @@ public abstract class Vector3 { //FAWE start - getter public Vector3 transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) { angle = Math.toRadians(angle); - double x = this.getX() - aboutX; - double z = this.getZ() - aboutZ; + double x = this.x() - aboutX; + double z = this.z() - aboutZ; double cos = Math.cos(angle); double sin = Math.sin(angle); double x2 = x * cos - z * sin; @@ -609,7 +668,7 @@ public abstract class Vector3 { return Vector3.at( x2 + aboutX + translateX, - getY(), + y(), z2 + aboutZ + translateZ ); } @@ -621,16 +680,16 @@ public abstract class Vector3 { * @return pitch in radians */ public double toPitch() { - double x = getX(); - double z = getZ(); + double x = x(); + double z = z(); if (x == 0 && z == 0) { - return getY() > 0 ? -90 : 90; + return y() > 0 ? -90 : 90; } else { double x2 = x * x; double z2 = z * z; double xz = Math.sqrt(x2 + z2); - return Math.toDegrees(Math.atan(-getY() / xz)); + return Math.toDegrees(Math.atan(-y() / xz)); } } @@ -640,8 +699,8 @@ public abstract class Vector3 { * @return yaw in radians */ public double toYaw() { - double x = getX(); - double z = getZ(); + double x = x(); + double z = z(); double t = Math.atan2(-x, z); double tau = 2 * Math.PI; @@ -658,9 +717,9 @@ public abstract class Vector3 { //FAWE start - getter public Vector3 getMinimum(Vector3 v2) { return Vector3.at( - Math.min(getX(), v2.getX()), - Math.min(getY(), v2.getY()), - Math.min(getZ(), v2.getZ()) + Math.min(x(), v2.x()), + Math.min(y(), v2.y()), + Math.min(z(), v2.z()) ); } //FAWE end @@ -674,9 +733,9 @@ public abstract class Vector3 { //FAWE start - getter public Vector3 getMaximum(Vector3 v2) { return Vector3.at( - Math.max(getX(), v2.getX()), - Math.max(getY(), v2.getY()), - Math.max(getZ(), v2.getZ()) + Math.max(x(), v2.x()), + Math.max(y(), v2.y()), + Math.max(z(), v2.z()) ); } //FAWE end @@ -700,7 +759,7 @@ public abstract class Vector3 { */ //FAWE start - getter public BlockVector3 toBlockPoint() { - return toBlockPoint(getX(), getY(), getZ()); + return toBlockPoint(x(), y(), z()); } //FAWE end @@ -711,24 +770,20 @@ public abstract class Vector3 { */ //FAWE start - getter public Vector2 toVector2() { - return Vector2.at(getX(), getZ()); + return Vector2.at(x(), z()); } //FAWE end + //FAWE start - not a record, need own implementations @Override public boolean equals(Object obj) { - if (!(obj instanceof Vector3)) { + if (!(obj instanceof final Vector3 other)) { return false; } - Vector3 other = (Vector3) obj; - //FAWE start - getter - return other.getX() == this.getX() && other.getY() == this.getY() && other.getZ() == this.getZ(); - //FAWE end + return other.x() == this.x() && other.y() == this.y() && other.z() == this.z(); } - //FAWE start - /** * Tests if vectors are equal, accounting for floating point errors * @@ -741,28 +796,27 @@ public abstract class Vector3 { } // Minecraft deals in whole blocks, thus any difference smaller than this is unnecessary - if (Math.abs(getX() - other.getX()) > 0.000001d) { + if (Math.abs(x() - other.x()) > 0.000001d) { return false; } - if (Math.abs(getY() - other.getY()) > 0.000001d) { + if (Math.abs(y() - other.y()) > 0.000001d) { return false; } - return !(Math.abs(getZ() - other.getZ()) > 0.000001d); + return !(Math.abs(z() - other.z()) > 0.000001d); + } + + @Override + public int hashCode() { + return (int) x() ^ (int) z() << 12 ^ (int) y() << 24; } //FAWE end - @Override - //FAWE start - XOR over get calculating all values independently - public int hashCode() { - return (int) getX() ^ (int) getZ() << 12 ^ (int) getY() << 24; - } - @Override public String toString() { //FAWE start - getter & ternary - String x = (getX() == getBlockX() ? "" + getBlockX() : "" + getX()); - String y = (getY() == getBlockY() ? "" + getBlockY() : "" + getY()); - String z = (getZ() == getBlockZ() ? "" + getBlockZ() : "" + getZ()); + String x = (x() == blockX() ? "" + blockX() : "" + x()); + String y = (y() == blockY() ? "" + blockY() : "" + y()); + String z = (z() == blockZ() ? "" + blockZ() : "" + z()); //FAWE end return "(" + x + ", " + y + ", " + z + ")"; } @@ -774,7 +828,7 @@ public abstract class Vector3 { */ //FAWE start - getter public String toParserString() { - return getX() + "," + getY() + "," + getZ(); + return x() + "," + y() + "," + z(); } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/Location.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/Location.java index 3a3cd6fb8..52c1a3e62 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/Location.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/Location.java @@ -302,11 +302,11 @@ public class Location extends Vector3Impl { @Override public Location clampY(int min, int max) { checkArgument(min <= max, "minimum cannot be greater than maximum"); - if (getY() < min) { - return new Location(extent, getX(), min, getZ()); + if (y() < min) { + return new Location(extent, x(), min, z()); } - if (getY() > max) { - return new Location(extent, getX(), max, getZ()); + if (y() > max) { + return new Location(extent, x(), max, z()); } return this; @@ -331,13 +331,13 @@ public class Location extends Vector3Impl { return false; } //FAWE start - if (this.getX() != location.getX()) { + if (this.x() != location.x()) { return false; } - if (this.getZ() != location.getZ()) { + if (this.z() != location.z()) { return false; } - if (this.getY() != location.getY()) { + if (this.y() != location.y()) { return false; } return extent.equals(location.extent); From 5225dddaa6dd58d3b854a1a83964640f431cc3d0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 00:23:10 +0000 Subject: [PATCH 137/220] Update dependency paperweight-userdev to v1.20.6-R0.1-20240526.222003-87 --- worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts index 80c044f91..8f97a8454 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/ - the().paperDevBundle("1.20.6-R0.1-20240523.202134-70") + the().paperDevBundle("1.20.6-R0.1-20240526.222003-87") compileOnly(libs.paperlib) } From df92febf7b911d49f4c2ce53a16c6c200a36d001 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 00:23:05 +0000 Subject: [PATCH 138/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.2.11 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 639b7b010..6d7a9bd85 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.2.9" +towny = "0.100.2.11" plotsquared = "7.3.8" # Third party From e9866fb4d7ed7fb8103df1b6e18d3f387f74411f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 03:21:30 +0000 Subject: [PATCH 139/220] Update dependency commons-cli:commons-cli to v1.8.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6d7a9bd85..38f8f3f32 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -35,7 +35,7 @@ jlibnoise = "1.0.0" jchronic = "0.2.4a" lz4-java = "1.8.0" lz4-stream = "1.0.0" -commons-cli = "1.7.0" +commons-cli = "1.8.0" paperlib = "1.0.8" paster = "1.1.6" vault = "1.7.1" From 73186856131c51244a0e1c00d89e6fe2d1ccc6c4 Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Mon, 27 May 2024 21:32:09 +0200 Subject: [PATCH 140/220] fix: ClassCastException on spigot (#2751) fix: ClassCastException on spigot due to method change --- .../impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java index 128897111..4f934129e 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java @@ -345,10 +345,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { .getChunkSource() .getChunkAtIfLoadedImmediately(chunkX, chunkZ); } else { - levelChunk = ((Optional) ((Either) chunkHolder - .getTickingChunkFuture() // method is not present with new paper chunk system - .getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left()) - .orElse(null); + levelChunk = chunkHolder.getTickingChunkFuture() + .getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK).orElse(null); } if (levelChunk == null) { return; From 36d2c85fdb850fa6b20ba0d12d2cee4a757e05cb Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Mon, 27 May 2024 18:48:46 +0100 Subject: [PATCH 141/220] chore: address deprecations in vector classes --- .../ext/fawe/v1_19_R3/PaperweightAdapter.java | 17 +- .../fawe/v1_19_R3/PaperweightFaweAdapter.java | 2 +- .../fawe/v1_19_R3/PaperweightGetBlocks.java | 6 +- .../ext/fawe/v1_20_R1/PaperweightAdapter.java | 16 +- .../fawe/v1_20_R1/PaperweightFaweAdapter.java | 2 +- .../fawe/v1_20_R1/PaperweightGetBlocks.java | 6 +- .../ext/fawe/v1_20_R2/PaperweightAdapter.java | 16 +- .../fawe/v1_20_R2/PaperweightFaweAdapter.java | 2 +- .../fawe/v1_20_R2/PaperweightGetBlocks.java | 6 +- .../ext.fawe/v1_20_R3/PaperweightAdapter.java | 16 +- .../fawe/v1_20_R3/PaperweightFaweAdapter.java | 2 +- .../fawe/v1_20_R3/PaperweightGetBlocks.java | 6 +- .../ext.fawe/v1_20_R4/PaperweightAdapter.java | 16 +- .../fawe/v1_20_R4/PaperweightFaweAdapter.java | 2 +- .../fawe/v1_20_R4/PaperweightGetBlocks.java | 6 +- .../bukkit/adapter/IBukkitAdapter.java | 4 +- .../bukkit/adapter/Regenerator.java | 24 +- .../bukkit/regions/WorldGuardFeature.java | 2 +- .../FaweDelegateSchematicHandler.java | 18 +- .../plotsquared/PlotSquaredFeature.java | 4 +- .../sk89q/worldedit/bukkit/BukkitAdapter.java | 8 +- .../sk89q/worldedit/bukkit/BukkitPlayer.java | 8 +- .../sk89q/worldedit/bukkit/BukkitWorld.java | 30 +-- .../com/fastasyncworldedit/core/FaweAPI.java | 8 +- .../core/command/tool/brush/BlendBall.java | 6 +- .../command/tool/brush/CatenaryBrush.java | 6 +- .../core/command/tool/brush/CommandBrush.java | 6 +- .../command/tool/brush/CopyPastaBrush.java | 4 +- .../core/command/tool/brush/ErodeBrush.java | 20 +- .../command/tool/brush/FallingSphere.java | 6 +- .../core/command/tool/brush/InspectBrush.java | 8 +- .../core/command/tool/brush/RecurseBrush.java | 4 +- .../core/command/tool/brush/RockBrush.java | 12 +- .../core/command/tool/brush/ScatterBrush.java | 8 +- .../command/tool/brush/ScatterCommand.java | 6 +- .../tool/brush/ScatterOverlayBrush.java | 8 +- .../core/command/tool/brush/ShatterBrush.java | 12 +- .../core/command/tool/brush/SplineBrush.java | 6 +- .../command/tool/brush/SurfaceSpline.java | 20 +- .../command/tool/sweep/ClipboardSpline.java | 10 +- .../core/command/tool/sweep/Spline.java | 4 +- .../core/command/tool/sweep/SweepBrush.java | 4 +- .../core/database/RollbackDatabase.java | 36 +-- .../core/extent/BlockTranslateExtent.java | 4 +- .../core/extent/FaweRegionExtent.java | 10 +- .../core/extent/HistoryExtent.java | 4 +- .../core/extent/LimitExtent.java | 4 +- .../core/extent/PositionTransformExtent.java | 28 +-- .../core/extent/ProcessedWEExtent.java | 4 +- .../core/extent/SourceMaskExtent.java | 4 +- .../core/extent/TemporalExtent.java | 6 +- .../core/extent/TransformExtent.java | 30 +-- .../clipboard/CPUOptimizedClipboard.java | 4 +- .../clipboard/DiskOptimizedClipboard.java | 22 +- .../clipboard/MemoryOptimizedClipboard.java | 4 +- .../extent/clipboard/SimpleClipboard.java | 6 +- .../extent/clipboard/WorldCopyClipboard.java | 2 +- .../clipboard/io/FastSchematicReader.java | 4 +- .../clipboard/io/FastSchematicWriter.java | 24 +- .../io/schematic/MinecraftStructure.java | 6 +- .../clipboard/io/schematic/PNGWriter.java | 6 +- .../core/extent/filter/ArrayImageMask.java | 2 +- .../block/AbstractSingleFilterBlock.java | 6 +- .../EntityInBlockRemovingProcessor.java | 6 +- .../processor/lighting/NMSRelighter.java | 58 ++--- .../extent/transform/OffsetTransform.java | 12 +- .../transform/RandomOffsetTransform.java | 12 +- .../core/extent/transform/ScaleTransform.java | 64 ++--- .../extent/transform/SelectTransform.java | 4 +- .../core/function/SurfaceRegionFunction.java | 4 +- .../core/function/block/BiomeCopy.java | 10 +- .../core/function/generator/CavesGen.java | 4 +- .../core/function/generator/GenBase.java | 4 +- .../core/function/generator/SchemGen.java | 2 +- .../core/function/mask/AdjacentAnyMask.java | 6 +- .../core/function/mask/AdjacentMask.java | 6 +- .../core/function/mask/AngleMask.java | 18 +- .../core/function/mask/CachedMask.java | 12 +- .../core/function/mask/ImageBrushMask.java | 14 +- .../core/function/mask/LayerBrushMask.java | 18 +- .../core/function/mask/PlaneMask.java | 18 +- .../core/function/mask/RadiusMask.java | 6 +- .../core/function/mask/SimplexMask.java | 2 +- .../core/function/mask/StencilBrushMask.java | 12 +- .../core/function/mask/SurfaceAngleMask.java | 14 +- .../core/function/mask/WallMakeMask.java | 4 +- .../core/function/mask/WallMask.java | 6 +- .../core/function/mask/XAxisMask.java | 4 +- .../core/function/mask/YAxisMask.java | 4 +- .../core/function/mask/ZAxisMask.java | 4 +- .../function/pattern/AngleColorPattern.java | 6 +- .../core/function/pattern/AnglePattern.java | 6 +- .../function/pattern/BufferedPattern2D.java | 2 +- .../function/pattern/ExpressionPattern.java | 2 +- .../pattern/Linear2DBlockPattern.java | 6 +- .../pattern/Linear3DBlockPattern.java | 8 +- .../core/function/pattern/NoXPattern.java | 8 +- .../core/function/pattern/NoYPattern.java | 8 +- .../core/function/pattern/NoZPattern.java | 9 +- .../core/function/pattern/OffsetPattern.java | 16 +- .../function/pattern/RandomOffsetPattern.java | 16 +- .../function/pattern/RelativePattern.java | 16 +- .../pattern/SolidRandomOffsetPattern.java | 18 +- .../pattern/SurfaceRandomOffsetPattern.java | 14 +- .../core/function/visitor/AboveVisitor.java | 2 +- .../core/function/visitor/DFSVisitor.java | 6 +- .../function/visitor/DirectionalVisitor.java | 12 +- .../history/RollbackOptimizedHistory.java | 12 +- .../history/changeset/AbstractChangeSet.java | 16 +- .../history/changeset/BlockBagChangeSet.java | 6 +- .../core/math/BlockVector3ChunkMap.java | 2 +- .../core/math/BlockVectorSet.java | 18 +- .../core/math/LocalBlockVectorSet.java | 12 +- .../core/math/heightmap/HeightMap.java | 13 +- .../math/heightmap/RotatableHeightMap.java | 2 +- .../math/heightmap/ScalableHeightMap.java | 16 +- .../math/random/SimplexNoiseGenerator.java | 4 +- .../core/queue/IChunkExtent.java | 14 +- .../core/queue/IChunkGet.java | 2 +- .../core/queue/IChunkSet.java | 2 +- .../core/queue/IQueueExtent.java | 2 +- .../implementation/ParallelQueueExtent.java | 6 +- .../SingleThreadQueueExtent.java | 2 +- .../implementation/blocks/CharSetBlocks.java | 4 +- .../blocks/ThreadUnsafeCharBlocks.java | 2 +- .../preloader/AsyncPreloader.java | 6 +- .../core/regions/FuzzyRegion.java | 4 +- .../core/regions/PolyhedralRegion.java | 18 +- .../core/regions/RegionWrapper.java | 24 +- .../core/regions/Triangle.java | 12 +- .../regions/filter/CuboidRegionFilter.java | 16 +- .../core/util/MainUtil.java | 6 +- .../core/util/WEManager.java | 4 +- .../core/util/collection/BlockSet.java | 6 +- .../core/util/collection/BlockVector3Set.java | 8 +- .../core/util/collection/MemBlockSet.java | 11 +- .../core/world/SimpleWorld.java | 4 +- .../core/wrappers/AsyncPlayer.java | 2 +- .../java/com/sk89q/util/yaml/YAMLNode.java | 20 +- .../java/com/sk89q/worldedit/EditSession.java | 220 +++++++++--------- .../worldedit/command/BrushCommands.java | 8 +- .../worldedit/command/ClipboardCommands.java | 12 +- .../command/FlattenedClipboardTransform.java | 12 +- .../worldedit/command/GenerationCommands.java | 22 +- .../worldedit/command/HistorySubCommands.java | 18 +- .../worldedit/command/RegionCommands.java | 14 +- .../worldedit/command/SelectionCommands.java | 24 +- .../worldedit/command/UtilityCommands.java | 13 +- .../command/argument/OffsetConverter.java | 6 +- .../worldedit/command/tool/BrushTool.java | 2 +- .../command/tool/brush/GravityBrush.java | 8 +- .../command/util/annotation/Confirm.java | 3 +- .../platform/AbstractPlayerActor.java | 8 +- .../com/sk89q/worldedit/extent/Extent.java | 20 +- .../sk89q/worldedit/extent/InputExtent.java | 14 +- .../sk89q/worldedit/extent/OutputExtent.java | 6 +- .../extent/clipboard/BlockArrayClipboard.java | 102 ++++---- .../worldedit/extent/clipboard/Clipboard.java | 28 +-- .../extent/clipboard/io/ClipboardWriter.java | 6 +- .../clipboard/io/SpongeSchematicReader.java | 8 +- .../clipboard/io/SpongeSchematicWriter.java | 24 +- .../extent/inventory/BlockBagExtent.java | 2 +- .../transform/BlockTransformExtent.java | 6 +- .../validation/DataValidatorExtent.java | 4 +- .../extent/world/SideEffectExtent.java | 2 +- .../function/biome/BiomeReplace.java | 2 +- .../function/biome/ExtentBiomeCopy.java | 2 +- .../function/block/SnowSimulator.java | 2 +- .../function/entity/ExtentEntityCopy.java | 12 +- .../function/factory/ApplyLayer.java | 4 +- .../worldedit/function/factory/Deform.java | 6 +- .../function/mask/BoundedHeightMask.java | 2 +- .../function/mask/ExpressionMask.java | 4 +- .../function/mask/ExpressionMask2D.java | 4 +- .../worldedit/function/mask/NoiseFilter.java | 2 +- .../worldedit/function/mask/OffsetMask.java | 2 +- .../worldedit/function/mask/OffsetMask2D.java | 4 +- .../operation/BackwardsExtentBlockCopy.java | 18 +- .../function/operation/ForwardExtentCopy.java | 28 +-- .../function/pattern/RandomPattern.java | 4 +- .../pattern/RepeatingExtentPattern.java | 6 +- .../function/visitor/BreadthFirstSearch.java | 14 +- .../function/visitor/DownwardVisitor.java | 4 +- .../function/visitor/RegionVisitor.java | 8 +- .../history/changeset/ArrayListHistory.java | 2 +- .../internal/anvil/ChunkDeleter.java | 22 +- .../internal/anvil/ChunkDeletionInfo.java | 2 +- .../internal/anvil/RegionAccess.java | 4 +- .../internal/cui/SelectionCylinderEvent.java | 10 +- .../cui/SelectionEllipsoidPointEvent.java | 6 +- .../internal/cui/SelectionPoint2DEvent.java | 16 +- .../internal/cui/SelectionPointEvent.java | 6 +- .../internal/cui/ServerCUIHandler.java | 16 +- .../util/RegionOptimizedVectorSorter.java | 6 +- .../internal/wna/WorldNativeAccess.java | 16 +- .../sk89q/worldedit/math/BlockVector2.java | 2 +- .../sk89q/worldedit/math/BlockVector3.java | 2 +- .../worldedit/math/convolution/HeightMap.java | 30 +-- .../math/convolution/SnowHeightMap.java | 16 +- .../KochanekBartelsInterpolation.java | 8 +- .../math/noise/JLibNoiseGenerator.java | 4 +- .../math/transform/AffineTransform.java | 24 +- .../worldedit/regions/AbstractFlatRegion.java | 4 +- .../worldedit/regions/AbstractRegion.java | 36 ++- .../sk89q/worldedit/regions/CuboidRegion.java | 210 ++++++++--------- .../worldedit/regions/CylinderRegion.java | 26 +-- .../worldedit/regions/EllipsoidRegion.java | 58 ++--- .../worldedit/regions/Polygonal2DRegion.java | 62 ++--- .../com/sk89q/worldedit/regions/Region.java | 18 +- .../worldedit/regions/RegionIntersection.java | 4 +- .../com/sk89q/worldedit/regions/Regions.java | 8 +- .../worldedit/regions/TransformRegion.java | 6 +- .../factory/CylinderRegionFactory.java | 4 +- .../iterator/FlatRegion3DIterator.java | 2 +- .../regions/iterator/FlatRegionIterator.java | 10 +- .../regions/iterator/RegionIterator.java | 16 +- .../ConvexPolyhedralRegionSelector.java | 4 +- .../selector/CylinderRegionSelector.java | 12 +- .../ExtendingCuboidRegionSelector.java | 12 +- .../selector/Polygonal2DRegionSelector.java | 14 +- .../selector/SphereRegionSelector.java | 6 +- .../regions/shape/ArbitraryBiomeShape.java | 18 +- .../regions/shape/ArbitraryShape.java | 18 +- .../com/sk89q/worldedit/util/Direction.java | 14 +- .../com/sk89q/worldedit/util/TargetBlock.java | 12 +- .../sk89q/worldedit/util/TreeGenerator.java | 10 +- .../worldedit/util/collection/BlockMap.java | 12 +- .../util/collection/VectorPositionList.java | 6 +- .../com/sk89q/worldedit/world/NullWorld.java | 2 +- .../worldedit/world/chunk/AnvilChunk.java | 12 +- .../worldedit/world/chunk/AnvilChunk13.java | 10 +- .../worldedit/world/chunk/AnvilChunk15.java | 6 +- .../worldedit/world/chunk/AnvilChunk17.java | 12 +- .../worldedit/world/chunk/AnvilChunk18.java | 14 +- .../sk89q/worldedit/world/chunk/OldChunk.java | 8 +- .../world/snapshot/SnapshotRestore.java | 8 +- .../experimental/SnapshotRestore.java | 8 +- .../worldedit/world/storage/ChunkStore.java | 2 +- .../world/storage/LegacyChunkStore.java | 8 +- .../world/storage/McRegionChunkStore.java | 4 +- .../world/storage/McRegionReader.java | 4 +- .../expression/RealExpressionTest.java | 2 +- .../util/RegionOptimizedVectorSorterTest.java | 10 +- .../sk89q/worldedit/util/LocationTest.java | 32 +-- 244 files changed, 1493 insertions(+), 1515 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java index 22c5a07b2..6d1038677 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java @@ -27,7 +27,6 @@ import com.google.common.collect.Sets; import com.google.common.util.concurrent.Futures; import com.mojang.datafixers.util.Either; import com.mojang.serialization.Lifecycle; -import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.NBTConstants; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseItem; @@ -531,7 +530,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) @@ -581,10 +580,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter>) - getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true)) + getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) .thenApply(either -> either.left().orElse(null)) ); } catch (IllegalAccessException | InvocationTargetException e) { @@ -797,7 +796,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter entry : tiles.entrySet()) { final CompoundTag nativeTag = entry.getValue(); final BlockVector3 blockHash = entry.getKey(); - final int x = blockHash.getX() + bx; - final int y = blockHash.getY(); - final int z = blockHash.getZ() + bz; + final int x = blockHash.x() + bx; + final int y = blockHash.y(); + final int z = blockHash.z() + bz; final BlockPos pos = new BlockPos(x, y, z); synchronized (nmsWorld) { diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java index b40c12b1a..6d7e28504 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java @@ -570,7 +570,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) @@ -631,10 +631,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter>) - getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true)) + getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) .thenApply(either -> either.left().orElse(null)) ); } catch (IllegalAccessException | InvocationTargetException e) { @@ -848,7 +848,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter entry : tiles.entrySet()) { final CompoundTag nativeTag = entry.getValue(); final BlockVector3 blockHash = entry.getKey(); - final int x = blockHash.getX() + bx; - final int y = blockHash.getY(); - final int z = blockHash.getZ() + bz; + final int x = blockHash.x() + bx; + final int y = blockHash.y(); + final int z = blockHash.z() + bz; final BlockPos pos = new BlockPos(x, y, z); synchronized (nmsWorld) { diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java index b73e6d06e..d8dafb8e5 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java @@ -530,7 +530,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) @@ -580,10 +580,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter>) - getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true)) + getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) .thenApply(either -> either.left().orElse(null)) ); } catch (IllegalAccessException | InvocationTargetException e) { @@ -797,7 +797,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter entry : tiles.entrySet()) { final CompoundTag nativeTag = entry.getValue(); final BlockVector3 blockHash = entry.getKey(); - final int x = blockHash.getX() + bx; - final int y = blockHash.getY(); - final int z = blockHash.getZ() + bz; + final int x = blockHash.x() + bx; + final int y = blockHash.y(); + final int z = blockHash.z() + bz; final BlockPos pos = new BlockPos(x, y, z); synchronized (nmsWorld) { diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java index 899c6e0c4..51b97b081 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java @@ -530,7 +530,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) @@ -580,10 +580,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter>) - getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true)) + getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) .thenApply(either -> either.left().orElse(null)) ); } catch (IllegalAccessException | InvocationTargetException e) { @@ -797,7 +797,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter entry : tiles.entrySet()) { final CompoundTag nativeTag = entry.getValue(); final BlockVector3 blockHash = entry.getKey(); - final int x = blockHash.getX() + bx; - final int y = blockHash.getY(); - final int z = blockHash.getZ() + bz; + final int x = blockHash.x() + bx; + final int y = blockHash.y(); + final int z = blockHash.z() + bz; final BlockPos pos = new BlockPos(x, y, z); synchronized (nmsWorld) { diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java index e629c4611..8218ec892 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java @@ -577,7 +577,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter>) - getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true)) + getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) .thenApply(either -> either.orElse(null)) ); } catch (IllegalAccessException | InvocationTargetException e) { @@ -874,7 +874,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter entry : tiles.entrySet()) { final CompoundTag nativeTag = entry.getValue(); final BlockVector3 blockHash = entry.getKey(); - final int x = blockHash.getX() + bx; - final int y = blockHash.getY(); - final int z = blockHash.getZ() + bz; + final int x = blockHash.x() + bx; + final int y = blockHash.y(); + final int z = blockHash.z() + bz; final BlockPos pos = new BlockPos(x, y, z); synchronized (nmsWorld) { diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java index 9792f9344..6ea8cad89 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java @@ -99,7 +99,7 @@ public interface IBukkitAdapter { checkNotNull(position); return new org.bukkit.Location( world, - position.getX(), position.getY(), position.getZ() + position.x(), position.y(), position.z() ); } @@ -119,7 +119,7 @@ public interface IBukkitAdapter { checkNotNull(location); return new org.bukkit.Location( world, - location.getX(), location.getY(), location.getZ(), + location.x(), location.y(), location.z(), location.getYaw(), location.getPitch() ); diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/Regenerator.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/Regenerator.java index 2a006d141..4afbe03a2 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/Regenerator.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/Regenerator.java @@ -354,7 +354,7 @@ public abstract class Regenerator> 4 << 4) - border * 16, - oldMin.getY(), - (oldMin.getZ() >> 4 << 4) - border * 16 + (oldMin.x() >> 4 << 4) - border * 16, + oldMin.y(), + (oldMin.z() >> 4 << 4) - border * 16 ); BlockVector3 oldMax = region.getMaximumPoint(); BlockVector3 newMax = BlockVector3.at( - (oldMax.getX() >> 4 << 4) + (border + 1) * 16 - 1, - oldMax.getY(), - (oldMax.getZ() >> 4 << 4) + (border + 1) * 16 - 1 + (oldMax.x() >> 4 << 4) + (border + 1) * 16 - 1, + oldMax.y(), + (oldMax.z() >> 4 << 4) + (border + 1) * 16 - 1 ); Region adjustedRegion = new CuboidRegion(newMin, newMax); return adjustedRegion.getChunks().stream() .sorted(Comparator - .comparingInt(BlockVector2::getZ) - .thenComparingInt(BlockVector2::getX)) //needed for RegionLimitedWorldAccess - .mapToLong(c -> MathMan.pairInt(c.getX(), c.getZ())) + .comparingInt(BlockVector2::z) + .thenComparingInt(BlockVector2::x)) //needed for RegionLimitedWorldAccess + .mapToLong(c -> MathMan.pairInt(c.x(), c.z())) .toArray(); } diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java index 1043d9a3e..c847a8688 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java @@ -56,7 +56,7 @@ public class WorldGuardFeature extends BukkitMaskManager implements Listener { if (region instanceof ProtectedPolygonalRegion casted) { BlockVector3 max = region.getMaximumPoint(); BlockVector3 min = region.getMinimumPoint(); - return new Polygonal2DRegion(null, casted.getPoints(), min.getBlockY(), max.getBlockY()); + return new Polygonal2DRegion(null, casted.getPoints(), min.y(), max.y()); } return new AdaptedRegion(region); } diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java index 6cf09da28..792f3937e 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java @@ -94,15 +94,15 @@ public class FaweDelegateSchematicHandler { return; } BlockVector3 dimension = schematic.getClipboard().getDimensions(); - final int WIDTH = dimension.getX(); - final int LENGTH = dimension.getZ(); - final int HEIGHT = dimension.getY(); + final int WIDTH = dimension.x(); + final int LENGTH = dimension.z(); + final int HEIGHT = dimension.y(); final int worldHeight = plot.getArea().getMaxGenHeight() - plot.getArea().getMinGenHeight() + 1; // Validate dimensions CuboidRegion region = plot.getLargestRegion(); boolean sizeMismatch = - ((region.getMaximumPoint().getX() - region.getMinimumPoint().getX() + xOffset + 1) < WIDTH) || ( - (region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ() + zOffset + 1) < LENGTH) || (HEIGHT + ((region.getMaximumPoint().x() - region.getMinimumPoint().x() + xOffset + 1) < WIDTH) || ( + (region.getMaximumPoint().z() - region.getMinimumPoint().z() + zOffset + 1) < LENGTH) || (HEIGHT > worldHeight); if (!Settings.Schematics.PASTE_MISMATCHES && sizeMismatch) { if (actor != null) { @@ -111,8 +111,8 @@ public class FaweDelegateSchematicHandler { TaskManager.runTask(whenDone); return; } - if (((region.getMaximumPoint().getX() - region.getMinimumPoint().getX() + xOffset + 1) < WIDTH) || ( - (region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ() + zOffset + 1) < LENGTH) || (HEIGHT + if (((region.getMaximumPoint().x() - region.getMinimumPoint().x() + xOffset + 1) < WIDTH) || ( + (region.getMaximumPoint().z() - region.getMinimumPoint().z() + zOffset + 1) < LENGTH) || (HEIGHT > worldHeight)) { if (whenDone != null) { TaskManager.runTask(whenDone); @@ -141,7 +141,7 @@ public class FaweDelegateSchematicHandler { } else { y_offset_actual = yOffset + pw.getMinBuildHeight() + editSession.getHighestTerrainBlock(region .getMinimumPoint() - .getX() + 1, region.getMinimumPoint().getZ() + 1, pw.getMinGenHeight(), pw.getMaxGenHeight() + .x() + 1, region.getMinimumPoint().z() + 1, pw.getMinGenHeight(), pw.getMaxGenHeight() ); } } @@ -150,7 +150,7 @@ public class FaweDelegateSchematicHandler { } final BlockVector3 to = BlockVector3 - .at(region.getMinimumPoint().getX() + xOffset, y_offset_actual, region.getMinimumPoint().getZ() + zOffset); + .at(region.getMinimumPoint().x() + xOffset, y_offset_actual, region.getMinimumPoint().z() + zOffset); final Clipboard clipboard = schematic.getClipboard(); clipboard.setOrigin(clipboard.getRegion().getMinimumPoint()); clipboard.paste(editSession, to, true, false, true); diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/PlotSquaredFeature.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/PlotSquaredFeature.java index e1ac20617..9f0916a4b 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/PlotSquaredFeature.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/PlotSquaredFeature.java @@ -159,8 +159,8 @@ public class PlotSquaredFeature extends FaweMaskManager { regions = WEManager.getMask(pp); if (regions.size() == 1) { CuboidRegion region = regions.iterator().next(); - if (region.getMinimumPoint().getX() == Integer.MIN_VALUE - && region.getMaximumPoint().getX() == Integer.MAX_VALUE) { + if (region.getMinimumPoint().x() == Integer.MIN_VALUE + && region.getMaximumPoint().x() == Integer.MAX_VALUE) { regions.clear(); } } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java index 41e7e7294..e0a643015 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitAdapter.java @@ -240,7 +240,7 @@ public enum BukkitAdapter { Vector3 position = location; return new org.bukkit.Location( adapt((World) location.getExtent()), - position.getX(), position.getY(), position.getZ(), + position.x(), position.y(), position.z(), location.getYaw(), location.getPitch() ); @@ -258,7 +258,7 @@ public enum BukkitAdapter { checkNotNull(position); return new org.bukkit.Location( world, - position.getX(), position.getY(), position.getZ() + position.x(), position.y(), position.z() ); } @@ -274,7 +274,7 @@ public enum BukkitAdapter { checkNotNull(position); return new org.bukkit.Location( world, - position.getX(), position.getY(), position.getZ() + position.x(), position.y(), position.z() ); } @@ -290,7 +290,7 @@ public enum BukkitAdapter { checkNotNull(location); return new org.bukkit.Location( world, - location.getX(), location.getY(), location.getZ(), + location.x(), location.y(), location.z(), location.getYaw(), location.getPitch() ); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index 9c5196e91..8a0081484 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -242,9 +242,9 @@ public class BukkitPlayer extends AbstractPlayerActor { //FAWE end return TaskManager.taskManager().sync(() -> player.teleport(new Location( finalWorld, - pos.getX(), - pos.getY(), - pos.getZ(), + pos.x(), + pos.y(), + pos.z(), yaw, pitch ))); @@ -422,7 +422,7 @@ public class BukkitPlayer extends AbstractPlayerActor { @Override public > void sendFakeBlock(BlockVector3 pos, B block) { - Location loc = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ()); + Location loc = new Location(player.getWorld(), pos.x(), pos.y(), pos.z()); if (block == null) { player.sendBlockChange(loc, player.getWorld().getBlockAt(loc).getBlockData()); } else { diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 1598cb547..b2fdeead9 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -247,7 +247,7 @@ public class BukkitWorld extends AbstractWorld { //FAWE start - safe edit region testCoords(pt); //FAWE end - return getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).getLightLevel(); + return getWorld().getBlockAt(pt.x(), pt.y(), pt.z()).getLightLevel(); } @Override @@ -284,7 +284,7 @@ public class BukkitWorld extends AbstractWorld { return false; } - Block block = getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); + Block block = getWorld().getBlockAt(pt.x(), pt.y(), pt.z()); BlockState state = PaperLib.getBlockState(block, false).getState(); if (!(state instanceof InventoryHolder)) { return false; @@ -363,8 +363,8 @@ public class BukkitWorld extends AbstractWorld { //FAWE end World world = getWorld(); //FAWE start - int X = pt.getBlockX() >> 4; - int Z = pt.getBlockZ() >> 4; + int X = pt.x() >> 4; + int Z = pt.z() >> 4; if (Fawe.isMainThread()) { world.getChunkAt(X, Z); } else if (PaperLib.isPaper()) { @@ -413,7 +413,7 @@ public class BukkitWorld extends AbstractWorld { public void fixAfterFastMode(Iterable chunks) { World world = getWorld(); for (BlockVector2 chunkPos : chunks) { - world.refreshChunk(chunkPos.getBlockX(), chunkPos.getBlockZ()); + world.refreshChunk(chunkPos.x(), chunkPos.z()); } } @@ -495,13 +495,13 @@ public class BukkitWorld extends AbstractWorld { //FAWE start - safe edit region testCoords(pt); //FAWE end - getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).breakNaturally(); + getWorld().getBlockAt(pt.x(), pt.y(), pt.z()).breakNaturally(); } //FAWE start @Override public Collection getBlockDrops(BlockVector3 position) { - return getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()).getDrops().stream() + return getWorld().getBlockAt(position.x(), position.y(), position.z()).getDrops().stream() .map(BukkitAdapter::adapt).collect(Collectors.toList()); } //FAWE end @@ -538,7 +538,7 @@ public class BukkitWorld extends AbstractWorld { } } if (WorldEditPlugin.getInstance().getLocalConfiguration().unsupportedVersionEditing) { - Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + Block bukkitBlock = getWorld().getBlockAt(position.x(), position.y(), position.z()); return BukkitAdapter.adapt(bukkitBlock.getBlockData()); } else { throw new RuntimeException(new UnsupportedVersionEditException()); @@ -562,7 +562,7 @@ public class BukkitWorld extends AbstractWorld { } } } - Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + Block bukkitBlock = getWorld().getBlockAt(position.x(), position.y(), position.z()); bukkitBlock.setBlockData(BukkitAdapter.adapt(block), sideEffects.doesApplyAny()); return true; } @@ -584,8 +584,8 @@ public class BukkitWorld extends AbstractWorld { if (!Settings.settings().REGION_RESTRICTIONS_OPTIONS.RESTRICT_TO_SAFE_RANGE) { return; } - int x = position.getX(); - int z = position.getZ(); + int x = position.x(); + int z = position.z(); if (x > 30000000 || z > 30000000 || x < -30000000 || z < -30000000) { throw FaweCache.OUTSIDE_SAFE_REGION; } @@ -636,9 +636,9 @@ public class BukkitWorld extends AbstractWorld { testCoords(position); //FAWE end if (HAS_3D_BIOMES) { - return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ())); + return BukkitAdapter.adapt(getWorld().getBiome(position.x(), position.y(), position.z())); } else { - return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockZ())); + return BukkitAdapter.adapt(getWorld().getBiome(position.x(), position.z())); } } @@ -649,9 +649,9 @@ public class BukkitWorld extends AbstractWorld { testCoords(position); //FAWE end if (HAS_3D_BIOMES) { - getWorld().setBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ(), BukkitAdapter.adapt(biome)); + getWorld().setBiome(position.x(), position.y(), position.z(), BukkitAdapter.adapt(biome)); } else { - getWorld().setBiome(position.getBlockX(), position.getBlockZ(), BukkitAdapter.adapt(biome)); + getWorld().setBiome(position.x(), position.z(), BukkitAdapter.adapt(biome)); } return true; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweAPI.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweAPI.java index 4c5339017..acc0d8bf3 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweAPI.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweAPI.java @@ -339,11 +339,11 @@ public class FaweAPI { final BlockVector3 bot = selection.getMinimumPoint(); final BlockVector3 top = selection.getMaximumPoint(); - final int minX = bot.getBlockX() >> 4; - final int minZ = bot.getBlockZ() >> 4; + final int minX = bot.x() >> 4; + final int minZ = bot.z() >> 4; - final int maxX = top.getBlockX() >> 4; - final int maxZ = top.getBlockZ() >> 4; + final int maxX = top.x() >> 4; + final int maxZ = top.z() >> 4; int count = 0; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/BlendBall.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/BlendBall.java index 902e48a9b..ec3e0766e 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/BlendBall.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/BlendBall.java @@ -50,9 +50,9 @@ public class BlendBall implements Brush { final int outsetSize = (int) (size + 1); double brushSizeSquared = size * size; - int tx = position.getBlockX(); - int ty = position.getBlockY(); - int tz = position.getBlockZ(); + int tx = position.x(); + int ty = position.y(); + int tz = position.z(); int[] frequency = new int[BlockTypes.size()]; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CatenaryBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CatenaryBrush.java index e380e74b0..7ad15cef4 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CatenaryBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CatenaryBrush.java @@ -81,9 +81,9 @@ public class CatenaryBrush implements Brush, ResettableTool { return pos1.add(pos2).divide(2).toBlockPoint(); } double curveLen = pos1.distance(pos2) * lenPercent; - double dy = pos2.getY() - pos1.getY(); - double dx = pos2.getX() - pos1.getX(); - double dz = pos2.getZ() - pos1.getZ(); + double dy = pos2.y() - pos1.y(); + double dx = pos2.x() - pos1.x(); + double dz = pos2.z() - pos1.z(); double dh = Math.sqrt(dx * dx + dz * dz); double g = Math.sqrt(curveLen * curveLen - dy * dy) / 2; double a = 0.00001; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CommandBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CommandBrush.java index 227960c1d..b71578b55 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CommandBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CommandBrush.java @@ -54,9 +54,9 @@ public class CommandBrush implements Brush { position.subtract(radius, radius, radius), position.add(radius, radius, radius) ); - String replaced = command.replace("{x}", Integer.toString(position.getBlockX())) - .replace("{y}", Integer.toString(position.getBlockY())) - .replace("{z}", Integer.toString(position.getBlockZ())) + String replaced = command.replace("{x}", Integer.toString(position.x())) + .replace("{y}", Integer.toString(position.y())) + .replace("{z}", Integer.toString(position.z())) .replace("{world}", editSession.getWorld().getName()) .replace("{size}", Integer.toString(radius)); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CopyPastaBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CopyPastaBrush.java index 4aeb2daeb..b635c1e7d 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CopyPastaBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CopyPastaBrush.java @@ -65,11 +65,11 @@ public class CopyPastaBrush implements Brush, ResettableTool { mask = Masks.alwaysTrue(); } final ResizableClipboardBuilder builder = new ResizableClipboardBuilder(editSession.getWorld()); - final int minY = position.getBlockY(); + final int minY = position.y(); mask = new AbstractDelegateMask(mask) { @Override public boolean test(BlockVector3 vector) { - if (super.test(vector) && vector.getBlockY() >= minY) { + if (super.test(vector) && vector.y() >= minY) { BaseBlock block = editSession.getFullBlock(vector); if (!block.getBlockType().getMaterial().isAir()) { builder.add(vector, BlockTypes.AIR.getDefaultState().toBaseBlock(), block); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ErodeBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ErodeBrush.java index 21879751c..da52bf504 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ErodeBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ErodeBrush.java @@ -63,9 +63,9 @@ public class ErodeBrush implements Brush { Clipboard buffer1 = new CPUOptimizedClipboard(region); Clipboard buffer2 = new CPUOptimizedClipboard(region); - final int bx = target.getBlockX(); - final int by = target.getBlockY(); - final int bz = target.getBlockZ(); + final int bx = target.x(); + final int by = target.y(); + final int bz = target.z(); for (int x = -brushSize, relx = 0; x <= brushSize && relx < buffer1.getWidth(); x++, relx++) { int x0 = x + bx; @@ -106,7 +106,7 @@ public class ErodeBrush implements Brush { for (BlockVector3 pos : finalBuffer) { BlockState block = pos.getBlock(finalBuffer); - es.setBlock(pos.getX() + bx - brushSize, pos.getY() + by - brushSize, pos.getZ() + bz - brushSize, block); + es.setBlock(pos.x() + bx - brushSize, pos.y() + by - brushSize, pos.z() + bz - brushSize, block); } } @@ -139,9 +139,9 @@ public class ErodeBrush implements Brush { int highest = 1; for (BlockVector3 offs : FACES_TO_CHECK) { BaseBlock next = current.getFullBlock( - relx + offs.getBlockX(), - rely + offs.getBlockY(), - relz + offs.getBlockZ() + relx + offs.x(), + rely + offs.y(), + relz + offs.z() ); if (!next.getBlockType().getMaterial().isMovementBlocker()) { continue; @@ -190,9 +190,9 @@ public class ErodeBrush implements Brush { int total = 0; for (BlockVector3 offs : FACES_TO_CHECK) { BaseBlock next = current.getFullBlock( - relx + offs.getBlockX(), - rely + offs.getBlockY(), - relz + offs.getBlockZ() + relx + offs.x(), + rely + offs.y(), + relz + offs.z() ); if (next.getMaterial().isMovementBlocker()) { continue; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/FallingSphere.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/FallingSphere.java index fd720c54e..d54bbebb6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/FallingSphere.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/FallingSphere.java @@ -12,9 +12,9 @@ public class FallingSphere implements Brush { @Override public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException { - int px = position.getBlockX(); - int py = position.getBlockY(); - int pz = position.getBlockZ(); + int px = position.x(); + int py = position.y(); + int pz = position.z(); int maxY = editSession.getMaxY(); int minY = editSession.getMinY(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/InspectBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/InspectBrush.java index 5ad9b818a..1ef2a27fa 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/InspectBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/InspectBrush.java @@ -14,7 +14,6 @@ import com.sk89q.worldedit.command.tool.BrushTool; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Platform; -import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.util.Location; @@ -25,7 +24,6 @@ import com.sk89q.worldedit.util.formatting.text.event.HoverEvent; import com.sk89q.worldedit.util.formatting.text.format.TextColor; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BlockState; -import org.apache.logging.log4j.Logger; import java.io.IOException; import java.util.Iterator; @@ -80,9 +78,9 @@ public class InspectBrush extends BrushTool { return true; } BlockVector3 target = targetVector.toBlockPoint(); - final int x = target.getBlockX(); - final int y = target.getBlockY(); - final int z = target.getBlockZ(); + final int x = target.x(); + final int y = target.y(); + final int z = target.z(); World world = player.getWorld(); RollbackDatabase db = DBHandler.dbHandler().getDatabase(world); int count = 0; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/RecurseBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/RecurseBrush.java index 869d45150..f87fee30e 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/RecurseBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/RecurseBrush.java @@ -35,7 +35,7 @@ public record RecurseBrush(boolean dfs) implements Brush { DFSRecursiveVisitor visitor = new DFSRecursiveVisitor(mask, replace, Integer.MAX_VALUE, Integer.MAX_VALUE) { @Override public boolean isVisitable(BlockVector3 from, BlockVector3 to) { - int y = to.getBlockY(); + int y = to.y(); return y < maxY && radMask.test(to) && super.isVisitable(from, to); } }; @@ -45,7 +45,7 @@ public record RecurseBrush(boolean dfs) implements Brush { RecursiveVisitor visitor = new RecursiveVisitor(mask, replace, radius, editSession.getMinY(), editSession.getMaxY()) { @Override public boolean isVisitable(BlockVector3 from, BlockVector3 to) { - int y = to.getBlockY(); + int y = to.y(); return y < maxY && super.isVisitable(from, to); } }; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/RockBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/RockBrush.java index 4196a7e11..27937b836 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/RockBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/RockBrush.java @@ -19,15 +19,15 @@ public record RockBrush(double amplitude, double frequency, Vector3 radius) impl double seedY = ThreadLocalRandom.current().nextDouble(); double seedZ = ThreadLocalRandom.current().nextDouble(); - int px = position.getBlockX(); - int py = position.getBlockY(); - int pz = position.getBlockZ(); + int px = position.x(); + int py = position.y(); + int pz = position.z(); double distort = this.frequency / size; - double modX = 1D / radius.getX(); - double modY = 1D / radius.getY(); - double modZ = 1D / radius.getZ(); + double modX = 1D / radius.x(); + double modY = 1D / radius.y(); + double modZ = 1D / radius.z(); int radiusSqr = (int) (size * size); int sizeInt = (int) size * 2; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterBrush.java index e14d0c599..26cf07558 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterBrush.java @@ -67,15 +67,15 @@ public class ScatterBrush implements Brush { } BlockVector3 patternSize = pattern.size(); BlockVector3Set placed = BlockVector3Set.getAppropriateVectorSet(patternSize.add(distance, distance, distance)); - placed.setOffset(position.getX(), position.getY(), position.getZ()); + placed.setOffset(position.x(), position.y(), position.z()); int maxFails = 1000; for (int i = 0; i < count; i++) { int index = ThreadLocalRandom.current().nextInt(length); BlockVector3 pos = visited.get(index); if (pos != null && canApply(pos)) { - int x = pos.getBlockX(); - int y = pos.getBlockY(); - int z = pos.getBlockZ(); + int x = pos.x(); + int y = pos.y(); + int z = pos.z(); if (placed.containsRadius(x, y, z, distance)) { if (maxFails-- <= 0) { break; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterCommand.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterCommand.java index 1d7841355..9e2c16555 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterCommand.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterCommand.java @@ -45,9 +45,9 @@ public class ScatterCommand extends ScatterBrush { position.subtract(radius, radius, radius), position.add(radius, radius, radius) ); - String replaced = command.replace("{x}", Integer.toString(position.getBlockX())) - .replace("{y}", Integer.toString(position.getBlockY())) - .replace("{z}", Integer.toString(position.getBlockZ())) + String replaced = command.replace("{x}", Integer.toString(position.x())) + .replace("{y}", Integer.toString(position.y())) + .replace("{z}", Integer.toString(position.z())) .replace("{world}", editSession.getWorld().getName()) .replace("{size}", Integer.toString(radius)); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterOverlayBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterOverlayBrush.java index cd7ce9aaa..d6a991234 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterOverlayBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ScatterOverlayBrush.java @@ -16,9 +16,9 @@ public class ScatterOverlayBrush extends ScatterBrush { @Override public void apply(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pt, Pattern p, double size) throws MaxChangedBlocksException { - final int x = pt.getBlockX(); - final int y = pt.getBlockY(); - final int z = pt.getBlockZ(); + final int x = pt.x(); + final int y = pt.y(); + final int z = pt.z(); BlockVector3 dir = getDirection(pt); if (dir == null) { getDir: @@ -37,7 +37,7 @@ public class ScatterOverlayBrush extends ScatterBrush { return; } } - editSession.setBlock(x + dir.getBlockX(), y + dir.getBlockY(), z + dir.getBlockZ(), p); + editSession.setBlock(x + dir.x(), y + dir.y(), z + dir.z(), p); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ShatterBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ShatterBrush.java index 41b36e12c..196b71f50 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ShatterBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/ShatterBrush.java @@ -80,13 +80,13 @@ public class ShatterBrush extends ScatterBrush { } for (int i1 = 0; i1 < BreadthFirstSearch.DIAGONAL_DIRECTIONS.length; i1++) { BlockVector3 direction = BreadthFirstSearch.DIAGONAL_DIRECTIONS[i1]; - int x2 = x + direction.getBlockX(); - int y2 = y + direction.getBlockY(); - int z2 = z + direction.getBlockZ(); + int x2 = x + direction.x(); + int y2 = y + direction.y(); + int z2 = z + direction.z(); // Check boundary - int dx = position.getBlockX() - x2; - int dy = position.getBlockY() - y2; - int dz = position.getBlockZ() - z2; + int dx = position.x() - x2; + int dy = position.y() - y2; + int dz = position.z() - z2; int dSqr = (dx * dx) + (dy * dy) + (dz * dz); if (dSqr <= radius2) { BlockVector3 bv = mutable.setComponents(x2, y2, z2); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/SplineBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/SplineBrush.java index 55d8fd96a..e1fa38708 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/SplineBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/SplineBrush.java @@ -130,9 +130,9 @@ public class SplineBrush implements Brush, ResettableTool { private Vector3 getCentroid(Collection points) { MutableVector3 sum = new MutableVector3(); for (BlockVector3 p : points) { - sum.mutX(sum.getX() + p.getX()); - sum.mutY(sum.getY() + p.getY()); - sum.mutZ(sum.getZ() + p.getZ()); + sum.mutX(sum.x() + p.x()); + sum.mutY(sum.y() + p.y()); + sum.mutZ(sum.z() + p.z()); } return sum.multiply(1.0 / points.size()); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/SurfaceSpline.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/SurfaceSpline.java index f652c4f94..8c94e76ad 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/SurfaceSpline.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/SurfaceSpline.java @@ -38,16 +38,16 @@ public class SurfaceSpline implements Brush { int minY = editSession.getMinY(); if (path.isEmpty() || !pos.equals(path.get(path.size() - 1))) { int max = editSession.getNearestSurfaceTerrainBlock( - pos.getBlockX(), - pos.getBlockZ(), - pos.getBlockY(), + pos.x(), + pos.z(), + pos.y(), minY, maxY ); if (max == -1) { return; } - path.add(BlockVector3.at(pos.getBlockX(), max, pos.getBlockZ())); + path.add(BlockVector3.at(pos.x(), max, pos.z())); if (editSession.getActor() != null) { editSession.getActor().print(Caption.of("fawe.worldedit.brush.spline.primary.2")); } @@ -69,9 +69,9 @@ public class SurfaceSpline implements Brush { LocalBlockVectorSet vset = new LocalBlockVectorSet(); for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) { final Vector3 tipv = interpol.getPosition(loop); - final int tipx = MathMan.roundInt(tipv.getX()); - final int tipz = (int) tipv.getZ(); - int tipy = MathMan.roundInt(tipv.getY()); + final int tipx = MathMan.roundInt(tipv.x()); + final int tipz = (int) tipv.z(); + int tipy = MathMan.roundInt(tipv.y()); tipy = editSession.getNearestSurfaceTerrainBlock(tipx, tipz, tipy, minY, maxY, Integer.MIN_VALUE, Integer.MAX_VALUE); if (tipy == Integer.MIN_VALUE || tipy == Integer.MAX_VALUE) { continue; @@ -88,15 +88,15 @@ public class SurfaceSpline implements Brush { LocalBlockVectorSet newSet = new LocalBlockVectorSet(); final int ceilrad = (int) Math.ceil(radius); for (BlockVector3 v : vset) { - final int tipx = v.getBlockX(); - final int tipz = v.getBlockZ(); + final int tipx = v.x(); + final int tipz = v.z(); for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) { for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) { if (MathMan.hypot2(loopx - tipx, 0, loopz - tipz) <= radius2) { int y = editSession.getNearestSurfaceTerrainBlock( loopx, loopz, - v.getBlockY(), + v.y(), minY, maxY, Integer.MIN_VALUE, diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/sweep/ClipboardSpline.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/sweep/ClipboardSpline.java index 87f1495f5..281c78c74 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/sweep/ClipboardSpline.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/sweep/ClipboardSpline.java @@ -83,7 +83,7 @@ public class ClipboardSpline extends Spline { Region region = clipboard.getRegion(); BlockVector3 origin = clipboard.getOrigin(); // center = region.getCenter().setY(origin.getY() - 1); - center = region.getCenter().withY(origin.getY() - 1).toBlockPoint(); + center = region.getCenter().withY(origin.y() - 1).toBlockPoint(); this.centerOffset = center.subtract(center.round()); this.center = center.subtract(centerOffset); this.transform = transform; @@ -108,15 +108,15 @@ public class ClipboardSpline extends Spline { clipboardHolder.setTransform(transform); BlockVector3 functionOffset = target.subtract(clipboard.getOrigin()); - final int offX = functionOffset.getBlockX(); - final int offY = functionOffset.getBlockY(); - final int offZ = functionOffset.getBlockZ(); + final int offX = functionOffset.x(); + final int offY = functionOffset.y(); + final int offZ = functionOffset.z(); Operation operation = clipboardHolder .createPaste(editSession) .to(target) .ignoreAirBlocks(true) - .filter(v -> buffer.add(v.getBlockX() + offX, v.getBlockY() + offY, v.getBlockZ() + offZ)) + .filter(v -> buffer.add(v.x() + offX, v.y() + offY, v.z() + offZ)) .build(); Operations.completeLegacy(operation); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/sweep/Spline.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/sweep/Spline.java index 945c10f5a..872ec495e 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/sweep/Spline.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/sweep/Spline.java @@ -121,7 +121,7 @@ public abstract class Spline { * 2 dimensional "cross" product. cross2D(v1, v2) = |v1|*|v2|*sin(theta) or v1 X v2 taking Y to be 0 */ private double cross2D(Vector2 v1, Vector2 v2) { - return v1.getX() * v2.getZ() - v2.getX() * v1.getZ(); + return v1.x() * v2.z() - v2.x() * v1.z(); } /** @@ -144,7 +144,7 @@ public abstract class Spline { // Calculate rotation from spline Vector3 deriv = interpolation.get1stDerivative(position); - Vector2 deriv2D = Vector2.at(deriv.getX(), deriv.getZ()).normalize(); + Vector2 deriv2D = Vector2.at(deriv.x(), deriv.z()).normalize(); double angle = Math.toDegrees( -Math.atan2(cross2D(direction, deriv2D), direction.dot(deriv2D)) ); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/sweep/SweepBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/sweep/SweepBrush.java index fa4bb971c..603fb4302 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/sweep/SweepBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/sweep/SweepBrush.java @@ -79,13 +79,13 @@ public class SweepBrush implements Brush, ResettableTool { Clipboard clipboard = holder.getClipboard(); BlockVector3 dimensions = clipboard.getDimensions(); - double quality = Math.max(dimensions.getBlockX(), dimensions.getBlockZ()); + double quality = Math.max(dimensions.x(), dimensions.z()); AffineTransform transform = new AffineTransform(); ClipboardSpline spline = new ClipboardSpline(editSession, holder, interpol, transform, nodes.size()); - if (dimensions.getBlockX() > dimensions.getBlockZ()) { + if (dimensions.x() > dimensions.z()) { spline.setDirection(Vector2.at(0, 1)); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java index 1677521fe..f8207f2dc 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java @@ -179,13 +179,13 @@ public class RollbackDatabase extends AsyncNotifyQueue { } try (PreparedStatement stmt = connection.prepareStatement(stmtStr.formatted(this.prefix))) { stmt.setInt(1, (int) (minTime / 1000)); - stmt.setInt(2, pos1.getBlockX()); - stmt.setInt(3, pos2.getBlockX()); - stmt.setInt(4, pos1.getBlockZ()); - stmt.setInt(5, pos2.getBlockZ()); + stmt.setInt(2, pos1.x()); + stmt.setInt(3, pos2.x()); + stmt.setInt(4, pos1.z()); + stmt.setInt(5, pos2.z()); // Keep 128 offset for backwards-compatibility - stmt.setInt(6, pos1.getBlockY() - 128); - stmt.setInt(7, pos2.getBlockY() - 128); + stmt.setInt(6, pos1.y() - 128); + stmt.setInt(7, pos2.y() - 128); if (uuid != null) { byte[] uuidBytes = toBytes(uuid); stmt.setBytes(8, uuidBytes); @@ -210,13 +210,13 @@ public class RollbackDatabase extends AsyncNotifyQueue { .array(); stmt.setBytes(1, uuidBytes); stmt.setInt(2, (int) (minTime / 1000)); - stmt.setInt(3, pos1.getBlockX()); - stmt.setInt(4, pos2.getBlockX()); - stmt.setInt(5, pos1.getBlockZ()); - stmt.setInt(6, pos2.getBlockZ()); + stmt.setInt(3, pos1.x()); + stmt.setInt(4, pos2.x()); + stmt.setInt(5, pos1.z()); + stmt.setInt(6, pos2.z()); // Keep 128 offset for backwards-compatibility - stmt.setInt(7, pos1.getBlockY() - 128); - stmt.setInt(8, pos2.getBlockY() - 128); + stmt.setInt(7, pos1.y() - 128); + stmt.setInt(8, pos2.y() - 128); } } return count; @@ -262,13 +262,13 @@ public class RollbackDatabase extends AsyncNotifyQueue { BlockVector3 pos1 = change.getMinimumPoint(); BlockVector3 pos2 = change.getMaximumPoint(); - stmt.setInt(4, pos1.getX()); - stmt.setInt(5, pos2.getX()); - stmt.setInt(6, pos1.getZ()); - stmt.setInt(7, pos2.getZ()); + stmt.setInt(4, pos1.x()); + stmt.setInt(5, pos2.x()); + stmt.setInt(6, pos1.z()); + stmt.setInt(7, pos2.z()); // Keep 128 offset for backwards-compatibility - stmt.setInt(8, pos1.getY() - 128); - stmt.setInt(9, pos2.getY() - 128); + stmt.setInt(8, pos1.y() - 128); + stmt.setInt(9, pos2.y() - 128); stmt.setString(10, change.getCommand()); stmt.setInt(11, change.size()); stmt.executeUpdate(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/BlockTranslateExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/BlockTranslateExtent.java index d7b8a986e..7f84be430 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/BlockTranslateExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/BlockTranslateExtent.java @@ -24,7 +24,7 @@ public class BlockTranslateExtent extends AbstractDelegateExtent { @Override public > boolean setBlock(BlockVector3 location, T block) throws WorldEditException { - return getExtent().setBlock(location.getX() + dx, location.getY() + dy, location.getZ() + dz, block); + return getExtent().setBlock(location.x() + dx, location.y() + dy, location.z() + dz, block); } @Override @@ -49,7 +49,7 @@ public class BlockTranslateExtent extends AbstractDelegateExtent { @Override public BlockState getBlock(BlockVector3 location) { - return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + return getBlock(location.x(), location.y(), location.z()); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/FaweRegionExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/FaweRegionExtent.java index 84044f9b2..103dd8824 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/FaweRegionExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/FaweRegionExtent.java @@ -64,11 +64,11 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc @Override public final boolean contains(BlockVector3 p) { - return contains(p.getBlockX(), p.getBlockY(), p.getBlockZ()); + return contains(p.x(), p.y(), p.z()); } public final boolean contains(BlockVector2 p) { - return contains(p.getBlockX(), p.getBlockZ()); + return contains(p.x(), p.z()); } @Override @@ -96,7 +96,7 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc @Override public BiomeType getBiome(BlockVector3 position) { - return getBiomeType(position.getX(), position.getY(), position.getZ()); + return getBiomeType(position.x(), position.y(), position.z()); } @Override @@ -112,7 +112,7 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc @Override public BaseBlock getFullBlock(BlockVector3 position) { - return getFullBlock(position.getX(), position.getY(), position.getZ()); + return getFullBlock(position.x(), position.y(), position.z()); } @Override @@ -128,7 +128,7 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc @Override public BlockState getBlock(BlockVector3 position) { - return getBlock(position.getX(), position.getY(), position.getZ()); + return getBlock(position.x(), position.y(), position.z()); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java index 2fc5133c6..d85594215 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java @@ -66,7 +66,7 @@ public class HistoryExtent extends AbstractDelegateExtent { @Override public > boolean setBlock(BlockVector3 location, B block) throws WorldEditException { - return setBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ(), block); + return setBlock(location.x(), location.y(), location.z(), block); } @Nullable @@ -111,7 +111,7 @@ public class HistoryExtent extends AbstractDelegateExtent { public boolean setBiome(BlockVector3 position, BiomeType newBiome) { BiomeType oldBiome = this.getBiome(position); if (!oldBiome.getId().equals(newBiome.getId())) { - this.changeSet.addBiomeChange(position.getBlockX(), position.getBlockY(), position.getBlockZ(), oldBiome, newBiome); + this.changeSet.addBiomeChange(position.x(), position.y(), position.z(), oldBiome, newBiome); return getExtent().setBiome(position, newBiome); } else { return false; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/LimitExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/LimitExtent.java index 24d440c57..d02ff9320 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/LimitExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/LimitExtent.java @@ -373,12 +373,12 @@ public class LimitExtent extends AbstractDelegateExtent { size = ((Collection) positions).size(); } else if (positions instanceof Region) { BlockVector3 dim = ((Region) positions).getDimensions(); - size = dim.getX() * dim.getY() * dim.getZ(); + size = dim.x() * dim.y() * dim.z(); } else if (positions instanceof Extent) { BlockVector3 min = ((Extent) positions).getMinimumPoint(); BlockVector3 max = ((Extent) positions).getMinimumPoint(); BlockVector3 dim = max.subtract(min).add(BlockVector3.ONE); - size = dim.getX() * dim.getY() * dim.getZ(); + size = dim.x() * dim.y() * dim.z(); } else { ExtentFilterBlock block = new ExtentFilterBlock(this); for (BlockVector3 pos : positions) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/PositionTransformExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/PositionTransformExtent.java index 6d74acc16..d5e8e57e8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/PositionTransformExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/PositionTransformExtent.java @@ -38,9 +38,9 @@ public class PositionTransformExtent extends ResettableExtent { if (min == null) { min = pos; } - mutable.mutX(pos.getX() - min.getX()); - mutable.mutY(pos.getY() - min.getY()); - mutable.mutZ(pos.getZ() - min.getZ()); + mutable.mutX(pos.x() - min.x()); + mutable.mutY(pos.y() - min.y()); + mutable.mutZ(pos.z() - min.z()); MutableVector3 tmp = new MutableVector3(transform.apply(mutable.toVector3())); return min.add(tmp.roundHalfUp().toBlockPoint()); } @@ -49,9 +49,9 @@ public class PositionTransformExtent extends ResettableExtent { if (min == null) { min = BlockVector3.at(x, y, z); } - mutable.mutX(x - min.getX()); - mutable.mutY(y - min.getY()); - mutable.mutZ(z - min.getZ()); + mutable.mutX(x - min.x()); + mutable.mutY(y - min.y()); + mutable.mutZ(z - min.z()); MutableVector3 tmp = new MutableVector3(transform.apply(mutable.toVector3())); return min.add(tmp.roundHalfUp().toBlockPoint()); } @@ -73,10 +73,10 @@ public class PositionTransformExtent extends ResettableExtent { @Override public BiomeType getBiome(BlockVector3 position) { - mutable.mutX(position.getBlockX()); - mutable.mutZ(position.getBlockZ()); - mutable.mutY(position.getBlockY()); - return super.getBiome(getPos(mutable.getX(), mutable.getY(), mutable.getZ())); + mutable.mutX(position.x()); + mutable.mutZ(position.z()); + mutable.mutY(position.y()); + return super.getBiome(getPos(mutable.x(), mutable.y(), mutable.z())); } @Override @@ -92,10 +92,10 @@ public class PositionTransformExtent extends ResettableExtent { @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { - mutable.mutX(position.getBlockX()); - mutable.mutZ(position.getBlockZ()); - mutable.mutY(position.getBlockY()); - return super.setBiome(getPos(mutable.getX(), mutable.getY(), mutable.getZ()), biome); + mutable.mutX(position.x()); + mutable.mutZ(position.z()); + mutable.mutY(position.y()); + return super.setBiome(getPos(mutable.x(), mutable.y(), mutable.z()), biome); } public void setTransform(Transform transform) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/ProcessedWEExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/ProcessedWEExtent.java index 5abe90348..e08e1535f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/ProcessedWEExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/ProcessedWEExtent.java @@ -80,12 +80,12 @@ public class ProcessedWEExtent extends AbstractDelegateExtent { @Override public > boolean setBlock(BlockVector3 location, B block) throws WorldEditException { - return setBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ(), block); + return setBlock(location.x(), location.y(), location.z(), block); } @Override public BlockState getBlock(BlockVector3 location) { - return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ()); + return getBlock(location.x(), location.y(), location.z()); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/SourceMaskExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/SourceMaskExtent.java index 6c2230372..6da0a2ac6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/SourceMaskExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/SourceMaskExtent.java @@ -41,8 +41,8 @@ public class SourceMaskExtent extends TemporalExtent { @Override public > boolean setBlock(BlockVector3 location, T block) throws WorldEditException { - set(location.getBlockX(), location.getBlockY(), location.getBlockZ(), block); - return mask.test(location) && super.setBlock(location.getX(), location.getY(), location.getZ(), block); + set(location.x(), location.y(), location.z(), block); + return mask.test(location) && super.setBlock(location.x(), location.y(), location.z(), block); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TemporalExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TemporalExtent.java index ac36bef5a..ff0fa5106 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TemporalExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TemporalExtent.java @@ -44,7 +44,7 @@ public class TemporalExtent extends PassthroughExtent { @Override public BlockState getBlock(BlockVector3 position) { - if (position.getX() == x && position.getY() == y && position.getZ() == z) { + if (position.x() == x && position.y() == y && position.z() == z) { return block.toImmutableState(); } return super.getBlock(position); @@ -60,7 +60,7 @@ public class TemporalExtent extends PassthroughExtent { @Override public BaseBlock getFullBlock(BlockVector3 position) { - if (position.getX() == x && position.getY() == y && position.getZ() == z) { + if (position.x() == x && position.y() == y && position.z() == z) { if (block instanceof BaseBlock) { return (BaseBlock) block; } else { @@ -72,7 +72,7 @@ public class TemporalExtent extends PassthroughExtent { @Override public BiomeType getBiome(BlockVector3 position) { - if (position.getX() == bx && position.getZ() == bz) { + if (position.x() == bx && position.z() == bz) { return biome; } return super.getBiome(position); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java index 250227439..c424c0f8c 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java @@ -55,13 +55,13 @@ public class TransformExtent extends BlockTransformExtent { if (min == null) { min = pos; } - mutable1.mutX(pos.getX() - min.getX()); - mutable1.mutY(pos.getY() - min.getY()); - mutable1.mutZ(pos.getZ() - min.getZ()); + mutable1.mutX(pos.x() - min.x()); + mutable1.mutY(pos.y() - min.y()); + mutable1.mutZ(pos.z() - min.z()); Vector3 tmp = getTransform().apply(mutable1); - mutable2.mutX(tmp.getX() + min.getX()); - mutable2.mutY(tmp.getY() + min.getY()); - mutable2.mutZ(tmp.getZ() + min.getZ()); + mutable2.mutX(tmp.x() + min.x()); + mutable2.mutY(tmp.y() + min.y()); + mutable2.mutZ(tmp.z() + min.z()); return mutable2; } @@ -69,20 +69,20 @@ public class TransformExtent extends BlockTransformExtent { if (min == null) { min = BlockVector3.at(x, y, z); } - mutable1.mutX(x - min.getX()); - mutable1.mutY(y - min.getY()); - mutable1.mutZ(z - min.getZ()); + mutable1.mutX(x - min.x()); + mutable1.mutY(y - min.y()); + mutable1.mutZ(z - min.z()); Vector3 tmp = getTransform().apply(mutable1); - mutable2.mutX(tmp.getX() + min.getX()); - mutable2.mutY(tmp.getY() + min.getY()); - mutable2.mutZ(tmp.getZ() + min.getZ()); + mutable2.mutX(tmp.x() + min.x()); + mutable2.mutY(tmp.y() + min.y()); + mutable2.mutZ(tmp.z() + min.z()); return tmp.toBlockPoint(); } @Override public BlockState getBlock(int x, int y, int z) { BlockVector3 p = getPos(x, y, z); - return transform(super.getBlock(p.getX(), p.getY(), p.getZ())); + return transform(super.getBlock(p.x(), p.y(), p.z())); } @Override @@ -93,7 +93,7 @@ public class TransformExtent extends BlockTransformExtent { @Override public BiomeType getBiomeType(int x, int y, int z) { BlockVector3 p = getPos(x, y, z); - return super.getBiomeType(p.getX(), y, p.getZ()); + return super.getBiomeType(p.x(), y, p.z()); } @Override @@ -114,7 +114,7 @@ public class TransformExtent extends BlockTransformExtent { @Override public boolean setBiome(int x, int y, int z, BiomeType biome) { BlockVector3 p = getPos(x, y, z); - return super.setBiome(p.getX(), p.getY(), p.getZ(), biome); + return super.setBiome(p.x(), p.y(), p.z(), biome); } } 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 1a30a0df8..6a306fc44 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 @@ -41,7 +41,7 @@ public class CPUOptimizedClipboard extends LinearClipboard { @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { - return setBiome(position.getX(), position.getY(), position.getZ(), biome); + return setBiome(position.x(), position.y(), position.z(), biome); } @Override @@ -92,7 +92,7 @@ public class CPUOptimizedClipboard extends LinearClipboard { @Override public BiomeType getBiome(BlockVector3 position) { - return getBiome(getBiomeIndex(position.getX(), position.getY(), position.getZ())); + return getBiome(getBiomeIndex(position.x(), position.y(), position.z())); } public void convertTilesToIndex() { 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 76f22a194..f42cdbbff 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 @@ -359,7 +359,7 @@ public class DiskOptimizedClipboard extends LinearClipboard { @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { - return setBiome(position.getX(), position.getY(), position.getZ(), biome); + return setBiome(position.x(), position.y(), position.z(), biome); } @Override @@ -417,7 +417,7 @@ public class DiskOptimizedClipboard extends LinearClipboard { @Override public BiomeType getBiome(BlockVector3 position) { - return getBiome(getBiomeIndex(position.getX(), position.getY(), position.getZ())); + return getBiome(getBiomeIndex(position.x(), position.y(), position.z())); } public BlockArrayClipboard toClipboard() { @@ -438,9 +438,9 @@ public class DiskOptimizedClipboard extends LinearClipboard { super.setOrigin(origin); origin = origin.subtract(offset); try { - byteBuffer.putShort(10, (short) origin.getBlockX()); - byteBuffer.putShort(12, (short) origin.getBlockY()); - byteBuffer.putShort(14, (short) origin.getBlockZ()); + byteBuffer.putShort(10, (short) origin.x()); + byteBuffer.putShort(12, (short) origin.y()); + byteBuffer.putShort(14, (short) origin.z()); } catch (Throwable e) { e.printStackTrace(); } @@ -450,9 +450,9 @@ public class DiskOptimizedClipboard extends LinearClipboard { protected void setOffset(BlockVector3 offset) { super.setOffset(offset); try { - byteBuffer.putShort(16, (short) offset.getBlockX()); - byteBuffer.putShort(18, (short) offset.getBlockY()); - byteBuffer.putShort(20, (short) offset.getBlockZ()); + byteBuffer.putShort(16, (short) offset.x()); + byteBuffer.putShort(18, (short) offset.y()); + byteBuffer.putShort(20, (short) offset.z()); } catch (Throwable e) { e.printStackTrace(); } @@ -588,9 +588,9 @@ public class DiskOptimizedClipboard extends LinearClipboard { CompoundTag data = entity.getState().getNbtData(); HashMap value = new HashMap<>(data.getValue()); List pos = new ArrayList<>(3); - pos.add(new DoubleTag(entity.getLocation().getX())); - pos.add(new DoubleTag(entity.getLocation().getX())); - pos.add(new DoubleTag(entity.getLocation().getX())); + pos.add(new DoubleTag(entity.getLocation().x())); + pos.add(new DoubleTag(entity.getLocation().x())); + pos.add(new DoubleTag(entity.getLocation().x())); value.put("Pos", new ListTag(DoubleTag.class, pos)); nbtOS.writeTag(new CompoundTag(value)); } 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 449795e5d..6c7a910f2 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 @@ -64,7 +64,7 @@ public class MemoryOptimizedClipboard extends LinearClipboard { @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { - return setBiome(position.getX(), position.getY(), position.getZ(), biome); + return setBiome(position.x(), position.y(), position.z(), biome); } @Override @@ -115,7 +115,7 @@ public class MemoryOptimizedClipboard extends LinearClipboard { @Override public BiomeType getBiome(BlockVector3 position) { - return getBiome(getBiomeIndex(position.getX(), position.getY(), position.getZ())); + return getBiome(getBiomeIndex(position.x(), position.y(), position.z())); } private int getOrdinal(int index) { 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 c01abd787..f902f6007 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 @@ -70,17 +70,17 @@ public abstract class SimpleClipboard implements Clipboard { @Override public final int getWidth() { - return size.getBlockX(); + return size.x(); } @Override public final int getHeight() { - return size.getBlockY(); + return size.y(); } @Override public final int getLength() { - return size.getBlockZ(); + return size.z(); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/WorldCopyClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/WorldCopyClipboard.java index cdd4ae8df..4bb50ca73 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/WorldCopyClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/WorldCopyClipboard.java @@ -56,7 +56,7 @@ public class WorldCopyClipboard extends ReadOnlyClipboard { @Override public BiomeType getBiome(BlockVector3 position) { - return getExtent().getBiomeType(position.getX(), position.getY(), position.getZ()); + return getExtent().getBiomeType(position.x(), position.y(), position.z()); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java index d884e0151..156e38544 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java @@ -396,8 +396,8 @@ public class FastSchematicReader extends NBTSchematicReader { int locY = loc.getBlockY(); int locZ = loc.getBlockZ(); BlockVector3 max = min.add(dimensions).subtract(BlockVector3.ONE); - if (locX < min.getX() || locY < min.getY() || locZ < min.getZ() - || locX > max.getX() || locY > max.getY() || locZ > max.getZ()) { + if (locX < min.x() || locY < min.y() || locZ < min.z() + || locX > max.x() || locY > max.y() || locZ > max.z()) { for (Entity e : clipboard.getEntities()) { clipboard.removeEntity(e); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java index db3452d29..5218b1c1e 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java @@ -114,15 +114,15 @@ public class FastSchematicWriter implements ClipboardWriter { // The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin' out.writeNamedTag("Offset", new int[]{ - min.getBlockX(), - min.getBlockY(), - min.getBlockZ(), + min.x(), + min.y(), + min.z(), }); out.writeLazyCompoundTag("Metadata", out1 -> { - out1.writeNamedTag("WEOffsetX", offset.getBlockX()); - out1.writeNamedTag("WEOffsetY", offset.getBlockY()); - out1.writeNamedTag("WEOffsetZ", offset.getBlockZ()); + out1.writeNamedTag("WEOffsetX", offset.x()); + out1.writeNamedTag("WEOffsetY", offset.y()); + out1.writeNamedTag("WEOffsetZ", offset.z()); out1.writeNamedTag("FAWEVersion", Fawe.instance().getVersion().build); }); @@ -162,9 +162,9 @@ public class FastSchematicWriter implements ClipboardWriter { // Dum. values.remove("id"); values.put("Pos", new IntArrayTag(new int[]{ - pos.getX(), - pos.getY(), - pos.getZ() + pos.x(), + pos.y(), + pos.z() })); numTiles++; @@ -282,10 +282,10 @@ public class FastSchematicWriter implements ClipboardWriter { int length = clipboard.getRegion().getLength(); MutableBlockVector3 mutable = new MutableBlockVector3(); for (int z = 0, i = 0; z < length; z++) { - int z0 = min.getBlockZ() + z; + int z0 = min.z() + z; for (int x = 0; x < width; x++, i++) { - int x0 = min.getBlockX() + x; - BiomeType biome = clipboard.getBiome(mutable.setComponents(x0, min.getY(), z0)); + int x0 = min.x() + x; + BiomeType biome = clipboard.getBiome(mutable.setComponents(x0, min.y(), z0)); task.applyInt(i, biome.getInternalId()); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java index 66deefeb7..d52d74b5a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java @@ -213,8 +213,8 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { if (block.getBlockType() != BlockTypes.STRUCTURE_VOID) { int combined = block.getInternalId(); int index = indexes.get(combined); - List pos = Arrays.asList(point.getX() - min.getX(), - point.getY() - min.getY(), point.getZ() - min.getZ() + List pos = Arrays.asList(point.x() - min.x(), + point.y() - min.y(), point.z() - min.z() ); if (!block.hasNbtData()) { blocks.add(FaweCache.INSTANCE.asMap("state", index, "pos", pos)); @@ -231,7 +231,7 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { ArrayList> entities = new ArrayList<>(); for (Entity entity : clipboard.getEntities()) { Location loc = entity.getLocation(); - List pos = Arrays.asList(loc.getX(), loc.getY(), loc.getZ()); + List pos = Arrays.asList(loc.x(), loc.y(), loc.z()); List blockPos = Arrays.asList(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); BaseEntity state = entity.getState(); if (state != null) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/PNGWriter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/PNGWriter.java index b5cbc7fb2..48a3315d5 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/PNGWriter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/PNGWriter.java @@ -75,9 +75,9 @@ public class PNGWriter implements ClipboardWriter { MutableBlockVector3 mutableLeft = new MutableBlockVector3(0, 0, 0); BlockVector3 min = clipboard.getMinimumPoint(); - int y0 = min.getBlockY(); - int z0 = min.getBlockZ(); - int x0 = min.getBlockX(); + int y0 = min.y(); + int z0 = min.z(); + int x0 = min.x(); for (int x = x0; x < x0 + width; x++) { mutable.mutX(x); mutableTop.mutX(x); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/ArrayImageMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/ArrayImageMask.java index 4976af5f7..07c9acac1 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/ArrayImageMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/ArrayImageMask.java @@ -20,7 +20,7 @@ public class ArrayImageMask implements FilterBlockMask { @Override public boolean applyBlock(FilterBlock block) { - int height = image.getRGB(block.getX(), block.getZ()) & 0xFF; + int height = image.getRGB(block.x(), block.z()) & 0xFF; return height == 255 || height > 0 && !white && random.nextInt(256) <= height; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/AbstractSingleFilterBlock.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/AbstractSingleFilterBlock.java index 95e50dc76..5d64ead7c 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/AbstractSingleFilterBlock.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/AbstractSingleFilterBlock.java @@ -83,18 +83,18 @@ public abstract class AbstractSingleFilterBlock extends FilterBlock { @Override public BlockVector3 getMinimumPoint() { - return at(getX(), getY(), getZ()); + return at(x(), y(), z()); } @Override public BlockVector3 getMaximumPoint() { - return at(getX(), getY(), getZ()); + return at(x(), y(), z()); } @Override public > boolean setBlock(int x, int y, int z, T block) throws WorldEditException { - if (x == this.getX() && y == this.getY() && z == this.getZ()) { + if (x == this.x() && y == this.y() && z == this.z()) { setFullBlock(block.toBaseBlock()); return true; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/EntityInBlockRemovingProcessor.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/EntityInBlockRemovingProcessor.java index 58baf8633..693356a7a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/EntityInBlockRemovingProcessor.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/EntityInBlockRemovingProcessor.java @@ -30,9 +30,9 @@ public class EntityInBlockRemovingProcessor implements IBatchProcessor { continue; } BlockVector3 pos = tag.getEntityPosition().toBlockPoint(); - int x = pos.getX() & 15; - int y = pos.getY(); - int z = pos.getZ() & 15; + int x = pos.x() & 15; + int y = pos.y(); + int z = pos.z() & 15; if (!set.hasSection(y >> 4)) { continue; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java index e38df12f5..dbe717e49 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java @@ -273,9 +273,9 @@ public class NMSRelighter implements Relighter { int lightLevel = (int) val[1]; this.computeRemoveBlockLight( - node.getX() - 1, - node.getY(), - node.getZ(), + node.x() - 1, + node.y(), + node.z(), lightLevel, lightRemovalQueue, lightPropagationQueue, @@ -283,20 +283,20 @@ public class NMSRelighter implements Relighter { visited ); this.computeRemoveBlockLight( - node.getX() + 1, - node.getY(), - node.getZ(), + node.x() + 1, + node.y(), + node.z(), lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited ); - if (node.getY() > minY) { + if (node.y() > minY) { this.computeRemoveBlockLight( - node.getX(), - node.getY() - 1, - node.getZ(), + node.x(), + node.y() - 1, + node.z(), lightLevel, lightRemovalQueue, lightPropagationQueue, @@ -304,11 +304,11 @@ public class NMSRelighter implements Relighter { visited ); } - if (node.getY() < maxY) { + if (node.y() < maxY) { this.computeRemoveBlockLight( - node.getX(), - node.getY() + 1, - node.getZ(), + node.x(), + node.y() + 1, + node.z(), lightLevel, lightRemovalQueue, lightPropagationQueue, @@ -317,9 +317,9 @@ public class NMSRelighter implements Relighter { ); } this.computeRemoveBlockLight( - node.getX(), - node.getY(), - node.getZ() - 1, + node.x(), + node.y(), + node.z() - 1, lightLevel, lightRemovalQueue, lightPropagationQueue, @@ -327,9 +327,9 @@ public class NMSRelighter implements Relighter { visited ); this.computeRemoveBlockLight( - node.getX(), - node.getY(), - node.getZ() + 1, + node.x(), + node.y(), + node.z() + 1, lightLevel, lightRemovalQueue, lightPropagationQueue, @@ -340,27 +340,27 @@ public class NMSRelighter implements Relighter { while (!lightPropagationQueue.isEmpty()) { MutableBlockVector3 node = lightPropagationQueue.poll(); - ChunkHolder iChunk = (ChunkHolder) queue.getOrCreateChunk(node.getX() >> 4, node.getZ() >> 4); + ChunkHolder iChunk = (ChunkHolder) queue.getOrCreateChunk(node.x() >> 4, node.z() >> 4); if (!iChunk.isInit()) { - iChunk.init(queue, node.getX() >> 4, node.getZ() >> 4); + iChunk.init(queue, node.x() >> 4, node.z() >> 4); } - int lightLevel = iChunk.getEmittedLight(node.getX() & 15, node.getY(), node.getZ() & 15); - BlockState state = this.queue.getBlock(node.getX(), node.getY(), node.getZ()); + int lightLevel = iChunk.getEmittedLight(node.x() & 15, node.y(), node.z() & 15); + BlockState state = this.queue.getBlock(node.x(), node.y(), node.z()); String id = state.getBlockType().getId().toLowerCase(Locale.ROOT); if (lightLevel <= 1) { continue; } if (id.contains("slab")) { boolean top = state.getState(slabHalf).equalsIgnoreCase("top"); - computeSlab(node.getX(), node.getY(), node.getZ(), lightLevel, lightPropagationQueue, visited, top); + computeSlab(node.x(), node.y(), node.z(), lightLevel, lightPropagationQueue, visited, top); } else if (id.contains("stair")) { boolean top = state.getState(stairHalf).equalsIgnoreCase("top"); Direction direction = getStairDir(state); String shape = getStairShape(state); computeStair( - node.getX(), - node.getY(), - node.getZ(), + node.x(), + node.y(), + node.z(), lightLevel, lightPropagationQueue, visited, @@ -369,7 +369,7 @@ public class NMSRelighter implements Relighter { shape ); } else { - computeNormal(node.getX(), node.getY(), node.getZ(), lightLevel, lightPropagationQueue, visited); + computeNormal(node.x(), node.y(), node.z(), lightLevel, lightPropagationQueue, visited); } } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/OffsetTransform.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/OffsetTransform.java index a8ade6df1..c2536deca 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/OffsetTransform.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/OffsetTransform.java @@ -30,9 +30,9 @@ public class OffsetTransform extends ResettableExtent { @Override public boolean setBiome(BlockVector3 location, BiomeType biome) { - int x = location.getX() + dx; - int y = location.getX() + dy; - int z = location.getX() + dz; + int x = location.x() + dx; + int y = location.x() + dy; + int z = location.x() + dz; if (!getExtent().contains(x, y, z)) { return false; } @@ -53,9 +53,9 @@ public class OffsetTransform extends ResettableExtent { @Override public > boolean setBlock(BlockVector3 location, T block) throws WorldEditException { - int x = location.getX() + dx; - int y = location.getX() + dy; - int z = location.getX() + dz; + int x = location.x() + dx; + int y = location.x() + dy; + int z = location.x() + dz; if (!getExtent().contains(x, y, z)) { return false; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/RandomOffsetTransform.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/RandomOffsetTransform.java index 268255bf2..4ad3189c7 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/RandomOffsetTransform.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/RandomOffsetTransform.java @@ -34,9 +34,9 @@ public class RandomOffsetTransform extends ResettableExtent { @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { - int x = position.getBlockX() + random.nextInt(1 + (dx << 1)) - dx; - int y = position.getBlockY() + random.nextInt(1 + (dy << 1)) - dy; - int z = position.getBlockZ() + random.nextInt(1 + (dz << 1)) - dz; + int x = position.x() + random.nextInt(1 + (dx << 1)) - dx; + int y = position.y() + random.nextInt(1 + (dy << 1)) - dy; + int z = position.z() + random.nextInt(1 + (dz << 1)) - dz; if (!getExtent().contains(x, y, z)) { return false; } @@ -57,9 +57,9 @@ public class RandomOffsetTransform extends ResettableExtent { @Override public > boolean setBlock(BlockVector3 pos, T block) throws WorldEditException { - int x = pos.getBlockX() + random.nextInt(1 + (dx << 1)) - dx; - int y = pos.getBlockY() + random.nextInt(1 + (dy << 1)) - dy; - int z = pos.getBlockZ() + random.nextInt(1 + (dz << 1)) - dz; + int x = pos.x() + random.nextInt(1 + (dx << 1)) - dx; + int y = pos.y() + random.nextInt(1 + (dy << 1)) - dy; + int z = pos.z() + random.nextInt(1 + (dz << 1)) - dz; if (!getExtent().contains(x, y, z)) { return false; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/ScaleTransform.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/ScaleTransform.java index 29af87055..c81d123df 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/ScaleTransform.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/ScaleTransform.java @@ -55,9 +55,9 @@ public class ScaleTransform extends ResettableExtent { if (min == null) { min = pos; } - mutable.mutX(min.getX() + (pos.getX() - min.getX()) * dx); - mutable.mutY(min.getY() + (pos.getY() - min.getY()) * dy); - mutable.mutZ(min.getZ() + (pos.getZ() - min.getZ()) * dz); + mutable.mutX(min.x() + (pos.x() - min.x()) * dx); + mutable.mutY(min.y() + (pos.y() - min.y()) * dy); + mutable.mutZ(min.z() + (pos.z() - min.z()) * dz); return new MutableVector3(mutable); } @@ -65,9 +65,9 @@ public class ScaleTransform extends ResettableExtent { if (min == null) { min = BlockVector3.at(x, y, z); } - mutable.mutX(min.getX() + (x - min.getX()) * dx); - mutable.mutY(min.getY() + (y - min.getY()) * dy); - mutable.mutZ(min.getZ() + (z - min.getZ()) * dz); + mutable.mutX(min.x() + (x - min.x()) * dx); + mutable.mutY(min.y() + (y - min.y()) * dy); + mutable.mutZ(min.z() + (z - min.z()) * dz); return new MutableVector3(mutable); } @@ -77,15 +77,15 @@ public class ScaleTransform extends ResettableExtent { boolean result = false; MutableVector3 vector3 = getPos(location); MutableBlockVector3 pos = new MutableBlockVector3(); - double sx = vector3.getX(); - double sy = vector3.getY(); - double sz = vector3.getZ(); + double sx = vector3.x(); + double sy = vector3.y(); + double sz = vector3.z(); double ex = sx + dx; double ey = Math.max(minY, Math.min(maxy, sy + dy)); double ez = sz + dz; - for (pos.mutY(sy); pos.getY() < ey; pos.mutY(pos.getY() + 1)) { - for (pos.mutZ(sz); pos.getZ() < ez; pos.mutZ(pos.getZ() + 1)) { - for (pos.mutX(sx); pos.getX() < ex; pos.mutX(pos.getX() + 1)) { + for (pos.mutY(sy); pos.y() < ey; pos.mutY(pos.y() + 1)) { + for (pos.mutZ(sz); pos.z() < ez; pos.mutZ(pos.z() + 1)) { + for (pos.mutX(sx); pos.x() < ex; pos.mutX(pos.x() + 1)) { if (!getExtent().contains(pos)) { continue; } @@ -101,15 +101,15 @@ public class ScaleTransform extends ResettableExtent { boolean result = false; MutableVector3 vector3 = getPos(position); MutableBlockVector3 pos = new MutableBlockVector3(); - double sx = vector3.getX(); - double sy = vector3.getY(); - double sz = vector3.getZ(); + double sx = vector3.x(); + double sy = vector3.y(); + double sz = vector3.z(); double ex = sx + dx; double ey = Math.max(minY, Math.min(maxy, sy + dy)); double ez = sz + dz; - for (pos.mutY(sy); pos.getY() < ey; pos.mutY(pos.getY() + 1)) { - for (pos.mutZ(sz); pos.getZ() < ez; pos.mutZ(pos.getZ() + 1)) { - for (pos.mutX(sx); pos.getX() < ex; pos.mutX(pos.getX() + 1)) { + for (pos.mutY(sy); pos.y() < ey; pos.mutY(pos.y() + 1)) { + for (pos.mutZ(sz); pos.z() < ez; pos.mutZ(pos.z() + 1)) { + for (pos.mutX(sx); pos.x() < ex; pos.mutX(pos.x() + 1)) { if (!getExtent().contains(pos)) { continue; } @@ -126,15 +126,15 @@ public class ScaleTransform extends ResettableExtent { boolean result = false; MutableVector3 vector3 = getPos(x1, y1, z1); MutableBlockVector3 pos = new MutableBlockVector3(); - double sx = vector3.getX(); - double sy = vector3.getY(); - double sz = vector3.getZ(); - double ex = vector3.getX() + dx; + double sx = vector3.x(); + double sy = vector3.y(); + double sz = vector3.z(); + double ex = vector3.x() + dx; double ey = Math.min(maxy, sy + dy); - double ez = vector3.getZ() + dz; - for (pos.mutY(sy); pos.getY() < ey; pos.mutY(pos.getY() + 1)) { - for (pos.mutZ(sz); pos.getZ() < ez; pos.mutZ(pos.getZ() + 1)) { - for (pos.mutX(sx); pos.getX() < ex; pos.mutX(pos.getX() + 1)) { + double ez = vector3.z() + dz; + for (pos.mutY(sy); pos.y() < ey; pos.mutY(pos.y() + 1)) { + for (pos.mutZ(sz); pos.z() < ez; pos.mutZ(pos.z() + 1)) { + for (pos.mutX(sx); pos.x() < ex; pos.mutX(pos.x() + 1)) { if (!getExtent().contains(pos)) { continue; } @@ -150,15 +150,15 @@ public class ScaleTransform extends ResettableExtent { boolean result = false; MutableVector3 vector3 = getPos(x1, y1, z1); MutableBlockVector3 pos = new MutableBlockVector3(); - double sx = vector3.getX(); - double sy = vector3.getY(); - double sz = vector3.getZ(); + double sx = vector3.x(); + double sy = vector3.y(); + double sz = vector3.z(); double ex = sx + dx; double ey = Math.max(minY, Math.min(maxy, sy + dy)); double ez = sz + dz; - for (pos.mutY(sy); pos.getY() < ey; pos.mutY(pos.getY() + 1)) { - for (pos.mutZ(sz); pos.getZ() < ez; pos.mutZ(pos.getZ() + 1)) { - for (pos.mutX(sx); pos.getX() < ex; pos.mutX(pos.getX() + 1)) { + for (pos.mutY(sy); pos.y() < ey; pos.mutY(pos.y() + 1)) { + for (pos.mutZ(sz); pos.z() < ez; pos.mutZ(pos.z() + 1)) { + for (pos.mutX(sx); pos.x() < ex; pos.mutX(pos.x() + 1)) { if (!getExtent().contains(pos)) { continue; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/SelectTransform.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/SelectTransform.java index 57f77b2fe..b3be0a43a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/SelectTransform.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/transform/SelectTransform.java @@ -27,11 +27,11 @@ public abstract class SelectTransform extends ResettableExtent { public abstract AbstractDelegateExtent getExtent(int x, int z); public Extent getExtent(BlockVector3 pos) { - return getExtent(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()); + return getExtent(pos.x(), pos.y(), pos.z()); } public Extent getExtent(BlockVector2 pos) { - return getExtent(pos.getBlockX(), pos.getBlockZ()); + return getExtent(pos.x(), pos.z()); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/SurfaceRegionFunction.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/SurfaceRegionFunction.java index 5f946c933..a6b9ace56 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/SurfaceRegionFunction.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/SurfaceRegionFunction.java @@ -26,8 +26,8 @@ public class SurfaceRegionFunction implements FlatRegionFunction { @Override public boolean apply(BlockVector2 position) throws WorldEditException { - int x = position.getBlockX(); - int z = position.getBlockZ(); + int x = position.x(); + int z = position.z(); int layer = extent.getNearestSurfaceTerrainBlock(x, z, lastY, minY, maxY, false); if (layer != -1) { lastY = layer; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/block/BiomeCopy.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/block/BiomeCopy.java index 3926c19a6..457fff477 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/block/BiomeCopy.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/block/BiomeCopy.java @@ -21,11 +21,11 @@ public class BiomeCopy implements RegionFunction { @Override public boolean apply(BlockVector3 position) throws WorldEditException { - int x = position.getBlockX(); - int y = position.getBlockY(); - int z = position.getBlockZ(); - if (x != mutableVector.getBlockX() || z != mutableVector.getBlockZ() || y != mutableVector - .getBlockY()) { + int x = position.x(); + int y = position.y(); + int z = position.z(); + if (x != mutableVector.x() || z != mutableVector.z() || y != mutableVector + .y()) { mutableVector.setComponents(x, y, z); return destination.setBiome(mutableVector, source.getBiome(mutableVector)); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java index 28bfa0a4c..b9a403f27 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java @@ -72,8 +72,8 @@ public class CavesGen extends GenBase { int maxAngle, double paramDouble4 ) throws WorldEditException { - int bx = chunkPos.getBlockX() << 4; - int bz = chunkPos.getBlockZ() << 4; + int bx = chunkPos.x() << 4; + int bz = chunkPos.z() << 4; double real_x = bx + 7; double real_z = bz + 7; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/GenBase.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/GenBase.java index af1a4e66e..f0637d127 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/GenBase.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/GenBase.java @@ -26,8 +26,8 @@ public abstract class GenBase { public void generate(BlockVector2 chunkPos, Extent chunk) throws WorldEditException { int i = this.checkAreaSize; - int chunkX = chunkPos.getBlockX(); - int chunkZ = chunkPos.getBlockZ(); + int chunkX = chunkPos.x(); + int chunkZ = chunkPos.z(); for (int x = chunkX - i; x <= chunkX + i; x++) { for (int z = chunkZ - i; z <= chunkZ + i; z++) { generateChunk(x, z, chunkPos, chunk); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/SchemGen.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/SchemGen.java index 1ced63f19..250914c05 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/SchemGen.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/SchemGen.java @@ -36,7 +36,7 @@ public class SchemGen implements Resource { int y = extent.getNearestSurfaceTerrainBlock( x, z, - mutable.getBlockY(), + mutable.y(), this.extent.getMinY(), this.extent.getMaxY(), Integer.MIN_VALUE, diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AdjacentAnyMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AdjacentAnyMask.java index 39bb0c41d..956daf67d 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AdjacentAnyMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AdjacentAnyMask.java @@ -44,9 +44,9 @@ public class AdjacentAnyMask extends AbstractMask implements ResettableMask { } public BlockVector3 direction(BlockVector3 v) { - int x = v.getBlockX(); - int y = v.getBlockY(); - int z = v.getBlockZ(); + int x = v.x(); + int y = v.y(); + int z = v.z(); if (mask.test(mutable.setComponents(x + 1, y, z))) { return mutable.setComponents(1, 0, 0); } else if (mask.test(mutable.setComponents(x - 1, y, z))) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AdjacentMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AdjacentMask.java index 23065ea7b..981492e0e 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AdjacentMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AdjacentMask.java @@ -22,9 +22,9 @@ public class AdjacentMask extends AbstractMask { @Override public boolean test(BlockVector3 bv) { vector.setComponents(bv); - double x = bv.getX(); - double y = bv.getY(); - double z = bv.getZ(); + double x = bv.x(); + double y = bv.y(); + double z = bv.z(); vector.mutX(x + 1); int count = 0; if (mask.test(vector) && ++count == min && max >= 8) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AngleMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AngleMask.java index 52de762ae..01cf15708 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AngleMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/AngleMask.java @@ -127,9 +127,9 @@ public class AngleMask extends AbstractExtentMask implements ResettableMask { } private boolean adjacentAir(Extent extent, MutableBlockVector3 mutable) { - int x = mutable.getBlockX(); - int y = mutable.getBlockY(); - int z = mutable.getBlockZ(); + int x = mutable.x(); + int y = mutable.y(); + int z = mutable.z(); if (!mask.test(extent, mutable.setComponents(x + 1, y, z))) { return true; } @@ -154,23 +154,23 @@ public class AngleMask extends AbstractExtentMask implements ResettableMask { if (!mask.test(vector)) { return false; } - int y = vector.getBlockY(); + int y = vector.y(); if (overlay) { MutableBlockVector3 mutable = new MutableBlockVector3(vector); if (y < maxY && !adjacentAir(null, mutable)) { return false; } } - int x = vector.getBlockX(); - int z = vector.getBlockZ(); + int x = vector.x(); + int z = vector.z(); return testSlope(getExtent(), x, y, z); } @Override public boolean test(final Extent extent, final BlockVector3 vector) { - int x = vector.getBlockX(); - int y = vector.getBlockY(); - int z = vector.getBlockZ(); + int x = vector.x(); + int y = vector.y(); + int z = vector.z(); if ((lastX == (lastX = x) & lastZ == (lastZ = z))) { int height = getHeight(extent, x, y, z); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/CachedMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/CachedMask.java index 27e4b9961..5bb757eb2 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/CachedMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/CachedMask.java @@ -60,9 +60,9 @@ public class CachedMask extends AbstractDelegateMask implements ResettableMask { @Override public boolean test(BlockVector3 vector) { - int x = vector.getX(); - int y = vector.getY(); - int z = vector.getZ(); + int x = vector.x(); + int y = vector.y(); + int z = vector.z(); try { boolean check = cache_checked.add(x, y, z); if (!check) { @@ -88,9 +88,9 @@ public class CachedMask extends AbstractDelegateMask implements ResettableMask { if (!hasExtent || !(extent instanceof AbstractExtentMask)) { return test(vector); } - int x = vector.getX(); - int y = vector.getY(); - int z = vector.getZ(); + int x = vector.x(); + int y = vector.y(); + int z = vector.z(); AbstractExtentMask mask = (AbstractExtentMask) getMask(); try { boolean check = cache_checked.add(x, y, z); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ImageBrushMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ImageBrushMask.java index ec31337de..d8ff64a76 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ImageBrushMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ImageBrushMask.java @@ -62,17 +62,17 @@ public class ImageBrushMask extends AbstractExtentMask { @Override public boolean test(BlockVector3 vector) { if (solid.test(vector)) { - int dx = vector.getBlockX() - center.getBlockX(); - int dy = vector.getBlockY() - center.getBlockY(); - int dz = vector.getBlockZ() - center.getBlockZ(); + int dx = vector.x() - center.x(); + int dy = vector.y() - center.y(); + int dz = vector.z() - center.z(); Vector3 pos1 = transform.apply(mutable.setComponents(dx - 0.5, dy - 0.5, dz - 0.5)); - int x1 = (int) (pos1.getX() * scale + centerImageX); - int z1 = (int) (pos1.getZ() * scale + centerImageZ); + int x1 = (int) (pos1.x() * scale + centerImageX); + int z1 = (int) (pos1.z() * scale + centerImageZ); Vector3 pos2 = transform.apply(mutable.setComponents(dx + 0.5, dy + 0.5, dz + 0.5)); - int x2 = (int) (pos2.getX() * scale + centerImageX); - int z2 = (int) (pos2.getZ() * scale + centerImageZ); + int x2 = (int) (pos2.x() * scale + centerImageX); + int z2 = (int) (pos2.z() * scale + centerImageZ); if (x2 < x1) { int tmp = x1; x1 = x2; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/LayerBrushMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/LayerBrushMask.java index 825039ed0..7f30ab64a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/LayerBrushMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/LayerBrushMask.java @@ -40,20 +40,20 @@ public class LayerBrushMask extends AbstractExtentMask { BlockState previous2 = layers[depth - 2]; for (BlockVector3 dir : BreadthFirstSearch.DEFAULT_DIRECTIONS) { mutable.setComponents( - pos.getBlockX() + dir.getBlockX(), - pos.getBlockY() + dir.getBlockY(), - pos.getBlockZ() + dir.getBlockZ() + pos.x() + dir.x(), + pos.y() + dir.y(), + pos.z() + dir.z() ); if (visitor.isVisited(mutable) && editSession.getBlock( - mutable.getBlockX(), - mutable.getBlockY(), - mutable.getBlockZ() + mutable.x(), + mutable.y(), + mutable.z() ) == previous) { - mutable.setComponents(pos.getBlockX() + dir.getBlockX() * 2, pos.getBlockY() + dir.getBlockY() * 2, - pos.getBlockZ() + dir.getBlockZ() * 2 + mutable.setComponents(pos.x() + dir.x() * 2, pos.y() + dir.y() * 2, + pos.z() + dir.z() * 2 ); if (visitor.isVisited(mutable) - && editSession.getBlock(mutable.getBlockX(), mutable.getBlockY(), mutable.getBlockZ()) == previous2) { + && editSession.getBlock(mutable.x(), mutable.y(), mutable.z()) == previous2) { found = true; break; } else { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/PlaneMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/PlaneMask.java index 6b8b1e4a1..5de393940 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/PlaneMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/PlaneMask.java @@ -15,9 +15,9 @@ public class PlaneMask extends AbstractMask implements ResettableMask { public boolean test(BlockVector3 vector) { switch (mode) { case -1: - originX = vector.getBlockX(); - originY = vector.getBlockY(); - originZ = vector.getBlockZ(); + originX = vector.x(); + originY = vector.y(); + originZ = vector.z(); mode = 0; return true; case 0: @@ -25,13 +25,13 @@ public class PlaneMask extends AbstractMask implements ResettableMask { case 2: case 4: int original = mode; - if (originX != vector.getBlockX()) { + if (originX != vector.x()) { mode &= 1; } - if (originY != vector.getBlockY()) { + if (originY != vector.y()) { mode &= 2; } - if (originZ != vector.getBlockZ()) { + if (originZ != vector.z()) { mode &= 4; } if (Integer.bitCount(mode) >= 3) { @@ -39,13 +39,13 @@ public class PlaneMask extends AbstractMask implements ResettableMask { return false; } default: - if (originX != vector.getBlockX() && (mode & 1) == 0) { + if (originX != vector.x() && (mode & 1) == 0) { return false; } - if (originZ != vector.getBlockZ() && (mode & 4) == 0) { + if (originZ != vector.z() && (mode & 4) == 0) { return false; } - return originY == vector.getBlockY() || (mode & 2) != 0; + return originY == vector.y() || (mode & 2) != 0; } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/RadiusMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/RadiusMask.java index b99e56ddc..c8893ae79 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/RadiusMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/RadiusMask.java @@ -30,17 +30,17 @@ public class RadiusMask extends AbstractMask implements ResettableMask { if (pos == null) { pos = to.toImmutable(); } - int dx = pos.getBlockX() - to.getBlockX(); + int dx = pos.x() - to.x(); int d = dx * dx; if (d > maxSqr) { return false; } - int dz = pos.getBlockZ() - to.getBlockZ(); + int dz = pos.z() - to.z(); d += dz * dz; if (d > maxSqr) { return false; } - int dy = pos.getBlockY() - to.getBlockY(); + int dy = pos.y() - to.y(); d += dy * dy; return d >= minSqr && d <= maxSqr; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SimplexMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SimplexMask.java index d337cd61a..a56238918 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SimplexMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SimplexMask.java @@ -19,7 +19,7 @@ public class SimplexMask extends AbstractMask { @Override public boolean test(BlockVector3 vector) { - double value = SimplexNoise.noise(vector.getBlockX() * scale, vector.getBlockY() * scale, vector.getBlockZ() * scale); + double value = SimplexNoise.noise(vector.x() * scale, vector.y() * scale, vector.z() * scale); return value >= min && value <= max; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/StencilBrushMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/StencilBrushMask.java index 3100f6a9e..25ee249d8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/StencilBrushMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/StencilBrushMask.java @@ -64,13 +64,13 @@ public class StencilBrushMask extends AbstractExtentMask { @Override public boolean test(BlockVector3 vector) { if (solid.test(vector)) { - int dx = vector.getBlockX() - center.getBlockX(); - int dy = vector.getBlockY() - center.getBlockY(); - int dz = vector.getBlockZ() - center.getBlockZ(); + int dx = vector.x() - center.x(); + int dy = vector.y() - center.y(); + int dz = vector.z() - center.z(); Vector3 srcPos = transform.apply(mutable.setComponents(dx, dy, dz)); - dx = MathMan.roundInt(srcPos.getX()); - dz = MathMan.roundInt(srcPos.getZ()); + dx = MathMan.roundInt(srcPos.x()); + dz = MathMan.roundInt(srcPos.z()); int distance = dx * dx + dz * dz; if (distance > size2 || Math.abs(dx) > 256 || Math.abs(dz) > 256) { @@ -83,7 +83,7 @@ public class StencilBrushMask extends AbstractExtentMask { return true; } if (val >= 255 || ThreadLocalRandom.current().nextInt(maxY) < val) { - editSession.setBlock(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ(), pattern); + editSession.setBlock(vector.x(), vector.y(), vector.z(), pattern); } return true; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SurfaceAngleMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SurfaceAngleMask.java index ce42a2d7e..15b347dbc 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SurfaceAngleMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SurfaceAngleMask.java @@ -24,7 +24,7 @@ public class SurfaceAngleMask extends AbstractExtentMask { @Override public boolean test(BlockVector3 vector) { if (!vector.getBlock(getExtent()).isAir() && nextToAir(vector)) { - double angle = 1 - getAverageAirDirection(vector.toVector3(), size).getY(); + double angle = 1 - getAverageAirDirection(vector.toVector3(), size).y(); return (angle >= (min / 90.0) && angle <= (max / 90.0)); } return false; @@ -33,7 +33,7 @@ public class SurfaceAngleMask extends AbstractExtentMask { @Override public boolean test(Extent extent, BlockVector3 vector) { if (!vector.getBlock(getExtent()).isAir() && nextToAir(vector)) { - double angle = 1 - getAverageAirDirection(vector.toVector3(), size).getY(); + double angle = 1 - getAverageAirDirection(vector.toVector3(), size).y(); return (angle >= (min / 90.0) && angle <= (max / 90.0)); } return false; @@ -44,7 +44,7 @@ public class SurfaceAngleMask extends AbstractExtentMask { for (int i = -size; i <= size; i++) { for (int j = -size; j <= size; j++) { for (int k = -size; k <= size; k++) { - Vector3 block = Vector3.at(currentLocation.getX(), currentLocation.getY(), currentLocation.getZ()).add( + Vector3 block = Vector3.at(currentLocation.x(), currentLocation.y(), currentLocation.z()).add( 0.5, 0.5, 0.5 @@ -65,13 +65,13 @@ public class SurfaceAngleMask extends AbstractExtentMask { double y = 0.0; double z = 0.0; for (Vector3 vector3 : airDirections) { - x += vector3.getX(); - y += vector3.getY(); - z += vector3.getZ(); + x += vector3.x(); + y += vector3.y(); + z += vector3.z(); } Vector3 averageAirDirection = Vector3.at(x / airDirections.size(), y / airDirections.size(), z / airDirections.size()); - return (Double.isNaN(averageAirDirection.getY()) ? Vector3.ZERO : averageAirDirection.normalize()); + return (Double.isNaN(averageAirDirection.y()) ? Vector3.ZERO : averageAirDirection.normalize()); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/WallMakeMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/WallMakeMask.java index 4246f8a82..9d7b7a729 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/WallMakeMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/WallMakeMask.java @@ -14,8 +14,8 @@ public class WallMakeMask implements Mask { @Override public boolean test(BlockVector3 position) { - int x = position.getBlockX(); - int z = position.getBlockZ(); + int x = position.x(); + int z = position.z(); return !region.contains(x, z + 1) || !region.contains(x, z - 1) || !region.contains(x + 1, z) || !region.contains( x - 1, z diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/WallMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/WallMask.java index 40a323e51..eee5ab286 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/WallMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/WallMask.java @@ -23,9 +23,9 @@ public class WallMask extends AbstractMask { public boolean test(BlockVector3 bv) { vector.setComponents(bv); int count = 0; - double x = vector.getX(); - double y = vector.getY(); - double z = vector.getZ(); + double x = vector.x(); + double y = vector.y(); + double z = vector.z(); vector.mutX(x + 1); if (mask.test(vector) && ++count == min && max >= 8) { vector.mutX(x); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/XAxisMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/XAxisMask.java index 7531d1465..82c0eca02 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/XAxisMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/XAxisMask.java @@ -16,9 +16,9 @@ public class XAxisMask extends AbstractMask implements ResettableMask { @Override public boolean test(BlockVector3 vector) { if (layer == -1) { - layer = vector.getBlockX(); + layer = vector.x(); } - return vector.getBlockX() == layer; + return vector.x() == layer; } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/YAxisMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/YAxisMask.java index ee852e70e..15ee08192 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/YAxisMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/YAxisMask.java @@ -14,9 +14,9 @@ public class YAxisMask extends AbstractMask implements ResettableMask { @Override public boolean test(BlockVector3 vector) { if (layer == -1) { - layer = vector.getBlockY(); + layer = vector.y(); } - return vector.getBlockY() == layer; + return vector.y() == layer; } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ZAxisMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ZAxisMask.java index 269fc5dd8..648b712d2 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ZAxisMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ZAxisMask.java @@ -14,9 +14,9 @@ public class ZAxisMask extends AbstractMask implements ResettableMask { @Override public boolean test(BlockVector3 vector) { if (layer == -1) { - layer = vector.getBlockZ(); + layer = vector.z(); } - return vector.getBlockZ() == layer; + return vector.z() == layer; } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/AngleColorPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/AngleColorPattern.java index a13061951..9f2becf76 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/AngleColorPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/AngleColorPattern.java @@ -42,9 +42,9 @@ public class AngleColorPattern extends AnglePattern { public > int getSlope(T block, BlockVector3 vector, Extent extent) { int slope = super.getSlope(block, vector, extent); if (slope != -1) { - int x = vector.getBlockX(); - int y = vector.getBlockY(); - int z = vector.getBlockZ(); + int x = vector.x(); + int y = vector.y(); + int z = vector.z(); int height = extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY); if (height > minY) { BlockState below = extent.getBlock(x, height - 1, z); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/AnglePattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/AnglePattern.java index 224d64434..caebfd6ff 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/AnglePattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/AnglePattern.java @@ -31,9 +31,9 @@ public abstract class AnglePattern extends AbstractPattern { } public > int getSlope(T block, BlockVector3 vector, Extent extent) { - int x = vector.getBlockX(); - int y = vector.getBlockY(); - int z = vector.getBlockZ(); + int x = vector.x(); + int y = vector.y(); + int z = vector.z(); if (!block.getBlockType().getMaterial().isMovementBlocker()) { return -1; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/BufferedPattern2D.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/BufferedPattern2D.java index 99414ca25..483629af4 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/BufferedPattern2D.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/BufferedPattern2D.java @@ -33,7 +33,7 @@ public class BufferedPattern2D extends BufferedPattern { @Override public boolean set(BlockVector3 pos) { - return set.add(pos.getBlockX(), 0, pos.getBlockY()); + return set.add(pos.x(), 0, pos.y()); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/ExpressionPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/ExpressionPattern.java index 638872ea8..9276acb40 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/ExpressionPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/ExpressionPattern.java @@ -50,7 +50,7 @@ public class ExpressionPattern extends AbstractPattern { if (expression.getEnvironment() instanceof WorldEditExpressionEnvironment) { ((WorldEditExpressionEnvironment) expression.getEnvironment()).setCurrentBlock(vector.toVector3()); } - double combined = expression.evaluate(vector.getX(), vector.getY(), vector.getZ()); + double combined = expression.evaluate(vector.x(), vector.y(), vector.z()); return BlockState.getFromOrdinal((int) combined).toBaseBlock(); } catch (EvaluationException e) { e.printStackTrace(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java index 13df9ca6f..d30206534 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java @@ -37,7 +37,7 @@ public class Linear2DBlockPattern extends AbstractPattern { @Override public BaseBlock applyBlock(BlockVector3 position) { - int index = (position.getBlockX() / this.xScale + position.getBlockZ() / this.zScale) % patternsArray.length; + int index = (position.x() / this.xScale + position.z() / this.zScale) % patternsArray.length; if (index < 0) { index += patternsArray.length; } @@ -46,8 +46,8 @@ public class Linear2DBlockPattern extends AbstractPattern { @Override public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { - int index = (floorDiv(get.getBlockX(), this.xScale) - + floorDiv(get.getBlockZ(), this.zScale)) % patternsArray.length; + int index = (floorDiv(get.x(), this.xScale) + + floorDiv(get.z(), this.zScale)) % patternsArray.length; if (index < 0) { index += patternsArray.length; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java index 6c9d039d0..de6e3257b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java @@ -40,8 +40,8 @@ public class Linear3DBlockPattern extends AbstractPattern { @Override public BaseBlock applyBlock(BlockVector3 position) { - int index = (position.getBlockX() / this.xScale - + position.getBlockY() / this.yScale + position.getBlockZ() / this.zScale) % patternsArray.length; + int index = (position.x() / this.xScale + + position.y() / this.yScale + position.z() / this.zScale) % patternsArray.length; if (index < 0) { index += patternsArray.length; } @@ -50,8 +50,8 @@ public class Linear3DBlockPattern extends AbstractPattern { @Override public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { - int index = (floorDiv(get.getBlockX(), this.xScale) - + floorDiv(get.getBlockY(), this.yScale) + floorDiv(get.getBlockZ(), this.zScale)) % patternsArray.length; + int index = (floorDiv(get.x(), this.xScale) + + floorDiv(get.y(), this.yScale) + floorDiv(get.z(), this.zScale)) % patternsArray.length; if (index < 0) { index += patternsArray.length; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoXPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoXPattern.java index b4e9aac37..2d4da9528 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoXPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoXPattern.java @@ -24,15 +24,15 @@ public class NoXPattern extends AbstractPattern { @Override public BaseBlock applyBlock(BlockVector3 pos) { - mutable.mutY(pos.getY()); - mutable.mutZ(pos.getZ()); + mutable.mutY(pos.y()); + mutable.mutZ(pos.z()); return pattern.applyBlock(mutable); } @Override public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { - mutable.mutY(get.getY()); - mutable.mutZ(get.getZ()); + mutable.mutY(get.y()); + mutable.mutZ(get.z()); return pattern.apply(extent, mutable, set); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoYPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoYPattern.java index 2fefaedfc..12ef8174d 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoYPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoYPattern.java @@ -24,15 +24,15 @@ public class NoYPattern extends AbstractPattern { @Override public BaseBlock applyBlock(BlockVector3 pos) { - mutable.mutX(pos.getX()); - mutable.mutZ(pos.getZ()); + mutable.mutX(pos.x()); + mutable.mutZ(pos.z()); return pattern.applyBlock(mutable); } @Override public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { - mutable.mutX(get.getX()); - mutable.mutZ(get.getZ()); + mutable.mutX(get.x()); + mutable.mutZ(get.z()); return pattern.apply(extent, mutable, set); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoZPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoZPattern.java index 8c100c5e3..f4d2a47ed 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoZPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoZPattern.java @@ -1,7 +1,6 @@ package com.fastasyncworldedit.core.function.pattern; import com.fastasyncworldedit.core.math.MutableBlockVector3; -import com.fastasyncworldedit.core.queue.Filter; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.pattern.AbstractPattern; @@ -25,15 +24,15 @@ public class NoZPattern extends AbstractPattern { @Override public BaseBlock applyBlock(BlockVector3 pos) { - mutable.mutX(pos.getX()); - mutable.mutY(pos.getY()); + mutable.mutX(pos.x()); + mutable.mutY(pos.y()); return pattern.applyBlock(mutable); } @Override public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { - mutable.mutX(get.getX()); - mutable.mutY(get.getY()); + mutable.mutX(get.x()); + mutable.mutY(get.y()); return pattern.apply(extent, mutable, set); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java index 9a5ca2ceb..5866766ef 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java @@ -40,10 +40,10 @@ public class OffsetPattern extends AbstractPattern { @Override public BaseBlock applyBlock(BlockVector3 position) { - mutable.mutX(position.getX() + dx); - mutable.mutY(position.getY() + dy); - mutable.mutZ(position.getZ() + dz); - if (mutable.getY() < minY || mutable.getY() > maxY) { + mutable.mutX(position.x() + dx); + mutable.mutY(position.y() + dy); + mutable.mutZ(position.z() + dz); + if (mutable.y() < minY || mutable.y() > maxY) { return BlockTypes.AIR.getDefaultState().toBaseBlock(); } return pattern.applyBlock(mutable); @@ -51,10 +51,10 @@ public class OffsetPattern extends AbstractPattern { @Override public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { - mutable.mutX(get.getX() + dx); - mutable.mutY(get.getY() + dy); - mutable.mutZ(get.getZ() + dz); - if (mutable.getY() < extent.getMinY() || mutable.getY() > extent.getMaxY()) { + mutable.mutX(get.x() + dx); + mutable.mutY(get.y() + dy); + mutable.mutZ(get.z() + dz); + if (mutable.y() < extent.getMinY() || mutable.y() > extent.getMaxY()) { return false; } return pattern.apply(extent, get, mutable); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java index c68bb24b1..5dc012f66 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java @@ -52,10 +52,10 @@ public class RandomOffsetPattern extends AbstractPattern { @Override public BaseBlock applyBlock(BlockVector3 position) { - mutable.mutX((position.getX() + r.nextInt(dx2) - dx)); - mutable.mutY((position.getY() + r.nextInt(dy2) - dy)); - mutable.mutZ((position.getZ() + r.nextInt(dz2) - dz)); - if (mutable.getY() < minY || mutable.getY() > maxY) { + mutable.mutX((position.x() + r.nextInt(dx2) - dx)); + mutable.mutY((position.y() + r.nextInt(dy2) - dy)); + mutable.mutZ((position.z() + r.nextInt(dz2) - dz)); + if (mutable.y() < minY || mutable.y() > maxY) { return BlockTypes.AIR.getDefaultState().toBaseBlock(); } return pattern.applyBlock(mutable); @@ -63,10 +63,10 @@ public class RandomOffsetPattern extends AbstractPattern { @Override public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { - mutable.mutX((set.getX() + r.nextInt(dx2) - dx)); - mutable.mutY((set.getY() + r.nextInt(dy2) - dy)); - mutable.mutZ((set.getZ() + r.nextInt(dz2) - dz)); - if (mutable.getY() < extent.getMinY() || mutable.getY() > extent.getMaxY()) { + mutable.mutX((set.x() + r.nextInt(dx2) - dx)); + mutable.mutY((set.y() + r.nextInt(dy2) - dy)); + mutable.mutZ((set.z() + r.nextInt(dz2) - dz)); + if (mutable.y() < extent.getMinY() || mutable.y() > extent.getMaxY()) { return false; } return pattern.apply(extent, get, mutable); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RelativePattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RelativePattern.java index 541aaa494..22e3a8d0b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RelativePattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RelativePattern.java @@ -35,10 +35,10 @@ public class RelativePattern extends AbstractPattern implements ResettablePatter if (origin == null) { origin = pos; } - mutable.mutX(pos.getX() - origin.getX()); - mutable.mutY(pos.getY() - origin.getY()); - mutable.mutZ(pos.getZ() - origin.getZ()); - if (mutable.getY() < minY || mutable.getY() > maxY) { + mutable.mutX(pos.x() - origin.x()); + mutable.mutY(pos.y() - origin.y()); + mutable.mutZ(pos.z() - origin.z()); + if (mutable.y() < minY || mutable.y() > maxY) { return BlockTypes.AIR.getDefaultState().toBaseBlock(); } return pattern.applyBlock(mutable); @@ -49,10 +49,10 @@ public class RelativePattern extends AbstractPattern implements ResettablePatter if (origin == null) { origin = set; } - mutable.mutX(set.getX() - origin.getX()); - mutable.mutY(set.getY() - origin.getY()); - mutable.mutZ(set.getZ() - origin.getZ()); - if (mutable.getY() < extent.getMinY() || mutable.getY() > extent.getMaxY()) { + mutable.mutX(set.x() - origin.x()); + mutable.mutY(set.y() - origin.y()); + mutable.mutZ(set.z() - origin.z()); + if (mutable.y() < extent.getMinY() || mutable.y() > extent.getMaxY()) { return false; } return pattern.apply(extent, get, mutable); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SolidRandomOffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SolidRandomOffsetPattern.java index 54ecf6676..698c0f199 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SolidRandomOffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SolidRandomOffsetPattern.java @@ -63,13 +63,13 @@ public class SolidRandomOffsetPattern extends AbstractPattern { @Override public BaseBlock applyBlock(BlockVector3 position) { - mutable.mutX(position.getX() + r.nextInt(dx2) - dx); - mutable.mutY(position.getY() + r.nextInt(dy2) - dy); - mutable.mutZ(position.getZ() + r.nextInt(dz2) - dz); - if (mutable.getY() < minY || mutable.getY() > maxY) { + mutable.mutX(position.x() + r.nextInt(dx2) - dx); + mutable.mutY(position.y() + r.nextInt(dy2) - dy); + mutable.mutZ(position.z() + r.nextInt(dz2) - dz); + if (mutable.y() < minY || mutable.y() > maxY) { return BlockTypes.AIR.getDefaultState().toBaseBlock(); } - if (mutable.getY() < minY || mutable.getY() > maxY) { + if (mutable.y() < minY || mutable.y() > maxY) { return BlockTypes.AIR.getDefaultState().toBaseBlock(); } BaseBlock block = pattern.applyBlock(mutable); @@ -81,10 +81,10 @@ public class SolidRandomOffsetPattern extends AbstractPattern { @Override public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { - mutable.mutX(set.getX() + r.nextInt(dx2) - dx); - mutable.mutY(set.getY() + r.nextInt(dy2) - dy); - mutable.mutZ(set.getZ() + r.nextInt(dz2) - dz); - if (mutable.getY() < extent.getMinY() || mutable.getY() > extent.getMaxY()) { + mutable.mutX(set.x() + r.nextInt(dx2) - dx); + mutable.mutY(set.y() + r.nextInt(dy2) - dy); + mutable.mutZ(set.z() + r.nextInt(dz2) - dz); + if (mutable.y() < extent.getMinY() || mutable.y() > extent.getMaxY()) { return false; } BaseBlock block = pattern.applyBlock(mutable); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java index 03e3126be..a7a1a3e2e 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java @@ -62,9 +62,9 @@ public class SurfaceRandomOffsetPattern extends AbstractPattern { next = buffer[i]; BlockVector3 dir = BreadthFirstSearch.DIAGONAL_DIRECTIONS[i]; next.setComponents( - cur.getBlockX() + dir.getBlockX(), - cur.getBlockY() + dir.getBlockY(), - cur.getBlockZ() + dir.getBlockZ() + cur.x() + dir.x(), + cur.y() + dir.y(), + cur.z() + dir.z() ); if (allowed(next)) { allowed[index++] = next; @@ -74,7 +74,7 @@ public class SurfaceRandomOffsetPattern extends AbstractPattern { return cur; } next = allowed[ThreadLocalRandom.current().nextInt(index)]; - cur.setComponents(next.getBlockX(), next.getBlockY(), next.getBlockZ()); + cur.setComponents(next.x(), next.y(), next.z()); } return cur; } @@ -85,9 +85,9 @@ public class SurfaceRandomOffsetPattern extends AbstractPattern { if (!block.getBlockType().getMaterial().isMovementBlocker()) { return false; } - int x = v.getBlockX(); - int y = v.getBlockY(); - int z = v.getBlockZ(); + int x = v.x(); + int y = v.y(); + int z = v.z(); v.mutY(y + 1); if (y < maxY && canPassthrough(v)) { v.mutY(y); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/visitor/AboveVisitor.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/visitor/AboveVisitor.java index d2503447b..67a48e2f7 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/visitor/AboveVisitor.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/visitor/AboveVisitor.java @@ -40,7 +40,7 @@ public class AboveVisitor extends RecursiveVisitor { @Override public boolean isVisitable(BlockVector3 from, BlockVector3 to) { - return (from.getBlockY() >= baseY) && super.isVisitable(from, to); + return (from.y() >= baseY) && super.isVisitable(from, to); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/visitor/DFSVisitor.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/visitor/DFSVisitor.java index 58b6f0e41..6a84af071 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/visitor/DFSVisitor.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/visitor/DFSVisitor.java @@ -64,13 +64,13 @@ public abstract class DFSVisitor implements Operation { IntTriple[] array = new IntTriple[directions.size()]; for (int i = 0; i < array.length; i++) { BlockVector3 dir = directions.get(i); - array[i] = new IntTriple(dir.getBlockX(), dir.getBlockY(), dir.getBlockZ()); + array[i] = new IntTriple(dir.x(), dir.y(), dir.z()); } return array; } public void visit(final BlockVector3 pos) { - Node node = new Node(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()); + Node node = new Node(pos.x(), pos.y(), pos.z()); if (!this.hashQueue.contains(node)) { isVisitable(pos, pos); // Ignore this, just to initialize mask on this point queue.addFirst(new NodePair(null, node, 0)); @@ -102,7 +102,7 @@ public abstract class DFSVisitor implements Operation { mutable2.mutY(from.getY() + direction.y()); mutable2.mutZ(from.getZ() + direction.z()); if (isVisitable(mutable, mutable2)) { - Node adjacent = new Node(mutable2.getBlockX(), mutable2.getBlockY(), mutable2.getBlockZ()); + Node adjacent = new Node(mutable2.x(), mutable2.y(), mutable2.z()); if (!adjacent.equals(current.from)) { AtomicInteger adjacentCount = visited.get(adjacent); if (adjacentCount == null) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/visitor/DirectionalVisitor.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/visitor/DirectionalVisitor.java index b7b14059b..f77b0b66b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/visitor/DirectionalVisitor.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/visitor/DirectionalVisitor.java @@ -52,22 +52,22 @@ public class DirectionalVisitor extends RecursiveVisitor { @Override public boolean isVisitable(final BlockVector3 from, final BlockVector3 to) { - int dx = to.getBlockX() - from.getBlockX(); - int dz = to.getBlockZ() - from.getBlockZ(); - int dy = to.getBlockY() - from.getBlockY(); + int dx = to.x() - from.x(); + int dz = to.z() - from.z(); + int dy = to.y() - from.y(); if (dx != 0) { - if (dirVec.getBlockX() != 0 && dirVec.getBlockX() != dx) { + if (dirVec.x() != 0 && dirVec.x() != dx) { return false; } } if (dy != 0) { - if (dirVec.getBlockY() != 0 && dirVec.getBlockY() != dy) { + if (dirVec.y() != 0 && dirVec.y() != dy) { return false; } } if (dz != 0) { - if (dirVec.getBlockZ() != 0 && dirVec.getBlockZ() != dz) { + if (dirVec.z() != 0 && dirVec.z() != dz) { return false; } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/RollbackOptimizedHistory.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/RollbackOptimizedHistory.java index 1f01f99de..e11fda2b1 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/RollbackOptimizedHistory.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/RollbackOptimizedHistory.java @@ -84,12 +84,12 @@ public class RollbackOptimizedHistory extends DiskStorageHistory { } public void setDimensions(BlockVector3 pos1, BlockVector3 pos2) { - this.minX = pos1.getBlockX(); - this.minY = pos1.getBlockY(); - this.minZ = pos1.getBlockZ(); - this.maxX = pos2.getBlockX(); - this.maxY = pos2.getBlockY(); - this.maxZ = pos2.getBlockZ(); + this.minX = pos1.x(); + this.minY = pos1.y(); + this.minZ = pos1.z(); + this.maxX = pos2.x(); + this.maxY = pos2.y(); + this.maxZ = pos2.z(); } public void setTime(long time) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java index 4bbe1a109..e5820fd44 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java @@ -127,18 +127,18 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { if (!tilesFrom.isEmpty()) { for (Map.Entry entry : tilesFrom.entrySet()) { BlockVector3 pos = entry.getKey(); - BlockState fromBlock = get.getBlock(pos.getX() & 15, pos.getY(), pos.getZ() & 15); - BlockState toBlock = set.getBlock(pos.getX() & 15, pos.getY(), pos.getZ() & 15); + BlockState fromBlock = get.getBlock(pos.x() & 15, pos.y(), pos.z() & 15); + BlockState toBlock = set.getBlock(pos.x() & 15, pos.y(), pos.z() & 15); if (fromBlock != toBlock || tilesTo.containsKey(pos)) { - addTileRemove(MainUtil.setPosition(entry.getValue(), entry.getKey().getX(), entry.getKey().getY(), - entry.getKey().getZ())); + addTileRemove(MainUtil.setPosition(entry.getValue(), entry.getKey().x(), entry.getKey().y(), + entry.getKey().z())); } } } if (!tilesTo.isEmpty()) { for (Map.Entry entry : tilesTo.entrySet()) { BlockVector3 pos = entry.getKey(); - addTileCreate(MainUtil.setPosition(entry.getValue(), pos.getX() + bx, pos.getY(), pos.getZ() + bz)); + addTileCreate(MainUtil.setPosition(entry.getValue(), pos.x() + bx, pos.y(), pos.z() + bz)); } } Set entRemoves = set.getEntityRemoves(); @@ -310,9 +310,9 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { } public void add(BlockVector3 loc, BaseBlock from, BaseBlock to) { - int x = loc.getBlockX(); - int y = loc.getBlockY(); - int z = loc.getBlockZ(); + int x = loc.x(); + int y = loc.y(); + int z = loc.z(); add(x, y, z, from, to); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/BlockBagChangeSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/BlockBagChangeSet.java index 22833d3b5..c0dc9756c 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/BlockBagChangeSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/BlockBagChangeSet.java @@ -68,9 +68,9 @@ public class BlockBagChangeSet extends AbstractDelegateChangeSet { @Override public void add(BlockVector3 loc, BaseBlock from, BaseBlock to) { - int x = loc.getBlockX(); - int y = loc.getBlockY(); - int z = loc.getBlockZ(); + int x = loc.x(); + int y = loc.y(); + int z = loc.z(); add(x, y, z, from, to); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BlockVector3ChunkMap.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BlockVector3ChunkMap.java index a9f8a0210..919556847 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BlockVector3ChunkMap.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BlockVector3ChunkMap.java @@ -31,7 +31,7 @@ public class BlockVector3ChunkMap implements IAdaptedMap implements int cx = (int) MathMan.untripleWorldCoordX(triple); int cy = (int) MathMan.untripleWorldCoordY(triple); int cz = (int) MathMan.untripleWorldCoordZ(triple); - pos.mutX((cx << 11) + pos.getBlockX()); - pos.mutY((cy << 9) + pos.getBlockY()); - pos.mutZ((cz << 11) + pos.getBlockZ()); + pos.mutX((cx << 11) + pos.x()); + pos.mutY((cy << 9) + pos.y()); + pos.mutZ((cz << 11) + pos.z()); return pos.toImmutable(); } } @@ -124,7 +124,7 @@ public class BlockVectorSet extends AbstractCollection implements @Override public boolean contains(Object o) { if (o instanceof BlockVector3 v) { - return contains(v.getBlockX(), v.getBlockY(), v.getBlockZ()); + return contains(v.x(), v.y(), v.z()); } return false; } @@ -166,9 +166,9 @@ public class BlockVectorSet extends AbstractCollection implements int cy = (int) MathMan.untripleWorldCoordY(triple); int cz = (int) MathMan.untripleWorldCoordZ(triple); return mutable.setComponents( - (cx << 11) + localPos.getBlockX(), - (cy << 9) + localPos.getBlockY(), - (cz << 11) + localPos.getBlockZ() + (cx << 11) + localPos.x(), + (cy << 9) + localPos.y(), + (cz << 11) + localPos.z() ); } }; @@ -176,7 +176,7 @@ public class BlockVectorSet extends AbstractCollection implements @Override public boolean add(BlockVector3 vector) { - return add(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()); + return add(vector.x(), vector.y(), vector.z()); } public boolean add(int x, int y, int z) { @@ -209,7 +209,7 @@ public class BlockVectorSet extends AbstractCollection implements @Override public boolean remove(Object o) { if (o instanceof BlockVector3 v) { - return remove(v.getBlockX(), v.getBlockY(), v.getBlockZ()); + return remove(v.x(), v.y(), v.z()); } return false; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/LocalBlockVectorSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/LocalBlockVectorSet.java index 2ed3a2f63..72287b0a1 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/LocalBlockVectorSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/LocalBlockVectorSet.java @@ -90,7 +90,7 @@ public class LocalBlockVectorSet implements BlockVector3Set { @Override public boolean contains(Object o) { if (o instanceof BlockVector3 v) { - return contains(v.getBlockX(), v.getBlockY(), v.getBlockZ()); + return contains(v.x(), v.y(), v.z()); } return false; } @@ -302,14 +302,14 @@ public class LocalBlockVectorSet implements BlockVector3Set { */ @Override public boolean add(BlockVector3 vector) { - return add(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()); + return add(vector.x(), vector.y(), vector.z()); } private int getIndex(BlockVector3 vector) { return MathMan.tripleSearchCoords( - vector.getBlockX() - offsetX, - vector.getBlockY() - offsetY, - vector.getBlockZ() - offsetZ + vector.x() - offsetX, + vector.y() - offsetY, + vector.z() - offsetZ ); } @@ -342,7 +342,7 @@ public class LocalBlockVectorSet implements BlockVector3Set { public boolean remove(Object o) { if (o instanceof BlockVector3) { BlockVector3 v = (BlockVector3) o; - return remove(v.getBlockX(), v.getBlockY(), v.getBlockZ()); + return remove(v.x(), v.y(), v.z()); } return false; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/heightmap/HeightMap.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/heightmap/HeightMap.java index f9b2ce914..eeafc8646 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/heightmap/HeightMap.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/heightmap/HeightMap.java @@ -10,7 +10,6 @@ import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; -import java.lang.reflect.InvocationTargetException; import java.util.concurrent.ThreadLocalRandom; public interface HeightMap { @@ -45,7 +44,7 @@ public interface HeightMap { boolean layers ) throws MaxChangedBlocksException { BlockVector3 top = session.getMaximumPoint(); - int maxY = top.getBlockY(); + int maxY = top.y(); Location min = new Location(session.getWorld(), pos.subtract(size, size, size).toVector3()); BlockVector3 max = pos.add(size, maxY, size); Region region = new CuboidRegion(session.getWorld(), min.toBlockPoint(), max); @@ -81,9 +80,9 @@ public interface HeightMap { int maxY = session.getMaxY(); int minY = session.getMinY(); int diameter = 2 * size + 1; - int centerX = pos.getBlockX(); - int centerZ = pos.getBlockZ(); - int centerY = pos.getBlockY(); + int centerX = pos.x(); + int centerZ = pos.z(); + int centerY = pos.y(); int[] oldData = new int[diameter * diameter]; int[] newData = new int[oldData.length]; if (layers) { // Pixel accuracy @@ -92,7 +91,7 @@ public interface HeightMap { } if (towards) { double sizePowInv = 1d / Math.pow(size, yscale); - int targetY = pos.getBlockY(); + int targetY = pos.y(); int tmpY = targetY; for (int x = -size; x <= size; x++) { int xx = centerX + x; @@ -133,7 +132,7 @@ public interface HeightMap { } } } else { - int height = pos.getBlockY(); + int height = pos.y(); for (int x = -size; x <= size; x++) { int xx = centerX + x; for (int z = -size; z <= size; z++) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/heightmap/RotatableHeightMap.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/heightmap/RotatableHeightMap.java index 291f8e754..a452a80f4 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/heightmap/RotatableHeightMap.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/heightmap/RotatableHeightMap.java @@ -24,7 +24,7 @@ public class RotatableHeightMap extends AbstractDelegateHeightMap { mutable.mutX(x); mutable.mutZ(z); BlockVector3 pos = transform.apply(mutable.setComponents(x, 0, z)).toBlockPoint(); - return super.getHeight(pos.getBlockX(), pos.getBlockZ()); + return super.getHeight(pos.x(), pos.z()); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/heightmap/ScalableHeightMap.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/heightmap/ScalableHeightMap.java index c4481da46..bc845127d 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/heightmap/ScalableHeightMap.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/heightmap/ScalableHeightMap.java @@ -56,22 +56,22 @@ public class ScalableHeightMap implements HeightMap { public static ScalableHeightMap fromClipboard(Clipboard clipboard, int minY, int maxY) { BlockVector3 dim = clipboard.getDimensions(); - char[][] heightArray = new char[dim.getBlockX()][dim.getBlockZ()]; - int clipMinX = clipboard.getMinimumPoint().getBlockX(); - int clipMinZ = clipboard.getMinimumPoint().getBlockZ(); - int clipMinY = clipboard.getMinimumPoint().getBlockY(); - int clipMaxY = clipboard.getMaximumPoint().getBlockY(); + char[][] heightArray = new char[dim.x()][dim.z()]; + int clipMinX = clipboard.getMinimumPoint().x(); + int clipMinZ = clipboard.getMinimumPoint().z(); + int clipMinY = clipboard.getMinimumPoint().y(); + int clipMaxY = clipboard.getMaximumPoint().y(); int clipHeight = clipMaxY - clipMinY + 1; HashSet visited = new HashSet<>(); MutableBlockVector3 bv = new MutableBlockVector3(); for (BlockVector3 pos : clipboard.getRegion()) { - IntPair pair = new IntPair(pos.getBlockX(), pos.getBlockZ()); + IntPair pair = new IntPair(pos.x(), pos.z()); if (visited.contains(pair)) { continue; } visited.add(pair); - int xx = pos.getBlockX(); - int zz = pos.getBlockZ(); + int xx = pos.x(); + int zz = pos.z(); int highestY = clipMinY; bv.setComponents(pos); for (int y = clipMinY; y <= clipMaxY; y++) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/SimplexNoiseGenerator.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/SimplexNoiseGenerator.java index 8d8aeedf5..d690509dc 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/SimplexNoiseGenerator.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/random/SimplexNoiseGenerator.java @@ -8,12 +8,12 @@ public class SimplexNoiseGenerator implements NoiseGenerator { @Override public float noise(Vector2 position) { - return convert(SimplexNoise.noise(position.getX(), position.getZ())); + return convert(SimplexNoise.noise(position.x(), position.z())); } @Override public float noise(Vector3 position) { - return convert(SimplexNoise.noise(position.getX(), position.getY(), position.getZ())); + return convert(SimplexNoise.noise(position.x(), position.y(), position.z())); } private float convert(double d) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkExtent.java index ec6162798..a56fe27d5 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkExtent.java @@ -52,8 +52,8 @@ public interface IChunkExtent extends Extent { @Override default boolean setBiome(BlockVector3 position, BiomeType biome) { - final IChunk chunk = getOrCreateChunk(position.getX() >> 4, position.getZ() >> 4); - return chunk.setBiome(position.getX() & 15, position.getY(), position.getZ() & 15, biome); + final IChunk chunk = getOrCreateChunk(position.x() >> 4, position.z() >> 4); + return chunk.setBiome(position.x() & 15, position.y(), position.z() & 15, biome); } @Override @@ -76,8 +76,8 @@ public interface IChunkExtent extends Extent { @Override default BiomeType getBiome(BlockVector3 position) { - final IChunk chunk = getOrCreateChunk(position.getX() >> 4, position.getZ() >> 4); - return chunk.getBiomeType(position.getX() & 15, position.getY(), position.getZ() & 15); + final IChunk chunk = getOrCreateChunk(position.x() >> 4, position.z() >> 4); + return chunk.getBiomeType(position.x() & 15, position.y(), position.z() & 15); } @Override @@ -129,9 +129,9 @@ public interface IChunkExtent extends Extent { //Set pos List posList = new ArrayList<>(); - posList.add(new DoubleTag(location.getX())); - posList.add(new DoubleTag(location.getY())); - posList.add(new DoubleTag(location.getZ())); + posList.add(new DoubleTag(location.x())); + posList.add(new DoubleTag(location.y())); + posList.add(new DoubleTag(location.z())); map.put("Pos", new ListTag(DoubleTag.class, posList)); NBTUtils.addUUIDToMap(map, uuid); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkGet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkGet.java index 458b1858c..b2ac59cb2 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkGet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkGet.java @@ -25,7 +25,7 @@ public interface IChunkGet extends IBlocks, Trimable, InputExtent, ITileInput { @Override default BiomeType getBiome(BlockVector3 position) { - return getBiomeType(position.getX(), position.getY(), position.getZ()); + return getBiomeType(position.x(), position.y(), position.z()); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkSet.java index 1af60b3a2..bc621e66a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkSet.java @@ -25,7 +25,7 @@ public interface IChunkSet extends IBlocks, OutputExtent { @Override default boolean setBiome(BlockVector3 position, BiomeType biome) { - return setBiome(position.getX(), position.getY(), position.getZ(), biome); + return setBiome(position.x(), position.y(), position.z(), biome); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueExtent.java index 104167d30..c13373d9a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueExtent.java @@ -152,7 +152,7 @@ public interface IQueueExtent extends Flushable, Trimable, ICh final Set chunks = region.getChunks(); ChunkFilterBlock block = null; for (BlockVector2 chunk : chunks) { - block = apply(block, filter, region, chunk.getX(), chunk.getZ(), full); + block = apply(block, filter, region, chunk.x(), chunk.z(), full); } flush(); return filter; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java index e88a9ccd3..38546ed1b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java @@ -135,7 +135,7 @@ public class ParallelQueueExtent extends PassthroughExtent { // if PQE is ever used with PARALLEL_THREADS = 1, or only one chunk is edited, just run sequentially while (chunksIter.hasNext()) { BlockVector2 pos = chunksIter.next(); - getExtent().apply(null, filter, region, pos.getX(), pos.getZ(), full); + getExtent().apply(null, filter, region, pos.x(), pos.z(), full); } } else { final ForkJoinTask[] tasks = IntStream.range(0, size).mapToObj(i -> handler.submit(() -> { @@ -159,8 +159,8 @@ public class ParallelQueueExtent extends PassthroughExtent { break; } final BlockVector2 pos = chunksIter.next(); - chunkX = pos.getX(); - chunkZ = pos.getZ(); + chunkX = pos.x(); + chunkZ = pos.z(); } block = queue.apply(block, newFilter, region, chunkX, chunkZ, full); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java index 6e06ce348..789547d83 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java @@ -356,7 +356,7 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen break; } loadCount++; - addChunkLoad(from.getBlockX(), from.getBlockZ()); + addChunkLoad(from.x(), from.z()); } } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharSetBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharSetBlocks.java index 9ab8734ea..da28e5925 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharSetBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharSetBlocks.java @@ -128,7 +128,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { @Override public > boolean setBlock(BlockVector3 position, T block) throws WorldEditException { - return setBlock(position.getX(), position.getY(), position.getZ(), block); + return setBlock(position.x(), position.y(), position.z(), block); } @Override @@ -255,7 +255,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { - return setBiome(position.getX(), position.getY(), position.getZ(), biome); + return setBiome(position.x(), position.y(), position.z(), biome); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeCharBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeCharBlocks.java index ca0dd3442..54331279f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeCharBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeCharBlocks.java @@ -218,7 +218,7 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks { @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { - return setBiome(position.getX(), position.getY(), position.getZ(), biome); + return setBiome(position.x(), position.y(), position.z(), biome); } public void set(int x, int y, int z, char value) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/preloader/AsyncPreloader.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/preloader/AsyncPreloader.java index 7a74ed8ac..672ecfc93 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/preloader/AsyncPreloader.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/preloader/AsyncPreloader.java @@ -111,8 +111,8 @@ public class AsyncPreloader implements Preloader, Runnable { while (chunksIter.hasNext() && pair.getValue() == chunks) { // Ensure the queued load is still valid BlockVector2 chunk = chunksIter.next(); if (Settings.settings().REGION_RESTRICTIONS_OPTIONS.RESTRICT_TO_SAFE_RANGE) { - int x = chunk.getX(); - int z = chunk.getZ(); + int x = chunk.x(); + int z = chunk.z(); // if any chunk coord is outside 30 million blocks if (x > 1875000 || z > 1875000 || x < -1875000 || z < -1875000) { continue; @@ -130,7 +130,7 @@ public class AsyncPreloader implements Preloader, Runnable { } private void queueLoad(World world, BlockVector2 chunk) { - world.checkLoadedChunk(BlockVector3.at(chunk.getX() << 4, 0, chunk.getZ() << 4)); + world.checkLoadedChunk(BlockVector3.at(chunk.x() << 4, 0, chunk.z() << 4)); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FuzzyRegion.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FuzzyRegion.java index 58061bfa0..e080baeaf 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FuzzyRegion.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FuzzyRegion.java @@ -52,7 +52,7 @@ public class FuzzyRegion extends AbstractRegion { */ public void select(BlockVector3 position) { RecursiveVisitor search = new RecursiveVisitor(mask, p -> { - setMinMax(p.getBlockX(), p.getBlockY(), p.getBlockZ()); + setMinMax(p.x(), p.y(), p.z()); return true; }, 256, extent.getMinY(), extent.getMaxY(), extent); search.setVisited(set); @@ -120,7 +120,7 @@ public class FuzzyRegion extends AbstractRegion { @Override public boolean contains(BlockVector3 position) { - return contains(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + return contains(position.x(), position.y(), position.z()); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java index 03dd750a5..dbfe840c8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java @@ -261,27 +261,27 @@ public class PolyhedralRegion extends AbstractRegion { if (!isDefined()) { return false; } - final int x = position.getBlockX(); - final int y = position.getBlockY(); - final int z = position.getBlockZ(); + final int x = position.x(); + final int y = position.y(); + final int z = position.z(); final BlockVector3 min = getMinimumPoint(); final BlockVector3 max = getMaximumPoint(); - if (x < min.getBlockX()) { + if (x < min.x()) { return false; } - if (x > max.getBlockX()) { + if (x > max.x()) { return false; } - if (z < min.getBlockZ()) { + if (z < min.z()) { return false; } - if (z > max.getBlockZ()) { + if (z > max.z()) { return false; } - if (y < min.getBlockY()) { + if (y < min.y()) { return false; } - if (y > max.getBlockY()) { + if (y > max.y()) { return false; } return containsRaw(position); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/RegionWrapper.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/RegionWrapper.java index e382583aa..40d0075e5 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/RegionWrapper.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/RegionWrapper.java @@ -44,12 +44,12 @@ public class RegionWrapper extends CuboidRegion { public RegionWrapper(final BlockVector3 pos1, final BlockVector3 pos2) { super(pos1, pos2); - this.minX = Math.min(pos1.getBlockX(), pos2.getBlockX()); - this.minZ = Math.min(pos1.getBlockZ(), pos2.getBlockZ()); - this.maxX = Math.max(pos1.getBlockX(), pos2.getBlockX()); - this.maxZ = Math.max(pos1.getBlockZ(), pos2.getBlockZ()); - this.minY = Math.min(pos1.getBlockY(), pos2.getBlockY()); - this.maxY = Math.max(pos1.getBlockY(), pos2.getBlockY()); + this.minX = Math.min(pos1.x(), pos2.x()); + this.minZ = Math.min(pos1.z(), pos2.z()); + this.maxX = Math.max(pos1.x(), pos2.x()); + this.maxZ = Math.max(pos1.z(), pos2.z()); + this.minY = Math.min(pos1.y(), pos2.y()); + this.maxY = Math.max(pos1.y(), pos2.y()); } public static RegionWrapper GLOBAL() { @@ -61,12 +61,12 @@ public class RegionWrapper extends CuboidRegion { super.recalculate(); BlockVector3 pos1 = getMinimumPoint(); BlockVector3 pos2 = getMaximumPoint(); - this.minX = Math.min(pos1.getBlockX(), pos2.getBlockX()); - this.minZ = Math.min(pos1.getBlockZ(), pos2.getBlockZ()); - this.maxX = Math.max(pos1.getBlockX(), pos2.getBlockX()); - this.maxZ = Math.max(pos1.getBlockZ(), pos2.getBlockZ()); - this.minY = Math.min(pos1.getBlockY(), pos2.getBlockY()); - this.maxY = Math.max(pos1.getBlockY(), pos2.getBlockY()); + this.minX = Math.min(pos1.x(), pos2.x()); + this.minZ = Math.min(pos1.z(), pos2.z()); + this.maxX = Math.max(pos1.x(), pos2.x()); + this.maxZ = Math.max(pos1.z(), pos2.z()); + this.minY = Math.min(pos1.y(), pos2.y()); + this.maxY = Math.max(pos1.y(), pos2.y()); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/Triangle.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/Triangle.java index 46e934bee..2bb9fc5ac 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/Triangle.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/Triangle.java @@ -28,9 +28,9 @@ public class Triangle { private final double b; public Triangle(BlockVector3 pos1, BlockVector3 pos2, BlockVector3 pos3) { - verts[0] = new double[]{pos1.getBlockX(), pos1.getBlockY(), pos1.getBlockZ()}; - verts[1] = new double[]{pos2.getBlockX(), pos2.getBlockY(), pos2.getBlockZ()}; - verts[2] = new double[]{pos3.getBlockX(), pos3.getBlockY(), pos3.getBlockZ()}; + verts[0] = new double[]{pos1.x(), pos1.y(), pos1.z()}; + verts[1] = new double[]{pos2.x(), pos2.y(), pos2.z()}; + verts[2] = new double[]{pos3.x(), pos3.y(), pos3.z()}; radius[0] = RADIUS; radius[1] = RADIUS; radius[2] = RADIUS; @@ -72,9 +72,9 @@ public class Triangle { } public boolean contains(BlockVector3 pos) { - center[0] = pos.getBlockX() + RADIUS; - center[1] = pos.getBlockY() + RADIUS; - center[2] = pos.getBlockZ() + RADIUS; + center[0] = pos.x() + RADIUS; + center[1] = pos.y() + RADIUS; + center[2] = pos.z() + RADIUS; return overlaps(center, radius, verts); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/filter/CuboidRegionFilter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/filter/CuboidRegionFilter.java index d354eae3b..72413e115 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/filter/CuboidRegionFilter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/filter/CuboidRegionFilter.java @@ -19,10 +19,10 @@ public abstract class CuboidRegionFilter implements RegionFilter { public abstract void calculateRegions(); public void add(BlockVector2 pos1, BlockVector2 pos2) { - int ccx1 = pos1.getBlockX() >> 9; - int ccz1 = pos1.getBlockZ() >> 9; - int ccx2 = pos2.getBlockX() >> 9; - int ccz2 = pos2.getBlockZ() >> 9; + int ccx1 = pos1.x() >> 9; + int ccz1 = pos1.z() >> 9; + int ccx2 = pos2.x() >> 9; + int ccz2 = pos2.z() >> 9; for (int x = ccx1; x <= ccx2; x++) { for (int z = ccz1; z <= ccz2; z++) { if (!occupiedRegions.containsKey(x, z)) { @@ -39,10 +39,10 @@ public abstract class CuboidRegionFilter implements RegionFilter { } } } - int cx1 = pos1.getBlockX() >> 4; - int cz1 = pos1.getBlockZ() >> 4; - int cx2 = pos2.getBlockX() >> 4; - int cz2 = pos2.getBlockZ() >> 4; + int cx1 = pos1.x() >> 4; + int cz1 = pos1.z() >> 4; + int cx2 = pos2.x() >> 4; + int cz2 = pos2.z() >> 4; for (int chunkZ = cz1; chunkZ <= cz2; chunkZ++) { for (int chunkX = cx1; chunkX <= cx2; chunkX++) { unoccupiedChunks.remove(chunkX, chunkZ); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java index 1c5fe044a..117ab8fab 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java @@ -450,9 +450,9 @@ public class MainUtil { Location loc = entity.getLocation(); // Create a copy, because the list is immutable... List posList = new ArrayList<>(pos.getValue()); - posList.set(0, new DoubleTag(loc.getX())); - posList.set(1, new DoubleTag(loc.getY())); - posList.set(2, new DoubleTag(loc.getZ())); + posList.set(0, new DoubleTag(loc.x())); + posList.set(1, new DoubleTag(loc.y())); + posList.set(2, new DoubleTag(loc.z())); map.put("Pos", new ListTag(pos.getType(), posList)); } return new CompoundTag(map); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/WEManager.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/WEManager.java index b31853dd0..00ededf1a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/WEManager.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/WEManager.java @@ -183,8 +183,8 @@ public class WEManager { BlockVector3 rg2P1 = region2.getMinimumPoint(); BlockVector3 rg2P2 = region2.getMaximumPoint(); - return rg1P1.getBlockX() <= rg2P2.getBlockX() && rg1P2.getBlockX() >= rg2P1.getBlockX() - && rg1P1.getBlockZ() <= rg2P2.getBlockZ() && rg1P2.getBlockZ() >= rg2P1.getBlockZ(); + return rg1P1.x() <= rg2P2.x() && rg1P2.x() >= rg2P1.x() + && rg1P1.z() <= rg2P2.z() && rg1P2.z() >= rg2P1.z(); } public boolean regionContains(Region selection, HashSet mask) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockSet.java index 0706a39d2..06e7d7cff 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockSet.java @@ -35,7 +35,7 @@ public abstract class BlockSet extends AbstractRegion { @Override public boolean contains(BlockVector3 obj) { - return contains(obj.getX(), obj.getY(), obj.getZ()); + return contains(obj.x(), obj.y(), obj.z()); } protected final int lowestBit(long bitBuffer) { @@ -71,11 +71,11 @@ public abstract class BlockSet extends AbstractRegion { @Override public boolean add(BlockVector3 p) { - return add(p.getX(), p.getY(), p.getZ()); + return add(p.x(), p.y(), p.z()); } public boolean remove(BlockVector3 p) { - return remove(p.getX(), p.getY(), p.getZ()); + return remove(p.x(), p.y(), p.z()); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockVector3Set.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockVector3Set.java index cadc35fc8..8bf9463f9 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockVector3Set.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/BlockVector3Set.java @@ -23,11 +23,11 @@ public interface BlockVector3Set extends Set { // Set default offset as many operations utilising a region are likely to start in a corner, this initialising the // LocalBlockVectorSet poorly // This needs to be ceiling as LocalBlockVector extends 1 block further "negative" - int offsetX = (int) Math.ceil((min.getX() + max.getX()) / 2d); - int offsetZ = (int) Math.ceil((min.getZ() + max.getZ()) / 2d); + int offsetX = (int) Math.ceil((min.x() + max.x()) / 2d); + int offsetZ = (int) Math.ceil((min.z() + max.z()) / 2d); int offsetY; if (region.getMinimumY() < -128 || region.getMaximumY() > 320) { - offsetY = (min.getY() + max.getY()) / 2; + offsetY = (min.y() + max.y()) / 2; } else { offsetY = 128; } @@ -43,7 +43,7 @@ public interface BlockVector3Set extends Set { * @return Appropriate {@link BlockVector3Set} implementation */ static BlockVector3Set getAppropriateVectorSet(BlockVector3 size) { - if (size.getBlockX() > 2048 || size.getBlockZ() > 2048 || size.getBlockY() > 512) { + if (size.x() > 2048 || size.z() > 2048 || size.y() > 512) { return new BlockVectorSet(); } else { return new LocalBlockVectorSet(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/MemBlockSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/MemBlockSet.java index 33fc963c3..68990cad1 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/MemBlockSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/collection/MemBlockSet.java @@ -1,7 +1,6 @@ package com.fastasyncworldedit.core.util.collection; import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.math.MutableBlockVector2; import com.fastasyncworldedit.core.math.MutableBlockVector3; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; @@ -167,9 +166,9 @@ public final class MemBlockSet extends BlockSet { @Override public boolean contains(Object o) { if (o instanceof BlockVector2 other) { - IRow rowx = rows[other.getX() - getChunkOffsetX()]; + IRow rowx = rows[other.x() - getChunkOffsetX()]; if (rowx instanceof RowX) { - return ((RowX) rowx).rows[other.getZ() - getChunkOffsetZ()] instanceof RowZ; + return ((RowX) rowx).rows[other.z() - getChunkOffsetZ()] instanceof RowZ; } } return false; @@ -269,11 +268,11 @@ public final class MemBlockSet extends BlockSet { @Override public boolean contains(Object o) { if (o instanceof BlockVector3 other) { - IRow rowx = rows[other.getX() - getChunkOffsetX()]; + IRow rowx = rows[other.x() - getChunkOffsetX()]; if (rowx instanceof RowX) { - IRow rowz = ((RowX) rowx).rows[other.getZ()]; + IRow rowz = ((RowX) rowx).rows[other.z()]; if (rowz instanceof RowZ) { - return ((RowZ) rowz).rows[other.getY() - (minSectionPosition << 4) - getChunkOffsetZ()] instanceof RowY; + return ((RowZ) rowz).rows[other.y() - (minSectionPosition << 4) - getChunkOffsetZ()] instanceof RowY; } } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/world/SimpleWorld.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/world/SimpleWorld.java index dcc65ae21..1619f114f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/world/SimpleWorld.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/world/SimpleWorld.java @@ -58,12 +58,12 @@ public interface SimpleWorld extends World { @Override default int getMaxY() { - return getMaximumPoint().getBlockY(); + return getMaximumPoint().y(); } @Override default int getMinY() { - return getMinimumPoint().getBlockY(); + return getMinimumPoint().y(); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/AsyncPlayer.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/AsyncPlayer.java index 700070611..077e87e8c 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/AsyncPlayer.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/wrappers/AsyncPlayer.java @@ -97,7 +97,7 @@ public class AsyncPlayer extends PlayerProxy { return false; } - while (y <= world.getMaximumPoint().getY()) { + while (y <= world.getMaximumPoint().y()) { // Found a ceiling! if (world.getBlock(mutable.mutY(y)).getBlockType().getMaterial() .isMovementBlocker()) { diff --git a/worldedit-core/src/main/java/com/sk89q/util/yaml/YAMLNode.java b/worldedit-core/src/main/java/com/sk89q/util/yaml/YAMLNode.java index d4cc816e7..a894cbe14 100644 --- a/worldedit-core/src/main/java/com/sk89q/util/yaml/YAMLNode.java +++ b/worldedit-core/src/main/java/com/sk89q/util/yaml/YAMLNode.java @@ -161,28 +161,28 @@ public class YAMLNode { if (value instanceof Vector3) { Map out = new LinkedHashMap<>(); Vector3 vec = (Vector3) value; - out.put("x", vec.getX()); - out.put("y", vec.getY()); - out.put("z", vec.getZ()); + out.put("x", vec.x()); + out.put("y", vec.y()); + out.put("z", vec.z()); return out; } else if (value instanceof BlockVector3) { Map out = new LinkedHashMap<>(); BlockVector3 vec = (BlockVector3) value; - out.put("x", vec.getBlockX()); - out.put("y", vec.getBlockY()); - out.put("z", vec.getBlockZ()); + out.put("x", vec.x()); + out.put("y", vec.y()); + out.put("z", vec.z()); return out; } else if (value instanceof Vector2) { Map out = new LinkedHashMap<>(); Vector2 vec = (Vector2) value; - out.put("x", vec.getX()); - out.put("z", vec.getZ()); + out.put("x", vec.x()); + out.put("z", vec.z()); return out; } else if (value instanceof BlockVector2) { Map out = new LinkedHashMap<>(); BlockVector2 vec = (BlockVector2) value; - out.put("x", vec.getBlockX()); - out.put("z", vec.getBlockZ()); + out.put("x", vec.x()); + out.put("z", vec.z()); return out; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index ecf859896..2e5e3c2ef 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -903,7 +903,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { //FAWE start - use extent - if (position.getY() < this.minY || position.getY() > this.maxY) { + if (position.y() < this.minY || position.y() > this.maxY) { return false; } this.changes++; @@ -984,7 +984,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { public > boolean setBlock(BlockVector3 position, B block, Stage stage) throws WorldEditException { //FAWE start - accumulate changes - if (position.getBlockY() < this.minY || position.getBlockY() > this.maxY) { + if (position.y() < this.minY || position.y() > this.maxY) { return false; } @@ -1014,7 +1014,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { */ @Deprecated public > boolean rawSetBlock(BlockVector3 position, B block) { - if (position.getBlockY() < this.minY || position.getBlockY() > this.maxY) { + if (position.y() < this.minY || position.y() > this.maxY) { return false; } @@ -1037,7 +1037,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { * @return whether the block changed */ public > boolean smartSetBlock(BlockVector3 position, B block) { - if (position.getBlockY() < this.minY || position.getBlockY() > this.maxY) { + if (position.y() < this.minY || position.y() > this.maxY) { return false; } @@ -1052,7 +1052,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { @Override @Deprecated public > boolean setBlock(BlockVector3 position, B block) throws MaxChangedBlocksException { - if (position.getBlockY() < this.minY || position.getBlockY() > this.maxY) { + if (position.y() < this.minY || position.y() > this.maxY) { return false; } @@ -1114,7 +1114,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { * @throws MaxChangedBlocksException thrown if too many blocks are changed */ public boolean setBlock(BlockVector3 position, Pattern pattern) throws MaxChangedBlocksException { - if (position.getBlockY() < this.minY || position.getBlockY() > this.maxY) { + if (position.y() < this.minY || position.y() > this.maxY) { return false; } @@ -1349,12 +1349,12 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { public > int fall(final Region region, boolean fullHeight, final B replace) { FlatRegion flat = asFlatRegion(region); - final int startPerformY = region.getMinimumPoint().getBlockY(); + final int startPerformY = region.getMinimumPoint().y(); final int startCheckY = fullHeight ? getMinY() : startPerformY; - final int endY = region.getMaximumPoint().getBlockY(); + final int endY = region.getMaximumPoint().y(); RegionVisitor visitor = new RegionVisitor(flat, pos -> { - int x = pos.getX(); - int z = pos.getZ(); + int x = pos.x(); + int z = pos.z(); int freeSpot = startCheckY; for (int y = startCheckY; y <= endY; y++) { if (y < startPerformY) { @@ -1479,8 +1479,8 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { // Avoid int overflow (negative coordinate space allows for overflow back round to positive if the depth is large enough). // Depth is always 1 or greater, thus the lower bound should always be <= origin y. - int lowerBound = origin.getBlockY() - depth + 1; - if (lowerBound > origin.getBlockY()) { + int lowerBound = origin.y() - depth + 1; + if (lowerBound > origin.y()) { lowerBound = Integer.MIN_VALUE; } @@ -1488,7 +1488,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))), new BoundedHeightMask( Math.max(lowerBound, minY), - Math.min(maxY, origin.getBlockY()) + Math.min(maxY, origin.y()) ), Masks.negate(new ExistingBlockMask(this)) ); @@ -1502,7 +1502,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { if (recursive) { visitor = new RecursiveVisitor(mask, replace, (int) (radius * 2 + 1), minY, maxY, this); } else { - visitor = new DownwardVisitor(mask, replace, origin.getBlockY(), (int) (radius * 2 + 1), minY, maxY, this); + visitor = new DownwardVisitor(mask, replace, origin.y(), (int) (radius * 2 + 1), minY, maxY, this); } //FAWE end @@ -1600,11 +1600,11 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { Vector3 center = region.getCenter(); Region centerRegion = new CuboidRegion( getWorld(), // Causes clamping of Y range - BlockVector3.at(((int) center.getX()), ((int) center.getY()), ((int) center.getZ())), + BlockVector3.at(((int) center.x()), ((int) center.y()), ((int) center.z())), BlockVector3.at( - MathUtils.roundHalfUp(center.getX()), - MathUtils.roundHalfUp(center.getY()), - MathUtils.roundHalfUp(center.getZ()) + MathUtils.roundHalfUp(center.x()), + MathUtils.roundHalfUp(center.y()), + MathUtils.roundHalfUp(center.z()) ) ); return setBlocks(centerRegion, pattern); @@ -1754,8 +1754,8 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { BlockReplace replace = new BlockReplace(this, pattern); RegionOffset offset = new RegionOffset(BlockVector3.UNIT_Y, replace); //FAWE start - int minY = region.getMinimumPoint().getBlockY(); - int maxY = Math.min(getMaximumPoint().getBlockY(), region.getMaximumPoint().getBlockY() + 1); + int minY = region.getMinimumPoint().y(); + int maxY = Math.min(getMaximumPoint().y(), region.getMaximumPoint().y() + 1); SurfaceRegionFunction surface = new SurfaceRegionFunction(this, offset, minY, maxY); FlatRegionVisitor visitor = new FlatRegionVisitor(asFlatRegion(region), surface, this); //FAWE end @@ -1905,7 +1905,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { BlockVector3 disAbs = displace.abs(); - if (disAbs.getBlockX() < size.getBlockX() && disAbs.getBlockY() < size.getBlockY() && disAbs.getBlockZ() < size.getBlockZ()) { + if (disAbs.x() < size.x() && disAbs.y() < size.y() && disAbs.z() < size.z()) { // Buffer if overlapping enableQueue(); } @@ -2068,7 +2068,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { // There are boundaries that the routine needs to stay in Mask mask = new MaskIntersection( - new BoundedHeightMask(minY, Math.min(origin.getBlockY(), maxY)), + new BoundedHeightMask(minY, Math.min(origin.y(), maxY)), new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))), blockMask ); @@ -2156,15 +2156,15 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { } else if (height < 0) { height = -height; //FAWE start - mutableBlockVector3.mutY(mutableBlockVector3.getY() - height); + mutableBlockVector3.mutY(mutableBlockVector3.y() - height); //FAWE end } //FAWE start - if (mutableBlockVector3.getBlockY() < getWorld().getMinY()) { + if (mutableBlockVector3.y() < getWorld().getMinY()) { mutableBlockVector3.mutY(world.getMinY()); - } else if (mutableBlockVector3.getBlockY() + height - 1 > maxY) { - height = maxY - mutableBlockVector3.getBlockY() + 1; + } else if (mutableBlockVector3.y() + height - 1 > maxY) { + height = maxY - mutableBlockVector3.y() + 1; } //FAWE end @@ -2172,9 +2172,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { final double invRadiusZ = 1 / radiusZ; //FAWE start - int px = mutableBlockVector3.getBlockX(); - int py = mutableBlockVector3.getBlockY(); - int pz = mutableBlockVector3.getBlockZ(); + int px = mutableBlockVector3.x(); + int py = mutableBlockVector3.y(); + int pz = mutableBlockVector3.z(); final int ceilRadiusX = (int) Math.ceil(radiusX); final int ceilRadiusZ = (int) Math.ceil(radiusZ); @@ -2319,9 +2319,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { double ry2 = Math.pow(height, 2); double rz2 = Math.pow(radiusZ, 2); - int cx = pos.getX(); - int cy = pos.getY(); - int cz = pos.getZ(); + int cx = pos.x(); + int cy = pos.y(); + int cz = pos.z(); for (int y = 0; y < height; ++y) { double ySquaredMinusHeightOverHeightSquared = Math.pow(y - height, 2) / ry2; @@ -2403,18 +2403,18 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { radiusZ += 0.5; normal = normal.normalize(); - double nx = normal.getX(); - double ny = normal.getY(); - double nz = normal.getZ(); + double nx = normal.x(); + double ny = normal.y(); + double nz = normal.z(); final double invRadiusX = 1 / radiusX; final double invRadiusY = 1 / radiusY; final double invRadiusZ = 1 / radiusZ; - int px = pos.getBlockX(); - int py = pos.getBlockY(); - int pz = pos.getBlockZ(); + int px = pos.x(); + int py = pos.y(); + int pz = pos.z(); final int ceilRadiusX = (int) Math.ceil(radiusX); final int ceilRadiusY = (int) Math.ceil(radiusY); @@ -2545,9 +2545,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { final double invRadiusY = 1 / radiusY; final double invRadiusZ = 1 / radiusZ; - int px = pos.getBlockX(); - int py = pos.getBlockY(); - int pz = pos.getBlockZ(); + int px = pos.x(); + int py = pos.y(); + int pz = pos.z(); final int ceilRadiusX = (int) Math.ceil(radiusX); final int ceilRadiusY = (int) Math.ceil(radiusY); @@ -2654,9 +2654,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { */ public int makePyramid(BlockVector3 position, Pattern block, int size, boolean filled) throws MaxChangedBlocksException { //FAWE start - abbreviated logic - int bx = position.getX(); - int by = position.getY(); - int bz = position.getZ(); + int bx = position.x(); + int by = position.y(); + int bz = position.z(); int height = size; int yy, xx, x_x, zz, z_z; @@ -2715,9 +2715,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { int affected = 0; double radiusSq = radius * radius; - int ox = position.getBlockX(); - int oy = position.getBlockY(); - int oz = position.getBlockZ(); + int ox = position.x(); + int oy = position.y(); + int oz = position.z(); BlockState air = BlockTypes.AIR.getDefaultState(); BlockState water = BlockTypes.WATER.getDefaultState(); @@ -2804,7 +2804,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { public int simulateSnow(BlockVector3 position, double radius, int height) throws MaxChangedBlocksException { - return simulateSnow(new CylinderRegion(position, Vector2.at(radius, radius), position.getBlockY(), height), false); + return simulateSnow(new CylinderRegion(position, Vector2.at(radius, radius), position.y(), height), false); } /** @@ -2860,9 +2860,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { int affected = 0; final double radiusSq = radius * radius; - final int ox = position.getBlockX(); - final int oy = position.getBlockY(); - final int oz = position.getBlockZ(); + final int ox = position.x(); + final int oy = position.y(); + final int oz = position.z(); final BlockState grass = BlockTypes.GRASS_BLOCK.getDefaultState(); @@ -3077,7 +3077,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { } } if (expression.evaluate( - new double[]{scaled.getX(), scaled.getY(), scaled.getZ(), typeVar, dataVar}, + new double[]{scaled.x(), scaled.y(), scaled.z(), typeVar, dataVar}, timeout ) <= 0) { return null; @@ -3180,10 +3180,10 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { final Vector3 scaled = position.toVector3().subtract(zero).divide(unit); // transform - expression.evaluate(new double[]{scaled.getX(), scaled.getY(), scaled.getZ()}, timeout); - int xv = (int) Math.floor(x.getValue() * unit.getX() + zero2.getX()); - int yv = (int) Math.floor(y.getValue() * unit.getY() + zero2.getY()); - int zv = (int) Math.floor(z.getValue() * unit.getZ() + zero2.getZ()); + expression.evaluate(new double[]{scaled.x(), scaled.y(), scaled.z()}, timeout); + int xv = (int) Math.floor(x.getValue() * unit.x() + zero2.x()); + int yv = (int) Math.floor(y.getValue() * unit.y() + zero2.y()); + int zv = (int) Math.floor(z.getValue() * unit.z() + zero2.z()); BlockState get; if (yv >= minY && yv <= maxY) { @@ -3222,12 +3222,12 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { final BlockVector3 min = region.getMinimumPoint(); final BlockVector3 max = region.getMaximumPoint(); - final int minX = min.getBlockX(); - final int minY = min.getBlockY(); - final int minZ = min.getBlockZ(); - final int maxX = max.getBlockX(); - final int maxY = max.getBlockY(); - final int maxZ = max.getBlockZ(); + final int minX = min.x(); + final int minY = min.y(); + final int minZ = min.z(); + final int maxX = max.x(); + final int maxY = max.y(); + final int maxZ = max.z(); //FAWE start - mutable MutableBlockVector3 mutable = new MutableBlockVector3(); @@ -3316,12 +3316,12 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { public int drawLine(Pattern pattern, BlockVector3 pos1, BlockVector3 pos2, double radius, boolean filled, boolean flat) throws MaxChangedBlocksException { - int x1 = pos1.getBlockX(); - int y1 = pos1.getBlockY(); - int z1 = pos1.getBlockZ(); - int x2 = pos2.getBlockX(); - int y2 = pos2.getBlockY(); - int z2 = pos2.getBlockZ(); + int x1 = pos1.x(); + int y1 = pos1.y(); + int z1 = pos1.z(); + int x2 = pos2.x(); + int y2 = pos2.y(); + int z2 = pos2.z(); int tipx = x1; int tipy = y1; int tipz = z1; @@ -3416,12 +3416,12 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { BlockVector3 pos1 = vectors.get(i); BlockVector3 pos2 = vectors.get(i + 1); - int x1 = pos1.getBlockX(); - int y1 = pos1.getBlockY(); - int z1 = pos1.getBlockZ(); - int x2 = pos2.getBlockX(); - int y2 = pos2.getBlockY(); - int z2 = pos2.getBlockZ(); + int x1 = pos1.x(); + int y1 = pos1.y(); + int z1 = pos1.z(); + int x2 = pos2.x(); + int y2 = pos2.y(); + int z2 = pos2.z(); int tipx = x1; int tipy = y1; int tipz = z1; @@ -3532,9 +3532,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { int ceilrad = (int) Math.ceil(radius); for (BlockVector3 v : vset) { - int tipx = v.getBlockX(); - int tipy = v.getBlockY(); - int tipz = v.getBlockZ(); + int tipx = v.x(); + int tipy = v.y(); + int tipz = v.z(); for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) { for (int loopy = tipy - ceilrad; loopy <= tipy + ceilrad; loopy++) { @@ -3557,13 +3557,13 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { final LocalBlockVectorSet returnset = new LocalBlockVectorSet(); final int ceilrad = (int) Math.ceil(radius); for (BlockVector3 v : vset) { - final int tipx = v.getBlockX(); - final int tipy = v.getBlockY(); - final int tipz = v.getBlockZ(); + final int tipx = v.x(); + final int tipy = v.y(); + final int tipz = v.z(); for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) { for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) { if (MathMan.hypot(loopx - tipx, 0, loopz - tipz) <= radius) { - returnset.add(loopx, v.getBlockY(), loopz); + returnset.add(loopx, v.y(), loopz); } } } @@ -3576,9 +3576,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { final LocalBlockVectorSet newset = new LocalBlockVectorSet(); newset.addAll(vset); for (BlockVector3 v : newset) { - final int x = v.getX(); - final int y = v.getY(); - final int z = v.getZ(); + final int x = v.x(); + final int y = v.y(); + final int z = v.z(); if (!(newset.contains(x + 1, y, z) && newset.contains(x - 1, y, z) && newset.contains(x, y, z + 1) @@ -3595,9 +3595,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { final LocalBlockVectorSet newset = new LocalBlockVectorSet(); newset.addAll(vset); for (BlockVector3 v : newset) { - final int x = v.getX(); - final int y = v.getY(); - final int z = v.getZ(); + final int x = v.x(); + final int y = v.y(); + final int z = v.z(); if (!(newset.contains(x + 1, y, z) && newset.contains(x - 1, y, z) && newset.contains(x, y + 1, z) @@ -3668,9 +3668,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { @Override protected BiomeType getBiome(int x, int y, int z, BiomeType defaultBiomeType) { environment.setCurrentBlock(x, y, z); - double scaledX = (x - zero.getX()) / unit.getX(); - double scaledY = (y - zero.getY()) / unit.getY(); - double scaledZ = (z - zero.getZ()) / unit.getZ(); + double scaledX = (x - zero.x()) / unit.x(); + double scaledY = (y - zero.y()) / unit.y(); + double scaledZ = (z - zero.z()) / unit.z(); try { if (expression.evaluate(new double[]{scaledX, scaledY, scaledZ}, timeout) <= 0) { @@ -3717,9 +3717,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { } private void setExistingBlocks(BlockVector3 pos1, BlockVector3 pos2) { - for (int x = pos1.getX(); x <= pos2.getX(); x++) { - for (int z = pos1.getBlockZ(); z <= pos2.getBlockZ(); z++) { - for (int y = pos1.getY(); y <= pos2.getY(); y++) { + for (int x = pos1.x(); x <= pos2.x(); x++) { + for (int z = pos1.z(); z <= pos2.z(); z++) { + for (int y = pos1.y(); y <= pos2.y(); y++) { setBlock(x, y, z, getFullBlock(x, y, z)); } } @@ -3735,10 +3735,10 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { if (fe != null && cuboid) { BlockVector3 max = region.getMaximumPoint(); BlockVector3 min = region.getMinimumPoint(); - if (!fe.contains(max.getBlockX(), max.getBlockY(), max.getBlockZ()) && !fe.contains( - min.getBlockX(), - min.getBlockY(), - min.getBlockZ() + if (!fe.contains(max.x(), max.y(), max.z()) && !fe.contains( + min.x(), + min.y(), + min.z() )) { throw FaweCache.OUTSIDE_REGION; } @@ -3748,17 +3748,17 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { MutableBlockVector3 mutable2 = new MutableBlockVector3(); MutableBlockVector2 mutable2D = new MutableBlockVector2(); for (BlockVector2 chunk : chunks) { - final int cx = chunk.getBlockX(); - final int cz = chunk.getBlockZ(); + final int cx = chunk.x(); + final int cz = chunk.z(); final int bx = cx << 4; final int bz = cz << 4; final BlockVector3 cmin = BlockVector3.at(bx, 0, bz); final BlockVector3 cmax = cmin.add(15, maxY, 15); final boolean containsBot1 = - fe == null || fe.contains(cmin.getBlockX(), cmin.getBlockY(), cmin.getBlockZ()); + fe == null || fe.contains(cmin.x(), cmin.y(), cmin.z()); final boolean containsBot2 = region.contains(cmin); final boolean containsTop1 = - fe == null || fe.contains(cmax.getBlockX(), cmax.getBlockY(), cmax.getBlockZ()); + fe == null || fe.contains(cmax.x(), cmax.y(), cmax.z()); final boolean containsTop2 = region.contains(cmax); if (containsBot2 && containsTop2 && !containsBot1 && !containsTop1) { continue; @@ -3917,15 +3917,15 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { double seedY = ThreadLocalRandom.current().nextDouble(); double seedZ = ThreadLocalRandom.current().nextDouble(); - int px = position.getBlockX(); - int py = position.getBlockY(); - int pz = position.getBlockZ(); + int px = position.x(); + int py = position.y(); + int pz = position.z(); double distort = frequency / size; - double modX = 1d / radius.getX(); - double modY = 1d / radius.getY(); - double modZ = 1d / radius.getZ(); + double modX = 1d / radius.x(); + double modY = 1d / radius.y(); + double modZ = 1d / radius.z(); int r = (int) size; int radiusSqr = (int) (size * size); int sizeInt = (int) size * 2; @@ -3986,9 +3986,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { // so it must be set each time mutable.setComponents(xr, yr, zr); Vector3 pt = transform.apply(mutable); - x = MathMan.roundInt(pt.getX()); - y = MathMan.roundInt(pt.getY()); - z = MathMan.roundInt(pt.getZ()); + x = MathMan.roundInt(pt.x()); + y = MathMan.roundInt(pt.y()); + z = MathMan.roundInt(pt.z()); xScaled = Math.abs(x) * modX; yScaled = Math.abs(y) * modY; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index bdd6a4ed4..7160be750 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -462,7 +462,7 @@ public class BrushCommands { @Arg(desc = "double", def = "50") double amplitude ) throws WorldEditException { - double max = MathMan.max(radius.getX(), radius.getY(), radius.getZ()); + double max = MathMan.max(radius.x(), radius.y(), radius.z()); worldEdit.checkMaxBrushRadius( max, context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) @@ -1368,15 +1368,15 @@ public class BrushCommands { BlockVector3 size = clipboard.getDimensions(); worldEdit.checkMaxBrushRadius( - size.getBlockX() / 2D - 1, + size.x() / 2D - 1, context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) ); worldEdit.checkMaxBrushRadius( - size.getBlockY() / 2D - 1, + size.y() / 2D - 1, context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) ); worldEdit.checkMaxBrushRadius( - size.getBlockZ() / 2D - 1, + size.z() / 2D - 1, context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) ); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index 177366651..b4037ba15 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -150,8 +150,8 @@ public class ClipboardCommands { BlockVector3 max = region.getMaximumPoint(); long volume = - ((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min - .getZ() + 1); + ((long) max.x() - (long) min.x() + 1) * ((long) max.y() - (long) min.y() + 1) * ((long) max.z() - (long) min + .z() + 1); FaweLimit limit = actor.getLimit(); if (volume >= limit.MAX_CHECKS) { throw FaweCache.MAX_CHECKS; @@ -184,8 +184,8 @@ public class ClipboardCommands { ) throws WorldEditException { BlockVector3 min = region.getMinimumPoint(); BlockVector3 max = region.getMaximumPoint(); - long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min - .getZ() + 1)); + long volume = (((long) max.x() - (long) min.x() + 1) * ((long) max.y() - (long) min.y() + 1) * ((long) max.z() - (long) min + .z() + 1)); FaweLimit limit = actor.getLimit(); if (volume >= limit.MAX_CHECKS) { throw FaweCache.MAX_CHECKS; @@ -257,8 +257,8 @@ public class ClipboardCommands { BlockVector3 min = region.getMinimumPoint(); BlockVector3 max = region.getMaximumPoint(); - long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min - .getZ() + 1)); + long volume = (((long) max.x() - (long) min.x() + 1) * ((long) max.y() - (long) min.y() + 1) * ((long) max.z() - (long) min + .z() + 1)); FaweLimit limit = actor.getLimit(); if (volume >= limit.MAX_CHECKS) { throw FaweCache.MAX_CHECKS; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/FlattenedClipboardTransform.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/FlattenedClipboardTransform.java index 14e3d3307..d32504ad4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/FlattenedClipboardTransform.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/FlattenedClipboardTransform.java @@ -79,12 +79,12 @@ public class FlattenedClipboardTransform { Vector3[] corners = new Vector3[]{ minimum, maximum, - minimum.withX(maximum.getX()), - minimum.withY(maximum.getY()), - minimum.withZ(maximum.getZ()), - maximum.withX(minimum.getX()), - maximum.withY(minimum.getY()), - maximum.withZ(minimum.getZ()) + minimum.withX(maximum.x()), + minimum.withY(maximum.y()), + minimum.withZ(maximum.z()), + maximum.withX(minimum.x()), + maximum.withY(minimum.y()), + maximum.withZ(minimum.z()) }; for (int i = 0; i < corners.length; i++) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java index 90b59cb52..4b2f98e0c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java @@ -440,13 +440,13 @@ public class GenerationCommands { zero = max.add(min).multiply(0.5); unit = max.subtract(zero); - if (unit.getX() == 0) { + if (unit.x() == 0) { unit = unit.withX(1.0); } - if (unit.getY() == 0) { + if (unit.y() == 0) { unit = unit.withY(1.0); } - if (unit.getZ() == 0) { + if (unit.z() == 0) { unit = unit.withZ(1.0); } } @@ -526,13 +526,13 @@ public class GenerationCommands { zero = max.add(min).multiply(0.5); unit = max.subtract(zero); - if (unit.getX() == 0) { + if (unit.x() == 0) { unit = unit.withX(1.0); } - if (unit.getY() == 0) { + if (unit.y() == 0) { unit = unit.withY(1.0); } - if (unit.getZ() == 0) { + if (unit.z() == 0) { unit = unit.withZ(1.0); } } @@ -636,7 +636,7 @@ public class GenerationCommands { MainUtil.checkImageHost(url.toURI()); if (dimensions != null) { checkCommandArgument( - (long) dimensions.getX() * dimensions.getZ() <= Settings.settings().WEB.MAX_IMAGE_SIZE, + (long) dimensions.x() * dimensions.z() <= Settings.settings().WEB.MAX_IMAGE_SIZE, Caption.of("fawe.error.image-dimensions", Settings.settings().WEB.MAX_IMAGE_SIZE) ); } @@ -644,7 +644,7 @@ public class GenerationCommands { Future future = executor.submit(() -> { BufferedImage image = MainUtil.readImage(url); if (dimensions != null) { - image = ImageUtil.getScaledInstance(image, dimensions.getBlockX(), dimensions.getBlockZ(), + image = ImageUtil.getScaledInstance(image, dimensions.x(), dimensions.z(), RenderingHints.VALUE_INTERPOLATION_BILINEAR, false ); } @@ -668,8 +668,8 @@ public class GenerationCommands { CuboidRegion region = new CuboidRegion(pos1, pos2); final BufferedImage finalImage = image; RegionVisitor visitor = new RegionVisitor(region, pos -> { - int x = pos.getBlockX() - pos1.getBlockX(); - int z = pos.getBlockZ() - pos1.getBlockZ(); + int x = pos.x() - pos1.x(); + int z = pos.z() - pos1.z(); int color = finalImage.getRGB(x, z); BlockType block = tu.getNearestBlock(color); if (block != null) { @@ -735,7 +735,7 @@ public class GenerationCommands { @Arg(desc = "double", def = "50") double amplitude ) throws WorldEditException { - double max = MathMan.max(radius.getX(), radius.getY(), radius.getZ()); + double max = MathMan.max(radius.x(), radius.y(), radius.z()); worldEdit.checkMaxRadius(max, actor); BlockVector3 pos = session.getPlacementPosition(actor); int affected = editSession.makeBlob( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistorySubCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistorySubCommands.java index 08f48b265..8d28ad1eb 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistorySubCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistorySubCommands.java @@ -13,10 +13,7 @@ import com.fastasyncworldedit.core.util.MainUtil; import com.fastasyncworldedit.core.util.StringMan; import com.google.common.base.Function; import com.google.common.collect.Lists; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.EditSessionBuilder; import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.command.argument.Arguments; import com.sk89q.worldedit.command.util.CommandPermissions; @@ -25,7 +22,6 @@ import com.sk89q.worldedit.command.util.annotation.Confirm; import com.sk89q.worldedit.command.util.annotation.Time; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; -import com.sk89q.worldedit.function.operation.ChangeSetExecutor; import com.sk89q.worldedit.history.changeset.ChangeSet; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; @@ -245,11 +241,11 @@ public class HistorySubCommands { BlockVector3 pos1 = edit.getMinimumPoint(); BlockVector3 pos2 = edit.getMaximumPoint(); - double distanceX = Math.min(Math.abs(pos1.getX() - origin.getX()), Math.abs(pos2.getX() - origin.getX())); - double distanceZ = Math.min(Math.abs(pos1.getZ() - origin.getZ()), Math.abs(pos2.getZ() - origin.getZ())); + double distanceX = Math.min(Math.abs(pos1.x() - origin.x()), Math.abs(pos2.x() - origin.x())); + double distanceZ = Math.min(Math.abs(pos1.z() - origin.z()), Math.abs(pos2.z() - origin.z())); int distance = (int) Math.sqrt(distanceX * distanceX + distanceZ * distanceZ); - BlockVector2 dirVec = BlockVector2.at(edit.getOriginX() - origin.getX(), edit.getOriginZ() - origin.getZ()); + BlockVector2 dirVec = BlockVector2.at(edit.getOriginX() - origin.x(), edit.getOriginZ() - origin.z()); Direction direction = Direction.findClosest(dirVec.toVector3(), Direction.Flag.ALL); long seconds = (System.currentTimeMillis() - edit.getBDFile().lastModified()) / 1000; @@ -326,13 +322,13 @@ public class HistorySubCommands { BlockVector3 pos1 = rollback.getMinimumPoint(); BlockVector3 pos2 = rollback.getMaximumPoint(); - double distanceX = Math.min(Math.abs(pos1.getX() - origin.getX()), Math.abs(pos2.getX() - origin.getX())); - double distanceZ = Math.min(Math.abs(pos1.getZ() - origin.getZ()), Math.abs(pos2.getZ() - origin.getZ())); + double distanceX = Math.min(Math.abs(pos1.x() - origin.x()), Math.abs(pos2.x() - origin.x())); + double distanceZ = Math.min(Math.abs(pos1.z() - origin.z()), Math.abs(pos2.z() - origin.z())); int distance = (int) Math.sqrt(distanceX * distanceX + distanceZ * distanceZ); BlockVector2 dirVec = BlockVector2.at( - rollback.getOriginX() - origin.getX(), - rollback.getOriginZ() - origin.getZ() + rollback.getOriginX() - origin.x(), + rollback.getOriginZ() - origin.z() ); Direction direction = Direction.findClosest(dirVec.toVector3(), Direction.Flag.ALL); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java index 73cb34274..6a121aa02 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java @@ -351,8 +351,8 @@ public class RegionCommands { int affected = 0; while (iter.hasNext()) { BlockVector2 pos = iter.next(); - int x = pos.getBlockX(); - int z = pos.getBlockZ(); + int x = pos.x(); + int z = pos.z(); //FAWE start - world min/maxY y = editSession.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY); //FAWE end @@ -449,8 +449,8 @@ public class RegionCommands { //FAWE end BlockVector3 min = region.getMinimumPoint(); BlockVector3 max = region.getMaximumPoint(); - long volume = (((long) max.getX() - (long) min.getX() + 1) * ((long) max.getY() - (long) min.getY() + 1) * ((long) max.getZ() - (long) min - .getZ() + 1)); + long volume = (((long) max.x() - (long) min.x() + 1) * ((long) max.y() - (long) min.y() + 1) * ((long) max.z() - (long) min + .z() + 1)); FaweLimit limit = actor.getLimit(); if (volume >= limit.MAX_CHECKS) { throw FaweCache.MAX_CHECKS; @@ -772,13 +772,13 @@ public class RegionCommands { zero = max.add(min).divide(2); unit = max.subtract(zero); - if (unit.getX() == 0) { + if (unit.x() == 0) { unit = unit.withX(1.0); } - if (unit.getY() == 0) { + if (unit.y() == 0) { unit = unit.withY(1.0); } - if (unit.getZ() == 0) { + if (unit.z() == 0) { unit = unit.withZ(1.0); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index a643742d2..d8e0943dc 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -262,12 +262,12 @@ public class SelectionCommands { actor.print(Caption.of( "worldedit.chunk.selected-multiple", - TextComponent.of(minChunk.getBlockX()), - TextComponent.of(minChunk.getBlockY()), - TextComponent.of(minChunk.getBlockZ()), - TextComponent.of(maxChunk.getBlockX()), - TextComponent.of(maxChunk.getBlockY()), - TextComponent.of(maxChunk.getBlockZ()) + TextComponent.of(minChunk.x()), + TextComponent.of(minChunk.y()), + TextComponent.of(minChunk.z()), + TextComponent.of(maxChunk.x()), + TextComponent.of(maxChunk.y()), + TextComponent.of(maxChunk.z()) )); } else { BlockVector3 minChunk; @@ -290,9 +290,9 @@ public class SelectionCommands { actor.print(Caption.of( "worldedit.chunk.selected", - TextComponent.of(minChunk.getBlockX()), - TextComponent.of(minChunk.getBlockY()), - TextComponent.of(minChunk.getBlockZ()) + TextComponent.of(minChunk.x()), + TextComponent.of(minChunk.y()), + TextComponent.of(minChunk.z()) )); } @@ -538,10 +538,10 @@ public class SelectionCommands { .subtract(region.getMinimumPoint()).add(1, 1, 1); BlockVector3 origin = clipboard.getOrigin(); - String sizeStr = size.getBlockX() + "*" + size.getBlockY() + "*" + size.getBlockZ(); - String originStr = origin.getBlockX() + "," + origin.getBlockY() + "," + origin.getBlockZ(); + String sizeStr = size.x() + "*" + size.y() + "*" + size.z(); + String originStr = origin.x() + "," + origin.y() + "," + origin.z(); - long numBlocks = ((long) size.getBlockX() * size.getBlockY() * size.getBlockZ()); + long numBlocks = ((long) size.x() * size.y() * size.z()); actor.print(Caption.of( "worldedit.size.offset", TextComponent.of(name), diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index a336f4b12..a289f7cff 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -50,19 +50,12 @@ import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; import com.sk89q.worldedit.function.EntityFunction; -import com.sk89q.worldedit.function.block.BlockReplace; import com.sk89q.worldedit.function.mask.BlockTypeMask; -import com.sk89q.worldedit.function.mask.BoundedHeightMask; import com.sk89q.worldedit.function.mask.ExistingBlockMask; import com.sk89q.worldedit.function.mask.Mask; -import com.sk89q.worldedit.function.mask.MaskIntersection; -import com.sk89q.worldedit.function.mask.Masks; -import com.sk89q.worldedit.function.mask.RegionMask; import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.function.pattern.Pattern; -import com.sk89q.worldedit.function.visitor.DownwardVisitor; import com.sk89q.worldedit.function.visitor.EntityVisitor; -import com.sk89q.worldedit.function.visitor.RecursiveVisitor; import com.sk89q.worldedit.internal.annotation.Direction; import com.sk89q.worldedit.internal.annotation.VertHeight; import com.sk89q.worldedit.internal.expression.EvaluationException; @@ -70,10 +63,8 @@ import com.sk89q.worldedit.internal.expression.Expression; import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector2; -import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CylinderRegion; -import com.sk89q.worldedit.regions.EllipsoidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.formatting.component.SubtleFormat; import com.sk89q.worldedit.util.formatting.text.Component; @@ -550,8 +541,8 @@ public class UtilityCommands { CylinderRegion region = new CylinderRegion( position, Vector2.at(size, size), - position.getBlockY() - height, - position.getBlockY() + height + position.y() - height, + position.y() + height ); int affected = editSession.simulateSnow(region, stack); actor.print(Caption.of( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/OffsetConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/OffsetConverter.java index 88b74a05f..22c755cb5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/OffsetConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/OffsetConverter.java @@ -98,9 +98,9 @@ public class OffsetConverter implements ArgumentConverter { // Create an affine transform of the columns (col4 is empty due to no translation) AffineTransform transform = new AffineTransform( - m1.getX(), m2.getX(), m3.getX(), 0, - m1.getY(), m2.getY(), m3.getY(), 0, - m1.getZ(), m2.getZ(), m3.getZ(), 0 + m1.x(), m2.x(), m3.x(), 0, + m1.y(), m2.y(), m3.y(), 0, + m1.z(), m2.z(), m3.z(), 0 ); return transform diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java index c4d45d683..6021102a2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java @@ -380,7 +380,7 @@ public class BrushTool pitch = 23 - (pitch / 4); d += (int) (Math.sin(Math.toRadians(pitch)) * 50); final Vector3 vector = loc.getDirection().withY(0).normalize().multiply(d) - .add(loc.getX(), loc.getY(), loc.getZ()); + .add(loc.x(), loc.y(), loc.z()); return offset(vector, loc).toBlockPoint(); } case TARGET_POINT_HEIGHT: { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java index b82601288..bfa19b7e3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/GravityBrush.java @@ -38,11 +38,11 @@ public class GravityBrush implements Brush { public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException { //FAWE start - Ours operates differently to upstream, but does the same - double endY = position.getY() + size; - double startPerformY = Math.max(editSession.getMinY(), position.getY() - size); + double endY = position.y() + size; + double startPerformY = Math.max(editSession.getMinY(), position.y() - size); double startCheckY = fullHeight ? editSession.getMinY() : startPerformY; - for (double x = position.getX() + size; x > position.getX() - size; --x) { - for (double z = position.getZ() + size; z > position.getZ() - size; --z) { + for (double x = position.x() + size; x > position.x() - size; --x) { + for (double z = position.z() + size; z > position.z() - size; --z) { double freeSpot = startCheckY; for (double y = startCheckY; y <= endY; y++) { BlockState block = editSession.getBlock((int) x, (int) y, (int) z); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/Confirm.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/Confirm.java index 37ea4abeb..b8980afc8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/Confirm.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/Confirm.java @@ -3,7 +3,6 @@ package com.sk89q.worldedit.command.util.annotation; import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.util.task.InterruptableCondition; import com.sk89q.worldedit.IncompleteRegionException; -import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.command.argument.Arguments; import com.sk89q.worldedit.event.Event; import com.sk89q.worldedit.event.platform.CommandEvent; @@ -57,7 +56,7 @@ public @interface Confirm { .orElseThrow(IncompleteRegionException::new); BlockVector3 pos1 = region.getMinimumPoint(); BlockVector3 pos2 = region.getMaximumPoint(); - long area = (pos2.getX() - pos1.getX()) * (pos2.getZ() - pos1.getZ() + 1) + long area = (pos2.x() - pos1.x()) * (pos2.z() - pos1.z() + 1) * (long) value; long max = 2 << 18; if (max != -1 && area > max) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java index ae4eb2144..5337fe720 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java @@ -162,8 +162,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { public void findFreePosition(Location searchPos) { Extent world = searchPos.getExtent(); - int worldMinY = world.getMinimumPoint().getY(); - int worldMaxY = world.getMaximumPoint().getY(); + int worldMinY = world.getMinimumPoint().y(); + int worldMaxY = world.getMaximumPoint().y(); int x = searchPos.getBlockX(); int y = Math.max(worldMinY, searchPos.getBlockY()); @@ -202,7 +202,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { public void setOnGround(Location searchPos) { Extent world = searchPos.getExtent(); - int worldMinY = world.getMinimumPoint().getY(); + int worldMinY = world.getMinimumPoint().y(); int x = searchPos.getBlockX(); int y = Math.max(worldMinY, searchPos.getBlockY()); @@ -436,7 +436,7 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { @Override public Location getBlockOn() { final Location location = getLocation(); - return location.setPosition(location.setY(location.getY() - 1).toVector().floor()); + return location.setPosition(location.setY(location.y() - 1).toVector().floor()); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java index 3d2a45642..6117c6850 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java @@ -504,8 +504,8 @@ public interface Extent extends InputExtent, OutputExtent { if (random.nextInt(100) > rarity) { continue; } - int x = (chunkPos.getBlockX() << 4) + random.nextInt(16); - int z = (chunkPos.getBlockZ() << 4) + random.nextInt(16); + int x = (chunkPos.x() << 4) + random.nextInt(16); + int z = (chunkPos.z() << 4) + random.nextInt(16); gen.spawn(random, x, z); } } @@ -534,9 +534,9 @@ public interface Extent extends InputExtent, OutputExtent { default boolean contains(int x, int y, int z) { BlockVector3 min = getMinimumPoint(); BlockVector3 max = getMaximumPoint(); - return min.getX() <= x && max.getX() >= x - && min.getY() <= y && max.getY() >= y - && min.getZ() <= z && max.getZ() >= z; + return min.x() <= x && max.x() >= x + && min.y() <= y && max.y() >= y + && min.z() <= z && max.z() >= z; } default void addOre( @@ -665,11 +665,11 @@ public interface Extent extends InputExtent, OutputExtent { } default int getMinY() { - return getMinimumPoint().getY(); + return getMinimumPoint().y(); } default int getMaxY() { - return getMaximumPoint().getY(); + return getMaximumPoint().y(); } /** @@ -832,9 +832,9 @@ public interface Extent extends InputExtent, OutputExtent { Vector3 center = region.getCenter(); Region centerRegion = new CuboidRegion( this instanceof World ? (World) this : null, // Causes clamping of Y range - BlockVector3.at(((int) center.getX()), ((int) center.getY()), ((int) center.getZ())), - BlockVector3.at(MathUtils.roundHalfUp(center.getX()), - center.getY(), MathUtils.roundHalfUp(center.getZ()) + BlockVector3.at(((int) center.x()), ((int) center.y()), ((int) center.z())), + BlockVector3.at(MathUtils.roundHalfUp(center.x()), + center.y(), MathUtils.roundHalfUp(center.z()) ) ); return setBlocks(centerRegion, pattern); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java index 58863920c..7393c7722 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/InputExtent.java @@ -50,7 +50,7 @@ public interface InputExtent { * @return the block */ default BlockState getBlock(BlockVector3 position) { - return getBlock(position.getX(), position.getY(), position.getZ()); + return getBlock(position.x(), position.y(), position.z()); } //FAWE start @@ -65,7 +65,7 @@ public interface InputExtent { * @return the block */ default BaseBlock getFullBlock(BlockVector3 position) { - return getFullBlock(position.getX(), position.getY(), position.getZ()); + return getFullBlock(position.x(), position.y(), position.z()); } default BaseBlock getFullBlock(int x, int y, int z) { @@ -85,7 +85,7 @@ public interface InputExtent { */ @Deprecated default BiomeType getBiome(BlockVector2 position) { - return getBiomeType(position.getX(), 0, position.getZ()); + return getBiomeType(position.x(), 0, position.z()); } default BiomeType getBiomeType(int x, int y, int z) { @@ -126,7 +126,7 @@ public interface InputExtent { * @return the light level at the location */ default int getEmittedLight(BlockVector3 position) { - return getEmittedLight(position.getX(), position.getY(), position.getZ()); + return getEmittedLight(position.x(), position.y(), position.z()); } default int getEmittedLight(int x, int y, int z) { @@ -140,7 +140,7 @@ public interface InputExtent { * @return the sky light level at the location */ default int getSkyLight(MutableBlockVector3 position) { - return getSkyLight(position.getX(), position.getY(), position.getZ()); + return getSkyLight(position.x(), position.y(), position.z()); } default int getSkyLight(int x, int y, int z) { @@ -148,7 +148,7 @@ public interface InputExtent { } default int getBrightness(MutableBlockVector3 position) { - return getBrightness(position.getX(), position.getY(), position.getZ()); + return getBrightness(position.x(), position.y(), position.z()); } default int getBrightness(int x, int y, int z) { @@ -156,7 +156,7 @@ public interface InputExtent { } default int getOpacity(MutableBlockVector3 position) { - return getOpacity(position.getX(), position.getY(), position.getZ()); + return getOpacity(position.x(), position.y(), position.z()); } default int getOpacity(int x, int y, int z) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java index d90bce937..9346bf380 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/OutputExtent.java @@ -60,7 +60,7 @@ public interface OutputExtent { */ @Deprecated default > boolean setBlock(BlockVector3 position, T block) throws WorldEditException { - return setBlock(position.getX(), position.getY(), position.getZ(), block); + return setBlock(position.x(), position.y(), position.z(), block); } // The defaults need to remain for compatibility (the actual implementation still needs to override one of these) @@ -148,7 +148,7 @@ public interface OutputExtent { * @param value light level to set */ default void setBlockLight(BlockVector3 position, int value) { - setBlockLight(position.getX(), position.getY(), position.getZ(), value); + setBlockLight(position.x(), position.y(), position.z(), value); } default void setBlockLight(int x, int y, int z, int value) { @@ -161,7 +161,7 @@ public interface OutputExtent { * @param value light level to set */ default void setSkyLight(BlockVector3 position, int value) { - setSkyLight(position.getX(), position.getY(), position.getZ(), value); + setSkyLight(position.x(), position.y(), position.z(), value); } //FAWE end 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 7b6be41d2..b861dbd6b 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 @@ -165,9 +165,9 @@ public class BlockArrayClipboard implements Clipboard { @Override public BlockState getBlock(BlockVector3 position) { if (region.contains(position)) { - int x = position.getBlockX() - offset.getX(); - int y = position.getBlockY() - offset.getY(); - int z = position.getBlockZ() - offset.getZ(); + int x = position.x() - offset.x(); + int y = position.y() - offset.y(); + int z = position.z() - offset.z(); return getParent().getBlock(x, y, z); } @@ -177,9 +177,9 @@ public class BlockArrayClipboard implements Clipboard { @Override public BaseBlock getFullBlock(BlockVector3 position) { if (region.contains(position)) { - int x = position.getBlockX() - offset.getX(); - int y = position.getBlockY() - offset.getY(); - int z = position.getBlockZ() - offset.getZ(); + int x = position.x() - offset.x(); + int y = position.y() - offset.y(); + int z = position.z() - offset.z(); return getParent().getFullBlock(x, y, z); } return BlockTypes.AIR.getDefaultState().toBaseBlock(); @@ -189,9 +189,9 @@ public class BlockArrayClipboard implements Clipboard { public > boolean setBlock(BlockVector3 position, B block) throws WorldEditException { if (region.contains(position)) { //FAWE - get points - final int x = position.getBlockX(); - final int y = position.getBlockY(); - final int z = position.getBlockZ(); + final int x = position.x(); + final int y = position.y(); + final int z = position.z(); return setBlock(x, y, z, block); //FAWE end } @@ -201,22 +201,22 @@ public class BlockArrayClipboard implements Clipboard { //FAWE start @Override public boolean setTile(int x, int y, int z, CompoundTag tag) { - x -= offset.getX(); - y -= offset.getY(); - z -= offset.getZ(); + x -= offset.x(); + y -= offset.y(); + z -= offset.z(); return getParent().setTile(x, y, z, tag); } public boolean setTile(BlockVector3 position, CompoundTag tag) { - return setTile(position.getX(), position.getY(), position.getZ(), tag); + return setTile(position.x(), position.y(), position.z(), tag); } @Override public > boolean setBlock(int x, int y, int z, B block) throws WorldEditException { - x -= offset.getX(); - y -= offset.getY(); - z -= offset.getZ(); + x -= offset.x(); + y -= offset.y(); + z -= offset.z(); return parent.setBlock(x, y, z, block); } @@ -230,25 +230,25 @@ public class BlockArrayClipboard implements Clipboard { if (!region.contains(position)) { return null; } - int x = position.getBlockX() - offset.getX(); - int y = position.getBlockY() - offset.getY(); - int z = position.getBlockZ() - offset.getZ(); + int x = position.x() - offset.x(); + int y = position.y() - offset.y(); + int z = position.z() - offset.z(); return getParent().getBiomeType(x, y, z); } @Override public boolean setBiome(BlockVector3 position, BiomeType biome) { - int x = position.getBlockX() - offset.getX(); - int y = position.getBlockY() - offset.getY(); - int z = position.getBlockZ() - offset.getZ(); + int x = position.x() - offset.x(); + int y = position.y() - offset.y(); + int z = position.z() - offset.z(); return getParent().setBiome(x, y, z, biome); } @Override public boolean setBiome(int x, int y, int z, BiomeType biome) { - x -= offset.getX(); - y -= offset.getY(); - z -= offset.getZ(); + x -= offset.x(); + y -= offset.y(); + z -= offset.z(); return getParent().setBiome(x, y, z, biome); } @@ -262,9 +262,9 @@ public class BlockArrayClipboard implements Clipboard { ClipboardEntity ce = (ClipboardEntity) e; Location oldloc = ce.getLocation(); Location loc = new Location(oldloc.getExtent(), - oldloc.getX() + offset.getBlockX(), - oldloc.getY() + offset.getBlockY(), - oldloc.getZ() + offset.getBlockZ(), + oldloc.x() + offset.x(), + oldloc.y() + offset.y(), + oldloc.z() + offset.z(), oldloc.getYaw(), oldloc.getPitch() ); return new ClipboardEntity(loc, ce.entity); @@ -281,9 +281,9 @@ public class BlockArrayClipboard implements Clipboard { ClipboardEntity ce = (ClipboardEntity) e; Location oldloc = ce.getLocation(); Location loc = new Location(oldloc.getExtent(), - oldloc.getX() + offset.getBlockX(), - oldloc.getY() + offset.getBlockY(), - oldloc.getZ() + offset.getBlockZ(), + oldloc.x() + offset.x(), + oldloc.y() + offset.y(), + oldloc.z() + offset.z(), oldloc.getYaw(), oldloc.getPitch() ); return new ClipboardEntity(loc, ce.entity); @@ -296,9 +296,9 @@ public class BlockArrayClipboard implements Clipboard { @Nullable public Entity createEntity(Location location, BaseEntity entity) { Location l = new Location(location.getExtent(), - location.getX() - offset.getBlockX(), - location.getY() - offset.getBlockY(), - location.getZ() - offset.getBlockZ(), + location.x() - offset.x(), + location.y() - offset.y(), + location.z() - offset.z(), location.getYaw(), location.getPitch() ); return getParent().createEntity(l, entity); @@ -308,9 +308,9 @@ public class BlockArrayClipboard implements Clipboard { @Nullable public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { Location l = new Location(location.getExtent(), - location.getX() - offset.getBlockX(), - location.getY() - offset.getBlockY(), - location.getZ() - offset.getBlockZ(), + location.x() - offset.x(), + location.y() - offset.y(), + location.z() - offset.z(), location.getYaw(), location.getPitch() ); return getParent().createEntity(l, entity, uuid); @@ -318,33 +318,33 @@ public class BlockArrayClipboard implements Clipboard { @Override public void removeEntity(int x, int y, int z, UUID uuid) { - x -= offset.getX(); - y -= offset.getY(); - z -= offset.getZ(); + x -= offset.x(); + y -= offset.y(); + z -= offset.z(); getParent().removeEntity(x, y, z, uuid); } @Override public BlockState getBlock(int x, int y, int z) { - x -= offset.getX(); - y -= offset.getY(); - z -= offset.getZ(); + x -= offset.x(); + y -= offset.y(); + z -= offset.z(); return getParent().getBlock(x, y, z); } @Override public BaseBlock getFullBlock(int x, int y, int z) { - x -= offset.getX(); - y -= offset.getY(); - z -= offset.getZ(); + x -= offset.x(); + y -= offset.y(); + z -= offset.z(); return getParent().getFullBlock(x, y, z); } @Override public BiomeType getBiomeType(int x, int y, int z) { - x -= offset.getX(); - y -= offset.getY(); - z -= offset.getZ(); + x -= offset.x(); + y -= offset.y(); + z -= offset.z(); return getParent().getBiomeType(x, y, z); } @@ -359,7 +359,7 @@ public class BlockArrayClipboard implements Clipboard { public Iterator iterator2d() { MutableBlockVector2 mutable = new MutableBlockVector2(); return Iterators.transform(getParent().iterator2d(), input -> - mutable.setComponents(input.getX() + offset.getX(), input.getZ() + offset.getZ())); + mutable.setComponents(input.x() + offset.x(), input.z() + offset.z())); } @Override @@ -409,7 +409,7 @@ public class BlockArrayClipboard implements Clipboard { private final float pitch; public ClipboardEntity(Location loc, BaseEntity entity) { - this((Clipboard) loc.getExtent(), loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch(), entity); + this((Clipboard) loc.getExtent(), loc.x(), loc.y(), loc.z(), loc.getYaw(), loc.getPitch(), entity); } public ClipboardEntity(Clipboard clipboard, double x, double y, double z, float yaw, float pitch, BaseEntity entity) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java index 76e866c33..d52fd1056 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java @@ -163,15 +163,15 @@ public interface Clipboard extends Extent, Iterable, Closeable, Fl void removeEntity(Entity entity); default int getWidth() { - return getDimensions().getBlockX(); + return getDimensions().x(); } default int getHeight() { - return getDimensions().getBlockY(); + return getDimensions().y(); } default int getLength() { - return getDimensions().getBlockZ(); + return getDimensions().z(); } default int getArea() { @@ -380,17 +380,17 @@ public interface Clipboard extends Extent, Iterable, Closeable, Fl final BlockVector3 origin = this.getOrigin(); // To must be relative to the clipboard origin ( player location - clipboard origin ) (as the locations supplied are relative to the world origin) - final int relx = to.getBlockX() - origin.getBlockX(); - final int rely = to.getBlockY() - origin.getBlockY(); - final int relz = to.getBlockZ() - origin.getBlockZ(); + final int relx = to.x() - origin.x(); + final int rely = to.y() - origin.y(); + final int relz = to.z() - origin.z(); pasteBiomes &= Clipboard.this.hasBiomes(); for (BlockVector3 pos : this) { BaseBlock block = pos.getFullBlock(this); - int xx = pos.getX() + relx; - int yy = pos.getY() + rely; - int zz = pos.getZ() + relz; + int xx = pos.x() + relx; + int yy = pos.y() + rely; + int zz = pos.z() + relz; if (pasteBiomes) { extent.setBiome(xx, yy, zz, pos.getBiome(this)); } @@ -400,9 +400,9 @@ public interface Clipboard extends Extent, Iterable, Closeable, Fl extent.setBlock(xx, yy, zz, block); } // Entity offset is the paste location subtract the clipboard origin (entity's location is already relative to the world origin) - final int entityOffsetX = to.getBlockX() - origin.getBlockX(); - final int entityOffsetY = to.getBlockY() - origin.getBlockY(); - final int entityOffsetZ = to.getBlockZ() - origin.getBlockZ(); + final int entityOffsetX = to.x() - origin.x(); + final int entityOffsetY = to.y() - origin.y(); + final int entityOffsetZ = to.z() - origin.z(); // entities if (pasteEntities) { for (Entity entity : this.getEntities()) { @@ -412,8 +412,8 @@ public interface Clipboard extends Extent, Iterable, Closeable, Fl continue; } Location pos = entity.getLocation(); - Location newPos = new Location(pos.getExtent(), pos.getX() + entityOffsetX, - pos.getY() + entityOffsetY, pos.getZ() + entityOffsetZ, pos.getYaw(), + Location newPos = new Location(pos.getExtent(), pos.x() + entityOffsetX, + pos.y() + entityOffsetY, pos.z() + entityOffsetZ, pos.getYaw(), pos.getPitch() ); extent.createEntity(newPos, entity.getState()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardWriter.java index b7cf7a050..d3420f658 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardWriter.java @@ -50,9 +50,9 @@ public interface ClipboardWriter extends Closeable { //FAWE start default Tag writeVector(Vector3 vector) { List list = new ArrayList<>(); - list.add(new DoubleTag(vector.getX())); - list.add(new DoubleTag(vector.getY())); - list.add(new DoubleTag(vector.getZ())); + list.add(new DoubleTag(vector.x())); + list.add(new DoubleTag(vector.y())); + list.add(new DoubleTag(vector.z())); return new ListTag(DoubleTag.class, list); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java index 83d8c3007..a140b666a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java @@ -263,9 +263,9 @@ public class SpongeSchematicReader extends NBTSchematicReader { int[] pos = requireTag(tileEntity, "Pos", IntArrayTag.class).getValue(); final BlockVector3 pt = BlockVector3.at(pos[0], pos[1], pos[2]); Map values = Maps.newHashMap(tileEntity); - values.put("x", new IntTag(pt.getBlockX())); - values.put("y", new IntTag(pt.getBlockY())); - values.put("z", new IntTag(pt.getBlockZ())); + values.put("x", new IntTag(pt.x())); + values.put("y", new IntTag(pt.y())); + values.put("z", new IntTag(pt.z())); //FAWE start - support old, corrupt schematics Tag id = values.get("Id"); if (id == null) { @@ -378,7 +378,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { palette.put(((IntTag) idTag).getValue(), biome); } - int width = clipboard.getDimensions().getX(); + int width = clipboard.getDimensions().x(); byte[] biomes = dataTag.getValue(); int biomeIndex = 0; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java index 2a10e9f4b..24860dd3c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java @@ -117,9 +117,9 @@ public class SpongeSchematicWriter implements ClipboardWriter { WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion())); Map metadata = new HashMap<>(); - metadata.put("WEOffsetX", new IntTag(offset.getBlockX())); - metadata.put("WEOffsetY", new IntTag(offset.getBlockY())); - metadata.put("WEOffsetZ", new IntTag(offset.getBlockZ())); + metadata.put("WEOffsetX", new IntTag(offset.x())); + metadata.put("WEOffsetY", new IntTag(offset.y())); + metadata.put("WEOffsetZ", new IntTag(offset.z())); metadata.put("FAWEVersion", new IntTag(Fawe.instance().getVersion().build)); schematic.put("Metadata", new CompoundTag(metadata)); @@ -130,9 +130,9 @@ public class SpongeSchematicWriter implements ClipboardWriter { // The Sponge format Offset refers to the 'min' points location in the world. That's our 'Origin' schematic.put("Offset", new IntArrayTag(new int[]{ - min.getBlockX(), - min.getBlockY(), - min.getBlockZ(), + min.x(), + min.y(), + min.z(), })); int paletteMax = 0; @@ -143,11 +143,11 @@ public class SpongeSchematicWriter implements ClipboardWriter { ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length); for (int y = 0; y < height; y++) { - int y0 = min.getBlockY() + y; + int y0 = min.y() + y; for (int z = 0; z < length; z++) { - int z0 = min.getBlockZ() + z; + int z0 = min.z() + z; for (int x = 0; x < width; x++) { - int x0 = min.getBlockX() + x; + int x0 = min.x() + x; BlockVector3 point = BlockVector3.at(x0, y0, z0); BaseBlock block = clipboard.getFullBlock(point); if (block.getNbtData() != null) { @@ -217,10 +217,10 @@ public class SpongeSchematicWriter implements ClipboardWriter { Map palette = new HashMap<>(); for (int z = 0; z < length; z++) { - int z0 = min.getBlockZ() + z; + int z0 = min.z() + z; for (int x = 0; x < width; x++) { - int x0 = min.getBlockX() + x; - BlockVector3 pt = BlockVector3.at(x0, min.getBlockY(), z0); + int x0 = min.x() + x; + BlockVector3 pt = BlockVector3.at(x0, min.y(), z0); BiomeType biome = clipboard.getBiome(pt); String biomeKey = biome.getId(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagExtent.java index ff516e4c9..18e69c7a0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/inventory/BlockBagExtent.java @@ -104,7 +104,7 @@ public class BlockBagExtent extends AbstractDelegateExtent { @Override public > boolean setBlock(BlockVector3 position, B block) throws WorldEditException { - return setBlock(position.getX(), position.getY(), position.getZ(), block); + return setBlock(position.x(), position.y(), position.z(), block); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java index f22d7036d..d9effa512 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java @@ -391,9 +391,9 @@ public class BlockTransformExtent extends ResettableExtent { if (direction != null) { Vector3 applyAbsolute = transform.apply(direction.toVector()); Vector3 applyOrigin = transform.apply(Vector3.ZERO); - applyAbsolute.mutX(applyAbsolute.getX() - applyOrigin.getX()); - applyAbsolute.mutY(applyAbsolute.getY() - applyOrigin.getY()); - applyAbsolute.mutZ(applyAbsolute.getZ() - applyOrigin.getZ()); + applyAbsolute.mutX(applyAbsolute.x() - applyOrigin.x()); + applyAbsolute.mutY(applyAbsolute.y() - applyOrigin.y()); + applyAbsolute.mutZ(applyAbsolute.z() - applyOrigin.z()); Direction newDirection = Direction.findClosest( applyAbsolute, diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/DataValidatorExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/DataValidatorExtent.java index bc498711b..1161779d9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/DataValidatorExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/validation/DataValidatorExtent.java @@ -63,7 +63,7 @@ public class DataValidatorExtent extends AbstractDelegateExtent { @Override public > boolean setBlock(BlockVector3 location, B block) throws WorldEditException { - final int y = location.getBlockY(); + final int y = location.y(); final BlockType type = block.getBlockType(); if (y < minY || y > maxY) { return false; @@ -79,7 +79,7 @@ public class DataValidatorExtent extends AbstractDelegateExtent { @Override public boolean setBiome(BlockVector3 location, BiomeType biome) { - final int y = location.getBlockY(); + final int y = location.y(); if (y < minY || y > maxY) { return false; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SideEffectExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SideEffectExtent.java index 5a90aebbb..413bd31bf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SideEffectExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SideEffectExtent.java @@ -88,7 +88,7 @@ public class SideEffectExtent extends AbstractDelegateExtent { @Override public > boolean setBlock(BlockVector3 location, B block) throws WorldEditException { if (sideEffectSet.getState(SideEffect.LIGHTING) == SideEffect.State.DELAYED) { - dirtyChunks.add(BlockVector2.at(location.getBlockX() >> 4, location.getBlockZ() >> 4)); + dirtyChunks.add(BlockVector2.at(location.x() >> 4, location.z() >> 4)); } if (postEditSimulation) { positions.put(location, world.getBlock(location)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/biome/BiomeReplace.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/biome/BiomeReplace.java index 6ae4ad2ec..90d7f31cf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/biome/BiomeReplace.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/biome/BiomeReplace.java @@ -70,7 +70,7 @@ public class BiomeReplace implements FlatRegionFunction, RegionFunction { @Deprecated public boolean apply(BlockVector2 position) throws WorldEditException { boolean success = false; - for (int y = extent.getMinimumPoint().getY(); y <= extent.getMaximumPoint().getY(); y++) { + for (int y = extent.getMinimumPoint().y(); y <= extent.getMaximumPoint().y(); y++) { success |= apply(position.toBlockVector3(y)); } return success; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/biome/ExtentBiomeCopy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/biome/ExtentBiomeCopy.java index 076c1f561..5643da36a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/biome/ExtentBiomeCopy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/biome/ExtentBiomeCopy.java @@ -102,7 +102,7 @@ public class ExtentBiomeCopy implements FlatRegionFunction, RegionFunction { @Deprecated public boolean apply(BlockVector2 position) throws WorldEditException { boolean success = false; - for (int y = destination.getMinimumPoint().getY(); y <= destination.getMaximumPoint().getY(); y++) { + for (int y = destination.getMinimumPoint().y(); y <= destination.getMaximumPoint().y(); y++) { success |= apply(position.toBlockVector3(y)); } return success; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java index c84fcc67a..4027220b2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java @@ -105,7 +105,7 @@ public class SnowSimulator implements LayerFunction { // Can't put snow this far up - if (position.getBlockY() == this.extent.getMaximumPoint().getBlockY()) { + if (position.y() == this.extent.getMaximumPoint().y()) { return false; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/entity/ExtentEntityCopy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/entity/ExtentEntityCopy.java index fa3ef1dc4..149464bef 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/entity/ExtentEntityCopy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/entity/ExtentEntityCopy.java @@ -206,9 +206,9 @@ public class ExtentEntityCopy implements EntityFunction { BlockVector3 newLeash = transform.apply(tilePosition.subtract(from)).add(to).toBlockPoint(); return new BaseEntity(state.getType(), tag.createBuilder() .put("Leash", leashCompound.createBuilder() - .putInt("X", newLeash.getBlockX()) - .putInt("Y", newLeash.getBlockY()) - .putInt("Z", newLeash.getBlockZ()) + .putInt("X", newLeash.x()) + .putInt("Y", newLeash.y()) + .putInt("Z", newLeash.z()) .build() ).build()); } @@ -226,9 +226,9 @@ public class ExtentEntityCopy implements EntityFunction { BlockVector3 newTilePosition = transform.apply(tilePosition.subtract(from)).add(to).toBlockPoint(); CompoundTagBuilder builder = tag.createBuilder() - .putInt("TileX", newTilePosition.getBlockX()) - .putInt("TileY", newTilePosition.getBlockY()) - .putInt("TileZ", newTilePosition.getBlockZ()); + .putInt("TileX", newTilePosition.x()) + .putInt("TileY", newTilePosition.y()) + .putInt("TileZ", newTilePosition.z()); if (hasFacing) { boolean isPainting = state.getType() == EntityTypes.PAINTING; // Paintings have different facing values diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/ApplyLayer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/ApplyLayer.java index 88e3218c0..c7ecc1207 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/ApplyLayer.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/ApplyLayer.java @@ -53,8 +53,8 @@ public class ApplyLayer implements Contextual { return new LayerVisitor( localRegion, - localRegion.getMinimumPoint().getY(), - localRegion.getMaximumPoint().getY(), + localRegion.getMinimumPoint().y(), + localRegion.getMaximumPoint().y(), function.createFromContext(context), //FAWE start - provide extent for preloading context.getDestination() diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/Deform.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/Deform.java index 115c05044..b4ccd0a55 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/Deform.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/Deform.java @@ -141,13 +141,13 @@ public class Deform implements Contextual { zero = max.add(min).multiply(0.5); unit = max.subtract(zero); - if (unit.getX() == 0) { + if (unit.x() == 0) { unit = unit.withX(1.0); } - if (unit.getY() == 0) { + if (unit.y() == 0) { unit = unit.withY(1.0); } - if (unit.getZ() == 0) { + if (unit.z() == 0) { unit = unit.withZ(1.0); } break; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BoundedHeightMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BoundedHeightMask.java index dfe1841d4..808465416 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BoundedHeightMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BoundedHeightMask.java @@ -48,7 +48,7 @@ public class BoundedHeightMask extends AbstractMask { @Override public boolean test(BlockVector3 vector) { - return vector.getY() >= minY && vector.getY() <= maxY; + return vector.y() >= minY && vector.y() <= maxY; } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java index 1b95057ba..e5647332e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask.java @@ -73,10 +73,10 @@ public class ExpressionMask extends AbstractMask { ((WorldEditExpressionEnvironment) expression.getEnvironment()).setCurrentBlock(vector.toVector3()); } if (timeout == null) { - return expression.evaluate(vector.getX(), vector.getY(), vector.getZ()) > 0; + return expression.evaluate(vector.x(), vector.y(), vector.z()) > 0; } else { return expression.evaluate( - new double[]{vector.getX(), vector.getY(), vector.getZ()}, + new double[]{vector.x(), vector.y(), vector.z()}, timeout.getAsInt() ) > 0; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java index 0d2854b7c..7d5e22e99 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExpressionMask2D.java @@ -63,9 +63,9 @@ public class ExpressionMask2D extends AbstractMask2D { public boolean test(BlockVector2 vector) { try { if (timeout == null) { - return expression.evaluate(vector.getX(), 0, vector.getZ()) > 0; + return expression.evaluate(vector.x(), 0, vector.z()) > 0; } else { - return expression.evaluate(timeout.getAsInt(), vector.getX(), 0, vector.getZ()) > 0; + return expression.evaluate(timeout.getAsInt(), vector.x(), 0, vector.z()) > 0; } } catch (EvaluationException e) { return false; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java index 684148505..d0a016639 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java @@ -97,7 +97,7 @@ public class NoiseFilter extends AbstractMask { @Override public boolean test(BlockVector3 vector) { //FAWE start - mutable - return noiseGenerator.noise(mutable.setComponents(vector.getX(), vector.getZ(), vector.getZ())) <= density; + return noiseGenerator.noise(mutable.setComponents(vector.x(), vector.z(), vector.z())) <= density; //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask.java index 2c809ada4..39eda315b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask.java @@ -116,7 +116,7 @@ public class OffsetMask extends AbstractMask { public boolean test(BlockVector3 vector) { //FAWE start - ignore resultant position outside world height range BlockVector3 testPos = vector.add(offset); - if (testPos.getBlockY() < minY || testPos.getBlockY() > maxY) { + if (testPos.y() < minY || testPos.y() > maxY) { return false; } return getMask().test(testPos); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask2D.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask2D.java index 3e70c9ddd..f08811513 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask2D.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/OffsetMask2D.java @@ -89,13 +89,13 @@ public class OffsetMask2D extends AbstractMask2D { //FAWE start @Override public boolean test(BlockVector2 vector) { - mutableBlockVector2.setComponents(vector.getX() + offset.getX(), vector.getZ() + offset.getZ()); + mutableBlockVector2.setComponents(vector.x() + offset.x(), vector.z() + offset.z()); return getMask().test(mutableBlockVector2); } @Override public Mask2D copy2D() { - return new OffsetMask2D(mask.copy2D(), BlockVector2.at(offset.getX(), offset.getZ())); + return new OffsetMask2D(mask.copy2D(), BlockVector2.at(offset.x(), offset.z())); } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/BackwardsExtentBlockCopy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/BackwardsExtentBlockCopy.java index f766cf8d7..75018d96d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/BackwardsExtentBlockCopy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/BackwardsExtentBlockCopy.java @@ -52,9 +52,9 @@ public class BackwardsExtentBlockCopy extends RegionVisitor implements Operation BlockVector3 max = BlockVector3.at(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); BlockVector3 pos1 = region.getMinimumPoint(); BlockVector3 pos2 = region.getMaximumPoint(); - for (int x : new int[]{pos1.getBlockX(), pos2.getBlockX()}) { - for (int y : new int[]{pos1.getBlockY(), pos2.getBlockY()}) { - for (int z : new int[]{pos1.getBlockZ(), pos2.getBlockZ()}) { + for (int x : new int[]{pos1.x(), pos2.x()}) { + for (int y : new int[]{pos1.y(), pos2.y()}) { + for (int z : new int[]{pos1.z(), pos2.z()}) { BlockVector3 pt = transform(transform, BlockVector3.at(x, y, z)); min = min.getMinimum(pt); max = max.getMaximum(pt); @@ -65,13 +65,13 @@ public class BackwardsExtentBlockCopy extends RegionVisitor implements Operation } private BlockVector3 transform(Transform transform, BlockVector3 pt) { - mutV3.mutX(((pt.getBlockX() - origin.getBlockX()))); - mutV3.mutY(((pt.getBlockY() - origin.getBlockY()))); - mutV3.mutZ(((pt.getBlockZ() - origin.getBlockZ()))); + mutV3.mutX(((pt.x() - origin.x()))); + mutV3.mutY(((pt.y() - origin.y()))); + mutV3.mutZ(((pt.z() - origin.z()))); Vector3 tmp = transform.apply(mutV3); - mutBV3.mutX((tmp.getBlockX() + origin.getBlockX())); - mutBV3.mutY((tmp.getBlockY() + origin.getBlockY())); - mutBV3.mutZ((tmp.getBlockZ() + origin.getBlockZ())); + mutBV3.mutX((tmp.getBlockX() + origin.x())); + mutBV3.mutY((tmp.getBlockY() + origin.y())); + mutBV3.mutZ((tmp.getBlockZ() + origin.z())); return mutBV3; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java index 99ee125ed..f98d5f924 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java @@ -306,9 +306,9 @@ public class ForwardExtentCopy implements Operation { if (!translation.equals(BlockVector3.ZERO)) { finalDest = new BlockTranslateExtent( finalDest, - translation.getBlockX(), - translation.getBlockY(), - translation.getBlockZ() + translation.x(), + translation.y(), + translation.z() ); } //FAWE end @@ -349,21 +349,21 @@ public class ForwardExtentCopy implements Operation { if (sourceFunction != null) { BlockVector3 disAbs = translation.abs(); BlockVector3 size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1); - boolean overlap = (disAbs.getBlockX() < size.getBlockX() && disAbs.getBlockY() < size.getBlockY() && disAbs.getBlockZ() < size - .getBlockZ()); + boolean overlap = (disAbs.x() < size.x() && disAbs.y() < size.y() && disAbs.z() < size + .z()); RegionFunction copySrcFunc = sourceFunction; if (overlap && translation.length() != 0) { - int x = translation.getBlockX(); - int y = translation.getBlockY(); - int z = translation.getBlockZ(); + int x = translation.x(); + int y = translation.y(); + int z = translation.z(); maskFunc = position -> { BlockVector3 bv = BlockVector3.at( - position.getBlockX() + x, - position.getBlockY() + y, - position.getBlockZ() + z + position.x() + x, + position.y() + y, + position.z() + z ); if (region.contains(bv)) { return sourceFunction.apply(bv); @@ -373,9 +373,9 @@ public class ForwardExtentCopy implements Operation { copySrcFunc = position -> { BlockVector3 bv = BlockVector3.at( - position.getBlockX() - x, - position.getBlockY() - y, - position.getBlockZ() - z + position.x() - x, + position.y() - y, + position.z() - z ); if (!region.contains(bv)) { return sourceFunction.apply(position); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java index c45629e5f..bc13fe4de 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java @@ -107,12 +107,12 @@ public class RandomPattern extends AbstractPattern { @Override public BaseBlock applyBlock(BlockVector3 position) { - return collection.next(position.getBlockX(), position.getBlockY(), position.getBlockZ()).applyBlock(position); + return collection.next(position.x(), position.y(), position.z()).applyBlock(position); } @Override public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { - return collection.next(get.getBlockX(), get.getBlockY(), get.getBlockZ()).apply(extent, get, set); + return collection.next(get.x(), get.y(), get.z()).apply(extent, get, set); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RepeatingExtentPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RepeatingExtentPattern.java index 490c47cf2..ed62f92d8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RepeatingExtentPattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RepeatingExtentPattern.java @@ -88,9 +88,9 @@ public class RepeatingExtentPattern extends AbstractExtentPattern { @Override public BaseBlock applyBlock(BlockVector3 position) { //FAWE start - calculate offset - int x = Math.floorMod(position.getBlockX() + offset.getBlockX(), size.getBlockX()) + origin.getBlockX(); - int y = Math.floorMod(position.getBlockY() + offset.getBlockY(), size.getBlockY()) + origin.getBlockY(); - int z = Math.floorMod(position.getBlockZ() + offset.getBlockZ(), size.getBlockZ()) + origin.getBlockZ(); + int x = Math.floorMod(position.x() + offset.x(), size.x()) + origin.x(); + int y = Math.floorMod(position.y() + offset.y(), size.y()) + origin.y(); + int z = Math.floorMod(position.z() + offset.z(), size.z()) + origin.z(); //FAWE end return getExtent().getFullBlock(x, y, z); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java index 7f3e5da63..796f02700 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java @@ -305,10 +305,10 @@ public abstract class BreadthFirstSearch implements Operation { if (loadCount > Settings.settings().QUEUE.PRELOAD_CHUNK_COUNT) { break outer; } - int x = from.getBlockX() + direction.getBlockX(); - int z = from.getBlockZ() + direction.getBlockX(); + int x = from.x() + direction.x(); + int z = from.z() + direction.x(); if (cx != (cx = x >> 4) || cz != (cz = z >> 4)) { - int y = from.getBlockY() + direction.getBlockY(); + int y = from.y() + direction.y(); if (y < singleQueue.getMinY() || y > singleQueue.getMaxY()) { continue; } @@ -320,7 +320,7 @@ public abstract class BreadthFirstSearch implements Operation { } } for (BlockVector3 chunk : chunkLoadSet) { - singleQueue.addChunkLoad(chunk.getBlockX(), chunk.getBlockZ()); + singleQueue.addChunkLoad(chunk.x(), chunk.z()); } } for (BlockVector3 from : queue) { @@ -329,12 +329,12 @@ public abstract class BreadthFirstSearch implements Operation { } for (int i = 0, j = 0; i < dirs.length && j < maxBranch; i++) { BlockVector3 direction = dirs[i]; - int y = from.getBlockY() + direction.getY(); + int y = from.y() + direction.y(); if (y < minY || y > maxY) { continue; } - int x = from.getBlockX() + direction.getX(); - int z = from.getBlockZ() + direction.getZ(); + int x = from.x() + direction.x(); + int z = from.z() + direction.z(); if (!visited.contains(x, y, z)) { if (isVisitable(from, mutable.setComponents(x, y, z))) { j++; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java index f8204b085..2e5f07736 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/DownwardVisitor.java @@ -102,8 +102,8 @@ public class DownwardVisitor extends RecursiveVisitor { @Override protected boolean isVisitable(BlockVector3 from, BlockVector3 to) { - int fromY = from.getBlockY(); - return (fromY == baseY || to.subtract(from).getBlockY() < 0) && super.isVisitable(from, to); + int fromY = from.y(); + return (fromY == baseY || to.subtract(from).y() < 0) && super.isVisitable(from, to); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/RegionVisitor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/RegionVisitor.java index ff6b67e03..5ed98c354 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/RegionVisitor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/visitor/RegionVisitor.java @@ -111,8 +111,8 @@ public class RegionVisitor implements Operation { while (trailIter.hasNext()) { BlockVector3 pt = trailIter.next(); apply(pt); - int cx = pt.getBlockX() >> 4; - int cz = pt.getBlockZ() >> 4; + int cx = pt.x() >> 4; + int cz = pt.z() >> 4; if (cx != lastTrailChunkX || cz != lastTrailChunkZ) { lastTrailChunkX = cx; lastTrailChunkZ = cz; @@ -128,8 +128,8 @@ public class RegionVisitor implements Operation { lead: for (int count = 0; count < amount; ) { BlockVector3 v = leadIter.next(); - int vcx = v.getBlockX() >> 4; - int vcz = v.getBlockZ() >> 4; + int vcx = v.x() >> 4; + int vcz = v.z() >> 4; if (vcx != lastLeadChunkX || vcz != lastLeadChunkZ) { lastLeadChunkX = vcx; lastLeadChunkZ = vcz; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/ArrayListHistory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/ArrayListHistory.java index ff624e81e..1bad79fb9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/ArrayListHistory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/ArrayListHistory.java @@ -83,7 +83,7 @@ public class ArrayListHistory implements ChangeSet { if (change instanceof BlockChange) { BlockChange blockChange = (BlockChange) change; BlockVector3 pos = blockChange.getPosition(); - summary.add(pos.getX(), pos.getZ(), blockChange.getCurrent().getOrdinal()); + summary.add(pos.x(), pos.z(), blockChange.getCurrent().getOrdinal()); } } return summary; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeleter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeleter.java index e4dcd99ab..1c88a1f2d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeleter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeleter.java @@ -54,7 +54,7 @@ public final class ChunkDeleter { private static final Logger LOGGER = LogManagerCompat.getLogger(); private static final Comparator chunkSorter = Comparator.comparing( - pos -> (pos.getBlockX() & 31) + (pos.getBlockZ() & 31) * 32 + pos -> (pos.x() & 31) + (pos.z() & 31) * 32 ); private static final Gson chunkDeleterGson = new GsonBuilder() @@ -182,15 +182,15 @@ public final class ChunkDeleter { int startZ = regZ << 5; int endZ = (regZ << 5) + 31; - int minX = Math.max(Math.min(startX, endX), minChunk.getBlockX()); - int minZ = Math.max(Math.min(startZ, endZ), minChunk.getBlockZ()); - int maxX = Math.min(Math.max(startX, endX), maxChunk.getBlockX()); - int maxZ = Math.min(Math.max(startZ, endZ), maxChunk.getBlockZ()); + int minX = Math.max(Math.min(startX, endX), minChunk.x()); + int minZ = Math.max(Math.min(startZ, endZ), minChunk.z()); + int maxX = Math.min(Math.max(startX, endX), maxChunk.x()); + int maxZ = Math.min(Math.max(startZ, endZ), maxChunk.z()); Stream stream = Stream.iterate( BlockVector2.at(minX, minZ), bv2 -> { - int nextX = bv2.getBlockX(); - int nextZ = bv2.getBlockZ(); + int nextX = bv2.x(); + int nextZ = bv2.z(); if (++nextX > maxX) { nextX = minX; if (++nextZ > maxZ) { @@ -295,8 +295,8 @@ public final class ChunkDeleter { @Override public void write(JsonWriter out, BlockVector2 value) throws IOException { out.beginArray(); - out.value(value.getBlockX()); - out.value(value.getBlockZ()); + out.value(value.x()); + out.value(value.z()); out.endArray(); } @@ -317,8 +317,8 @@ public final class ChunkDeleter { private final int z; RegionFilePos(BlockVector2 chunk) { - this.x = chunk.getBlockX() >> 5; - this.z = chunk.getBlockZ() >> 5; + this.x = chunk.x() >> 5; + this.z = chunk.z() >> 5; } RegionFilePos(int regX, int regZ) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeletionInfo.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeletionInfo.java index 13b9d3847..ffcb5f885 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeletionInfo.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/ChunkDeletionInfo.java @@ -45,7 +45,7 @@ public class ChunkDeletionInfo { return chunks.size(); } final BlockVector2 dist = maxChunk.subtract(minChunk).add(1, 1); - return dist.getBlockX() * dist.getBlockZ(); + return dist.x() * dist.z(); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/RegionAccess.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/RegionAccess.java index 80eb6989e..7c545040e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/RegionAccess.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/anvil/RegionAccess.java @@ -57,8 +57,8 @@ class RegionAccess implements AutoCloseable { } private static int indexChunk(BlockVector2 pos) { - int x = pos.getBlockX() & 31; - int z = pos.getBlockZ() & 31; + int x = pos.x() & 31; + int z = pos.z() & 31; return x + z * 32; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionCylinderEvent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionCylinderEvent.java index b9cf79fe0..4150f9a5c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionCylinderEvent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionCylinderEvent.java @@ -42,11 +42,11 @@ public class SelectionCylinderEvent implements CUIEvent { @Override public String[] getParameters() { return new String[]{ - String.valueOf(pos.getBlockX()), - String.valueOf(pos.getBlockY()), - String.valueOf(pos.getBlockZ()), - String.valueOf(radius.getX()), - String.valueOf(radius.getZ()) + String.valueOf(pos.x()), + String.valueOf(pos.y()), + String.valueOf(pos.z()), + String.valueOf(radius.x()), + String.valueOf(radius.z()) }; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionEllipsoidPointEvent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionEllipsoidPointEvent.java index 3bf609b1b..4e0131329 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionEllipsoidPointEvent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionEllipsoidPointEvent.java @@ -40,9 +40,9 @@ public class SelectionEllipsoidPointEvent implements CUIEvent { public String[] getParameters() { return new String[]{ String.valueOf(id), - String.valueOf(pos.getBlockX()), - String.valueOf(pos.getBlockY()), - String.valueOf(pos.getBlockZ()) + String.valueOf(pos.x()), + String.valueOf(pos.y()), + String.valueOf(pos.z()) }; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPoint2DEvent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPoint2DEvent.java index f27eda25c..f01c240a2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPoint2DEvent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPoint2DEvent.java @@ -32,30 +32,30 @@ public class SelectionPoint2DEvent implements CUIEvent { @Deprecated public SelectionPoint2DEvent(int id, BlockVector2 pos, int area) { this.id = id; - this.blockX = pos.getX(); - this.blockZ = pos.getZ(); + this.blockX = pos.x(); + this.blockZ = pos.z(); this.area = area; } @Deprecated public SelectionPoint2DEvent(int id, BlockVector3 pos, int area) { this.id = id; - this.blockX = pos.getX(); - this.blockZ = pos.getZ(); + this.blockX = pos.x(); + this.blockZ = pos.z(); this.area = area; } public SelectionPoint2DEvent(int id, BlockVector2 pos, long area) { this.id = id; - this.blockX = pos.getX(); - this.blockZ = pos.getZ(); + this.blockX = pos.x(); + this.blockZ = pos.z(); this.area = area; } public SelectionPoint2DEvent(int id, BlockVector3 pos, long area) { this.id = id; - this.blockX = pos.getX(); - this.blockZ = pos.getZ(); + this.blockX = pos.x(); + this.blockZ = pos.z(); this.area = area; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPointEvent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPointEvent.java index 1ee2e466d..42718c7ae 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPointEvent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/SelectionPointEvent.java @@ -49,9 +49,9 @@ public class SelectionPointEvent implements CUIEvent { public String[] getParameters() { return new String[]{ String.valueOf(id), - String.valueOf(pos.getBlockX()), - String.valueOf(pos.getBlockY()), - String.valueOf(pos.getBlockZ()), + String.valueOf(pos.x()), + String.valueOf(pos.y()), + String.valueOf(pos.z()), String.valueOf(area) }; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java index b9f3891f3..8cc91f969 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java @@ -79,9 +79,9 @@ public class ServerCUIHandler { try { CuboidRegion region = ((CuboidRegionSelector) regionSelector).getRegion(); - posX = region.getMinimumPoint().getBlockX(); - posY = region.getMinimumPoint().getBlockY(); - posZ = region.getMinimumPoint().getBlockZ(); + posX = region.getMinimumPoint().x(); + posY = region.getMinimumPoint().y(); + posZ = region.getMinimumPoint().z(); width = region.getWidth(); height = region.getHeight(); @@ -104,9 +104,9 @@ public class ServerCUIHandler { } // Just select the point. - posX = point.getBlockX(); - posY = point.getBlockY(); - posZ = point.getBlockZ(); + posX = point.x(); + posY = point.y(); + posZ = point.z(); width = 1; height = 1; length = 1; @@ -128,8 +128,8 @@ public class ServerCUIHandler { double rotX = location.getYaw(); double rotY = location.getPitch(); double xz = Math.cos(Math.toRadians(rotY)); - int x = (int) (location.getX() - (-xz * Math.sin(Math.toRadians(rotX))) * 12); - int z = (int) (location.getZ() - (xz * Math.cos(Math.toRadians(rotX))) * 12); + int x = (int) (location.x() - (-xz * Math.sin(Math.toRadians(rotX))) * 12); + int z = (int) (location.z() - (xz * Math.cos(Math.toRadians(rotX))) * 12); int y = Math.max( player.getWorld().getMinY(), Math.min(Math.min(player.getWorld().getMaxY(), posY + MAX_DISTANCE), posY + 3) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/RegionOptimizedVectorSorter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/RegionOptimizedVectorSorter.java index b30bd8f49..4fdcb2118 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/RegionOptimizedVectorSorter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/RegionOptimizedVectorSorter.java @@ -62,13 +62,13 @@ public class RegionOptimizedVectorSorter { private static final long FLIP_REGION_Z_SIGN = 0x1_00_00L << REGION_Z_SHIFT; private static long key(BlockVector3 elem) { - long x = elem.getX(); - long z = elem.getZ(); + long x = elem.x(); + long z = elem.z(); return (((x << (REGION_X_SHIFT - 9)) & REGION_X_MASK) ^ FLIP_REGION_X_SIGN) | (((z << (REGION_Z_SHIFT - 9)) & REGION_Z_MASK) ^ FLIP_REGION_Z_SIGN) | ((x << (CHUNK_X_SHIFT - 4)) & CHUNK_X_MASK) | ((z << (CHUNK_Z_SHIFT - 4)) & CHUNK_Z_MASK) - | (Y_MAX - elem.getY()); + | (Y_MAX - elem.y()); } private static final int NUMBER_OF_BITS = 64; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java index 769773b96..aa90cb816 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java @@ -50,9 +50,9 @@ public interface WorldNativeAccess { checkNotNull(block); setCurrentSideEffectSet(sideEffects); - int x = position.getBlockX(); - int y = position.getBlockY(); - int z = position.getBlockZ(); + int x = position.x(); + int y = position.y(); + int z = position.z(); // First set the block NC chunk = getChunk(x >> 4, z >> 4); @@ -75,9 +75,9 @@ public interface WorldNativeAccess { if (tag != null) { tag = tag.put(ImmutableMap.of( "id", StringBinaryTag.of(baseBlock.getNbtId()), - "x", IntBinaryTag.of(position.getX()), - "y", IntBinaryTag.of(position.getY()), - "z", IntBinaryTag.of(position.getZ()) + "x", IntBinaryTag.of(position.x()), + "y", IntBinaryTag.of(position.y()), + "z", IntBinaryTag.of(position.z()) )); // update if TE changed as well @@ -99,8 +99,8 @@ public interface WorldNativeAccess { default void applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) { setCurrentSideEffectSet(sideEffectSet); - NP pos = getPosition(position.getX(), position.getY(), position.getZ()); - NC chunk = getChunk(position.getX() >> 4, position.getZ() >> 4); + NP pos = getPosition(position.x(), position.y(), position.z()); + NC chunk = getChunk(position.x() >> 4, position.z() >> 4); NBS oldData = toNative(previousType); NBS newData = getBlockState(chunk, pos); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java index cb5784cce..baed5ffde 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java @@ -53,7 +53,7 @@ public class BlockVector2 { * */ public static final Comparator COMPARING_GRID_ARRANGEMENT = - Comparator.comparingInt(BlockVector2::getZ).thenComparingInt(BlockVector2::getX); + Comparator.comparingInt(BlockVector2::z).thenComparingInt(BlockVector2::x); public static BlockVector2 at(double x, double z) { return at((int) Math.floor(x), (int) Math.floor(z)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java index e48355d63..3d239b352 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java @@ -254,7 +254,7 @@ public abstract class BlockVector3 { */ //FAWE start - getter public BlockVector3 withY(int y) { - return BlockVector3.at(getX(), y, getZ()); + return BlockVector3.at(x(), y, z()); } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java index 68e62e937..0eeabee70 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/convolution/HeightMap.java @@ -89,10 +89,10 @@ public class HeightMap { this.maxSessionY = session.getMaxY(); //FAWE end - int minX = region.getMinimumPoint().getBlockX(); - int minY = region.getMinimumPoint().getBlockY(); - int minZ = region.getMinimumPoint().getBlockZ(); - int maxY = region.getMaximumPoint().getBlockY(); + int minX = region.getMinimumPoint().x(); + int minY = region.getMinimumPoint().y(); + int minZ = region.getMinimumPoint().z(); + int maxY = region.getMaximumPoint().y(); // Store current heightmap data data = new int[width * height]; @@ -100,14 +100,14 @@ public class HeightMap { //FAWE start if (layers) { BlockVector3 min = region.getMinimumPoint(); - int bx = min.getBlockX(); - int bz = min.getBlockZ(); + int bx = min.x(); + int bz = min.z(); Iterator flat = Regions.asFlatRegion(region).asFlatRegion().iterator(); int layer = session.getMinY(); while (flat.hasNext()) { BlockVector2 pos = flat.next(); - int x = pos.getBlockX(); - int z = pos.getBlockZ(); + int x = pos.x(); + int z = pos.z(); layer = session.getNearestSurfaceLayer(x, z, (layer + 7) >> 3, session.getMinY(), maxY); data[(z - bz) * width + (x - bx)] = layer; } @@ -169,10 +169,10 @@ public class HeightMap { checkNotNull(data); BlockVector3 min = region.getMinimumPoint(); - int originX = min.getBlockX(); - int originZ = min.getBlockZ(); + int originX = min.x(); + int originZ = min.z(); - int maxY = region.getMaximumPoint().getBlockY(); + int maxY = region.getMaximumPoint().y(); BlockState fillerAir = BlockTypes.AIR.getDefaultState(); @@ -261,11 +261,11 @@ public class HeightMap { checkNotNull(data); BlockVector3 min = region.getMinimumPoint(); - int originX = min.getBlockX(); - int originY = min.getBlockY(); - int originZ = min.getBlockZ(); + int originX = min.x(); + int originY = min.y(); + int originZ = min.z(); - int maxY = region.getMaximumPoint().getBlockY(); + int maxY = region.getMaximumPoint().y(); BlockState fillerAir = BlockTypes.AIR.getDefaultState(); int blocksChanged = 0; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/convolution/SnowHeightMap.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/convolution/SnowHeightMap.java index 97f58f9e1..0c12c4652 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/convolution/SnowHeightMap.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/convolution/SnowHeightMap.java @@ -65,10 +65,10 @@ public class SnowHeightMap { this.width = region.getWidth(); this.height = region.getLength(); - int minX = region.getMinimumPoint().getBlockX(); - int minY = region.getMinimumPoint().getBlockY(); - int minZ = region.getMinimumPoint().getBlockZ(); - int maxY = region.getMaximumPoint().getBlockY(); + int minX = region.getMinimumPoint().x(); + int minY = region.getMinimumPoint().y(); + int minZ = region.getMinimumPoint().z(); + int maxY = region.getMaximumPoint().y(); // Store current heightmap data data = new float[width * height]; @@ -134,11 +134,11 @@ public class SnowHeightMap { checkNotNull(data); BlockVector3 minY = region.getMinimumPoint(); - int originX = minY.getBlockX(); - int originY = minY.getBlockY(); - int originZ = minY.getBlockZ(); + int originX = minY.x(); + int originY = minY.y(); + int originZ = minY.z(); - int maxY = region.getMaximumPoint().getBlockY(); + int maxY = region.getMaximumPoint().y(); BlockState fillerAir = BlockTypes.AIR.getDefaultState(); BlockState fillerSnow = BlockTypes.SNOW_BLOCK.getDefaultState(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/interpolation/KochanekBartelsInterpolation.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/interpolation/KochanekBartelsInterpolation.java index 561ba14bf..0ecced12e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/interpolation/KochanekBartelsInterpolation.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/interpolation/KochanekBartelsInterpolation.java @@ -164,10 +164,10 @@ public class KochanekBartelsInterpolation implements Interpolation { //FAWE start double r2 = remainder * remainder; double r3 = r2 * remainder; - mutable.mutX((a.getX() * r3 + b.getX() * r2 + c.getX() * remainder + d.getX())); - mutable.mutY((a.getY() * r3 + b.getY() * r2 + c.getY() * remainder + d.getY())); - mutable.mutZ((a.getZ() * r3 + b.getZ() * r2 + c.getZ() * remainder + d.getZ())); - return Vector3.at(mutable.getX(), mutable.getY(), mutable.getZ()); + mutable.mutX((a.x() * r3 + b.x() * r2 + c.x() * remainder + d.x())); + mutable.mutY((a.y() * r3 + b.y() * r2 + c.y() * remainder + d.y())); + mutable.mutZ((a.z() * r3 + b.z() * r2 + c.z() * remainder + d.z())); + return Vector3.at(mutable.x(), mutable.y(), mutable.z()); //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/noise/JLibNoiseGenerator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/noise/JLibNoiseGenerator.java index a7f3fe449..c541d2d3d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/noise/JLibNoiseGenerator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/noise/JLibNoiseGenerator.java @@ -47,12 +47,12 @@ abstract class JLibNoiseGenerator implements NoiseGenerator { @Override public float noise(Vector2 position) { - return forceRange(module.GetValue(position.getX(), 0, position.getZ())); + return forceRange(module.GetValue(position.x(), 0, position.z())); } @Override public float noise(Vector3 position) { - return forceRange(module.GetValue(position.getX(), position.getY(), position.getZ())); + return forceRange(module.GetValue(position.x(), position.y(), position.z())); } private float forceRange(double value) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/transform/AffineTransform.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/transform/AffineTransform.java index 02ee75d44..92e81eea2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/transform/AffineTransform.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/transform/AffineTransform.java @@ -265,11 +265,11 @@ public class AffineTransform implements Transform, Serializable { } public AffineTransform translate(Vector3 vec) { - return translate(vec.getX(), vec.getY(), vec.getZ()); + return translate(vec.x(), vec.y(), vec.z()); } public AffineTransform translate(BlockVector3 vec) { - return translate(vec.getX(), vec.getY(), vec.getZ()); + return translate(vec.x(), vec.y(), vec.z()); } public AffineTransform translate(double x, double y, double z) { @@ -315,29 +315,29 @@ public class AffineTransform implements Transform, Serializable { } public AffineTransform scale(Vector3 vec) { - return scale(vec.getX(), vec.getY(), vec.getZ()); + return scale(vec.x(), vec.y(), vec.z()); } //FAWE start public boolean isScaled(Vector3 vector) { - boolean flip = vector.getX() != 0 && m00 < 0; - if (vector.getY() != 0 && m11 < 0) { + boolean flip = vector.x() != 0 && m00 < 0; + if (vector.y() != 0 && m11 < 0) { flip = !flip; } - if (vector.getZ() != 0 && m22 < 0) { + if (vector.z() != 0 && m22 < 0) { flip = !flip; } if (flip) { return true; } // Check for flip-and-rotate - if (vector.getX() != 0 && vector.getY() != 0 && ((m01 < 0 && m10 < 0) || (m01 > 0 && m10 > 0))) { + if (vector.x() != 0 && vector.y() != 0 && ((m01 < 0 && m10 < 0) || (m01 > 0 && m10 > 0))) { flip = true; } - if (vector.getX() != 0 && vector.getZ() != 0 && ((m02 < 0 && m20 < 0) || (m02 > 0 && m20 > 0))) { + if (vector.x() != 0 && vector.z() != 0 && ((m02 < 0 && m20 < 0) || (m02 > 0 && m20 > 0))) { flip = !flip; } - if (vector.getY() != 0 && vector.getZ() != 0 && ((m12 < 0 && m21 < 0) || (m12 > 0 && m21 > 0))) { + if (vector.y() != 0 && vector.z() != 0 && ((m12 < 0 && m21 < 0) || (m12 > 0 && m21 > 0))) { flip = !flip; } return flip; @@ -346,9 +346,9 @@ public class AffineTransform implements Transform, Serializable { @Override public Vector3 apply(Vector3 vector) { - double x = (vector.getX() * m00 + vector.getY() * m01 + vector.getZ() * m02 + m03); - double y = (vector.getX() * m10 + vector.getY() * m11 + vector.getZ() * m12 + m13); - double z = (vector.getX() * m20 + vector.getY() * m21 + vector.getZ() * m22 + m23); + double x = (vector.x() * m00 + vector.y() * m01 + vector.z() * m02 + m03); + double y = (vector.x() * m10 + vector.y() * m11 + vector.z() * m12 + m13); + double z = (vector.x() * m20 + vector.y() * m21 + vector.z() * m22 + m23); vector = vector.mutX(x); vector = vector.mutY(y); vector = vector.mutZ(z); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractFlatRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractFlatRegion.java index 8534f0f35..a868e0262 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractFlatRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractFlatRegion.java @@ -29,12 +29,12 @@ public abstract class AbstractFlatRegion extends AbstractRegion implements FlatR @Override public int getMinimumY() { - return getMinimumPoint().getBlockY(); + return getMinimumPoint().y(); } @Override public int getMaximumY() { - return getMaximumPoint().getBlockY(); + return getMaximumPoint().y(); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java index 85979b217..f87f9741b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/AbstractRegion.java @@ -20,8 +20,6 @@ package com.sk89q.worldedit.regions; import com.fastasyncworldedit.core.math.BlockVectorSet; -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.math.Vector3; @@ -109,10 +107,10 @@ public abstract class AbstractRegion extends AbstractSet implement final List points = new ArrayList<>(4); - points.add(BlockVector2.at(min.getX(), min.getZ())); - points.add(BlockVector2.at(min.getX(), max.getZ())); - points.add(BlockVector2.at(max.getX(), max.getZ())); - points.add(BlockVector2.at(max.getX(), min.getZ())); + points.add(BlockVector2.at(min.x(), min.z())); + points.add(BlockVector2.at(min.x(), max.z())); + points.add(BlockVector2.at(max.x(), max.z())); + points.add(BlockVector2.at(max.x(), min.z())); return points; } @@ -122,9 +120,9 @@ public abstract class AbstractRegion extends AbstractSet implement BlockVector3 min = getMinimumPoint(); BlockVector3 max = getMaximumPoint(); - return (max.getX() - min.getX() + 1L) - * (max.getY() - min.getY() + 1L) - * (max.getZ() - min.getZ() + 1L); + return (max.x() - min.x() + 1L) + * (max.y() - min.y() + 1L) + * (max.z() - min.z() + 1L); } /** @@ -137,7 +135,7 @@ public abstract class AbstractRegion extends AbstractSet implement BlockVector3 min = getMinimumPoint(); BlockVector3 max = getMaximumPoint(); - return max.getX() - min.getX() + 1; + return max.x() - min.x() + 1; } /** @@ -150,7 +148,7 @@ public abstract class AbstractRegion extends AbstractSet implement BlockVector3 min = getMinimumPoint(); BlockVector3 max = getMaximumPoint(); - return max.getY() - min.getY() + 1; + return max.y() - min.y() + 1; } /** @@ -163,7 +161,7 @@ public abstract class AbstractRegion extends AbstractSet implement BlockVector3 min = getMinimumPoint(); BlockVector3 max = getMaximumPoint(); - return max.getZ() - min.getZ() + 1; + return max.z() - min.z() + 1; } /** @@ -179,12 +177,12 @@ public abstract class AbstractRegion extends AbstractSet implement final BlockVector3 maxBlock = getMaximumPoint(); //FAWE start - final BlockVector2 min = BlockVector2.at(minBlock.getX() >> 4, minBlock.getZ() >> 4); - final BlockVector2 max = BlockVector2.at(maxBlock.getX() >> 4, maxBlock.getZ() >> 4); + final BlockVector2 min = BlockVector2.at(minBlock.x() >> 4, minBlock.z() >> 4); + final BlockVector2 max = BlockVector2.at(maxBlock.x() >> 4, maxBlock.z() >> 4); //FAWE end - for (int X = min.getBlockX(); X <= max.getBlockX(); ++X) { - for (int Z = min.getBlockZ(); Z <= max.getBlockZ(); ++Z) { + for (int X = min.x(); X <= max.x(); ++X) { + for (int Z = min.z(); Z <= max.z(); ++Z) { if (containsChunk(X, Z)) { chunks.add(BlockVector2.at(X, Z)); } @@ -201,9 +199,9 @@ public abstract class AbstractRegion extends AbstractSet implement final BlockVector3 min = getMinimumPoint(); final BlockVector3 max = getMaximumPoint(); - for (int x = min.getBlockX(); x <= max.getBlockX(); ++x) { - for (int y = min.getBlockY(); y <= max.getBlockY(); ++y) { - for (int z = min.getBlockZ(); z <= max.getBlockZ(); ++z) { + for (int x = min.x(); x <= max.x(); ++x) { + for (int y = min.y(); y <= max.y(); ++y) { + for (int z = min.z(); z <= max.z(); ++z) { if (!contains(BlockVector3.at(x, y, z))) { continue; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java index d04e5aa8c..8616cbb2b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java @@ -160,12 +160,12 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { } pos1 = pos1.clampY(getWorldMinY(), getWorldMaxY()); pos2 = pos2.clampY(getWorldMinY(), getWorldMaxY()); - 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()); + minX = Math.min(pos1.x(), pos2.x()); + minY = Math.min(pos1.y(), pos2.y()); + minZ = Math.min(pos1.z(), pos2.z()); + maxX = Math.max(pos1.x(), pos2.x()); + maxY = Math.max(pos1.y(), pos2.y()); + maxZ = Math.max(pos1.z(), pos2.z()); } //FAWE start - allow region to be created without clamping Y @@ -176,12 +176,12 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { 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()); + minX = Math.min(pos1.x(), pos2.x()); + minY = Math.min(pos1.y(), pos2.y()); + minZ = Math.min(pos1.z(), pos2.z()); + maxX = Math.max(pos1.x(), pos2.x()); + maxY = Math.max(pos1.y(), pos2.y()); + maxZ = Math.max(pos1.z(), pos2.z()); } //FAWE end @@ -196,16 +196,16 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { return new RegionIntersection( // Project to Z-Y plane - new CuboidRegion(pos1.withX(min.getX()), pos2.withX(min.getX())), - new CuboidRegion(pos1.withX(max.getX()), pos2.withX(max.getX())), + new CuboidRegion(pos1.withX(min.x()), pos2.withX(min.x())), + new CuboidRegion(pos1.withX(max.x()), pos2.withX(max.x())), // Project to X-Y plane - new CuboidRegion(pos1.withZ(min.getZ()), pos2.withZ(min.getZ())), - new CuboidRegion(pos1.withZ(max.getZ()), pos2.withZ(max.getZ())), + new CuboidRegion(pos1.withZ(min.z()), pos2.withZ(min.z())), + new CuboidRegion(pos1.withZ(max.z()), pos2.withZ(max.z())), // Project to the X-Z plane - new CuboidRegion(pos1.withY(min.getY()), pos2.withY(min.getY())), - new CuboidRegion(pos1.withY(max.getY()), pos2.withY(max.getY())) + new CuboidRegion(pos1.withY(min.y()), pos2.withY(min.y())), + new CuboidRegion(pos1.withY(max.y()), pos2.withY(max.y())) ); } @@ -221,7 +221,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { BlockVector3 dimensions = getDimensions(); //FAWE start - if (dimensions.getX() <= 2 || dimensions.getZ() <= 2) { + if (dimensions.x() <= 2 || dimensions.z() <= 2) { // The wall are the region return new RegionIntersection(this); } @@ -229,18 +229,18 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { return new RegionIntersection( // Project to Z-Y plane - new CuboidRegion(pos1.withX(min.getX()), pos2.withX(min.getX())), - new CuboidRegion(pos1.withX(max.getX()), pos2.withX(max.getX())), + new CuboidRegion(pos1.withX(min.x()), pos2.withX(min.x())), + new CuboidRegion(pos1.withX(max.x()), pos2.withX(max.x())), // Project to X-Y plane //FAWE start = prevent overlap new CuboidRegion( - pos1.withZ(min.getZ()).add(BlockVector3.UNIT_X), - pos2.withZ(min.getZ()).subtract(BlockVector3.UNIT_X) + pos1.withZ(min.z()).add(BlockVector3.UNIT_X), + pos2.withZ(min.z()).subtract(BlockVector3.UNIT_X) ), new CuboidRegion( - pos1.withZ(max.getZ()).add(BlockVector3.UNIT_X), - pos2.withZ(max.getZ()).subtract(BlockVector3.UNIT_X) + pos1.withZ(max.z()).add(BlockVector3.UNIT_X), + pos2.withZ(max.z()).subtract(BlockVector3.UNIT_X) ) //FAWE end ); @@ -276,45 +276,45 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { checkNotNull(changes); for (BlockVector3 change : changes) { - if (change.getX() > 0) { - if (Math.max(pos1.getX(), pos2.getX()) == pos1.getX()) { - pos1 = pos1.add(change.getX(), 0, 0); + if (change.x() > 0) { + if (Math.max(pos1.x(), pos2.x()) == pos1.x()) { + pos1 = pos1.add(change.x(), 0, 0); } else { - pos2 = pos2.add(change.getX(), 0, 0); + pos2 = pos2.add(change.x(), 0, 0); } } else { - if (Math.min(pos1.getX(), pos2.getX()) == pos1.getX()) { - pos1 = pos1.add(change.getX(), 0, 0); + if (Math.min(pos1.x(), pos2.x()) == pos1.x()) { + pos1 = pos1.add(change.x(), 0, 0); } else { - pos2 = pos2.add(change.getX(), 0, 0); + pos2 = pos2.add(change.x(), 0, 0); } } - if (change.getY() > 0) { - if (Math.max(pos1.getY(), pos2.getY()) == pos1.getY()) { - pos1 = pos1.add(0, change.getY(), 0); + if (change.y() > 0) { + if (Math.max(pos1.y(), pos2.y()) == pos1.y()) { + pos1 = pos1.add(0, change.y(), 0); } else { - pos2 = pos2.add(0, change.getY(), 0); + pos2 = pos2.add(0, change.y(), 0); } } else { - if (Math.min(pos1.getY(), pos2.getY()) == pos1.getY()) { - pos1 = pos1.add(0, change.getY(), 0); + if (Math.min(pos1.y(), pos2.y()) == pos1.y()) { + pos1 = pos1.add(0, change.y(), 0); } else { - pos2 = pos2.add(0, change.getY(), 0); + pos2 = pos2.add(0, change.y(), 0); } } - if (change.getZ() > 0) { - if (Math.max(pos1.getZ(), pos2.getZ()) == pos1.getZ()) { - pos1 = pos1.add(0, 0, change.getZ()); + if (change.z() > 0) { + if (Math.max(pos1.z(), pos2.z()) == pos1.z()) { + pos1 = pos1.add(0, 0, change.z()); } else { - pos2 = pos2.add(0, 0, change.getZ()); + pos2 = pos2.add(0, 0, change.z()); } } else { - if (Math.min(pos1.getZ(), pos2.getZ()) == pos1.getZ()) { - pos1 = pos1.add(0, 0, change.getZ()); + if (Math.min(pos1.z(), pos2.z()) == pos1.z()) { + pos1 = pos1.add(0, 0, change.z()); } else { - pos2 = pos2.add(0, 0, change.getZ()); + pos2 = pos2.add(0, 0, change.z()); } } } @@ -327,45 +327,45 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { checkNotNull(changes); for (BlockVector3 change : changes) { - if (change.getX() < 0) { - if (Math.max(pos1.getX(), pos2.getX()) == pos1.getX()) { - pos1 = pos1.add(change.getX(), 0, 0); + if (change.x() < 0) { + if (Math.max(pos1.x(), pos2.x()) == pos1.x()) { + pos1 = pos1.add(change.x(), 0, 0); } else { - pos2 = pos2.add(change.getX(), 0, 0); + pos2 = pos2.add(change.x(), 0, 0); } } else { - if (Math.min(pos1.getX(), pos2.getX()) == pos1.getX()) { - pos1 = pos1.add(change.getX(), 0, 0); + if (Math.min(pos1.x(), pos2.x()) == pos1.x()) { + pos1 = pos1.add(change.x(), 0, 0); } else { - pos2 = pos2.add(change.getX(), 0, 0); + pos2 = pos2.add(change.x(), 0, 0); } } - if (change.getY() < 0) { - if (Math.max(pos1.getY(), pos2.getY()) == pos1.getY()) { - pos1 = pos1.add(0, change.getY(), 0); + if (change.y() < 0) { + if (Math.max(pos1.y(), pos2.y()) == pos1.y()) { + pos1 = pos1.add(0, change.y(), 0); } else { - pos2 = pos2.add(0, change.getY(), 0); + pos2 = pos2.add(0, change.y(), 0); } } else { - if (Math.min(pos1.getY(), pos2.getY()) == pos1.getY()) { - pos1 = pos1.add(0, change.getY(), 0); + if (Math.min(pos1.y(), pos2.y()) == pos1.y()) { + pos1 = pos1.add(0, change.y(), 0); } else { - pos2 = pos2.add(0, change.getY(), 0); + pos2 = pos2.add(0, change.y(), 0); } } - if (change.getZ() < 0) { - if (Math.max(pos1.getZ(), pos2.getZ()) == pos1.getZ()) { - pos1 = pos1.add(0, 0, change.getZ()); + if (change.z() < 0) { + if (Math.max(pos1.z(), pos2.z()) == pos1.z()) { + pos1 = pos1.add(0, 0, change.z()); } else { - pos2 = pos2.add(0, 0, change.getZ()); + pos2 = pos2.add(0, 0, change.z()); } } else { - if (Math.min(pos1.getZ(), pos2.getZ()) == pos1.getZ()) { - pos1 = pos1.add(0, 0, change.getZ()); + if (Math.min(pos1.z(), pos2.z()) == pos1.z()) { + pos1 = pos1.add(0, 0, change.z()); } else { - pos2 = pos2.add(0, 0, change.getZ()); + pos2 = pos2.add(0, 0, change.z()); } } } @@ -385,10 +385,10 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { public Set getChunks() { BlockVector3 min = getMinimumPoint(); BlockVector3 max = getMaximumPoint(); - final int maxX = max.getBlockX() >> ChunkStore.CHUNK_SHIFTS; - final int minX = min.getBlockX() >> ChunkStore.CHUNK_SHIFTS; - final int maxZ = max.getBlockZ() >> ChunkStore.CHUNK_SHIFTS; - final int minZ = min.getBlockZ() >> ChunkStore.CHUNK_SHIFTS; + final int maxX = max.x() >> ChunkStore.CHUNK_SHIFTS; + final int minX = min.x() >> ChunkStore.CHUNK_SHIFTS; + final int maxZ = max.z() >> ChunkStore.CHUNK_SHIFTS; + final int minZ = min.z() >> ChunkStore.CHUNK_SHIFTS; final int size = (maxX - minX + 1) * (maxZ - minZ + 1); //FAWE start @@ -471,7 +471,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { public boolean contains(Object o) { if (o instanceof BlockVector2) { BlockVector2 cv = (BlockVector2) o; - return cv.getX() >= minX && cv.getX() <= maxX && cv.getZ() >= minZ && cv.getZ() <= maxZ; + return cv.x() >= minX && cv.x() <= maxX && cv.z() >= minZ && cv.z() <= maxZ; } return false; } @@ -488,9 +488,9 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { BlockVector3 min = getMinimumPoint(); BlockVector3 max = getMaximumPoint(); - for (int x = min.getBlockX() >> ChunkStore.CHUNK_SHIFTS; x <= max.getBlockX() >> ChunkStore.CHUNK_SHIFTS; ++x) { - for (int z = min.getBlockZ() >> ChunkStore.CHUNK_SHIFTS; z <= max.getBlockZ() >> ChunkStore.CHUNK_SHIFTS; ++z) { - for (int y = min.getBlockY() >> ChunkStore.CHUNK_SHIFTS; y <= max.getBlockY() >> ChunkStore.CHUNK_SHIFTS; ++y) { + for (int x = min.x() >> ChunkStore.CHUNK_SHIFTS; x <= max.x() >> ChunkStore.CHUNK_SHIFTS; ++x) { + for (int z = min.z() >> ChunkStore.CHUNK_SHIFTS; z <= max.z() >> ChunkStore.CHUNK_SHIFTS; ++z) { + for (int y = min.y() >> ChunkStore.CHUNK_SHIFTS; y <= max.y() >> ChunkStore.CHUNK_SHIFTS; ++y) { chunks.add(BlockVector3.at(x, y, z)); } } @@ -503,7 +503,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { @Override public boolean contains(BlockVector3 position) { //FAWE start - return contains(position.getX(), position.getY(), position.getZ()); + return contains(position.x(), position.y(), position.z()); //FAWE end } @@ -532,17 +532,17 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { private final BlockVector3 min = getMinimumPoint(); private final BlockVector3 max = getMaximumPoint(); - final int bx = min.getBlockX(); - final int by = min.getBlockY(); - final int bz = min.getBlockZ(); + final int bx = min.x(); + final int by = min.y(); + final int bz = min.z(); - final int tx = max.getBlockX(); - final int ty = max.getBlockY(); - final int tz = max.getBlockZ(); + final int tx = max.x(); + final int ty = max.y(); + final int tz = max.z(); - private int x = min.getBlockX(); - private int y = min.getBlockY(); - private int z = min.getBlockZ(); + private int x = min.x(); + private int y = min.y(); + private int z = min.z(); int cx = x >> 4; int cz = z >> 4; @@ -611,9 +611,9 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { return new Iterator() { private final BlockVector3 min = getMinimumPoint(); private final BlockVector3 max = getMaximumPoint(); - private int nextX = min.getBlockX(); - private int nextY = min.getBlockY(); - private int nextZ = min.getBlockZ(); + private int nextX = min.x(); + private int nextY = min.y(); + private int nextZ = min.z(); private boolean hasNext = true; @Override @@ -626,17 +626,17 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { mutable.mutX(nextX); mutable.mutY(nextY); mutable.mutZ(nextZ); - if (++nextX > max.getBlockX()) { - nextX = min.getBlockX(); - if (++nextZ > max.getBlockZ()) { - nextZ = min.getBlockZ(); - if (++nextY > max.getBlockY()) { + if (++nextX > max.x()) { + nextX = min.x(); + if (++nextZ > max.z()) { + nextZ = min.z(); + if (++nextY > max.y()) { if (!hasNext()) { throw new NoSuchElementException(); } - nextX = max.getBlockX(); - nextZ = max.getBlockZ(); - nextY = max.getBlockY(); + nextX = max.x(); + nextZ = max.z(); + nextY = max.y(); hasNext = false; } } @@ -652,8 +652,8 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { return () -> new Iterator() { private final BlockVector3 min = getMinimumPoint(); private final BlockVector3 max = getMaximumPoint(); - private int nextX = min.getBlockX(); - private int nextZ = min.getBlockZ(); + private int nextX = min.x(); + private int nextZ = min.z(); @Override public boolean hasNext() { @@ -666,9 +666,9 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { throw new NoSuchElementException(); } BlockVector2 answer = BlockVector2.at(nextX, nextZ); - if (++nextX > max.getBlockX()) { - nextX = min.getBlockX(); - if (++nextZ > max.getBlockZ()) { + if (++nextX > max.x()) { + nextX = min.x(); + if (++nextZ > max.z()) { nextZ = Integer.MAX_VALUE; nextX = Integer.MAX_VALUE; } @@ -705,10 +705,10 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { public static boolean contains(CuboidRegion region) { BlockVector3 min = region.getMinimumPoint(); BlockVector3 max = region.getMaximumPoint(); - return region.contains(min.getBlockX(), min.getBlockY(), min.getBlockZ()) && region.contains( - max.getBlockX(), - max.getBlockY(), - max.getBlockZ() + return region.contains(min.x(), min.y(), min.z()) && region.contains( + max.x(), + max.y(), + max.z() ); } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java index 6439d6079..85c62e771 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java @@ -197,8 +197,8 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { @Override public long getVolume() { - return BigDecimal.valueOf(radius.getX()) - .multiply(BigDecimal.valueOf(radius.getZ())) + return BigDecimal.valueOf(radius.x()) + .multiply(BigDecimal.valueOf(radius.z())) .multiply(PI) .multiply(BigDecimal.valueOf(getHeight())) .setScale(0, RoundingMode.FLOOR) @@ -207,7 +207,7 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { @Override public int getWidth() { - return (int) (2 * radius.getX()); + return (int) (2 * radius.x()); } @Override @@ -217,7 +217,7 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { @Override public int getLength() { - return (int) (2 * radius.getZ()); + return (int) (2 * radius.z()); } private BlockVector2 calculateDiff2D(BlockVector3... changes) throws RegionOperationException { @@ -226,7 +226,7 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { diff = diff.add(change.toBlockVector2()); } - if ((diff.getBlockX() & 1) + (diff.getBlockZ() & 1) != 0) { + if ((diff.x() & 1) + (diff.z() & 1) != 0) { throw new RegionOperationException(Caption.of("worldedit.selection.cylinder.error.even-horizontal")); } @@ -254,7 +254,7 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { radius = radius.add(calculateChanges2D(changes).toVector2()); this.radiusInverse = Vector2.ONE.divide(radius); for (BlockVector3 change : changes) { - int changeY = change.getBlockY(); + int changeY = change.y(); if (changeY > 0) { maxY += changeY; } else { @@ -276,7 +276,7 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { this.radiusInverse = Vector2.ONE.divide(radius); for (BlockVector3 change : changes) { int height = maxY - minY; - int changeY = change.getBlockY(); + int changeY = change.y(); if (changeY > 0) { minY += Math.min(height, changeY); } else { @@ -289,7 +289,7 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { public void shift(BlockVector3 change) throws RegionOperationException { center = center.add(change.toBlockVector2()); - int changeY = change.getBlockY(); + int changeY = change.y(); maxY += changeY; minY += changeY; } @@ -322,15 +322,15 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { @Override public boolean contains(int x, int z) { - double dx = Math.abs(x - center.getBlockX()) * radiusInverse.getX(); - double dz = Math.abs(z - center.getBlockZ()) * radiusInverse.getZ(); + double dx = Math.abs(x - center.x()) * radiusInverse.x(); + double dz = Math.abs(z - center.z()) * radiusInverse.z(); return dx * dx + dz * dz <= 1; } @Override public boolean contains(BlockVector3 position) { - return contains(position.getX(), position.getY(), position.getZ()); + return contains(position.x(), position.y(), position.z()); } //FAWE end @@ -402,8 +402,8 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { checkNotNull(extent); checkNotNull(center); Vector2 radiusVec = Vector2.at(radius, radius); - int minY = extent.getMinimumPoint().getBlockY(); - int maxY = extent.getMaximumPoint().getBlockY(); + int minY = extent.getMinimumPoint().y(); + int maxY = extent.getMaximumPoint().y(); return new CylinderRegion(center, radiusVec, minY, maxY); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java index c3aed2a53..944e7a14c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java @@ -102,32 +102,32 @@ public class EllipsoidRegion extends AbstractRegion { @Override public long getVolume() { return ELLIPSOID_BASE_MULTIPLIER - .multiply(BigDecimal.valueOf(radius.getX())) - .multiply(BigDecimal.valueOf(radius.getY())) - .multiply(BigDecimal.valueOf(radius.getZ())) + .multiply(BigDecimal.valueOf(radius.x())) + .multiply(BigDecimal.valueOf(radius.y())) + .multiply(BigDecimal.valueOf(radius.z())) .setScale(0, RoundingMode.FLOOR) .longValue(); } @Override public int getWidth() { - return (int) (2 * radius.getX()); + return (int) (2 * radius.x()); } @Override public int getHeight() { - return (int) (2 * radius.getY()); + return (int) (2 * radius.y()); } @Override public int getLength() { - return (int) (2 * radius.getZ()); + return (int) (2 * radius.z()); } private BlockVector3 calculateDiff(BlockVector3... changes) throws RegionOperationException { BlockVector3 diff = BlockVector3.ZERO.add(changes); - if ((diff.getBlockX() & 1) + (diff.getBlockY() & 1) + (diff.getBlockZ() & 1) != 0) { + if ((diff.x() & 1) + (diff.y() & 1) + (diff.z() & 1) != 0) { throw new RegionOperationException(Caption.of("worldedit.selection.ellipsoid.error.even-horizontal")); } @@ -198,8 +198,8 @@ public class EllipsoidRegion extends AbstractRegion { this.radius = radius.add(0.5, 0.5, 0.5); //FAWE start radiusSqr = radius.multiply(radius); - radiusLengthSqr = (int) radiusSqr.getX(); - this.sphere = radius.getY() == radius.getX() && radius.getX() == radius.getZ(); + radiusLengthSqr = (int) radiusSqr.x(); + this.sphere = radius.y() == radius.x() && radius.x() == radius.z(); inverseRadiusSqr = Vector3.ONE.divide(radiusSqr); //FAWE end } @@ -210,10 +210,10 @@ public class EllipsoidRegion extends AbstractRegion { final BlockVector3 min = getMinimumPoint(); final BlockVector3 max = getMaximumPoint(); - final int centerY = center.getBlockY(); + final int centerY = center.y(); - for (int x = min.getBlockX(); x <= max.getBlockX(); ++x) { - for (int z = min.getBlockZ(); z <= max.getBlockZ(); ++z) { + for (int x = min.x(); x <= max.x(); ++x) { + for (int z = min.z(); z <= max.z(); ++z) { if (!contains(x, centerY, z)) { continue; } @@ -231,17 +231,17 @@ public class EllipsoidRegion extends AbstractRegion { //FAWE start @Override public boolean contains(int x, int y, int z) { - int cx = x - center.getBlockX(); + int cx = x - center.x(); int cx2 = cx * cx; if (cx2 > radiusSqr.getBlockX()) { return false; } - int cz = z - center.getBlockZ(); + int cz = z - center.z(); int cz2 = cz * cz; if (cz2 > radiusSqr.getBlockZ()) { return false; } - int cy = y - center.getBlockY(); + int cy = y - center.y(); int cy2 = cy * cy; if (radiusSqr.getBlockY() < getWorldMaxY() && cy2 > radiusSqr.getBlockY()) { return false; @@ -249,9 +249,9 @@ public class EllipsoidRegion extends AbstractRegion { if (sphere) { return cx2 + cy2 + cz2 <= radiusLengthSqr; } - double cxd = cx2 * inverseRadiusSqr.getX(); - double cyd = cy2 * inverseRadiusSqr.getY(); - double czd = cz2 * inverseRadiusSqr.getZ(); + double cxd = cx2 * inverseRadiusSqr.x(); + double cyd = cy2 * inverseRadiusSqr.y(); + double czd = cz2 * inverseRadiusSqr.z(); return cxd + cyd + czd <= 1; } @@ -265,23 +265,23 @@ public class EllipsoidRegion extends AbstractRegion { @Override public boolean contains(BlockVector3 position) { - return contains(position.getX(), position.getY(), position.getZ()); + return contains(position.x(), position.y(), position.z()); } @Override public boolean contains(int x, int z) { - int cx = x - center.getBlockX(); + int cx = x - center.x(); int cx2 = cx * cx; if (cx2 > radiusSqr.getBlockX()) { return false; } - int cz = z - center.getBlockZ(); + int cz = z - center.z(); int cz2 = cz * cz; if (cz2 > radiusSqr.getBlockZ()) { return false; } - double cxd = cx2 * inverseRadiusSqr.getX(); - double czd = cz2 * inverseRadiusSqr.getZ(); + double cxd = cx2 * inverseRadiusSqr.x(); + double czd = cz2 * inverseRadiusSqr.z(); return cxd + czd <= 1; } //FAWE end @@ -339,9 +339,9 @@ public class EllipsoidRegion extends AbstractRegion { int layer, int y1, int y2, int bx, int bz, Filter filter, ChunkFilterBlock block, IChunkGet get, IChunkSet set ) { - int cx = center.getBlockX(); - int cy = center.getBlockY(); - int cz = center.getBlockZ(); + int cx = center.x(); + int cy = center.y(); + int cz = center.z(); block.initLayer(get, set, layer); @@ -376,8 +376,8 @@ public class EllipsoidRegion extends AbstractRegion { ) { // Check bounds // This needs to be able to perform 50M blocks/sec otherwise it becomes a bottleneck - int cx = center.getBlockX(); - int cz = center.getBlockZ(); + int cx = center.x(); + int cz = center.z(); int bx = chunk.getX() << 4; int bz = chunk.getZ() << 4; int tx = bx + 15; @@ -415,7 +415,7 @@ public class EllipsoidRegion extends AbstractRegion { block = block.initChunk(chunk.getX(), chunk.getZ()); // Get the solid layers - int cy = center.getBlockY(); + int cy = center.y(); int diffYFull = MathMan.usqrt(diffY2); int yBotFull = Math.max(getWorldMinY(), cy - diffYFull); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegion.java index 021e042be..b07503762 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Polygonal2DRegion.java @@ -111,14 +111,14 @@ public class Polygonal2DRegion extends AbstractRegion implements FlatRegion { return; } - int minX = points.get(0).getBlockX(); - int minZ = points.get(0).getBlockZ(); - int maxX = points.get(0).getBlockX(); - int maxZ = points.get(0).getBlockZ(); + int minX = points.get(0).x(); + int minZ = points.get(0).z(); + int maxX = points.get(0).x(); + int maxZ = points.get(0).z(); for (BlockVector2 v : points) { - int x = v.getBlockX(); - int z = v.getBlockZ(); + int x = v.x(); + int z = v.z(); if (x < minX) { minX = x; } @@ -161,7 +161,7 @@ public class Polygonal2DRegion extends AbstractRegion implements FlatRegion { * @param position the position */ public void addPoint(BlockVector3 position) { - points.add(BlockVector2.at(position.getBlockX(), position.getBlockZ())); + points.add(BlockVector2.at(position.x(), position.z())); recalculate(); } @@ -214,8 +214,8 @@ public class Polygonal2DRegion extends AbstractRegion implements FlatRegion { int j = points.size() - 1; for (i = 0; i < points.size(); ++i) { - long x = points.get(j).getBlockX() + points.get(i).getBlockX(); - long z = points.get(j).getBlockZ() - points.get(i).getBlockZ(); + long x = points.get(j).x() + points.get(i).x(); + long z = points.get(j).z() - points.get(i).z(); area += x * z; j = i; } @@ -229,7 +229,7 @@ public class Polygonal2DRegion extends AbstractRegion implements FlatRegion { @Override public int getWidth() { - return max.getBlockX() - min.getBlockX() + 1; + return max.x() - min.x() + 1; } @Override @@ -239,16 +239,16 @@ public class Polygonal2DRegion extends AbstractRegion implements FlatRegion { @Override public int getLength() { - return max.getBlockZ() - min.getBlockZ() + 1; + return max.z() - min.z() + 1; } @Override public void expand(BlockVector3... changes) throws RegionOperationException { for (BlockVector3 change : changes) { - if (change.getBlockX() != 0 || change.getBlockZ() != 0) { + if (change.x() != 0 || change.z() != 0) { throw new RegionOperationException(Caption.of("worldedit.selection.polygon2d.error.expand-only-vertical")); } - int changeY = change.getBlockY(); + int changeY = change.y(); if (changeY > 0) { maxY += changeY; } else { @@ -261,10 +261,10 @@ public class Polygonal2DRegion extends AbstractRegion implements FlatRegion { @Override public void contract(BlockVector3... changes) throws RegionOperationException { for (BlockVector3 change : changes) { - if (change.getBlockX() != 0 || change.getBlockZ() != 0) { + if (change.x() != 0 || change.z() != 0) { throw new RegionOperationException(Caption.of("worldedit.selection.polygon2d.error.contract-only-vertical")); } - int changeY = change.getBlockY(); + int changeY = change.y(); if (changeY > 0) { minY += changeY; } else { @@ -276,13 +276,13 @@ public class Polygonal2DRegion extends AbstractRegion implements FlatRegion { @Override public void shift(BlockVector3 change) throws RegionOperationException { - final double changeX = change.getX(); - final double changeY = change.getY(); - final double changeZ = change.getZ(); + final double changeX = change.x(); + final double changeY = change.y(); + final double changeZ = change.z(); for (int i = 0; i < points.size(); ++i) { BlockVector2 point = points.get(i); - points.set(i, BlockVector2.at(point.getX() + changeX, point.getZ() + changeZ)); + points.set(i, BlockVector2.at(point.x() + changeX, point.z() + changeZ)); } minY += changeY; @@ -307,12 +307,12 @@ public class Polygonal2DRegion extends AbstractRegion implements FlatRegion { long crossproduct; int i; - xOld = points.get(npoints - 1).getBlockX(); - zOld = points.get(npoints - 1).getBlockZ(); + xOld = points.get(npoints - 1).x(); + zOld = points.get(npoints - 1).z(); for (i = 0; i < npoints; ++i) { - xNew = points.get(i).getBlockX(); - zNew = points.get(i).getBlockZ(); + xNew = points.get(i).x(); + zNew = points.get(i).z(); //Check for corner if (xNew == targetX && zNew == targetZ) { return true; @@ -365,9 +365,9 @@ public class Polygonal2DRegion extends AbstractRegion implements FlatRegion { if (points.size() < 3) { return false; } - int targetX = pt.getBlockX(); //wide - int targetY = pt.getBlockY(); //height - int targetZ = pt.getBlockZ(); //depth + int targetX = pt.x(); //wide + int targetY = pt.y(); //height + int targetZ = pt.z(); //depth if (targetY < minY || targetY > maxY) { return false; @@ -384,12 +384,12 @@ public class Polygonal2DRegion extends AbstractRegion implements FlatRegion { long crossproduct; int i; - int xOld = points.get(npoints - 1).getBlockX(); - int zOld = points.get(npoints - 1).getBlockZ(); + int xOld = points.get(npoints - 1).x(); + int zOld = points.get(npoints - 1).z(); for (i = 0; i < npoints; ++i) { - xNew = points.get(i).getBlockX(); - zNew = points.get(i).getBlockZ(); + xNew = points.get(i).x(); + zNew = points.get(i).z(); //Check for corner if (xNew == targetX && zNew == targetZ) { return true; @@ -478,7 +478,7 @@ public class Polygonal2DRegion extends AbstractRegion implements FlatRegion { Iterator it = pts.iterator(); while (it.hasNext()) { BlockVector2 current = it.next(); - sb.append("(").append(current.getBlockX()).append(", ").append(current.getBlockZ()).append(")"); + sb.append("(").append(current.x()).append(", ").append(current.z()).append(")"); if (it.hasNext()) { sb.append(" - "); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java index d2fa35310..e8c6da179 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java @@ -235,15 +235,15 @@ public interface Region extends Iterable, Cloneable, IBatchProcess default boolean isGlobal() { BlockVector3 pos1 = getMinimumPoint(); BlockVector3 pos2 = getMaximumPoint(); - return pos1.getBlockX() == Integer.MIN_VALUE && pos1.getBlockZ() == Integer.MIN_VALUE && pos2.getBlockX() == Integer.MAX_VALUE && pos2 - .getBlockZ() == Integer.MAX_VALUE - && pos1.getBlockY() <= WorldEdit + return pos1.x() == Integer.MIN_VALUE && pos1.z() == Integer.MIN_VALUE && pos2.x() == Integer.MAX_VALUE && pos2 + .z() == Integer.MAX_VALUE + && pos1.y() <= WorldEdit .getInstance() .getPlatformManager() .queryCapability( Capability.WORLD_EDITING) .versionMinY() - && pos2.getBlockY() >= WorldEdit + && pos2.y() >= WorldEdit .getInstance() .getPlatformManager() .queryCapability(Capability.WORLD_EDITING) @@ -251,11 +251,11 @@ public interface Region extends Iterable, Cloneable, IBatchProcess } default int getMinimumY() { - return getMinimumPoint().getY(); + return getMinimumPoint().y(); } default int getMaximumY() { - return getMaximumPoint().getY(); + return getMaximumPoint().y(); } default void filter( @@ -385,7 +385,7 @@ public interface Region extends Iterable, Cloneable, IBatchProcess int tz = bz + 15; BlockVector3 min = getMinimumPoint(); BlockVector3 max = getMaximumPoint(); - return tx >= min.getX() && bx <= max.getX() && tz >= min.getZ() && bz <= max.getZ(); + return tx >= min.x() && bx <= max.x() && tz >= min.z() && bz <= max.z(); } @Override @@ -397,7 +397,7 @@ public interface Region extends Iterable, Cloneable, IBatchProcess BlockVector3 min = getMinimumPoint(); BlockVector3 max = getMaximumPoint(); - if (tx >= min.getX() && bx <= max.getX() && tz >= min.getZ() && bz <= max.getZ()) { + if (tx >= min.x() && bx <= max.x() && tz >= min.z() && bz <= max.z()) { // contains some boolean processExtra = false; for (int layer = getMinimumY() >> 4; layer <= getMaximumY() >> 4; layer++) { @@ -451,7 +451,7 @@ public interface Region extends Iterable, Cloneable, IBatchProcess BlockVector3 min = getMinimumPoint(); BlockVector3 max = getMaximumPoint(); - if (tx >= min.getX() && bx <= max.getX() && tz >= min.getZ() && bz <= max.getZ()) { + if (tx >= min.x() && bx <= max.x() && tz >= min.z() && bz <= max.z()) { // contains some boolean processExtra = false; for (int layer = getMinimumY() >> 4; layer <= getMaximumY() >> 4; layer++) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java index 7a3e91343..c1a81834c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java @@ -168,7 +168,7 @@ public class RegionIntersection extends AbstractRegion { for (Region region : regions) { BlockVector3 regMin = region.getMinimumPoint(); BlockVector3 regMax = region.getMaximumPoint(); - if (tx >= regMin.getX() && bx <= regMax.getX() && tz >= regMin.getZ() && bz <= regMax.getZ()) { + if (tx >= regMin.x() && bx <= regMax.x() && tz >= regMin.z() && bz <= regMax.z()) { intersecting.add(region); } } @@ -204,7 +204,7 @@ public class RegionIntersection extends AbstractRegion { for (Region region : regions) { BlockVector3 regMin = region.getMinimumPoint(); BlockVector3 regMax = region.getMaximumPoint(); - if (tx >= regMin.getX() && bx <= regMax.getX() && tz >= regMin.getZ() && bz <= regMax.getZ()) { + if (tx >= regMin.x() && bx <= regMax.x() && tz >= regMin.z() && bz <= regMax.z()) { return region.processSet(chunk, get, set, true); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Regions.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Regions.java index 040ec2803..d562190cb 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Regions.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Regions.java @@ -35,7 +35,7 @@ public final class Regions { * @return the Y coordinate */ public static double minimumY(Region region) { - return region.getMinimumPoint().getY(); + return region.getMinimumPoint().y(); } /** @@ -46,7 +46,7 @@ public final class Regions { * @return the Y coordinate */ public static double maximumY(Region region) { - return region.getMaximumPoint().getY(); + return region.getMaximumPoint().y(); } /** @@ -57,7 +57,7 @@ public final class Regions { * @return the Y coordinate */ public static int minimumBlockY(Region region) { - return region.getMinimumPoint().getBlockY(); + return region.getMinimumPoint().y(); } /** @@ -68,7 +68,7 @@ public final class Regions { * @return the Y coordinate */ public static int maximumBlockY(Region region) { - return region.getMaximumPoint().getBlockY(); + return region.getMaximumPoint().y(); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/TransformRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/TransformRegion.java index b2471af32..782fcebae 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/TransformRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/TransformRegion.java @@ -119,17 +119,17 @@ public class TransformRegion extends AbstractRegion { @Override public int getWidth() { - return getMaximumPoint().subtract(getMinimumPoint()).getBlockX() + 1; + return getMaximumPoint().subtract(getMinimumPoint()).x() + 1; } @Override public int getHeight() { - return getMaximumPoint().subtract(getMinimumPoint()).getBlockY() + 1; + return getMaximumPoint().subtract(getMinimumPoint()).y() + 1; } @Override public int getLength() { - return getMaximumPoint().subtract(getMinimumPoint()).getBlockZ() + 1; + return getMaximumPoint().subtract(getMinimumPoint()).z() + 1; } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/factory/CylinderRegionFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/factory/CylinderRegionFactory.java index 386700b1e..67112c68c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/factory/CylinderRegionFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/factory/CylinderRegionFactory.java @@ -37,8 +37,8 @@ public class CylinderRegionFactory implements RegionFactory { return new CylinderRegion( position, Vector2.at(size, size), - position.getBlockY() - (int) (height / 2), - position.getBlockY() + (int) (height / 2) + position.y() - (int) (height / 2), + position.y() + (int) (height / 2) ); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegion3DIterator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegion3DIterator.java index e7ae99340..12c5f90d9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegion3DIterator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegion3DIterator.java @@ -68,7 +68,7 @@ public class FlatRegion3DIterator implements Iterator { throw new NoSuchElementException(); } - BlockVector3 current = BlockVector3.at(next2D.getBlockX(), nextY, next2D.getBlockZ()); + BlockVector3 current = BlockVector3.at(next2D.x(), nextY, next2D.z()); if (nextY < maxY) { nextY++; } else if (flatIterator.hasNext()) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegionIterator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegionIterator.java index e62c72ecd..3db019499 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegionIterator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/FlatRegionIterator.java @@ -46,15 +46,15 @@ public class FlatRegionIterator implements Iterator { BlockVector3 min = region.getMinimumPoint(); BlockVector3 max = region.getMaximumPoint(); - this.y = min.getBlockY(); + this.y = min.y(); - this.minX = min.getBlockX(); + this.minX = min.x(); this.nextX = minX; - this.nextZ = min.getBlockZ(); + this.nextZ = min.z(); - this.maxX = max.getBlockX(); - this.maxZ = max.getBlockZ(); + this.maxX = max.x(); + this.maxZ = max.z(); forward(); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/RegionIterator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/RegionIterator.java index 9e2c9b8e8..54f67b4de 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/RegionIterator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/iterator/RegionIterator.java @@ -43,14 +43,14 @@ public class RegionIterator implements Iterator { this.region = region; BlockVector3 max = region.getMaximumPoint(); - this.maxX = max.getBlockX(); - this.maxY = max.getBlockY(); - this.maxZ = max.getBlockZ(); + this.maxX = max.x(); + this.maxY = max.y(); + this.maxZ = max.z(); this.min = region.getMinimumPoint(); - this.nextX = min.getBlockX(); - this.nextY = min.getBlockY(); - this.nextZ = min.getBlockZ(); + this.nextX = min.x(); + this.nextY = min.y(); + this.nextZ = min.z(); forward(); } @@ -84,12 +84,12 @@ public class RegionIterator implements Iterator { if (++nextX <= maxX) { return; } - nextX = min.getBlockX(); + nextX = min.x(); if (++nextY <= maxY) { return; } - nextY = min.getBlockY(); + nextY = min.y(); if (++nextZ <= maxZ) { return; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java index 70471ceae..ac3141c02 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java @@ -101,8 +101,8 @@ public class ConvexPolyhedralRegionSelector implements RegionSelector, CUIRegion return; } - final int minY = oldRegion.getMinimumPoint().getBlockY(); - final int maxY = oldRegion.getMaximumPoint().getBlockY(); + final int minY = oldRegion.getMinimumPoint().y(); + final int maxY = oldRegion.getMaximumPoint().y(); region = new ConvexPolyhedralRegion(oldRegion.getWorld()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java index 0798b06e6..5a9d3748b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java @@ -115,8 +115,8 @@ public class CylinderRegionSelector implements RegionSelector, CUIRegion { region.setCenter(center.toBlockVector2()); region.setRadius(pos2.toBlockVector2().subtract(center.toBlockVector2()).toVector2()); - region.setMaximumY(Math.max(pos1.getBlockY(), pos2.getBlockY())); - region.setMinimumY(Math.min(pos1.getBlockY(), pos2.getBlockY())); + region.setMaximumY(Math.max(pos1.y(), pos2.y())); + region.setMinimumY(Math.min(pos1.y(), pos2.y())); selectedCenter = true; selectedRadius = true; @@ -164,7 +164,7 @@ public class CylinderRegionSelector implements RegionSelector, CUIRegion { region = new CylinderRegion(region.getWorld()); region.setCenter(position.toBlockVector2()); - region.setY(position.getBlockY()); + region.setY(position.y()); selectedCenter = true; selectedRadius = false; @@ -182,7 +182,7 @@ public class CylinderRegionSelector implements RegionSelector, CUIRegion { final Vector2 minRadius = diff.getMaximum(diff.multiply(-1.0)); region.extendRadius(minRadius); - region.setY(position.getBlockY()); + region.setY(position.y()); selectedRadius = true; @@ -201,8 +201,8 @@ public class CylinderRegionSelector implements RegionSelector, CUIRegion { if (selectedCenter) { player.print(Caption.of( "worldedit.selection.cylinder.explain.secondary", - TextComponent.of(NUMBER_FORMAT.format(region.getRadius().getX())), - TextComponent.of(NUMBER_FORMAT.format(region.getRadius().getZ())), + TextComponent.of(NUMBER_FORMAT.format(region.getRadius().x())), + TextComponent.of(NUMBER_FORMAT.format(region.getRadius().z())), TextComponent.of(region.getVolume()) )); } else { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ExtendingCuboidRegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ExtendingCuboidRegionSelector.java index 5d74d7ae6..e75f8bbb5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ExtendingCuboidRegionSelector.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/ExtendingCuboidRegionSelector.java @@ -107,13 +107,13 @@ public class ExtendingCuboidRegionSelector extends CuboidRegionSelector { return false; } - double x1 = Math.min(position.getX(), position1.getX()); - double y1 = Math.min(position.getY(), position1.getY()); - double z1 = Math.min(position.getZ(), position1.getZ()); + double x1 = Math.min(position.x(), position1.x()); + double y1 = Math.min(position.y(), position1.y()); + double z1 = Math.min(position.z(), position1.z()); - double x2 = Math.max(position.getX(), position2.getX()); - double y2 = Math.max(position.getY(), position2.getY()); - double z2 = Math.max(position.getZ(), position2.getZ()); + double x2 = Math.max(position.x(), position2.x()); + double y2 = Math.max(position.y(), position2.y()); + double z2 = Math.max(position.z(), position2.z()); final BlockVector3 o1 = position1; final BlockVector3 o2 = position2; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java index bf472615a..be9134f15 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java @@ -96,8 +96,8 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion { return; } - final int minY = oldRegion.getMinimumPoint().getBlockY(); - final int maxY = oldRegion.getMaximumPoint().getBlockY(); + final int minY = oldRegion.getMinimumPoint().y(); + final int maxY = oldRegion.getMaximumPoint().y(); List points = oldRegion.polygonize(Integer.MAX_VALUE); @@ -118,7 +118,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion { checkNotNull(points); final BlockVector2 pos2D = points.get(0); - pos1 = BlockVector3.at(pos2D.getX(), minY, pos2D.getZ()); + pos1 = BlockVector3.at(pos2D.x(), minY, pos2D.z()); region = new Polygonal2DRegion(world, points, minY, maxY); } @@ -142,7 +142,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion { pos1 = position; region = new Polygonal2DRegion(region.getWorld()); region.addPoint(position); - region.expandY(position.getBlockY()); + region.expandY(position.y()); return true; } @@ -153,7 +153,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion { final List points = region.getPoints(); final BlockVector2 lastPoint = points.get(region.size() - 1); - if (lastPoint.getBlockX() == position.getBlockX() && lastPoint.getBlockZ() == position.getBlockZ()) { + if (lastPoint.x() == position.x() && lastPoint.z() == position.z()) { return false; } @@ -165,7 +165,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion { } region.addPoint(position); - region.expandY(position.getBlockY()); + region.expandY(position.y()); return true; } @@ -228,7 +228,7 @@ public class Polygonal2DRegionSelector implements RegionSelector, CUIRegion { @Override public void learnChanges() { BlockVector2 pt = region.getPoints().get(0); - pos1 = BlockVector3.at(pt.getBlockX(), region.getMinimumPoint().getBlockY(), pt.getBlockZ()); + pos1 = BlockVector3.at(pt.x(), region.getMinimumPoint().y(), pt.z()); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/SphereRegionSelector.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/SphereRegionSelector.java index a0eff3046..7394015ab 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/SphereRegionSelector.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/selector/SphereRegionSelector.java @@ -61,7 +61,7 @@ public class SphereRegionSelector extends EllipsoidRegionSelector { super(oldSelector); if (selectedRadius) { final Vector3 radius = region.getRadius(); - final double radiusScalar = Math.max(Math.max(radius.getX(), radius.getY()), radius.getZ()); + final double radiusScalar = Math.max(Math.max(radius.x(), radius.y()), radius.z()); region.setRadius(Vector3.at(radiusScalar, radiusScalar, radiusScalar)); } } @@ -96,11 +96,11 @@ public class SphereRegionSelector extends EllipsoidRegionSelector { if (isDefined()) { player.print(Caption.of( "worldedit.selection.sphere.explain.secondary-defined", - TextComponent.of(region.getRadius().getX()), + TextComponent.of(region.getRadius().x()), TextComponent.of(region.getVolume()) )); } else { - player.print(Caption.of("worldedit.selection.sphere.explain.secondary", TextComponent.of(region.getRadius().getX()))); + player.print(Caption.of("worldedit.selection.sphere.explain.secondary", TextComponent.of(region.getRadius().x()))); } session.describeCUI(player); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java index 9f2ef87b0..2fb9e6588 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryBiomeShape.java @@ -59,13 +59,13 @@ public abstract class ArbitraryBiomeShape { BlockVector3 min = extent.getMinimumPoint(); BlockVector3 max = extent.getMaximumPoint(); - cacheOffsetX = min.getBlockX() - 1; - cacheOffsetY = min.getBlockY() - 1; - cacheOffsetZ = min.getBlockZ() - 1; + cacheOffsetX = min.x() - 1; + cacheOffsetY = min.y() - 1; + cacheOffsetZ = min.z() - 1; - cacheSizeX = max.getX() - cacheOffsetX + 2; - cacheSizeY = max.getY() - cacheOffsetY + 2; - cacheSizeZ = max.getZ() - cacheOffsetZ + 2; + cacheSizeX = max.x() - cacheOffsetX + 2; + cacheSizeY = max.y() - cacheOffsetY + 2; + cacheSizeZ = max.z() - cacheOffsetZ + 2; cache = new BiomeType[cacheSizeX * cacheSizeY * cacheSizeZ]; isCached = new BitSet(cache.length); @@ -128,9 +128,9 @@ public abstract class ArbitraryBiomeShape { int affected = 0; for (BlockVector3 position : getExtent()) { - int x = position.getBlockX(); - int y = position.getBlockY(); - int z = position.getBlockZ(); + int x = position.x(); + int y = position.y(); + int z = position.z(); if (!hollow) { final BiomeType material = getBiome(x, y, z, baseBiome); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryShape.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryShape.java index 4feff6b8f..dbb516b1b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryShape.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/shape/ArbitraryShape.java @@ -59,13 +59,13 @@ public abstract class ArbitraryShape { BlockVector3 min = extent.getMinimumPoint(); BlockVector3 max = extent.getMaximumPoint(); - cacheOffsetX = min.getBlockX() - 1; - cacheOffsetY = min.getBlockY() - 1; - cacheOffsetZ = min.getBlockZ() - 1; + cacheOffsetX = min.x() - 1; + cacheOffsetY = min.y() - 1; + cacheOffsetZ = min.z() - 1; - cacheSizeX = max.getX() - cacheOffsetX + 2; - cacheSizeY = max.getY() - cacheOffsetY + 2; - cacheSizeZ = max.getZ() - cacheOffsetZ + 2; + cacheSizeX = max.x() - cacheOffsetX + 2; + cacheSizeY = max.y() - cacheOffsetY + 2; + cacheSizeZ = max.z() - cacheOffsetZ + 2; cache = new byte[cacheSizeX * cacheSizeY * cacheSizeZ]; } @@ -98,9 +98,9 @@ public abstract class ArbitraryShape { int affected = 0; for (BlockVector3 position : getExtent()) { - int x = position.getBlockX(); - int y = position.getBlockY(); - int z = position.getBlockZ(); + int x = position.x(); + int y = position.y(); + int z = position.z(); if (!hollow) { BaseBlock material = getMaterial(x, y, z, pattern.applyBlock(position)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/Direction.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/Direction.java index d117ff328..c10312503 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/Direction.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/Direction.java @@ -84,7 +84,7 @@ public enum Direction { } Direction(Vector3 vector, int flags, int left, int right) { - this.blockPoint = BlockVector3.at(Math.signum(vector.getX()), Math.signum(vector.getY()), Math.signum(vector.getZ())); + this.blockPoint = BlockVector3.at(Math.signum(vector.x()), Math.signum(vector.y()), Math.signum(vector.z())); this.direction = vector.normalize(); this.flags = flags; this.left = left; @@ -104,27 +104,27 @@ public enum Direction { } public double getX() { - return direction.getX(); + return direction.x(); } public double getY() { - return direction.getY(); + return direction.y(); } public double getZ() { - return direction.getZ(); + return direction.z(); } public int getBlockX() { - return blockPoint.getX(); + return blockPoint.x(); } public int getBlockY() { - return blockPoint.getY(); + return blockPoint.y(); } public int getBlockZ() { - return blockPoint.getZ(); + return blockPoint.z(); } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/TargetBlock.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/TargetBlock.java index 01444f269..557709931 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/TargetBlock.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/TargetBlock.java @@ -223,15 +223,15 @@ public class TargetBlock { curDistance += checkDistance; targetPosDouble = offset.add( - targetPosDouble.getX(), - targetPosDouble.getY(), - targetPosDouble.getZ() + targetPosDouble.x(), + targetPosDouble.y(), + targetPosDouble.z() ); targetPos = targetPosDouble.toBlockPoint(); } while (curDistance <= maxDistance - && targetPos.getBlockX() == prevPos.getBlockX() - && targetPos.getBlockY() == prevPos.getBlockY() - && targetPos.getBlockZ() == prevPos.getBlockZ()); + && targetPos.x() == prevPos.x() + && targetPos.y() == prevPos.y() + && targetPos.z() == prevPos.z()); if (curDistance > maxDistance) { return null; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/TreeGenerator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/TreeGenerator.java index cf5c05278..f529b6c5e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/TreeGenerator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/TreeGenerator.java @@ -135,9 +135,9 @@ public final class TreeGenerator { public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException { //FAWE start - perform sanity check on generation location if (editSession - .getBlockType(pos.getX(), pos.getY(), pos.getZ()) + .getBlockType(pos.x(), pos.y(), pos.z()) .getMaterial() - .isAir() && canGenerateOn(editSession.getBlockType(pos.getX(), pos.getY() - 1, pos.getZ()))) { + .isAir() && canGenerateOn(editSession.getBlockType(pos.x(), pos.y() - 1, pos.z()))) { makePineTree(editSession, pos); return true; } @@ -151,7 +151,7 @@ public final class TreeGenerator { //FAWE start - ensure canGenerateOn is called. // chorus plants have to generate starting in the end stone itself, not the air above the ground BlockVector3 down = pos.subtract(0, 1, 0); - if (!canGenerateOn(editSession.getBlockType(down.getX(), down.getY(), down.getZ()))) { + if (!canGenerateOn(editSession.getBlockType(down.x(), down.y(), down.z()))) { return false; } return editSession.getWorld().generateTree(this, editSession, down); @@ -212,9 +212,9 @@ public final class TreeGenerator { public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException { //FAWE start - check for ability for tree to generate on block if (editSession - .getBlockType(pos.getX(), pos.getY(), pos.getZ()) + .getBlockType(pos.x(), pos.y(), pos.z()) .getMaterial() - .isAir() && canGenerateOn(editSession.getBlockType(pos.getX(), pos.getY() - 1, pos.getZ()))) { + .isAir() && canGenerateOn(editSession.getBlockType(pos.x(), pos.y() - 1, pos.z()))) { return editSession.getWorld().generateTree(this, editSession, pos); } return false; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/BlockMap.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/BlockMap.java index 43c175dbc..a17f6a04f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/BlockMap.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/BlockMap.java @@ -85,15 +85,15 @@ public class BlockMap extends AbstractMap { private static final int BITS_6 = mask(6); private static long toGroupKey(BlockVector3 location) { - return ((location.getX() >>> 6) & BITS_20) - | (((location.getZ() >>> 6) & BITS_20) << 20) - | (((location.getY() >>> 8) & BITS_24) << (20 + 20)); + return ((location.x() >>> 6) & BITS_20) + | (((location.z() >>> 6) & BITS_20) << 20) + | (((location.y() >>> 8) & BITS_24) << (20 + 20)); } private static int toInnerKey(BlockVector3 location) { - return (location.getX() & BITS_6) - | ((location.getZ() & BITS_6) << 6) - | ((location.getY() & BITS_8) << (6 + 6)); + return (location.x() & BITS_6) + | ((location.z() & BITS_6) << 6) + | ((location.y() & BITS_8) << (6 + 6)); } private static final long GROUP_X = BITS_20; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/VectorPositionList.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/VectorPositionList.java index 3a2759e67..3e725712d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/VectorPositionList.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/collection/VectorPositionList.java @@ -46,9 +46,9 @@ class VectorPositionList implements PositionList { @Override public void add(BlockVector3 vector) { - delegateX.add(vector.getX()); - delegateY.add(vector.getY()); - delegateZ.add(vector.getZ()); + delegateX.add(vector.x()); + delegateY.add(vector.y()); + delegateZ.add(vector.z()); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java index 908e0bac6..ccf8d8535 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java @@ -184,7 +184,7 @@ public class NullWorld extends AbstractWorld { @Override public BlockState getBlock(BlockVector3 position) { - return this.getBlock(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + return this.getBlock(position.x(), position.y(), position.z()); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java index 5e4292cd4..5535f4305 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java @@ -130,9 +130,9 @@ public class AnvilChunk implements Chunk { } private int getBlockID(BlockVector3 position) throws DataException { - int x = position.getX() - rootX * 16; - int y = position.getY(); - int z = position.getZ() - rootZ * 16; + int x = position.x() - rootX * 16; + int y = position.y(); + int z = position.z() - rootZ * 16; int section = y >> 4; if (section < 0 || section >= blocks.length) { @@ -163,9 +163,9 @@ public class AnvilChunk implements Chunk { } private int getBlockData(BlockVector3 position) throws DataException { - int x = position.getX() - rootX * 16; - int y = position.getY(); - int z = position.getZ() - rootZ * 16; + int x = position.x() - rootX * 16; + int y = position.y(); + int z = position.z() - rootZ * 16; int section = y >> 4; int yIndex = y & 0x0F; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java index 9b0d764f1..31bb7606c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java @@ -231,9 +231,9 @@ public class AnvilChunk13 implements Chunk { @Override public BaseBlock getBlock(BlockVector3 position) throws DataException { //FAWE start - simplified - int x = position.getX() & 15; - int y = position.getY(); - int z = position.getZ() & 15; + int x = position.x() & 15; + int y = position.y(); + int z = position.z() & 15; //FAWE end int section = y >> 4; @@ -261,8 +261,8 @@ public class AnvilChunk13 implements Chunk { if (biomes == null) { populateBiomes(); } - int rx = position.getX() & 15; - int rz = position.getZ() & 15; + int rx = position.x() & 15; + int rz = position.z() & 15; return biomes[rz << 4 | rx]; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk15.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk15.java index 7565f66c1..60b9d9617 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk15.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk15.java @@ -60,9 +60,9 @@ public class AnvilChunk15 extends AnvilChunk13 { if (biomes == null) { populateBiomes(); } - int x = (position.getX() & 15) >> 2; - int y = position.getY() >> 2; - int z = (position.getZ() & 15) >> 2; + int x = (position.x() & 15) >> 2; + int y = position.y() >> 2; + int z = (position.z() & 15) >> 2; return biomes[y << 4 | z << 2 | x]; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java index a6fa95b53..6d366c295 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java @@ -234,9 +234,9 @@ public class AnvilChunk17 implements Chunk { @Override public BaseBlock getBlock(BlockVector3 position) throws DataException { - int x = position.getX() & 15; - int y = position.getY(); - int z = position.getZ() & 15; + int x = position.x() & 15; + int y = position.y(); + int z = position.z() & 15; int section = y >> 4; int yIndex = y & 0x0F; @@ -262,9 +262,9 @@ public class AnvilChunk17 implements Chunk { if (biomes == null) { populateBiomes(); } - int x = (position.getX() & 15) >> 2; - int y = (position.getY() - (minSectionPosition << 4)) >> 2; // normalize - int z = (position.getZ() & 15) >> 2; + int x = (position.x() & 15) >> 2; + int y = (position.y() - (minSectionPosition << 4)) >> 2; // normalize + int z = (position.z() & 15) >> 2; return biomes[y << 4 | z << 2 | x]; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java index bb18e8ed5..4fa50629e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java @@ -232,9 +232,9 @@ public class AnvilChunk18 implements Chunk { @Override public BaseBlock getBlock(BlockVector3 position) throws DataException { - int x = position.getX() & 15; - int y = position.getY(); - int z = position.getZ() & 15; + int x = position.x() & 15; + int y = position.y(); + int z = position.z() & 15; int section = y >> 4; int yIndex = y & 0x0F; @@ -259,10 +259,10 @@ public class AnvilChunk18 implements Chunk { if (biomes == null) { populateBiomes(); } - int x = (position.getX() & 15) >> 2; - int y = (position.getY() & 15) >> 2; - int z = (position.getZ() & 15) >> 2; - int section = position.getY() >> 4; + int x = (position.x() & 15) >> 2; + int y = (position.y() & 15) >> 2; + int z = (position.z() & 15) >> 2; + int section = position.y() >> 4; BiomeType[] sectionBiomes = biomes.get(section); if (sectionBiomes.length == 1) { return sectionBiomes[0]; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java index aabf38ac9..7edb163e3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java @@ -162,15 +162,15 @@ public class OldChunk implements Chunk { @Override public BaseBlock getBlock(BlockVector3 position) throws DataException { - if (position.getY() >= 128) { + if (position.y() >= 128) { return BlockTypes.VOID_AIR.getDefaultState().toBaseBlock(); } int id; int dataVal; - int x = position.getX() - rootX * 16; - int y = position.getY(); - int z = position.getZ() - rootZ * 16; + int x = position.x() - rootX * 16; + int y = position.y(); + int z = position.z() - rootZ * 16; int index = y + (z * 128 + (x * 128 * 16)); try { id = blocks[index]; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java index 0d86679cf..3e3201fb6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java @@ -114,9 +114,9 @@ public class SnapshotRestore { // First, we need to group points by chunk so that we only need // to keep one chunk in memory at any given moment - for (int x = min.getBlockX(); x <= max.getBlockX(); ++x) { - for (int y = min.getBlockY(); y <= max.getBlockY(); ++y) { - for (int z = min.getBlockZ(); z <= max.getBlockZ(); ++z) { + for (int x = min.x(); x <= max.x(); ++x) { + for (int y = min.y(); y <= max.y(); ++y) { + for (int z = min.z(); z <= max.z(); ++z) { BlockVector3 pos = BlockVector3.at(x, y, z); checkAndAddBlock(pos); } @@ -185,7 +185,7 @@ public class SnapshotRestore { try { editSession.setBlock(pos, chunk.getBlock(pos)); //FAWE start - biome and entity restore - if (restoreBiomes && (pos.getX() & 3) == 0 && (pos.getY() & 3) == 0 && (pos.getZ() & 3) == 0) { + if (restoreBiomes && (pos.x() & 3) == 0 && (pos.y() & 3) == 0 && (pos.z() & 3) == 0) { editSession.setBiome(pos, chunk.getBiome(pos)); } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/experimental/SnapshotRestore.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/experimental/SnapshotRestore.java index 9493fc76f..5f9880fc0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/experimental/SnapshotRestore.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/experimental/SnapshotRestore.java @@ -109,9 +109,9 @@ public class SnapshotRestore { // First, we need to group points by chunk so that we only need // to keep one chunk in memory at any given moment - for (int x = min.getBlockX(); x <= max.getBlockX(); ++x) { - for (int y = min.getBlockY(); y <= max.getBlockY(); ++y) { - for (int z = min.getBlockZ(); z <= max.getBlockZ(); ++z) { + for (int x = min.x(); x <= max.x(); ++x) { + for (int y = min.y(); y <= max.y(); ++y) { + for (int z = min.z(); z <= max.z(); ++z) { BlockVector3 pos = BlockVector3.at(x, y, z); checkAndAddBlock(pos); } @@ -181,7 +181,7 @@ public class SnapshotRestore { try { editSession.setBlock(pos, chunk.getBlock(pos)); //FAWE start - biome and entity restore - if (restoreBiomes && (pos.getX() & 3) == 0 && (pos.getY() & 3) == 0 && (pos.getZ() & 3) == 0) { + if (restoreBiomes && (pos.x() & 3) == 0 && (pos.y() & 3) == 0 && (pos.z() & 3) == 0) { editSession.setBiome(pos, chunk.getBiome(pos)); } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ChunkStore.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ChunkStore.java index 6b8de78fc..6b42ba727 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ChunkStore.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ChunkStore.java @@ -73,7 +73,7 @@ public abstract class ChunkStore implements Closeable { * @return chunk coordinates */ public static BlockVector2 toChunk(BlockVector3 position) { - return BlockVector2.at(position.getX() >> CHUNK_SHIFTS, position.getZ() >> CHUNK_SHIFTS); + return BlockVector2.at(position.x() >> CHUNK_SHIFTS, position.z() >> CHUNK_SHIFTS); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/LegacyChunkStore.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/LegacyChunkStore.java index 5e534765a..0159c3880 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/LegacyChunkStore.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/LegacyChunkStore.java @@ -44,8 +44,8 @@ public abstract class LegacyChunkStore extends ChunkStore { * @return pathname */ public static String getFilename(BlockVector2 position, String separator) { - int x = position.getBlockX(); - int z = position.getBlockZ(); + int x = position.x(); + int z = position.z(); String folder1 = Integer.toString(divisorMod(x, 64), 36); String folder2 = Integer.toString(divisorMod(z, 64), 36); @@ -68,8 +68,8 @@ public abstract class LegacyChunkStore extends ChunkStore { @Override public CompoundTag getChunkTag(BlockVector2 position, World world) throws DataException, IOException { - int x = position.getBlockX(); - int z = position.getBlockZ(); + int x = position.x(); + int z = position.z(); String folder1 = Integer.toString(divisorMod(x, 64), 36); String folder2 = Integer.toString(divisorMod(z, 64), 36); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/McRegionChunkStore.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/McRegionChunkStore.java index 5b43de521..a4e06145e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/McRegionChunkStore.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/McRegionChunkStore.java @@ -40,8 +40,8 @@ public abstract class McRegionChunkStore extends ChunkStore { * @return the filename */ public static String getFilename(BlockVector2 position) { - int x = position.getBlockX(); - int z = position.getBlockZ(); + int x = position.x(); + int z = position.z(); return "r." + (x >> 5) + "." + (z >> 5) + ".mca"; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/McRegionReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/McRegionReader.java index 193f03b06..88e455200 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/McRegionReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/McRegionReader.java @@ -119,8 +119,8 @@ public class McRegionReader { * @throws DataException if there is an error getting the chunk data */ public synchronized InputStream getChunkInputStream(BlockVector2 position) throws IOException, DataException { - int x = position.getBlockX() & 31; - int z = position.getBlockZ() & 31; + int x = position.x() & 31; + int z = position.z() & 31; int offset = getOffset(x, z); diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/RealExpressionTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/RealExpressionTest.java index 444e1db9d..a4dd3062a 100644 --- a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/RealExpressionTest.java +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/expression/RealExpressionTest.java @@ -74,7 +74,7 @@ class RealExpressionTest extends BaseExpressionTest { Expression compiled = compile(expr, "x", "y", "z"); for (TestCase aCase : cases) { Vector3 loc = aCase.loc; - assertEquals(aCase.result, compiled.evaluate(loc.getX(), loc.getY(), loc.getZ()), 0, + assertEquals(aCase.result, compiled.evaluate(loc.x(), loc.y(), loc.z()), 0, "Test case " + aCase + " failed (result)" ); aCase.postChecks.accept(compiled); diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/util/RegionOptimizedVectorSorterTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/util/RegionOptimizedVectorSorterTest.java index a1582bf04..11057ca25 100644 --- a/worldedit-core/src/test/java/com/sk89q/worldedit/internal/util/RegionOptimizedVectorSorterTest.java +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/internal/util/RegionOptimizedVectorSorterTest.java @@ -100,10 +100,10 @@ public class RegionOptimizedVectorSorterTest { for (int i = 0; i < toSort.size() - 1; i++) { BlockVector3 curr = toSort.get(i); BlockVector3 next = toSort.get(i + 1); - int currChunkX = curr.getX() >> 4; - int nextChunkX = next.getX() >> 4; - int currChunkZ = curr.getZ() >> 4; - int nextChunkZ = next.getZ() >> 4; + int currChunkX = curr.x() >> 4; + int nextChunkX = next.x() >> 4; + int currChunkZ = curr.z() >> 4; + int nextChunkZ = next.z() >> 4; int currRegionX = currChunkX >> 5; int nextRegionX = nextChunkX >> 5; int currRegionZ = currChunkZ >> 5; @@ -125,7 +125,7 @@ public class RegionOptimizedVectorSorterTest { fail(spaceship + " " + currChunkZ + " chunk z should be less than or equal to " + nextChunkZ); } else if (currChunkZ == nextChunkZ) { - if (curr.getY() < next.getY()) { + if (curr.y() < next.y()) { fail(spaceship + " " + curr + " y should be greater than or equal to " + next); } diff --git a/worldedit-core/src/test/java/com/sk89q/worldedit/util/LocationTest.java b/worldedit-core/src/test/java/com/sk89q/worldedit/util/LocationTest.java index 44962055b..2a16b4373 100644 --- a/worldedit-core/src/test/java/com/sk89q/worldedit/util/LocationTest.java +++ b/worldedit-core/src/test/java/com/sk89q/worldedit/util/LocationTest.java @@ -65,7 +65,7 @@ public class LocationTest { public void testGetX() throws Exception { World world = mock(World.class); Location location = new Location(world, Vector3.at(TEST_VALUE, 0, 0)); - assertEquals(TEST_VALUE, location.getX(), EPSILON); + assertEquals(TEST_VALUE, location.x(), EPSILON); } @Test @@ -80,17 +80,17 @@ public class LocationTest { World world = mock(World.class); Location location1 = new Location(world, Vector3.ZERO); Location location2 = location1.setX(TEST_VALUE); - assertEquals(0, location1.getX(), EPSILON); - assertEquals(TEST_VALUE, location2.getX(), EPSILON); - assertEquals(0, location2.getY(), EPSILON); - assertEquals(0, location2.getZ(), EPSILON); + assertEquals(0, location1.x(), EPSILON); + assertEquals(TEST_VALUE, location2.x(), EPSILON); + assertEquals(0, location2.y(), EPSILON); + assertEquals(0, location2.z(), EPSILON); } @Test public void testGetY() throws Exception { World world = mock(World.class); Location location = new Location(world, Vector3.at(0, TEST_VALUE, 0)); - assertEquals(TEST_VALUE, location.getY(), EPSILON); + assertEquals(TEST_VALUE, location.y(), EPSILON); } @Test @@ -105,17 +105,17 @@ public class LocationTest { World world = mock(World.class); Location location1 = new Location(world, Vector3.ZERO); Location location2 = location1.setY(TEST_VALUE); - assertEquals(0, location1.getY(), EPSILON); - assertEquals(0, location2.getX(), EPSILON); - assertEquals(TEST_VALUE, location2.getY(), EPSILON); - assertEquals(0, location2.getZ(), EPSILON); + assertEquals(0, location1.y(), EPSILON); + assertEquals(0, location2.x(), EPSILON); + assertEquals(TEST_VALUE, location2.y(), EPSILON); + assertEquals(0, location2.z(), EPSILON); } @Test public void testGetZ() throws Exception { World world = mock(World.class); Location location = new Location(world, Vector3.at(0, 0, TEST_VALUE)); - assertEquals(TEST_VALUE, location.getZ(), EPSILON); + assertEquals(TEST_VALUE, location.z(), EPSILON); } @Test @@ -130,10 +130,10 @@ public class LocationTest { World world = mock(World.class); Location location1 = new Location(world, Vector3.ZERO); Location location2 = location1.setZ(TEST_VALUE); - assertEquals(0, location1.getZ(), EPSILON); - assertEquals(0, location2.getX(), EPSILON); - assertEquals(0, location2.getY(), EPSILON); - assertEquals(TEST_VALUE, location2.getZ(), EPSILON); + assertEquals(0, location1.z(), EPSILON); + assertEquals(0, location2.x(), EPSILON); + assertEquals(0, location2.y(), EPSILON); + assertEquals(TEST_VALUE, location2.z(), EPSILON); } @RepeatedTest(value = 5) @@ -141,7 +141,7 @@ public class LocationTest { World world = mock(World.class); long start = System.currentTimeMillis(); BlockVector3 location1 = BlockVector3.ZERO; - BlockVector3.at(location1.getX() + 10, location1.getY() + 10, location1.getZ() + 10); + BlockVector3.at(location1.x() + 10, location1.y() + 10, location1.z() + 10); System.out.println(System.currentTimeMillis() - start + " ms"); } From 5da6c65df610ef276ee1d189d4c40b874d0112b1 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Mon, 27 May 2024 19:33:52 +0100 Subject: [PATCH 142/220] fix: use correct coordinates in BufferedPattern2D and NoiseFilter --- .../core/function/pattern/BufferedPattern2D.java | 2 +- .../java/com/sk89q/worldedit/function/mask/NoiseFilter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/BufferedPattern2D.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/BufferedPattern2D.java index 483629af4..7748c8633 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/BufferedPattern2D.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/BufferedPattern2D.java @@ -33,7 +33,7 @@ public class BufferedPattern2D extends BufferedPattern { @Override public boolean set(BlockVector3 pos) { - return set.add(pos.x(), 0, pos.y()); + return set.add(pos.x(), 0, pos.z()); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java index d0a016639..8dd9c26d9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/NoiseFilter.java @@ -97,7 +97,7 @@ public class NoiseFilter extends AbstractMask { @Override public boolean test(BlockVector3 vector) { //FAWE start - mutable - return noiseGenerator.noise(mutable.setComponents(vector.x(), vector.z(), vector.z())) <= density; + return noiseGenerator.noise(mutable.setComponents(vector.x(), vector.y(), vector.z())) <= density; //FAWE end } From 7635eec2e47f8caf1454f3744c3949990c9cf41e Mon Sep 17 00:00:00 2001 From: Jordan Date: Sun, 2 Jun 2024 17:11:53 +0200 Subject: [PATCH 143/220] fix: improve how we determine if using FAWE from jenkins (#2754) - SNAPSHOT will usually only be removed if it's a release version - If others remove SNAPSHOT, then they're probably doing their own stuff, just use this as the "release" check - fixes #2744 --- .../com/fastasyncworldedit/core/util/UpdateNotification.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/UpdateNotification.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/UpdateNotification.java index 73ad01361..fdfe7c56c 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/UpdateNotification.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/UpdateNotification.java @@ -59,12 +59,12 @@ public class UpdateNotification { Document doc = db.parse(body); faweVersion = doc.getElementsByTagName("lastSuccessfulBuild").item(0).getFirstChild().getTextContent(); FaweVersion faweVersion = Fawe.instance().getVersion(); - if (faweVersion.build == 0 && !faweVersion.snapshot) { + if (faweVersion.build == 0 && faweVersion.snapshot) { LOGGER.warn("You are using a snapshot or a custom version of FAWE. This is not an official build distributed " + "via https://www.spigotmc.org/resources/13932/"); return; } - if (faweVersion.build < Integer.parseInt(UpdateNotification.faweVersion)) { + if (faweVersion.snapshot && faweVersion.build < Integer.parseInt(UpdateNotification.faweVersion)) { hasUpdate = true; int versionDifference = Integer.parseInt(UpdateNotification.faweVersion) - faweVersion.build; LOGGER.warn( From 261ebfa754c1a2e4ffd4e44aa6952e0a5e73b0b1 Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Sun, 2 Jun 2024 18:21:56 +0200 Subject: [PATCH 144/220] feat: schematic share system, add missing Clipboard method for api compat (#2745) * Allow plugins to register new clipboard share destinations (#1707) * Allow plugins to register new clipboard share destinations * Rename file, as per request * Don't use the base enginehub name for EH_pastebin * Address review comments * Fixed wrong usage * Use a second metadata class for clipboard shares * Newline * Address comments * Improve docs * Apply suggestions from code review Co-authored-by: Octavia Togami * Use a consumer so that we handle serialization * Update worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java Co-authored-by: Octavia Togami * Update worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareDestination.java Co-authored-by: Octavia Togami * Update worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ShareOutputConsumer.java Co-authored-by: Octavia Togami * Update worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ShareOutputConsumer.java Co-authored-by: Octavia Togami * Fixed a lot of random comments * Return a consumer from share rather than a URL, allows the share destination to control output Co-authored-by: Octavia Togami (cherry picked from commit 6e2b0a1df8a6077c3cf8193e38dc9817038bcbe9) * chore: cleanup cherry-pick remainders * chore/feat: add ark as (default) schematic paster / sharing endpoint * chore: default to fast schematic writer in share * chore: re-format strings.json (seems to adjusted indentation when merging) * chore: hopefully fixing strings.json (again) --------- Co-authored-by: Maddy Miller --- .../core/configuration/Settings.java | 7 + .../arkitektonika/ArkitektonikaResponse.java | 4 + .../ArkitektonikaSchematicUploader.java | 58 +++++ .../worldedit/command/ClipboardCommands.java | 7 +- .../worldedit/command/SchematicCommands.java | 224 ++++++++---------- .../argument/ClipboardFormatConverter.java | 76 ++++++ .../ClipboardShareDestinationConverter.java | 72 ++++++ .../platform/PlatformCommandManager.java | 6 +- .../worldedit/extent/clipboard/Clipboard.java | 24 +- .../extent/clipboard/io/ClipboardFormats.java | 6 +- .../BuiltInClipboardShareDestinations.java | 149 ++++++++++++ .../io/share/ClipboardShareDestination.java | 72 ++++++ .../io/share/ClipboardShareDestinations.java | 80 +++++++ .../io/share/ClipboardShareMetadata.java | 49 ++++ .../io/share/ShareOutputProvider.java | 37 +++ .../util/ClipboardTransformBaker.java} | 37 +-- .../src/main/resources/lang/strings.json | 5 + 17 files changed, 764 insertions(+), 149 deletions(-) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/util/arkitektonika/ArkitektonikaResponse.java create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/util/arkitektonika/ArkitektonikaSchematicUploader.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/ClipboardFormatConverter.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/ClipboardShareDestinationConverter.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/BuiltInClipboardShareDestinations.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareDestination.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareDestinations.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareMetadata.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ShareOutputProvider.java rename worldedit-core/src/main/java/com/sk89q/worldedit/{command/FlattenedClipboardTransform.java => internal/util/ClipboardTransformBaker.java} (79%) 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 33c8c94f0..cf0ba6f35 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 @@ -668,6 +668,13 @@ public class Settings extends Config { @Comment({"The web interface for clipboards", " - All schematics are anonymous and private", " - Downloads can be deleted by the user", " - Supports clipboard uploads, downloads and saves",}) public String URL = "https://schem.intellectualsites.com/fawe/"; + @Comment({"The url of the backend server (Arkitektonika)"}) + public String ARKITEKTONIKA_BACKEND_URL = "https://api.schematic.cloud/"; + @Comment({"The url used to generate a download link from.", "{key} will be replaced with the generated key"}) + public String ARKITEKTONIKA_DOWNLOAD_URL = "https://schematic.cloud/download/{key}"; + @Comment({"The url used to generate a deletion link from.", "{key} will be replaced with the generated key"}) + public String ARKITEKTONIKA_DELETE_URL = "https://schematic.cloud/delete/{key}"; + @Comment("The maximum amount of time in seconds the plugin can attempt to load images for.") public int MAX_IMAGE_LOAD_TIME = 5; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/arkitektonika/ArkitektonikaResponse.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/arkitektonika/ArkitektonikaResponse.java new file mode 100644 index 000000000..821751c2a --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/arkitektonika/ArkitektonikaResponse.java @@ -0,0 +1,4 @@ +package com.fastasyncworldedit.core.util.arkitektonika; + +public record ArkitektonikaResponse(String downloadKey, String deletionKey) { +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/arkitektonika/ArkitektonikaSchematicUploader.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/arkitektonika/ArkitektonikaSchematicUploader.java new file mode 100644 index 000000000..152bca058 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/arkitektonika/ArkitektonikaSchematicUploader.java @@ -0,0 +1,58 @@ +package com.fastasyncworldedit.core.util.arkitektonika; + +import com.fastasyncworldedit.core.internal.exception.FaweException; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.sk89q.worldedit.extent.clipboard.io.share.ClipboardShareMetadata; +import com.sk89q.worldedit.extent.clipboard.io.share.ShareOutputProvider; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.format.TextColor; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.UUID; + +public class ArkitektonikaSchematicUploader { + + private static final String BOUNDARY_IDENTIFIER = "--"; + private static final HttpClient HTTP_CLIENT = HttpClient.newHttpClient(); + private final String apiUrl; + + public ArkitektonikaSchematicUploader(String apiUrl) { + this.apiUrl = apiUrl.endsWith("/") ? apiUrl.substring(0, apiUrl.length() - 1) : apiUrl; + } + + public ArkitektonikaResponse uploadBlocking(ClipboardShareMetadata meta, ShareOutputProvider provider) throws IOException, + InterruptedException { + String boundary = UUID.randomUUID().toString(); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + provider.writeTo(outputStream); + + final HttpRequest.BodyPublisher bodyPublisher = HttpRequest.BodyPublishers.concat( + HttpRequest.BodyPublishers.ofString(BOUNDARY_IDENTIFIER + boundary + "\r\n"), + HttpRequest.BodyPublishers.ofString("Content-Disposition: form-data; name=\"schematic\"; filename=\"" + meta.name() + "." + meta.format().getPrimaryFileExtension() + "\"\r\n\r\n"), + HttpRequest.BodyPublishers.ofByteArray(outputStream.toByteArray()), + HttpRequest.BodyPublishers.ofString("\r\n" + BOUNDARY_IDENTIFIER + boundary + BOUNDARY_IDENTIFIER) + ); + + final HttpResponse response = HTTP_CLIENT.send(HttpRequest.newBuilder() + .uri(URI.create(this.apiUrl + "/upload")) + .header("Content-Type", "multipart/form-data; boundary=\"" + boundary + "\"") + .POST(bodyPublisher).build(), HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() != 200) { + throw new FaweException(TextComponent + .of("Arkitektonika returned status code " + response.statusCode()) + .color(TextColor.RED)); + } + JsonObject json = JsonParser.parseString(response.body()).getAsJsonObject(); + return new ArkitektonikaResponse( + json.get("download_key").getAsString(), + json.get("delete_key").getAsString() + ); + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index b4037ba15..8c0b69ec9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -340,7 +340,7 @@ public class ClipboardCommands { aliases = {"/download"}, desc = "Downloads your clipboard through the configured web interface" ) - @Deprecated + @Deprecated(forRemoval = true, since = "TODO") @CommandPermissions({"worldedit.clipboard.download"}) public void download( final Actor actor, @@ -402,10 +402,7 @@ public class ClipboardCommands { final Clipboard target; // If we have a transform, bake it into the copy if (!transform.isIdentity()) { - final FlattenedClipboardTransform result = FlattenedClipboardTransform.transform(clipboard, transform); - target = new BlockArrayClipboard(result.getTransformedRegion(), actor.getUniqueId()); - target.setOrigin(clipboard.getOrigin()); - Operations.completeLegacy(result.copyTo(target)); + target = clipboard.transform(transform); } else { target = clipboard; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java index e711e61ee..920a24901 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java @@ -26,7 +26,6 @@ import com.fastasyncworldedit.core.extent.clipboard.MultiClipboardHolder; import com.fastasyncworldedit.core.extent.clipboard.URIClipboardHolder; import com.fastasyncworldedit.core.extent.clipboard.io.schematic.MinecraftStructure; import com.fastasyncworldedit.core.util.MainUtil; -import com.google.common.collect.ImmutableList; import com.google.common.collect.Multimap; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; @@ -38,13 +37,13 @@ import com.sk89q.worldedit.command.util.CommandPermissions; import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Capability; -import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader; import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; -import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.extent.clipboard.io.share.ClipboardShareDestination; +import com.sk89q.worldedit.extent.clipboard.io.share.ClipboardShareMetadata; import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.math.transform.Transform; @@ -61,19 +60,15 @@ import com.sk89q.worldedit.util.formatting.text.format.TextColor; import com.sk89q.worldedit.util.io.Closer; import com.sk89q.worldedit.util.io.file.FilenameException; import org.apache.logging.log4j.Logger; -import com.sk89q.worldedit.util.paste.EngineHubPaste; -import com.sk89q.worldedit.util.paste.PasteMetadata; import org.enginehub.piston.annotation.Command; import org.enginehub.piston.annotation.CommandContainer; import org.enginehub.piston.annotation.param.Arg; import org.enginehub.piston.annotation.param.ArgFlag; import org.enginehub.piston.annotation.param.Switch; -import org.enginehub.piston.exception.CommandException; import org.enginehub.piston.exception.StopExecutionException; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -85,11 +80,9 @@ import java.net.URL; import java.nio.channels.Channels; import java.nio.channels.ReadableByteChannel; import java.io.OutputStream; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Base64; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -98,6 +91,7 @@ import java.util.Map; import java.util.Objects; import java.util.UUID; import java.util.concurrent.Callable; +import java.util.function.Consumer; import java.util.concurrent.ThreadLocalRandom; import java.util.function.Function; import java.util.regex.Pattern; @@ -321,7 +315,7 @@ public class SchematicCommands { Actor actor, LocalSession session, @Arg(desc = "File name.") String filename, - //FAWE start - random rotation + //FAWE start - use format-name, random rotation @Arg(desc = "Format name.", def = "") String formatName, @Switch(name = 'r', desc = "Apply random rotation to the clipboard") @@ -445,8 +439,8 @@ public class SchematicCommands { Actor actor, LocalSession session, @Arg(desc = "File name.") String filename, - @Arg(desc = "Format name.", def = "fast") - String formatName, + @Arg(desc = "Format name.", def = "fast") //FAWE: def: sponge -> fast + ClipboardFormat format, @Switch(name = 'f', desc = "Overwrite an existing file.") boolean allowOverwrite, //FAWE start @@ -474,12 +468,6 @@ public class SchematicCommands { dir = new File(dir, actor.getUniqueId().toString()); } - ClipboardFormat format = ClipboardFormats.findByAlias(formatName); - if (format == null) { - actor.print(Caption.of("worldedit.schematic.unknown-format", TextComponent.of(formatName))); - return; - } - boolean other = false; if (filename.contains("../")) { other = true; @@ -551,35 +539,98 @@ public class SchematicCommands { @CommandPermissions({ "worldedit.clipboard.share", "worldedit.schematic.share" }) public void share(Actor actor, LocalSession session, @Arg(desc = "Schematic name. Defaults to name-millis", def = "") - String schematicName, - @Arg(desc = "Format name.", def = "sponge") - String formatName) throws WorldEditException { - if (true) { - throw new UnsupportedOperationException("This feature is currently not implemented"); - } + String schematicName, + @Arg(desc = "Share location", def = "arkitektonika") //FAWE: def: ehpaste -> arkitektonika + ClipboardShareDestination destination, + @Arg(desc = "Format name", def = "fast") //FAWE: def: sponge -> fast + ClipboardFormat format) throws WorldEditException { if (worldEdit.getPlatformManager().queryCapability(Capability.GAME_HOOKS).getDataVersion() == -1) { actor.printError(TranslatableComponent.of("worldedit.schematic.unsupported-minecraft-version")); return; } - ClipboardFormat format = ClipboardFormats.findByAlias(formatName); if (format == null) { - actor.printError(TranslatableComponent.of("worldedit.schematic.unknown-format", TextComponent.of(formatName))); + format = destination.getDefaultFormat(); + } + + if (!destination.supportsFormat(format)) { + actor.printError(Caption.of( //FAWE: TranslatableComponent -> Caption + "worldedit.schematic.share.unsupported-format", + TextComponent.of(destination.getName()), + TextComponent.of(format.getName()) + )); return; } ClipboardHolder holder = session.getClipboard(); - SchematicShareTask task = new SchematicShareTask(actor, format, holder, schematicName); + SchematicShareTask task = new SchematicShareTask(actor, holder, destination, format, schematicName); AsyncCommandBuilder.wrap(task, actor) .registerWithSupervisor(worldEdit.getSupervisor(), "Sharing schematic") .setDelayMessage(TranslatableComponent.of("worldedit.schematic.save.saving")) .setWorkingMessage(TranslatableComponent.of("worldedit.schematic.save.still-saving")) - .onSuccess("Shared", (url -> actor.printInfo(TextComponent.of(url.toExternalForm() + ".schem").clickEvent(ClickEvent.openUrl(url.toExternalForm() + ".schem"))))) + .onSuccess("Shared", (consumer -> consumer.accept(actor))) .onFailure("Failed to share schematic", worldEdit.getPlatformManager().getPlatformCommandManager().getExceptionConverter()) .buildAndExec(worldEdit.getExecutorService()); } + @Command( + name = "delete", + aliases = {"d"}, + desc = "Delete a saved schematic" + ) + @CommandPermissions("worldedit.schematic.delete") + public void delete( + Actor actor, LocalSession session, + @Arg(desc = "File name.") + String filename + ) throws WorldEditException, IOException { + LocalConfiguration config = worldEdit.getConfiguration(); + //FAWE start + File working = worldEdit.getWorkingDirectoryPath(config.saveDir).toFile(); + File dir = Settings.settings().PATHS.PER_PLAYER_SCHEMATICS ? new File(working, actor.getUniqueId().toString()) : working; + List files = new ArrayList<>(); + + if (filename.equalsIgnoreCase("*")) { + files.addAll(getFiles(session.getClipboard())); + } else { + File f = MainUtil.resolveRelative(new File(dir, filename)); + files.add(f); + } + + if (files.isEmpty()) { + actor.print(Caption.of("worldedit.schematic.delete.does-not-exist", TextComponent.of(filename))); + return; + } + for (File f : files) { + if (!MainUtil.isInSubDirectory(working, f) || !f.exists()) { + actor.print(Caption.of("worldedit.schematic.delete.does-not-exist", TextComponent.of(filename))); + continue; + } + if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && !MainUtil.isInSubDirectory(dir, f) && !actor.hasPermission( + "worldedit.schematic.delete.other")) { + actor.print(Caption.of("fawe.error.no-perm", "worldedit.schematic.delete.other")); + continue; + } + if (!deleteFile(f)) { + actor.print(Caption.of("worldedit.schematic.delete.failed", TextComponent.of(filename))); + continue; + } + actor.print(Caption.of("worldedit.schematic.delete.deleted", filename)); + } + //FAWE end + } + + //FAWE start + private boolean deleteFile(File file) { + if (file.delete()) { + new File(file.getParentFile(), "." + file.getName() + ".cached").delete(); + return true; + } + return false; + } + //FAWE end + @Command( name = "formats", aliases = {"listformats", "f"}, @@ -764,68 +815,11 @@ public class SchematicCommands { } - @Command( - name = "delete", - aliases = {"d"}, - desc = "Delete a saved schematic" - ) - @CommandPermissions("worldedit.schematic.delete") - public void delete( - Actor actor, LocalSession session, - @Arg(desc = "File name.") - String filename - ) throws WorldEditException, IOException { - LocalConfiguration config = worldEdit.getConfiguration(); - File working = worldEdit.getWorkingDirectoryPath(config.saveDir).toFile(); - //FAWE start - File dir = Settings.settings().PATHS.PER_PLAYER_SCHEMATICS ? new File(working, actor.getUniqueId().toString()) : working; - List files = new ArrayList<>(); - - if (filename.equalsIgnoreCase("*")) { - files.addAll(getFiles(session.getClipboard())); - } else { - File f = MainUtil.resolveRelative(new File(dir, filename)); - files.add(f); - } - - if (files.isEmpty()) { - actor.print(Caption.of("worldedit.schematic.delete.does-not-exist", TextComponent.of(filename))); - return; - } - for (File f : files) { - if (!MainUtil.isInSubDirectory(working, f) || !f.exists()) { - actor.print(Caption.of("worldedit.schematic.delete.does-not-exist", TextComponent.of(filename))); - continue; - } - if (Settings.settings().PATHS.PER_PLAYER_SCHEMATICS && !MainUtil.isInSubDirectory(dir, f) && !actor.hasPermission( - "worldedit.schematic.delete.other")) { - actor.print(Caption.of("fawe.error.no-perm", "worldedit.schematic.delete.other")); - continue; - } - if (!deleteFile(f)) { - actor.print(Caption.of("worldedit.schematic.delete.failed", TextComponent.of(filename))); - continue; - } - actor.print(Caption.of("worldedit.schematic.delete.deleted", filename)); - } - //FAWE end - } - - //FAWE start - private boolean deleteFile(File file) { - if (file.delete()) { - new File(file.getParentFile(), "." + file.getName() + ".cached").delete(); - return true; - } - return false; - } - //FAWE end - private static class SchematicLoadTask implements Callable { private final Actor actor; - private final ClipboardFormat format; private final File file; + private final ClipboardFormat format; SchematicLoadTask(Actor actor, File file, ClipboardFormat format) { this.actor = actor; @@ -863,19 +857,10 @@ public class SchematicCommands { this.holder = holder; } - protected void writeToOutputStream(OutputStream outputStream) throws Exception { + protected void writeToOutputStream(OutputStream outputStream) throws IOException, WorldEditException { Clipboard clipboard = holder.getClipboard(); Transform transform = holder.getTransform(); - Clipboard target; - // If we have a transform, bake it into the copy - if (transform.isIdentity()) { - target = clipboard; - } else { - FlattenedClipboardTransform result = FlattenedClipboardTransform.transform(clipboard, transform); - target = new BlockArrayClipboard(result.getTransformedRegion()); - target.setOrigin(clipboard.getOrigin()); - Operations.completeLegacy(result.copyTo(target)); - } + Clipboard target = clipboard.transform(transform); try (Closer closer = Closer.create()) { OutputStream stream = closer.register(outputStream); @@ -887,9 +872,10 @@ public class SchematicCommands { } private static class SchematicSaveTask extends SchematicOutputTask { - private File file; + private final Actor actor; + private File file; //FAWE: un-finalize private final boolean overwrite; - private final File rootDir; + private final File rootDir; //FAWE: add root-dir SchematicSaveTask( Actor actor, @@ -900,9 +886,10 @@ public class SchematicCommands { boolean overwrite ) { super(actor, format, holder); + this.actor = actor; this.file = file; - this.rootDir = rootDir; this.overwrite = overwrite; + this.rootDir = rootDir; //FAWE: add root-dir } @Override @@ -975,10 +962,7 @@ public class SchematicCommands { if (transform.isIdentity()) { target = clipboard; } else { - FlattenedClipboardTransform result = FlattenedClipboardTransform.transform(clipboard, transform); - target = new BlockArrayClipboard(result.getTransformedRegion()); - target.setOrigin(clipboard.getOrigin()); - Operations.completeLegacy(result.copyTo(target)); + target = clipboard.transform(transform); } try (Closer closer = Closer.create()) { @@ -1062,29 +1046,31 @@ public class SchematicCommands { } } - private static class SchematicShareTask extends SchematicOutputTask { + private static class SchematicShareTask extends SchematicOutputTask> { + private final Actor actor; private final String name; + private final ClipboardShareDestination destination; - SchematicShareTask(Actor actor, ClipboardFormat format, ClipboardHolder holder, String name) { + SchematicShareTask(Actor actor, + ClipboardHolder holder, + ClipboardShareDestination destination, + ClipboardFormat format, + String name) { super(actor, format, holder); + this.actor = actor; this.name = name; + this.destination = destination; } @Override - public URL call() throws Exception { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try { - writeToOutputStream(baos); - } catch (Exception e) { - throw new CommandException(TextComponent.of(e.getMessage()), e, ImmutableList.of()); - } + public Consumer call() throws Exception { + ClipboardShareMetadata metadata = new ClipboardShareMetadata( + format, + this.actor.getName(), + name == null ? actor.getName() + "-" + System.currentTimeMillis() : name + ); - EngineHubPaste pasteService = new EngineHubPaste(); - PasteMetadata metadata = new PasteMetadata(); - metadata.author = this.actor.getName(); - metadata.extension = "schem"; - metadata.name = name == null ? actor.getName() + "-" + System.currentTimeMillis() : name; - return pasteService.paste(new String(Base64.getEncoder().encode(baos.toByteArray()), StandardCharsets.UTF_8), metadata).call(); + return destination.share(metadata, this::writeToOutputStream); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/ClipboardFormatConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/ClipboardFormatConverter.java new file mode 100644 index 000000000..cfa0a1ed4 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/ClipboardFormatConverter.java @@ -0,0 +1,76 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command.argument; + +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; +import com.sk89q.worldedit.extent.clipboard.io.share.ClipboardShareDestination; +import com.sk89q.worldedit.util.formatting.text.Component; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import org.enginehub.piston.CommandManager; +import org.enginehub.piston.converter.ArgumentConverter; +import org.enginehub.piston.converter.ConversionResult; +import org.enginehub.piston.converter.FailedConversion; +import org.enginehub.piston.converter.SuccessfulConversion; +import org.enginehub.piston.inject.InjectedValueAccess; +import org.enginehub.piston.inject.Key; + +import java.util.List; +import java.util.Set; + +import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix; + +public class ClipboardFormatConverter implements ArgumentConverter { + + public static void register(CommandManager commandManager) { + commandManager.registerConverter(Key.of(ClipboardFormat.class), + new ClipboardFormatConverter() + ); + } + + private final TextComponent choices; + + private ClipboardFormatConverter() { + this.choices = TextComponent.of("any clipboard format"); + } + + @Override + public Component describeAcceptableArguments() { + return this.choices; + } + + @Override + public List getSuggestions(String input, InjectedValueAccess context) { + ClipboardShareDestination destination = context.injectedValue(Key.of(ClipboardShareDestination.class)).orElse(null); + + return limitByPrefix(ClipboardFormats.getAll().stream() + .filter(format -> destination == null || destination.supportsFormat(format)) + .map(ClipboardFormat::getAliases) + .flatMap(Set::stream), input); + } + + @Override + public ConversionResult convert(String s, InjectedValueAccess injectedValueAccess) { + ClipboardFormat result = ClipboardFormats.findByAlias(s); + return result == null + ? FailedConversion.from(new IllegalArgumentException("Not a valid schematic format: " + s)) + : SuccessfulConversion.fromSingle(result); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/ClipboardShareDestinationConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/ClipboardShareDestinationConverter.java new file mode 100644 index 000000000..5af81bb1d --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/ClipboardShareDestinationConverter.java @@ -0,0 +1,72 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.command.argument; + +import com.sk89q.worldedit.extent.clipboard.io.share.ClipboardShareDestination; +import com.sk89q.worldedit.extent.clipboard.io.share.ClipboardShareDestinations; +import com.sk89q.worldedit.util.formatting.text.Component; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import org.enginehub.piston.CommandManager; +import org.enginehub.piston.converter.ArgumentConverter; +import org.enginehub.piston.converter.ConversionResult; +import org.enginehub.piston.converter.FailedConversion; +import org.enginehub.piston.converter.SuccessfulConversion; +import org.enginehub.piston.inject.InjectedValueAccess; +import org.enginehub.piston.inject.Key; + +import java.util.List; +import java.util.Set; + +import static org.enginehub.piston.converter.SuggestionHelper.limitByPrefix; + +public class ClipboardShareDestinationConverter implements ArgumentConverter { + + public static void register(CommandManager commandManager) { + commandManager.registerConverter(Key.of(ClipboardShareDestination.class), + new ClipboardShareDestinationConverter() + ); + } + + private final TextComponent choices; + + private ClipboardShareDestinationConverter() { + this.choices = TextComponent.of("any clipboard share destination"); + } + + @Override + public Component describeAcceptableArguments() { + return this.choices; + } + + @Override + public List getSuggestions(String input, InjectedValueAccess context) { + return limitByPrefix(ClipboardShareDestinations.getAll().stream() + .map(ClipboardShareDestination::getAliases) + .flatMap(Set::stream), input); + } + + @Override + public ConversionResult convert(String s, InjectedValueAccess injectedValueAccess) { + ClipboardShareDestination result = ClipboardShareDestinations.findByAlias(s); + return result == null + ? FailedConversion.from(new IllegalArgumentException("Not a valid clipboard share destination: " + s)) + : SuccessfulConversion.fromSingle(result); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java index 7b493cf98..b03e4ce54 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java @@ -86,6 +86,8 @@ import com.sk89q.worldedit.command.WorldEditCommandsRegistration; import com.sk89q.worldedit.command.argument.Arguments; import com.sk89q.worldedit.command.argument.BooleanConverter; import com.sk89q.worldedit.command.argument.Chunk3dVectorConverter; +import com.sk89q.worldedit.command.argument.ClipboardFormatConverter; +import com.sk89q.worldedit.command.argument.ClipboardShareDestinationConverter; import com.sk89q.worldedit.command.argument.CommaSeparatedValuesConverter; import com.sk89q.worldedit.command.argument.DirectionConverter; import com.sk89q.worldedit.command.argument.DirectionVectorConverter; @@ -174,7 +176,6 @@ import java.util.stream.Stream; import static com.google.common.base.Preconditions.checkNotNull; - /** * Handles the registration and invocation of commands. * @@ -272,6 +273,8 @@ public final class PlatformCommandManager { SideEffectConverter.register(commandManager); HeightConverter.register(commandManager); OffsetConverter.register(worldEdit, commandManager); + ClipboardFormatConverter.register(commandManager); + ClipboardShareDestinationConverter.register(commandManager); //FAWE start commandManager.registerConverter( Key.of(com.sk89q.worldedit.function.pattern.Pattern.class, Annotations.patternList()), @@ -604,7 +607,6 @@ public final class PlatformCommandManager { void registerCommandsWith(Platform platform) { LOGGER.info("Registering commands with " + platform.getClass().getCanonicalName()); - LocalConfiguration config = platform.getConfiguration(); boolean logging = config.logCommands; String path = config.logFile; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java index d52fd1056..4cd2ead97 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java @@ -31,6 +31,7 @@ import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSessionBuilder; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; @@ -40,6 +41,7 @@ import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.operation.ForwardExtentCopy; import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.internal.util.ClipboardTransformBaker; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.regions.Region; @@ -98,7 +100,7 @@ public interface Clipboard extends Extent, Iterable, Closeable, Fl * - {@link DiskOptimizedClipboard} * - {@link CPUOptimizedClipboard} * - {@link MemoryOptimizedClipboard} - * + * * @deprecated Internal use only. Use {@link BlockArrayClipboard#BlockArrayClipboard(Region, UUID)} */ @Deprecated @@ -144,10 +146,9 @@ public interface Clipboard extends Extent, Iterable, Closeable, Fl void setOrigin(BlockVector3 origin); /** - * Returns true if the clipboard has biome data. This can be checked since {@link Extent#getBiome(BlockVector2)} + * Returns true if the clipboard has biome data. This can be checked since {@link Extent#getBiome(BlockVector3)} * strongly suggests returning {@link com.sk89q.worldedit.world.biome.BiomeTypes#OCEAN} instead of {@code null} - * if biomes aren't present. However, it might not be desired to set areas to ocean if the clipboard is defaulting - * to ocean, instead of having biomes explicitly set. + * if biomes aren't present. * * @return true if the clipboard has biome data set */ @@ -155,6 +156,21 @@ public interface Clipboard extends Extent, Iterable, Closeable, Fl return false; } + /** + * Returns a clipboard with a given transform baked in. + * + *

    + * Note: This method may return the same clipboard object, if a copy is needed then you should check the returned value for identity equality and copy if needed. + *

    + * + * @param transform The transform + * @return The new clipboard + * @throws WorldEditException if the copy encounters an error + */ + default Clipboard transform(Transform transform) throws WorldEditException { + return ClipboardTransformBaker.bakeTransform(this, transform); + } + //FAWE start /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java index 03cce5d80..b69a7a0cc 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java @@ -73,7 +73,7 @@ public class ClipboardFormats { checkNotNull(format); for (String key : format.getAliases()) { - String lowKey = key.toLowerCase(Locale.ENGLISH); + String lowKey = key.toLowerCase(Locale.ROOT); ClipboardFormat old = aliasMap.put(lowKey, format); if (old != null) { aliasMap.put(lowKey, old); @@ -83,7 +83,7 @@ public class ClipboardFormats { } } for (String ext : format.getFileExtensions()) { - String lowExt = ext.toLowerCase(Locale.ENGLISH); + String lowExt = ext.toLowerCase(Locale.ROOT); fileExtensionMap.put(lowExt, format); } registeredFormats.add(format); @@ -104,7 +104,7 @@ public class ClipboardFormats { @Nullable public static ClipboardFormat findByAlias(String alias) { checkNotNull(alias); - return aliasMap.get(alias.toLowerCase(Locale.ENGLISH).trim()); + return aliasMap.get(alias.toLowerCase(Locale.ROOT).trim()); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/BuiltInClipboardShareDestinations.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/BuiltInClipboardShareDestinations.java new file mode 100644 index 000000000..981debe4b --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/BuiltInClipboardShareDestinations.java @@ -0,0 +1,149 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io.share; + +import com.fastasyncworldedit.core.configuration.Caption; +import com.fastasyncworldedit.core.configuration.Settings; +import com.fastasyncworldedit.core.util.arkitektonika.ArkitektonikaResponse; +import com.fastasyncworldedit.core.util.arkitektonika.ArkitektonikaSchematicUploader; +import com.google.common.collect.ImmutableSet; +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.event.ClickEvent; +import com.sk89q.worldedit.util.formatting.text.format.TextColor; +import com.sk89q.worldedit.util.paste.EngineHubPaste; +import com.sk89q.worldedit.util.paste.PasteMetadata; + +import java.io.ByteArrayOutputStream; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.function.Consumer; + +/** + * A collection of natively supported clipboard share destinations. + */ +public enum BuiltInClipboardShareDestinations implements ClipboardShareDestination { + + /** + * The EngineHub pastebin service, at https://paste.enginehub.org/ + */ + ENGINEHUB_PASTEBIN("enginehub_paste", "ehpaste") { + @Override + public String getName() { + return "EngineHub Paste"; + } + + @Override + public Consumer share(ClipboardShareMetadata metadata, ShareOutputProvider serializer) throws Exception { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + serializer.writeTo(outputStream); + + PasteMetadata pasteMetadata = new PasteMetadata(); + pasteMetadata.author = metadata.author(); + pasteMetadata.extension = "schem"; + pasteMetadata.name = metadata.name(); + EngineHubPaste pasteService = new EngineHubPaste(); + + URL url = pasteService.paste(new String( + Base64.getEncoder().encode(outputStream.toByteArray()), + StandardCharsets.UTF_8 + ), pasteMetadata).call(); + String urlString = url.toExternalForm() + ".schem"; + return actor -> actor.printInfo(TextComponent.of(urlString).clickEvent(ClickEvent.openUrl(urlString))); + } + + @Override + public ClipboardFormat getDefaultFormat() { + return BuiltInClipboardFormat.SPONGE_SCHEMATIC; + } + + @Override + public boolean supportsFormat(ClipboardFormat format) { + return format == getDefaultFormat(); + } + }, + + //FAWE start - add arkitektonika + ARKITEKTONIKA("arkitektonika", "fawe") { + + private ArkitektonikaSchematicUploader uploader; + + @Override + public String getName() { + return "Arkitektonika"; + } + + @Override + public Consumer share(final ClipboardShareMetadata metadata, final ShareOutputProvider serializer) throws + Exception { + if (uploader == null) { + uploader = new ArkitektonikaSchematicUploader(Settings.settings().WEB.ARKITEKTONIKA_BACKEND_URL); + } + final ArkitektonikaResponse response = uploader.uploadBlocking(metadata, serializer); + final String downloadUrl = Settings.settings().WEB.ARKITEKTONIKA_DOWNLOAD_URL.replace("{key}", response.downloadKey()); + final String deletionUrl = Settings.settings().WEB.ARKITEKTONIKA_DELETE_URL.replace("{key}", response.deletionKey()); + return actor -> { + actor.print(Caption.of( + "worldedit.schematic.share.response.arkitektonika.download", + Caption.of("worldedit.schematic.share.response.arkitektonika.click-here") + .color(TextColor.GREEN).clickEvent(ClickEvent.openUrl(downloadUrl)) + )); + actor.print(Caption.of( + "worldedit.schematic.share.response.arkitektonika.delete", + Caption.of("worldedit.schematic.share.response.arkitektonika.click-here") + .color(TextColor.RED).clickEvent(ClickEvent.openUrl(deletionUrl)) + )); + }; + } + + @Override + public ClipboardFormat getDefaultFormat() { + return BuiltInClipboardFormat.FAST; + } + + @Override + public boolean supportsFormat(final ClipboardFormat format) { + return format == BuiltInClipboardFormat.SPONGE_SCHEMATIC || + format == BuiltInClipboardFormat.FAST || + format == BuiltInClipboardFormat.MCEDIT_SCHEMATIC; + } + }; + //FAWE end + + private final ImmutableSet aliases; + + BuiltInClipboardShareDestinations(String... aliases) { + this.aliases = ImmutableSet.copyOf(aliases); + } + + @Override + public ImmutableSet getAliases() { + return this.aliases; + } + + @Override + public String getName() { + return name(); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareDestination.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareDestination.java new file mode 100644 index 000000000..1b0cb9e21 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareDestination.java @@ -0,0 +1,72 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io.share; + +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; + +import java.util.Set; +import java.util.function.Consumer; + +public interface ClipboardShareDestination { + + /** + * Gets the name of this share destination. + * + * @return The name + */ + String getName(); + + /** + * Get a set of aliases. + * + * @return a set of aliases + */ + Set getAliases(); + + /** + * Share a clipboard output stream and return a URL. + * + *

    + * The serialized schematic can be retrieved by providing an {@link java.io.OutputStream} to {@code serializer}. + *

    + * + * @param metadata The clipboard metadata + * @param serializer A function taking the {@link java.io.OutputStream} + * @return A consumer to provide the actor with the share results + * @throws Exception if it failed to share + */ + Consumer share(ClipboardShareMetadata metadata, ShareOutputProvider serializer) throws Exception; + + /** + * Gets the default clipboard format for this share destination. + * + * @return The default format + */ + ClipboardFormat getDefaultFormat(); + + /** + * Gets whether the share destination supports the given format. + * + * @param format The format + * @return If it's supported + */ + boolean supportsFormat(ClipboardFormat format); +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareDestinations.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareDestinations.java new file mode 100644 index 000000000..cf9b408f1 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareDestinations.java @@ -0,0 +1,80 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io.share; + +import com.sk89q.worldedit.WorldEdit; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import javax.annotation.Nullable; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +public class ClipboardShareDestinations { + + private static final Map aliasMap = new HashMap<>(); + private static final List registeredDestinations = new ArrayList<>(); + + public static void registerClipboardShareDestination(ClipboardShareDestination destination) { + checkNotNull(destination); + checkState(destination.supportsFormat(destination.getDefaultFormat()), "Destination must accept its default format"); + + for (String key : destination.getAliases()) { + String lowKey = key.toLowerCase(Locale.ROOT); + ClipboardShareDestination old = aliasMap.put(lowKey, destination); + if (old != null) { + aliasMap.put(lowKey, old); + WorldEdit.logger.warn(destination.getClass().getName() + " cannot override existing alias '" + lowKey + "' used by " + old.getClass().getName()); + } + } + registeredDestinations.add(destination); + } + + static { + for (BuiltInClipboardShareDestinations destination : BuiltInClipboardShareDestinations.values()) { + registerClipboardShareDestination(destination); + } + } + + /** + * Find the clipboard format named by the given alias. + * + * @param alias the alias + * @return the format, otherwise null if none is matched + */ + @Nullable + public static ClipboardShareDestination findByAlias(String alias) { + checkNotNull(alias); + return aliasMap.get(alias.toLowerCase(Locale.ROOT).trim()); + } + + public static Collection getAll() { + return Collections.unmodifiableCollection(registeredDestinations); + } + + private ClipboardShareDestinations() { + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareMetadata.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareMetadata.java new file mode 100644 index 000000000..2e5f6c042 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareMetadata.java @@ -0,0 +1,49 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io.share; + +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; + +/** + * Items of metadata about shared clipboards. + */ +public class ClipboardShareMetadata { + private final ClipboardFormat format; + private final String name; + private final String author; + + public ClipboardShareMetadata(ClipboardFormat format, String name, String author) { + this.format = format; + this.name = name; + this.author = author; + } + + public ClipboardFormat format() { + return this.format; + } + + public String name() { + return this.name; + } + + public String author() { + return this.author; + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ShareOutputProvider.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ShareOutputProvider.java new file mode 100644 index 000000000..6d7587925 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ShareOutputProvider.java @@ -0,0 +1,37 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io.share; + +import com.sk89q.worldedit.WorldEditException; + +import java.io.IOException; +import java.io.OutputStream; + +@FunctionalInterface +public interface ShareOutputProvider { + + /** + * Provides the share output to {@code stream}. + * + * @throws IOException if it failed + * @throws WorldEditException if WorldEdit failed to serialize to the stream + */ + void writeTo(OutputStream stream) throws IOException, WorldEditException; +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/FlattenedClipboardTransform.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/ClipboardTransformBaker.java similarity index 79% rename from worldedit-core/src/main/java/com/sk89q/worldedit/command/FlattenedClipboardTransform.java rename to worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/ClipboardTransformBaker.java index d32504ad4..daa969080 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/FlattenedClipboardTransform.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/ClipboardTransformBaker.java @@ -17,13 +17,16 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.command; +package com.sk89q.worldedit.internal.util; +import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.transform.BlockTransformExtent; import com.sk89q.worldedit.function.operation.ForwardExtentCopy; import com.sk89q.worldedit.function.operation.Operation; +import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.math.transform.CombinedTransform; @@ -36,12 +39,10 @@ import static com.google.common.base.Preconditions.checkNotNull; /** * Helper class to 'bake' a transform into a clipboard. * - *

    This class needs a better name and may need to be made more generic.

    - * * @see Clipboard * @see Transform */ -public class FlattenedClipboardTransform { +public class ClipboardTransformBaker { private final Clipboard original; private final Transform transform; @@ -52,7 +53,7 @@ public class FlattenedClipboardTransform { * @param original the original clipboard * @param transform the transform */ - private FlattenedClipboardTransform(Clipboard original, Transform transform) { + private ClipboardTransformBaker(Clipboard original, Transform transform) { checkNotNull(original); checkNotNull(transform); this.original = original; @@ -64,7 +65,7 @@ public class FlattenedClipboardTransform { * * @return the transformed region */ - public Region getTransformedRegion() { + private Region getTransformedRegion() { Region region = original.getRegion(); Vector3 minimum = region.getMinimumPoint().toVector3(); Vector3 maximum = region.getMaximumPoint().toVector3(); @@ -73,8 +74,7 @@ public class FlattenedClipboardTransform { new CombinedTransform( new AffineTransform().translate(original.getOrigin().multiply(-1)), transform, - new AffineTransform().translate(original.getOrigin()) - ); + new AffineTransform().translate(original.getOrigin())); Vector3[] corners = new Vector3[]{ minimum, @@ -113,7 +113,7 @@ public class FlattenedClipboardTransform { * @param target the target * @return the operation */ - public Operation copyTo(Extent target) { + private Operation copyTo(Extent target) { //FAWE start Extent extent = original; if (transform != null && !transform.isIdentity()) { @@ -121,11 +121,7 @@ public class FlattenedClipboardTransform { } //FAWE end ForwardExtentCopy copy = new ForwardExtentCopy( - extent, - original.getRegion(), - original.getOrigin(), - target, - original.getOrigin() + extent, original.getRegion(), original.getOrigin(), target, original.getOrigin() ); copy.setTransform(transform); if (original.hasBiomes()) { @@ -140,9 +136,18 @@ public class FlattenedClipboardTransform { * @param original the original clipboard * @param transform the transform * @return a builder + * @throws WorldEditException if an error occurred during copy */ - public static FlattenedClipboardTransform transform(Clipboard original, Transform transform) { - return new FlattenedClipboardTransform(original, transform); + public static Clipboard bakeTransform(Clipboard original, Transform transform) throws WorldEditException { + if (transform.isIdentity()) { + return original; + } + ClipboardTransformBaker baker = new ClipboardTransformBaker(original, transform); + Clipboard target = new BlockArrayClipboard(baker.getTransformedRegion()); + target.setOrigin(original.getOrigin()); + Operations.complete(baker.copyTo(target)); + + return target; } } diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index c343dd623..c67da38d7 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -360,6 +360,11 @@ "worldedit.schematic.save.already-exists": "That schematic already exists. Use the -f flag to overwrite it.", "worldedit.schematic.save.failed-directory": "Could not create folder for schematics!", "worldedit.schematic.save.saving": "(Please wait... saving schematic.)", + "worldedit.schematic.save.still-saving": "(Please wait... still saving schematic.)", + "worldedit.schematic.share.unsupported-format": "The schematic share destination \"{0}\" does not support the \"{1}\" format.", + "worldedit.schematic.share.response.arkitektonika.download" : "Download: {0}", + "worldedit.schematic.share.response.arkitektonika.delete" : "Delete: {0}", + "worldedit.schematic.share.response.arkitektonika.click-here" : "[Click here]", "worldedit.schematic.delete.empty": "Schematic {0} not found!", "worldedit.schematic.delete.does-not-exist": "Schematic {0} does not exist!", "worldedit.schematic.delete.failed": "Deletion of {0} failed! Is it read-only?", From c41e38202c959f6f89c56e945800f16866c0081e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 00:48:40 +0000 Subject: [PATCH 145/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.2.12 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 38f8f3f32..d6bf97dcb 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.2.11" +towny = "0.100.2.12" plotsquared = "7.3.8" # Third party From da81530f869e0f3269eeabad89b2a8ed93396c4d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 00:48:46 +0000 Subject: [PATCH 146/220] Update dependency net.kyori:adventure-platform-bukkit to v4.3.3 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d6bf97dcb..12c34eeca 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ bstats = "3.0.2" sparsebitset = "1.3" parallelgzip = "1.0.5" adventure = "4.17.0" -adventure-bukkit = "4.3.2" +adventure-bukkit = "4.3.3" checkerqual = "3.43.0" truezip = "6.8.4" auto-value = "1.10.4" From e044b92d45bad2536b881418cf52b1eab8b2b9ae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 03:30:53 +0000 Subject: [PATCH 147/220] Update dependency paperweight-userdev --- worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts | 2 +- worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts index 821b6c52d..c82a5bd55 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_4/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT - the().paperDevBundle("1.20.4-R0.1-20240424.165410-174") + the().paperDevBundle("1.20.4-R0.1-20240528.102248-175") compileOnly(libs.paperlib) } diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts index 8f97a8454..43bc53f15 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/ - the().paperDevBundle("1.20.6-R0.1-20240526.222003-87") + the().paperDevBundle("1.20.6-R0.1-20240602.222958-106") compileOnly(libs.paperlib) } From 393ed005245bd51f1251a5e62664a237af87d37b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 03:30:58 +0000 Subject: [PATCH 148/220] Update eps1lon/actions-label-merge-conflict action to v3.0.2 --- .github/workflows/label-merge-conflicts.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/label-merge-conflicts.yaml b/.github/workflows/label-merge-conflicts.yaml index 551b39417..8a2c30125 100644 --- a/.github/workflows/label-merge-conflicts.yaml +++ b/.github/workflows/label-merge-conflicts.yaml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Label conflicting PRs - uses: eps1lon/actions-label-merge-conflict@v3.0.1 + uses: eps1lon/actions-label-merge-conflict@v3.0.2 with: dirtyLabel: "unresolved-merge-conflict" repoToken: "${{ secrets.GITHUB_TOKEN }}" From a82ba31185e9142c8ce0b12d83d2a9d0ad573df6 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sun, 2 Jun 2024 09:23:31 +0100 Subject: [PATCH 149/220] feat: allow NBT on wand items - closes #2383 --- .../core/util/gson/BaseItemAdapter.java | 61 +++++++++++++ .../com/sk89q/worldedit/LocalSession.java | 87 ++++++++++++++----- .../com/sk89q/worldedit/blocks/BaseItem.java | 1 + .../worldedit/command/SelectionCommands.java | 32 ++++--- .../sk89q/worldedit/command/ToolCommands.java | 4 +- .../util/PropertiesConfiguration.java | 4 +- .../worldedit/util/YAMLConfiguration.java | 4 +- .../sk89q/worldedit/util/gson/GsonUtil.java | 3 + 8 files changed, 156 insertions(+), 40 deletions(-) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/BaseItemAdapter.java diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/BaseItemAdapter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/BaseItemAdapter.java new file mode 100644 index 000000000..859ed9194 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/BaseItemAdapter.java @@ -0,0 +1,61 @@ +package com.fastasyncworldedit.core.util.gson; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.sk89q.worldedit.blocks.BaseItem; +import com.sk89q.worldedit.util.concurrency.LazyReference; +import com.sk89q.worldedit.util.nbt.TagStringIO; +import com.sk89q.worldedit.world.item.ItemType; +import com.sk89q.worldedit.world.item.ItemTypes; + +import java.io.IOException; +import java.lang.reflect.Type; + +public final class BaseItemAdapter implements JsonDeserializer, JsonSerializer { + + @Override + public BaseItem deserialize(JsonElement json, Type type, JsonDeserializationContext cont) throws JsonParseException { + JsonObject jsonObject = json.getAsJsonObject(); + JsonElement id = jsonObject.get("id"); + if (id != null) { + ItemType itemType = ItemTypes.get(id.getAsString()); + if (itemType == null) { + throw new JsonParseException("Could not parse item type `" + id + "`"); + } + return new BaseItem(itemType); + } + ItemType itemType = cont.deserialize(jsonObject.get("itemType").getAsJsonObject(), ItemType.class); + JsonElement nbt = jsonObject.get("nbt"); + if (nbt == null) { + return new BaseItem(itemType); + } + try { + return new BaseItem(itemType, LazyReference.computed(TagStringIO.get().asCompound(nbt.getAsString()))); + } catch (IOException e) { + throw new JsonParseException("Could not deserialize BaseItem", e); + } + } + + @Override + public JsonElement serialize( + final BaseItem baseItem, + final Type type, + final JsonSerializationContext jsonSerializationContext + ) { + JsonObject obj = new JsonObject(); + obj.add("itemType", jsonSerializationContext.serialize(baseItem.getType())); + try { + obj.add("nbt", baseItem.getNbt() == null ? null : new JsonPrimitive(TagStringIO.get().asString(baseItem.getNbt()))); + return obj; + } catch (IOException e) { + throw new JsonParseException("Could not deserialize BaseItem", e); + } + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index 5a5fa654e..8bf84ab8b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -52,6 +52,7 @@ import com.sk89q.worldedit.command.tool.SelectionWand; import com.sk89q.worldedit.command.tool.SinglePickaxe; import com.sk89q.worldedit.command.tool.Tool; import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Locatable; import com.sk89q.worldedit.extent.NullExtent; @@ -80,7 +81,6 @@ import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.item.ItemType; -import com.sk89q.worldedit.world.item.ItemTypes; import com.sk89q.worldedit.world.snapshot.experimental.Snapshot; import com.zaxxer.sparsebits.SparseBitSet; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; @@ -182,8 +182,10 @@ public class LocalSession implements TextureHolder { private String lastScript; private RegionSelectorType defaultSelector; private boolean useServerCUI = false; // Save this to not annoy players. - private ItemType wandItem; - private ItemType navWandItem; + //FAWE start - allow NBT + private BaseItem wandItem; + private BaseItem navWandItem; + //FAWE end /** * Construct the object. @@ -1199,7 +1201,7 @@ public class LocalSession implements TextureHolder { tool = tools.get(item.getInternalId()); } if (tool == SelectionWand.INSTANCE && !SelectionWand.INSTANCE.canUse(player)) { - tools.remove(wandItem.getInternalId()); + tools.remove(wandItem.getType().getInternalId()); loadDefaults(player, true); // Permissions have changed so redo the player's current tools. return null; } @@ -1253,18 +1255,20 @@ public class LocalSession implements TextureHolder { if (loadDefaults || force) { loadDefaults = false; LocalConfiguration config = WorldEdit.getInstance().getConfiguration(); + ParserContext context = new ParserContext(); + context.setActor(actor); if (wandItem == null) { - wandItem = ItemTypes.parse(config.wandItem); + wandItem = WorldEdit.getInstance().getItemFactory().parseFromInput(config.wandItem, context); } if (navWandItem == null) { - navWandItem = ItemTypes.parse(config.navigationWand); + navWandItem = WorldEdit.getInstance().getItemFactory().parseFromInput(config.navigationWand, context); } synchronized (this.tools) { - if (tools.get(navWandItem.getInternalId()) == null && NavigationWand.INSTANCE.canUse(actor)) { - tools.put(navWandItem.getInternalId(), NavigationWand.INSTANCE); + if (tools.get(navWandItem.getType().getInternalId()) == null && NavigationWand.INSTANCE.canUse(actor)) { + tools.put(navWandItem.getType().getInternalId(), NavigationWand.INSTANCE); } - if (tools.get(wandItem.getInternalId()) == null && SelectionWand.INSTANCE.canUse(actor)) { - tools.put(wandItem.getInternalId(), SelectionWand.INSTANCE); + if (tools.get(wandItem.getType().getInternalId()) == null && SelectionWand.INSTANCE.canUse(actor)) { + tools.put(wandItem.getType().getInternalId(), SelectionWand.INSTANCE); } } } @@ -1334,10 +1338,23 @@ public class LocalSession implements TextureHolder { * @param item the item type * @param tool the tool to set, which can be {@code null} * @throws InvalidToolBindException if the item can't be bound to that item + * @deprecated use {@link #setTool(BaseItem, Tool)} */ + @Deprecated public void setTool(ItemType item, @Nullable Tool tool) throws InvalidToolBindException { - if (item.hasBlockType()) { - throw new InvalidToolBindException(item, Caption.of("worldedit.error.blocks-cant-be-used")); + setTool(new BaseItem(item), tool); + } + + /** + * Set the tool. + * + * @param item the item type + * @param tool the tool to set, which can be {@code null} + * @throws InvalidToolBindException if the item can't be bound to that item + */ + public void setTool(BaseItem item, @Nullable Tool tool) throws InvalidToolBindException { + if (item.getType().hasBlockType()) { + throw new InvalidToolBindException(item.getType(), Caption.of("worldedit.error.blocks-cant-be-used")); } if (tool instanceof SelectionWand) { changeTool(this.wandItem, this.wandItem = item, tool); @@ -1348,7 +1365,7 @@ public class LocalSession implements TextureHolder { setDirty(); return; } - setTool(item.getDefaultState(), tool, null); + setTool(item, tool, null); } public void setTool(Player player, @Nullable Tool tool) throws InvalidToolBindException { @@ -1356,17 +1373,17 @@ public class LocalSession implements TextureHolder { setTool(item, tool, player); } - private void changeTool(ItemType oldType, ItemType newType, Tool newTool) { - if (oldType != null) { + private void changeTool(BaseItem oldItem, BaseItem newItem, Tool newTool) { + if (oldItem != null) { synchronized (this.tools) { - this.tools.remove(oldType.getInternalId()); + this.tools.remove(oldItem.getType().getInternalId()); } } synchronized (this.tools) { if (newTool == null) { - this.tools.remove(newType.getInternalId()); + this.tools.remove(newItem.getType().getInternalId()); } else { - this.tools.put(newType.getInternalId(), newTool); + this.tools.put(newItem.getType().getInternalId(), newTool); } } } @@ -1376,11 +1393,11 @@ public class LocalSession implements TextureHolder { if (type.hasBlockType() && type.getBlockType().getMaterial().isAir()) { throw new InvalidToolBindException(type, Caption.of("worldedit.error.blocks-cant-be-used")); } else if (tool instanceof SelectionWand) { - changeTool(this.wandItem, this.wandItem = item.getType(), tool); + changeTool(this.wandItem, this.wandItem = item, tool); setDirty(); return; } else if (tool instanceof NavigationWand) { - changeTool(this.navWandItem, this.navWandItem = item.getType(), tool); + changeTool(this.navWandItem, this.navWandItem = item, tool); setDirty(); return; } @@ -1877,9 +1894,32 @@ public class LocalSession implements TextureHolder { * Get the preferred wand item for this user, or {@code null} to use the default * * @return item id of wand item, or {@code null} + * @deprecated use {@link #getWandBaseItem()} */ + @Deprecated public String getWandItem() { - return wandItem.getId(); + return wandItem.getType().getId(); + } + + /** + * Get the preferred navigation wand item for this user, or {@code null} to use the default + * + * @return item id of nav wand item, or {@code null} + * @deprecated use {@link #getNavWandBaseItem()} + */ + @Deprecated + public String getNavWandItem() { + return navWandItem.getType().getId(); + } + + //FAWE start + /** + * Get the preferred wand item for this user, or {@code null} to use the default + * + * @return item id of wand item, or {@code null} + */ + public BaseItem getWandBaseItem() { + return wandItem == null ? null : new BaseItem(wandItem.getType(), wandItem.getNbtReference()); } /** @@ -1887,9 +1927,10 @@ public class LocalSession implements TextureHolder { * * @return item id of nav wand item, or {@code null} */ - public String getNavWandItem() { - return navWandItem.getId(); + public BaseItem getNavWandBaseItem() { + return navWandItem == null ? null : new BaseItem(navWandItem.getType(), navWandItem.getNbtReference()); } + //FAWE end /** * Get the last block distribution stored in this session. diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java index 1dab627c7..ac8236297 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java @@ -71,6 +71,7 @@ public class BaseItem implements NbtValued { * @param itemType The type to set */ public void setType(ItemType itemType) { + checkNotNull(itemType); this.itemType = itemType; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index d8e0943dc..ac13defc3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -30,6 +30,7 @@ import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.command.argument.SelectorChoice; import com.sk89q.worldedit.command.tool.NavigationWand; @@ -38,6 +39,8 @@ import com.sk89q.worldedit.command.util.CommandPermissions; import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator; import com.sk89q.worldedit.command.util.Logging; import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Locatable; import com.sk89q.worldedit.extension.platform.permission.ActorSelectorLimits; @@ -325,22 +328,29 @@ public class SelectionCommands { //FAWE start session.loadDefaults(player, true); //FAWE end - String wandId = navWand ? session.getNavWandItem() : session.getWandItem(); - if (wandId == null) { - wandId = navWand ? we.getConfiguration().navigationWand : we.getConfiguration().wandItem; + BaseItem wand = navWand ? session.getNavWandBaseItem() : session.getWandBaseItem(); + if (wand == null) { + String wandId = navWand ? we.getConfiguration().navigationWand : we.getConfiguration().wandItem; + //FAWE start - allow item NBT + ParserContext parserContext = new ParserContext(); + parserContext.setActor(player); + parserContext.setSession(session); + try { + wand = WorldEdit.getInstance().getItemFactory().parseFromInput(wandId, parserContext); + } catch (InputParseException e) { + player.print(Caption.of("worldedit.wand.invalid")); + return; + } } - ItemType itemType = ItemTypes.parse(wandId); - if (itemType == null) { - player.print(Caption.of("worldedit.wand.invalid")); - return; - } - player.giveItem(new BaseItemStack(itemType, 1)); + System.out.println("a "+ wand); + player.giveItem(new BaseItemStack(wand.getType(), wand.getNbtReference(), 1)); + //FAWE end //FAWE start - instance-iate session if (navWand) { - session.setTool(itemType, NavigationWand.INSTANCE); + session.setTool(wand, NavigationWand.INSTANCE); player.print(Caption.of("worldedit.wand.navwand.info")); } else { - session.setTool(itemType, SelectionWand.INSTANCE); + session.setTool(wand, SelectionWand.INSTANCE); player.print(Caption.of("worldedit.wand.selwand.info")); //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java index 95499372c..f3be41469 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ToolCommands.java @@ -149,7 +149,7 @@ public class ToolCommands { throws InvalidToolBindException { //FAWE start isBrush = session.getTool(player) instanceof BrushTool; - session.setTool(player.getItemInHand(HandSide.MAIN_HAND).getType(), null); + session.setTool(player.getItemInHand(HandSide.MAIN_HAND), null); //FAWE end player.print(Caption.of(isBrush ? "worldedit.brush.none.equip" : "worldedit.tool.none.equip")); } @@ -163,7 +163,7 @@ public class ToolCommands { String translationKey ) throws InvalidToolBindException { BaseItemStack itemStack = player.getItemInHand(HandSide.MAIN_HAND); - session.setTool(itemStack.getType(), tool); + session.setTool(itemStack, tool); player.print(Caption.of(translationKey, itemStack.getRichName())); sendUnbindInstruction(player, UNBIND_COMMAND_COMPONENT); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java index 3804be8d3..7bec7c2f5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java @@ -112,7 +112,7 @@ public class PropertiesConfiguration extends LocalConfiguration { logFile = getString("log-file", logFile); logFormat = getString("log-format", logFormat); registerHelp = getBool("register-help", registerHelp); - wandItem = getString("wand-item", wandItem).toLowerCase(Locale.ROOT); + wandItem = getString("wand-item", wandItem); try { wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId(); } catch (Throwable ignored) { @@ -122,7 +122,7 @@ public class PropertiesConfiguration extends LocalConfiguration { useInventory = getBool("use-inventory", useInventory); useInventoryOverride = getBool("use-inventory-override", useInventoryOverride); useInventoryCreativeOverride = getBool("use-inventory-creative-override", useInventoryCreativeOverride); - navigationWand = getString("nav-wand-item", navigationWand).toLowerCase(Locale.ROOT); + navigationWand = getString("nav-wand-item", navigationWand); try { navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId(); } catch (Throwable ignored) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java index 7b0cbf4b8..4a5e45713 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java @@ -58,7 +58,7 @@ public class YAMLConfiguration extends LocalConfiguration { profile = config.getBoolean("debug", profile); traceUnflushedSessions = config.getBoolean("debugging.trace-unflushed-sessions", traceUnflushedSessions); - wandItem = convertLegacyItem(config.getString("wand-item", wandItem)).toLowerCase(Locale.ROOT); + wandItem = convertLegacyItem(config.getString("wand-item", wandItem)); defaultChangeLimit = Math.max(-1, config.getInt( "limits.max-blocks-changed.default", defaultChangeLimit)); @@ -130,7 +130,7 @@ public class YAMLConfiguration extends LocalConfiguration { useInventoryCreativeOverride ); - navigationWand = convertLegacyItem(config.getString("navigation-wand.item", navigationWand)).toLowerCase(Locale.ROOT); + navigationWand = convertLegacyItem(config.getString("navigation-wand.item", navigationWand)); navigationWandMaxDistance = config.getInt("navigation-wand.max-distance", navigationWandMaxDistance); navigationUseGlass = config.getBoolean("navigation.use-glass", navigationUseGlass); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java index e5d05ee6d..416fbeaae 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/gson/GsonUtil.java @@ -19,10 +19,12 @@ package com.sk89q.worldedit.util.gson; +import com.fastasyncworldedit.core.util.gson.BaseItemAdapter; import com.fastasyncworldedit.core.util.gson.ItemTypeAdapter; import com.fastasyncworldedit.core.util.gson.RegionSelectorAdapter; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.regions.RegionSelector; @@ -48,6 +50,7 @@ public final class GsonUtil { //FAWE start gsonBuilder.registerTypeAdapter(RegionSelector.class, new RegionSelectorAdapter()); gsonBuilder.registerTypeAdapter(ItemType.class, new ItemTypeAdapter()); + gsonBuilder.registerTypeAdapter(BaseItem.class, new BaseItemAdapter()); //FAWE end return gsonBuilder; } From 47b0ece3777ae13564575cc6569ed2c34cac40d4 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sun, 2 Jun 2024 09:27:56 +0100 Subject: [PATCH 150/220] Add since tags to new methods --- .../src/main/java/com/sk89q/worldedit/LocalSession.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index 8bf84ab8b..5df95414b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -1351,6 +1351,7 @@ public class LocalSession implements TextureHolder { * @param item the item type * @param tool the tool to set, which can be {@code null} * @throws InvalidToolBindException if the item can't be bound to that item + * @since TODO */ public void setTool(BaseItem item, @Nullable Tool tool) throws InvalidToolBindException { if (item.getType().hasBlockType()) { @@ -1917,6 +1918,7 @@ public class LocalSession implements TextureHolder { * Get the preferred wand item for this user, or {@code null} to use the default * * @return item id of wand item, or {@code null} + * @since TODO */ public BaseItem getWandBaseItem() { return wandItem == null ? null : new BaseItem(wandItem.getType(), wandItem.getNbtReference()); @@ -1926,6 +1928,7 @@ public class LocalSession implements TextureHolder { * Get the preferred navigation wand item for this user, or {@code null} to use the default * * @return item id of nav wand item, or {@code null} + * @since TODO */ public BaseItem getNavWandBaseItem() { return navWandItem == null ? null : new BaseItem(navWandItem.getType(), navWandItem.getNbtReference()); From a7e4d19605484b7eb3f2619ea270114be8fa56cf Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sun, 2 Jun 2024 17:25:32 +0100 Subject: [PATCH 151/220] Remove debug --- .../main/java/com/sk89q/worldedit/command/SelectionCommands.java | 1 - 1 file changed, 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index ac13defc3..d000fcef7 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -342,7 +342,6 @@ public class SelectionCommands { return; } } - System.out.println("a "+ wand); player.giveItem(new BaseItemStack(wand.getType(), wand.getNbtReference(), 1)); //FAWE end //FAWE start - instance-iate session From 5714a526756e1819b1598f31211e26b48cdd217d Mon Sep 17 00:00:00 2001 From: Jordan Date: Wed, 5 Jun 2024 21:23:12 +0200 Subject: [PATCH 152/220] fix: correctly trim the max chunk section (#2753) - fixes #2727 - fixes IntellectualSites/Plotsquared#4436 --- .../regions/plotsquared/PlotSquaredFeature.java | 14 ++++++-------- .../core/queue/IBatchProcessor.java | 12 ++++-------- .../com/sk89q/worldedit/regions/CuboidRegion.java | 4 ++-- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/PlotSquaredFeature.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/PlotSquaredFeature.java index 9f0916a4b..49955a4fa 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/PlotSquaredFeature.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/PlotSquaredFeature.java @@ -1,6 +1,5 @@ package com.fastasyncworldedit.bukkit.regions.plotsquared; -import com.fastasyncworldedit.core.FaweAPI; import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.regions.FaweMask; import com.fastasyncworldedit.core.regions.FaweMaskManager; @@ -174,22 +173,21 @@ public class PlotSquaredFeature extends FaweMaskManager { return null; } + final World world = player.getWorld(); + int min = area != null ? area.getMinBuildHeight() : world.getMinY(); + // PlotSquared uses exclusive max height, WorldEdit uses inclusive max height -> subtract 1 + int max = area != null ? Math.min(world.getMaxY(), area.getMaxBuildHeight() - 1) : world.getMaxY(); Region maskedRegion; if (regions.size() == 1) { - final World world = player.getWorld(); - int min = area != null ? area.getMinBuildHeight() : world.getMinY(); - // PlotSquared uses exclusive max height, WorldEdit uses inclusive max height -> subtract 1 - int max = area != null ? Math.min(world.getMaxY(), area.getMaxBuildHeight() - 1) : world.getMaxY(); final CuboidRegion region = regions.iterator().next(); final BlockVector3 pos1 = BlockVector3.at(region.getMinimumX(), min, region.getMinimumZ()); final BlockVector3 pos2 = BlockVector3.at(region.getMaximumX(), max, region.getMaximumZ()); maskedRegion = new CuboidRegion(pos1, pos2); } else { - World world = FaweAPI.getWorld(area.getWorldName()); List weRegions = regions.stream().map( - r -> new CuboidRegion(world, BlockVector3.at(r.getMinimumX(), r.getMinimumY(), r.getMinimumZ()), - BlockVector3.at(r.getMaximumX(), r.getMaximumY(), r.getMaximumZ()) + r -> new CuboidRegion(world, BlockVector3.at(r.getMinimumX(), min, r.getMinimumZ()), + BlockVector3.at(r.getMaximumX(), max, r.getMaximumZ()) )).collect(Collectors.toList()); maskedRegion = new RegionIntersection(world, weRegions); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java index 778f85ce4..4ba91a4f3 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java @@ -58,7 +58,7 @@ public interface IBatchProcessor { /** * Utility method to trim a chunk based on min and max Y (inclusive). * - * @param keepInsideRange if all blocks inside the range (inclusive) should be kept (default) + * @param keepInsideRange if all blocks inside the range (inclusive) should be kept (default), or removed * @return false if chunk is empty of blocks */ default boolean trimY(IChunkSet set, int minY, int maxY, final boolean keepInsideRange) { @@ -74,16 +74,14 @@ public interface IBatchProcessor { for (int i = 0; i < index; i++) { arr[i] = BlockTypesCache.ReservedIDs.__RESERVED__; } - } else { - arr = new char[4096]; + set.setBlocks(layer, arr); } - set.setBlocks(layer, arr); } else { set.setBlocks(layer, null); } } } - for (int layer = maxLayer; layer < set.getMaxSectionPosition(); layer++) { + for (int layer = maxLayer; layer <= set.getMaxSectionPosition(); layer++) { if (set.hasSection(layer)) { if (layer == maxLayer) { char[] arr = set.loadIfPresent(layer); @@ -92,10 +90,8 @@ public interface IBatchProcessor { for (int i = index; i < arr.length; i++) { arr[i] = BlockTypesCache.ReservedIDs.__RESERVED__; } - } else { - arr = new char[4096]; + set.setBlocks(layer, arr); } - set.setBlocks(layer, arr); } else { set.setBlocks(layer, null); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java index 8616cbb2b..8e4da9214 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java @@ -828,7 +828,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { return set; } - for (int layer = get.getMinSectionPosition(); layer < get.getMaxSectionPosition(); layer++) { + for (int layer = get.getMinSectionPosition(); layer <= get.getMaxSectionPosition(); layer++) { if (!set.hasSection(layer)) { continue; } @@ -912,7 +912,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { boolean trimX = lowerX != 0 || upperX != 15; boolean trimZ = lowerZ != 0 || upperZ != 15; - for (int layer = get.getMinSectionPosition(); layer < get.getMaxSectionPosition(); layer++) { + for (int layer = get.getMinSectionPosition(); layer <= get.getMaxSectionPosition(); layer++) { if (!set.hasSection(layer)) { continue; } From c095c492e0264fc19a9d6f453183adf0f9f3f2e7 Mon Sep 17 00:00:00 2001 From: EpicPlayerA10 <62206933+EpicPlayerA10@users.noreply.github.com> Date: Fri, 7 Jun 2024 12:30:31 +0200 Subject: [PATCH 153/220] fix: normalize layer when setting ordinal to ThreadUnsafeCharBlocks (#2764) - fixes #2763 --- .../queue/implementation/blocks/ThreadUnsafeCharBlocks.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeCharBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeCharBlocks.java index 54331279f..90ae6b32e 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeCharBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeCharBlocks.java @@ -222,7 +222,7 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks { } public void set(int x, int y, int z, char value) { - final int layer = y >> 4; + final int layer = (y >> 4) - minSectionPosition; final int index = (y & 15) << 8 | z << 4 | x; try { blocks[layer][index] = value; From ee5d1caa2c568ee40eecc9523453bb132265cfab Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Sat, 8 Jun 2024 10:07:05 +0200 Subject: [PATCH 154/220] Fix more upstream incompatibilities (#2767) * Move more public types to records (cherry picked from commit 35e58895f5379e78b856e8997a593701c6d9db21) * chore: pull in PlacementType * fix: mask reference in NegatedMask * Use records in expression impl (cherry picked from commit 453537c5b4783412aa1b4e982d7b72c637d0db8e) * fix: variable record getter access * chore: add since to Deprecated annotation * chore: revert weird merge in ClientProxy * chore: cleanup remaining deprecations * chore: code-style --------- Co-authored-by: Octavia Togami --- .../java/com/sk89q/worldedit/EditSession.java | 10 +- .../io/share/ClipboardShareMetadata.java | 27 +--- .../worldedit/function/factory/Deform.java | 26 ++-- .../sk89q/worldedit/function/mask/Mask.java | 2 +- .../sk89q/worldedit/function/mask/Masks.java | 18 +-- .../history/change/BiomeChange3D.java | 24 ++-- .../worldedit/history/change/BlockChange.java | 30 +++-- .../exception/ExceptionConverterHelper.java | 14 +-- .../internal/event/InteractionDebouncer.java | 9 +- .../internal/expression/ExecutionData.java | 27 ++-- .../internal/expression/ExpressionHelper.java | 26 ++-- .../internal/expression/Functions.java | 12 +- .../internal/expression/LocalSlot.java | 19 +-- .../internal/expression/SlotTable.java | 2 +- .../expression/invoke/CompilingVisitor.java | 22 ++-- .../internal/expression/invoke/ExecNode.java | 13 +- .../expression/invoke/ExpressionHandles.java | 26 ++-- .../com/sk89q/worldedit/registry/Keyed.java | 22 +++- .../sk89q/worldedit/session/Placement.java | 52 ++++++++ .../worldedit/session/PlacementType.java | 119 ++++++++++++++++++ .../sk89q/worldedit/util/LocatedBlock.java | 48 +++---- .../worldedit/util/report/DataReport.java | 11 +- .../worldedit/world/biome/BiomeType.java | 25 ++-- .../worldedit/world/entity/EntityType.java | 30 ++++- .../worldedit/world/fluid/FluidType.java | 20 ++- .../worldedit/world/gamemode/GameMode.java | 28 +---- .../world/registry/ItemMaterial.java | 37 +++++- .../registry/PassthroughItemMaterial.java | 8 +- .../world/registry/SimpleItemMaterial.java | 20 +-- .../worldedit/world/weather/WeatherType.java | 29 +---- 30 files changed, 435 insertions(+), 321 deletions(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/session/Placement.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/session/PlacementType.java diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index 2e5e3c2ef..1469ffb96 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -3082,8 +3082,8 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { ) <= 0) { return null; } - int newType = (int) typeVariable.getValue(); - int newData = (int) dataVariable.getValue(); + int newType = (int) typeVariable.value(); + int newData = (int) dataVariable.value(); if (newType != typeVar || newData != dataVar) { BlockState state = LegacyMapper.getInstance().getBlockFromLegacy(newType, newData); return state == null ? defaultMaterial : state.toBaseBlock(); @@ -3181,9 +3181,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { // transform expression.evaluate(new double[]{scaled.x(), scaled.y(), scaled.z()}, timeout); - int xv = (int) Math.floor(x.getValue() * unit.x() + zero2.x()); - int yv = (int) Math.floor(y.getValue() * unit.y() + zero2.y()); - int zv = (int) Math.floor(z.getValue() * unit.z() + zero2.z()); + int xv = (int) Math.floor(x.value() * unit.x() + zero2.x()); + int yv = (int) Math.floor(y.value() * unit.y() + zero2.y()); + int zv = (int) Math.floor(z.value() * unit.z() + zero2.z()); BlockState get; if (yv >= minY && yv <= maxY) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareMetadata.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareMetadata.java index 2e5f6c042..a670ea7cc 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareMetadata.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/ClipboardShareMetadata.java @@ -23,27 +23,10 @@ import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat; /** * Items of metadata about shared clipboards. + * + * @param format the format of the clipboard + * @param name the name of the clipboard + * @param author the author of the clipboard */ -public class ClipboardShareMetadata { - private final ClipboardFormat format; - private final String name; - private final String author; - - public ClipboardShareMetadata(ClipboardFormat format, String name, String author) { - this.format = format; - this.name = name; - this.author = author; - } - - public ClipboardFormat format() { - return this.format; - } - - public String name() { - return this.name; - } - - public String author() { - return this.author; - } +public record ClipboardShareMetadata(ClipboardFormat format, String name, String author) { } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/Deform.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/Deform.java index b4ccd0a55..6dea78892 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/Deform.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/factory/Deform.java @@ -167,24 +167,14 @@ public class Deform implements Contextual { ); } - private static final class DeformOperation implements Operation { - - private final Extent destination; - private final Region region; - private final Vector3 zero; - private final Vector3 unit; - private final String expression; - private final int timeout; - - private DeformOperation(Extent destination, Region region, Vector3 zero, Vector3 unit, String expression, int timeout) { - this.destination = destination; - this.region = region; - this.zero = zero; - this.unit = unit; - this.expression = expression; - this.timeout = timeout; - } - + private record DeformOperation( + Extent destination, + Region region, + Vector3 zero, + Vector3 unit, + String expression, //FAWE: Expression -> String + int timeout + ) implements Operation { @Override public Operation resume(RunContext run) throws WorldEditException { try { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Mask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Mask.java index 3c4cb1378..94141278d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Mask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Mask.java @@ -87,7 +87,7 @@ public interface Mask { } else if (this instanceof Masks.AlwaysFalse) { return Masks.ALWAYS_TRUE; } else if (this instanceof Masks.NegatedMask) { - return ((Masks.NegatedMask) this).mask; + return ((Masks.NegatedMask) this).mask(); } return new InverseMask(this); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Masks.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Masks.java index d3cb4cad7..478d2732a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Masks.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/Masks.java @@ -211,15 +211,7 @@ public final class Masks { } - //FAWE start - protected > private - protected static class NegatedMask implements Mask { - - //FAWE end - protected final Mask mask; - - private NegatedMask(Mask mask) { - this.mask = mask; - } + protected record NegatedMask(Mask mask) implements Mask { @Override public boolean test(BlockVector3 vector) { @@ -245,13 +237,7 @@ public final class Masks { } - private static class NegatedMask2D implements Mask2D { - - private final Mask2D mask; - - private NegatedMask2D(Mask2D mask) { - this.mask = mask; - } + private record NegatedMask2D(Mask2D mask) implements Mask2D { @Override public boolean test(BlockVector2 vector) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BiomeChange3D.java b/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BiomeChange3D.java index 74a16e90e..1106899f8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BiomeChange3D.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BiomeChange3D.java @@ -33,34 +33,30 @@ import static com.google.common.base.Preconditions.checkNotNull; *

    This biome change does not have an {@link Extent} assigned to it because * one will be taken from the passed {@link UndoContext}. If the context * does not have an extent (it is null), cryptic errors may occur.

    + * + * @param position the position + * @param previous the previous biome + * @param current the current biome */ -public class BiomeChange3D implements Change { - - private final BlockVector3 position; - private final BiomeType previous; - private final BiomeType current; +public record BiomeChange3D(BlockVector3 position, BiomeType previous, BiomeType current) implements Change { /** * Create a new biome change. * - * @param position the position - * @param previous the previous biome - * @param current the current biome */ - public BiomeChange3D(BlockVector3 position, BiomeType previous, BiomeType current) { + public BiomeChange3D { checkNotNull(position); checkNotNull(previous); checkNotNull(current); - this.position = position; - this.previous = previous; - this.current = current; } /** * Get the position. * * @return the position + * @deprecated Use {@link #position()}. */ + @Deprecated(forRemoval = true, since = "TODO") public BlockVector3 getPosition() { return position; } @@ -69,7 +65,9 @@ public class BiomeChange3D implements Change { * Get the previous biome. * * @return the previous biome + * @deprecated Use {@link #previous()}. */ + @Deprecated(forRemoval = true, since = "TODO") public BiomeType getPrevious() { return previous; } @@ -78,7 +76,9 @@ public class BiomeChange3D implements Change { * Get the current biome. * * @return the current biome + * @deprecated Use {@link #current()}. */ + @Deprecated(forRemoval = true, since = "TODO") public BiomeType getCurrent() { return current; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BlockChange.java b/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BlockChange.java index ec9bb104d..16fc50e0d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BlockChange.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BlockChange.java @@ -34,12 +34,21 @@ import static com.google.common.base.Preconditions.checkNotNull; *

    This block change does not have an {@link Extent} assigned to it because * one will be taken from the passed {@link UndoContext}. If the context * does not have an extent (it is null), cryptic errors may occur.

    + * + * @param position the position + * @param previous the previous block + * @param current the current block */ -public class BlockChange implements Change { +public record BlockChange(BlockVector3 position, BaseBlock previous, BaseBlock current) implements Change { - private final BlockVector3 position; - private final BaseBlock previous; - private final BaseBlock current; + /** + * Create a new block change. + */ + public BlockChange { + checkNotNull(position); + checkNotNull(previous); + checkNotNull(current); + } /** * Create a new block change. @@ -53,19 +62,16 @@ public class BlockChange implements Change { BP previous, BC current ) { - checkNotNull(position); - checkNotNull(previous); - checkNotNull(current); - this.position = position; - this.previous = previous.toBaseBlock(); - this.current = current.toBaseBlock(); + this(position, previous.toBaseBlock(), current.toBaseBlock()); } /** * Get the position. * * @return the position + * @deprecated use {@link #position()} */ + @Deprecated(forRemoval = true, since = "TODO") public BlockVector3 getPosition() { return position; } @@ -74,7 +80,9 @@ public class BlockChange implements Change { * Get the previous block. * * @return the previous block + * @deprecated use {@link #previous()} */ + @Deprecated(forRemoval = true, since = "TODO") public BaseBlock getPrevious() { return previous; } @@ -83,7 +91,9 @@ public class BlockChange implements Change { * Get the current block. * * @return the current block + * @deprecated use {@link #current()} */ + @Deprecated(forRemoval = true, since = "TODO") public BaseBlock getCurrent() { return current; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/ExceptionConverterHelper.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/ExceptionConverterHelper.java index 73f76280e..64e78250a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/ExceptionConverterHelper.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/ExceptionConverterHelper.java @@ -87,16 +87,10 @@ public abstract class ExceptionConverterHelper implements ExceptionConverter { } } - private static class ExceptionHandler implements Comparable { - - final Class cls; - final Method method; - - private ExceptionHandler(Class cls, Method method) { - this.cls = cls; - this.method = method; - } - + private record ExceptionHandler( + Class cls, + Method method + ) implements Comparable { @Override public int compareTo(ExceptionHandler o) { if (cls.equals(o.cls)) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/event/InteractionDebouncer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/event/InteractionDebouncer.java index b33570cd9..37e9442b7 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/event/InteractionDebouncer.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/event/InteractionDebouncer.java @@ -57,13 +57,6 @@ public class InteractionDebouncer { return Optional.empty(); } - private static class Interaction { - public final long tick; - public final boolean result; - - public Interaction(long tick, boolean result) { - this.tick = tick; - this.result = result; - } + private record Interaction(long tick, boolean result) { } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/ExecutionData.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/ExecutionData.java index 1fef5aa81..bcf04b907 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/ExecutionData.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/ExecutionData.java @@ -23,36 +23,23 @@ import java.time.Instant; import static java.util.Objects.requireNonNull; -public class ExecutionData { - +public record ExecutionData(SlotTable slots, Functions functions, Instant deadline) { /** - * Special execution context for evaluating constant values. As long as no variables are used, - * it can be considered constant. + * Special execution context for evaluating constant values. As long as no variables are used, it can be considered + * constant. */ public static final ExecutionData CONSTANT_EVALUATOR = new ExecutionData(null, null, Instant.MAX); - private final SlotTable slots; - private final Functions functions; - private final Instant deadline; - - public ExecutionData(SlotTable slots, Functions functions, Instant deadline) { - this.slots = slots; - this.functions = functions; - this.deadline = deadline; - } - - public SlotTable getSlots() { + @Override + public SlotTable slots() { return requireNonNull(slots, "Cannot use variables in a constant"); } - public Functions getFunctions() { + @Override + public Functions functions() { return requireNonNull(functions, "Cannot use functions in a constant"); } - public Instant getDeadline() { - return deadline; - } - public void checkDeadline() { if (Instant.now().isAfter(deadline)) { throw new ExpressionTimeoutException("Calculations exceeded time limit."); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/ExpressionHelper.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/ExpressionHelper.java index 0afeb6dd3..0521c0a50 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/ExpressionHelper.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/ExpressionHelper.java @@ -40,6 +40,12 @@ public class ExpressionHelper { } } + public static void check(boolean condition, int positionInLine, String message) { + if (!condition) { + throw evalException(positionInLine, message); + } + } + public static int getErrorPosition(Token token) { return token.getCharPositionInLine(); } @@ -49,14 +55,18 @@ public class ExpressionHelper { } public static EvaluationException evalException(Token token, String message) { + return evalException(getErrorPosition(token), message); + } + + public static EvaluationException evalException(int positionInLine, String message) { return new EvaluationException( - getErrorPosition(token), - message + positionInLine, + message ); } - public static void checkIterations(int iterations, ParserRuleContext ctx) { - check(iterations <= 256, ctx, "Loop exceeded 256 iterations"); + public static void checkIterations(int iterations, int positionInLine) { + check(iterations <= 256, positionInLine, "Loop exceeded 256 iterations"); } public static MethodHandle resolveFunction( @@ -72,10 +82,10 @@ public class ExpressionHelper { // last param is the array, turn that varargs int keptParams = nParams - 1; function = function.asCollector( - // collect into the last array - function.type().parameterType(nParams - 1), - // collect the variable args (args over kept) - ctx.args.size() - keptParams + // collect into the last array + function.type().parameterType(nParams - 1), + // collect the variable args (args over kept) + ctx.args.size() - keptParams ); // re-wrap it for the inner arguments function = function.asType(function.type().wrap()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Functions.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Functions.java index 6f3a63787..ef219e3f8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Functions.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/Functions.java @@ -211,8 +211,8 @@ public final class Functions { final double cosF = Math.cos(angle); final double sinF = Math.sin(angle); - final double xOld = x.getValue(); - final double yOld = y.getValue(); + final double xOld = x.value(); + final double yOld = y.value(); x.setValue(xOld * cosF - yOld * sinF); y.setValue(xOld * sinF + yOld * cosF); @@ -221,9 +221,9 @@ public final class Functions { } private static double swap(Variable x, Variable y) { - final double tmp = x.getValue(); + final double tmp = x.value(); - x.setValue(y.getValue()); + x.setValue(y.value()); y.setValue(tmp); return 0.0; @@ -391,8 +391,8 @@ public final class Functions { private static double queryInternal(LocalSlot type, LocalSlot data, double typeId, double dataValue) { // Compare to input values and determine return value // -1 is a wildcard, always true - double ret = ((type.getValue() == -1 || typeId == type.getValue()) - && (data.getValue() == -1 || dataValue == data.getValue())) ? 1.0 : 0.0; + double ret = ((type.value() == -1 || typeId == type.value()) + && (data.value() == -1 || dataValue == data.value())) ? 1.0 : 0.0; if (type instanceof Variable) { ((Variable) type).setValue(typeId); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/LocalSlot.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/LocalSlot.java index 2b02fa036..0b2a5bc48 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/LocalSlot.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/LocalSlot.java @@ -24,19 +24,7 @@ package com.sk89q.worldedit.internal.expression; */ public interface LocalSlot { - final class Constant implements LocalSlot { - - private final double value; - - public Constant(double value) { - this.value = value; - } - - @Override - public double getValue() { - return value; - } - + record Constant(double value) implements LocalSlot { @Override public String toString() { return String.valueOf(value); @@ -57,7 +45,7 @@ public interface LocalSlot { } @Override - public double getValue() { + public double value() { return value; } @@ -65,9 +53,8 @@ public interface LocalSlot { public String toString() { return String.valueOf(value); } - } - double getValue(); + double value(); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/SlotTable.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/SlotTable.java index a94c9dc62..e7090f461 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/SlotTable.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/SlotTable.java @@ -58,7 +58,7 @@ public class SlotTable { public OptionalDouble getSlotValue(String name) { LocalSlot slot = slots.get(name); - return slot == null ? OptionalDouble.empty() : OptionalDouble.of(slot.getValue()); + return slot == null ? OptionalDouble.empty() : OptionalDouble.of(slot.value()); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/invoke/CompilingVisitor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/invoke/CompilingVisitor.java index 7645c8413..0c6e87810 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/invoke/CompilingVisitor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/invoke/CompilingVisitor.java @@ -106,7 +106,7 @@ class CompilingVisitor extends ExpressionBaseVisitor { if (ctx.parent instanceof ParserRuleContext) { checkHandle(mh, (ParserRuleContext) ctx.parent); } - return new ExecNode(ctx, mh); + return new ExecNode(ctx.start.getCharPositionInLine(), mh); } private void checkHandle(MethodHandle mh, ParserRuleContext ctx) { @@ -127,7 +127,7 @@ class CompilingVisitor extends ExpressionBaseVisitor { MethodHandles.identity(Double.class) ); // now pass `result` into `guard` - MethodHandle result = evaluate(ctx).handle; + MethodHandle result = evaluate(ctx).handle(); return MethodHandles.collectArguments(guard, 0, result); } @@ -151,8 +151,8 @@ class CompilingVisitor extends ExpressionBaseVisitor { // easiest one of the bunch return MethodHandles.guardWithTest( evaluateBoolean(condition), - trueBranch == null ? NULL_DOUBLE : evaluate(trueBranch).handle, - falseBranch == null ? NULL_DOUBLE : evaluate(falseBranch).handle + trueBranch == null ? NULL_DOUBLE : evaluate(trueBranch).handle(), + falseBranch == null ? NULL_DOUBLE : evaluate(falseBranch).handle() ); } @@ -185,10 +185,10 @@ class CompilingVisitor extends ExpressionBaseVisitor { @Override public MethodHandle visitForStatement(ExpressionParser.ForStatementContext ctx) { return ExpressionHandles.forLoop( - evaluate(ctx.init).handle, + evaluate(ctx.init).handle(), evaluateBoolean(ctx.condition), evaluate(ctx.body), - evaluate(ctx.update).handle + evaluate(ctx.update).handle() ); } @@ -235,7 +235,7 @@ class CompilingVisitor extends ExpressionBaseVisitor { RETURN_STATEMENT_BASE, 0, // map the Double back to ExecutionData via the returnValue - evaluate(ctx.value).handle + evaluate(ctx.value).handle() ); } @@ -262,7 +262,7 @@ class CompilingVisitor extends ExpressionBaseVisitor { @Override public MethodHandle visitExpressionStatement(ExpressionParser.ExpressionStatementContext ctx) { - return evaluate(ctx.expression()).handle; + return evaluate(ctx.expression()).handle(); } @Override @@ -271,7 +271,7 @@ class CompilingVisitor extends ExpressionBaseVisitor { int opType = ctx.op.getType(); return ExpressionHandles.call(data -> { LocalSlot.Variable variable = ExpressionHandles.getVariable(data, target); - double value = variable.getValue(); + double value = variable.value(); double result = value; if (opType == INCREMENT) { value++; @@ -289,7 +289,7 @@ class CompilingVisitor extends ExpressionBaseVisitor { int opType = ctx.op.getType(); return ExpressionHandles.call(data -> { LocalSlot.Variable variable = ExpressionHandles.getVariable(data, target); - double value = variable.getValue(); + double value = variable.value(); if (opType == INCREMENT) { value++; } else { @@ -547,7 +547,7 @@ class CompilingVisitor extends ExpressionBaseVisitor { value = arg; } else { variable = ExpressionHandles.getVariable(data, target); - value = variable.getValue(); + value = variable.value(); switch (type) { case POWER_ASSIGN: value = Math.pow(value, arg); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/invoke/ExecNode.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/invoke/ExecNode.java index 6c53a13e5..86a944f03 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/invoke/ExecNode.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/invoke/ExecNode.java @@ -19,18 +19,7 @@ package com.sk89q.worldedit.internal.expression.invoke; -import org.antlr.v4.runtime.ParserRuleContext; - import java.lang.invoke.MethodHandle; -class ExecNode { - - final ParserRuleContext ctx; - final MethodHandle handle; - - ExecNode(ParserRuleContext ctx, MethodHandle handle) { - this.ctx = ctx; - this.handle = handle; - } - +record ExecNode(int positionInLine, MethodHandle handle) { } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/invoke/ExpressionHandles.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/invoke/ExpressionHandles.java index a2d0ad483..dab0be01b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/invoke/ExpressionHandles.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/expression/invoke/ExpressionHandles.java @@ -200,7 +200,7 @@ class ExpressionHandles { static LocalSlot.Variable initVariable(ExecutionData data, Token nameToken) { String name = nameToken.getText(); - return data.getSlots().initVariable(name) + return data.slots().initVariable(name) .orElseThrow(() -> ExpressionHelper.evalException( nameToken, "Cannot overwrite non-variable '" + name + "'" )); @@ -218,7 +218,7 @@ class ExpressionHandles { static LocalSlot.Variable getVariable(ExecutionData data, Token nameToken) { String name = nameToken.getText(); - LocalSlot slot = data.getSlots().getSlot(name) + LocalSlot slot = data.slots().getSlot(name) .orElseThrow(varNotInitException(nameToken)); if (!(slot instanceof LocalSlot.Variable)) { throw ExpressionHelper.evalException( @@ -230,7 +230,7 @@ class ExpressionHandles { static double getSlotValue(ExecutionData data, Token nameToken) { String name = nameToken.getText(); - return data.getSlots().getSlotValue(name) + return data.slots().getSlotValue(name) .orElseThrow(varNotInitException(nameToken)); } @@ -302,11 +302,11 @@ class ExpressionHandles { standardInvoke(init, data); } while ((boolean) standardInvoke(condition, data)) { - checkIterations(iterations, body.ctx); + checkIterations(iterations, body.positionInLine()); data.checkDeadline(); iterations++; try { - result = (Double) standardInvoke(body.handle, data); + result = (Double) standardInvoke(body.handle(), data); } catch (BreakException ex) { if (!ex.doContinue) { break; @@ -331,11 +331,11 @@ class ExpressionHandles { Double result = null; int iterations = 0; do { - checkIterations(iterations, body.ctx); + checkIterations(iterations, body.positionInLine()); data.checkDeadline(); iterations++; try { - result = (Double) standardInvoke(body.handle, data); + result = (Double) standardInvoke(body.handle(), data); } catch (BreakException ex) { if (!ex.doContinue) { break; @@ -369,12 +369,12 @@ class ExpressionHandles { double last = (double) standardInvoke(getLast, data); LocalSlot.Variable variable = initVariable(data, counterToken); for (double i = first; i <= last; i++) { - checkIterations(iterations, body.ctx); + checkIterations(iterations, body.positionInLine()); data.checkDeadline(); iterations++; variable.setValue(i); try { - result = (Double) standardInvoke(body.handle, data); + result = (Double) standardInvoke(body.handle(), data); } catch (BreakException ex) { if (!ex.doContinue) { break; @@ -406,10 +406,10 @@ class ExpressionHandles { if (falling || entry.getDoubleKey() == value) { matched = true; try { - evaluated = (Double) standardInvoke(entry.getValue().handle, data); + evaluated = (Double) standardInvoke(entry.getValue().handle(), data); falling = true; } catch (BreakException brk) { - check(!brk.doContinue, entry.getValue().ctx, "Cannot continue in a switch"); + check(!brk.doContinue, entry.getValue().positionInLine(), "Cannot continue in a switch"); falling = false; break; } @@ -418,9 +418,9 @@ class ExpressionHandles { // This if is like the one in the loop, default's "case" is `!matched` & present if ((falling || !matched) && defaultCase != null) { try { - evaluated = (Double) standardInvoke(defaultCase.handle, data); + evaluated = (Double) standardInvoke(defaultCase.handle(), data); } catch (BreakException brk) { - check(!brk.doContinue, defaultCase.ctx, "Cannot continue in a switch"); + check(!brk.doContinue, defaultCase.positionInLine(), "Cannot continue in a switch"); } } return evaluated; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Keyed.java b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Keyed.java index e892ba1f1..b31e62d7f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Keyed.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Keyed.java @@ -19,6 +19,9 @@ package com.sk89q.worldedit.registry; +import com.sk89q.worldedit.internal.util.DeprecationUtil; +import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility; + /** * Represents an objects that can be added to a registry and referenced by an id which is unique within its registry. */ @@ -28,7 +31,24 @@ public interface Keyed { * The id of this object in the registry. Must be unique, and lowercase. Certain registries (e.g Namespaced ones) may have additional restrictions. * * @return an id + * @deprecated Use {@link #id()} instead. */ - String getId(); + @Deprecated(forRemoval = true, since = "TODO") + default String getId() { + return id(); + } + + /** + * The id of this object in the registry. Must be unique and lowercase. Certain registries (e.g namespaced ones) + * may have additional restrictions. + * + * @return an id + * @since TODO + */ + @NonAbstractForCompatibility(delegateName = "getId", delegateParams = {}) + default String id() { + DeprecationUtil.checkDelegatingOverride(getClass()); + return getId(); + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/session/Placement.java b/worldedit-core/src/main/java/com/sk89q/worldedit/session/Placement.java new file mode 100644 index 000000000..3171bc66e --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/session/Placement.java @@ -0,0 +1,52 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.session; + +import com.sk89q.worldedit.IncompleteRegionException; +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.RegionSelector; +import com.sk89q.worldedit.util.formatting.text.Component; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; + +//FAWE: not in use (yet) +public record Placement(PlacementType placementType, BlockVector3 offset) { + public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException { + return placementType.getPlacementPosition(selector, actor).add(offset); + } + + public boolean canBeUsedBy(Actor actor) { + return placementType.canBeUsedBy(actor); + } + + public Component getInfo() { + if (offset.equals(BlockVector3.ZERO)) { + return TranslatableComponent.of(placementType.getTranslationKey()); + } else { + return TranslatableComponent.of( + placementType.getTranslationKeyWithOffset(), + TextComponent.of(offset.getX()), + TextComponent.of(offset.getY()), + TextComponent.of(offset.getZ()) + ); + } + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/session/PlacementType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/session/PlacementType.java new file mode 100644 index 000000000..90b6ff01e --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/session/PlacementType.java @@ -0,0 +1,119 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.session; + +import com.sk89q.worldedit.IncompleteRegionException; +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.extension.platform.Locatable; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.RegionSelector; + +import static com.google.common.base.Preconditions.checkNotNull; + +//FAWE: not in use (yet) +public enum PlacementType { + WORLD("worldedit.toggleplace.world", "worldedit.toggleplace.world-offset") { + @Override + public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException { + return BlockVector3.ZERO; + } + }, + + PLAYER("worldedit.toggleplace.player", "worldedit.toggleplace.player-offset") { + @Override + public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException { + if (!canBeUsedBy(actor)) { + throw new IncompleteRegionException(); + } + return ((Locatable) actor).getBlockLocation().toVector().toBlockPoint(); + } + + @Override + public boolean canBeUsedBy(Actor actor) { + checkNotNull(actor); + return actor instanceof Locatable; + } + }, + + HERE(null, null) { + @Override + public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException { + throw new IllegalStateException("PlacementType.HERE cannot be used. Use PLAYER or WORLD instead."); + } + + @Override + public boolean canBeUsedBy(Actor actor) { + return PLAYER.canBeUsedBy(actor); + } + + @Override + public String getTranslationKey() { + throw new IllegalStateException("PlacementType.HERE cannot be used. Use PLAYER or WORLD instead."); + } + + @Override + public String getTranslationKeyWithOffset() { + throw new IllegalStateException("PlacementType.HERE cannot be used. Use PLAYER or WORLD instead."); + } + }, + + POS1("worldedit.toggleplace.pos1", "worldedit.toggleplace.pos1-offset") { + @Override + public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException { + return selector.getPrimaryPosition(); + } + }, + + MIN("worldedit.toggleplace.min", "worldedit.toggleplace.min-offset") { + @Override + public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException { + return selector.getRegion().getMinimumPoint(); + } + }, + + MAX("worldedit.toggleplace.max", "worldedit.toggleplace.max-offset") { + @Override + public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException { + return selector.getRegion().getMaximumPoint(); + } + }; + + private final String translationKey; + private final String translationKeyWithOffset; + + PlacementType(String translationKey, String translationKeyWithOffset) { + this.translationKey = translationKey; + this.translationKeyWithOffset = translationKeyWithOffset; + } + + public abstract BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException; + + public boolean canBeUsedBy(Actor actor) { + return true; + } + + public String getTranslationKey() { + return translationKey; + } + + public String getTranslationKeyWithOffset() { + return translationKeyWithOffset; + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/LocatedBlock.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/LocatedBlock.java index 2ea1d1d59..ff946e458 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/LocatedBlock.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/LocatedBlock.java @@ -22,46 +22,38 @@ package com.sk89q.worldedit.util; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; -import java.util.Objects; - import static com.google.common.base.Preconditions.checkNotNull; /** * Represents a block located at some position. */ -public final class LocatedBlock { +public record LocatedBlock(BlockVector3 location, BaseBlock block) { - private final BlockVector3 location; - private final BaseBlock block; - - public LocatedBlock(BlockVector3 location, BaseBlock block) { - this.location = checkNotNull(location); - this.block = checkNotNull(block); + public LocatedBlock { + checkNotNull(location); + checkNotNull(block); } + /** + * Gets the location. + * + * @return The location + * @deprecated This class is now a record. Use {@link #location()} instead. + */ + @Deprecated(forRemoval = true, since = "TODO") public BlockVector3 getLocation() { - return location; + return this.location; } + /** + * Gets the block. + * + * @return The block + * @deprecated This class is now a record. Use {@link #block()} instead. + */ + @Deprecated(forRemoval = true, since = "TODO") public BaseBlock getBlock() { - return block; - } - - @Override - public int hashCode() { - return Objects.hash(location, block); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (this.getClass() != obj.getClass()) { - return false; - } - LocatedBlock lb = (LocatedBlock) obj; - return Objects.equals(location, lb.location) && Objects.equals(block, lb.block); + return this.block; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/report/DataReport.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/report/DataReport.java index 8a18f07b3..62e83a7b0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/report/DataReport.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/report/DataReport.java @@ -168,16 +168,7 @@ public class DataReport implements Report { } } - private static class Line { - - private final String key; - private final String value; - - public Line(String key, String value) { - this.key = key; - this.value = value; - } - + private record Line(String key, String value) { } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java index e8501da69..e7ec152a9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java @@ -28,21 +28,32 @@ import com.sk89q.worldedit.registry.NamespacedRegistry; /** * All the types of biomes in the game. */ -//FAWE start - RegistryItem +//FAWE start - RegistryItem + not a record (legacyId + internalId need mutability) public class BiomeType implements RegistryItem, Keyed, BiomePattern { //FAWE end public static final NamespacedRegistry REGISTRY = new NamespacedRegistry<>("biome type", true); + //FAWE start private final String id; private int legacyId = -1; private int internalId; - //FAWE start public BiomeType(String id) { this.id = id; } + /** + * Gets the ID of this biome. + * + * @return The id + * @since TODO + */ + @Override + public String id() { + return this.id; + } + public int getLegacyId() { return legacyId; } @@ -60,13 +71,14 @@ public class BiomeType implements RegistryItem, Keyed, BiomePattern { public int getInternalId() { return internalId; } - //FAWE end /** * Gets the ID of this biome. * * @return The id + * @deprecated use {@link #id()} */ + @Deprecated(forRemoval = true, since = "TODO") @Override public String getId() { return this.id; @@ -74,20 +86,19 @@ public class BiomeType implements RegistryItem, Keyed, BiomePattern { @Override public String toString() { - return getId(); + return id(); } @Override public int hashCode() { - //FAWE start - internalId > hashCode - return this.internalId; // stop changing this - //FAWE end + return this.internalId; // stop changing this (ok) } @Override public boolean equals(Object obj) { return obj instanceof BiomeType && this.id.equals(((BiomeType) obj).id); } + //FAWE end @Override public BiomeType applyBiome(BlockVector3 position) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java index 5a530c8a6..1faf3bc4c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java @@ -23,13 +23,15 @@ import com.fastasyncworldedit.core.registry.RegistryItem; import com.sk89q.worldedit.registry.Keyed; import com.sk89q.worldedit.registry.NamespacedRegistry; -//FAWE start - implements RegistryItem +//FAWE start - implements RegistryItem, not a record (internalId needs mutability) public class EntityType implements RegistryItem, Keyed { //FAWE end public static final NamespacedRegistry REGISTRY = new NamespacedRegistry<>("entity type", true); + //FAWE start private final String id; + private int internalId; public EntityType(String id) { // If it has no namespace, assume minecraft. @@ -39,14 +41,28 @@ public class EntityType implements RegistryItem, Keyed { this.id = id; } + /** + * Gets the id of this entity type. + * + * @return the id + * @since TODO + */ + public String id() { + return this.id; + } + + /** + * Gets the id of this entity type. + * + * @return the id + * @deprecated use {@link #id()} + */ + @Deprecated(forRemoval = true, since = "TODO") @Override public String getId() { return this.id; } - //FAWE start - private int internalId; - @Override public void setInternalId(int internalId) { this.internalId = internalId; @@ -64,14 +80,15 @@ public class EntityType implements RegistryItem, Keyed { * @return The name, or ID */ public String getName() { - return getId(); + return id(); } @Override public String toString() { - return getId(); + return id(); } + //FAWE start @Override public int hashCode() { return this.id.hashCode(); @@ -81,5 +98,6 @@ public class EntityType implements RegistryItem, Keyed { public boolean equals(Object obj) { return obj instanceof EntityType && this.id.equals(((EntityType) obj).id); } + //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java index d62d13b51..1642ed4e9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java @@ -24,15 +24,15 @@ import com.sk89q.worldedit.registry.Keyed; import com.sk89q.worldedit.registry.NamespacedRegistry; /** - * Minecraft now has a 'fluid' system. This is a - * stub class to represent what it may be in the future. + * Minecraft now has a 'fluid' system. This is a stub class to represent what it may be in the future. */ -//FAWE start - implements RegistryItem +//FAWE start - implements RegistryItem, not a record (internalId needs mutability) public class FluidType implements RegistryItem, Keyed { //FAWE end public static final NamespacedRegistry REGISTRY = new NamespacedRegistry<>("fluid type"); + //FAWE start private final String id; public FluidType(String id) { @@ -43,7 +43,19 @@ public class FluidType implements RegistryItem, Keyed { * Gets the ID of this block. * * @return The id + * @since TODO */ + public String id() { + return this.id; + } + + /** + * Gets the ID of this block. + * + * @return The id + * @deprecated use {@link #id()} + */ + @Deprecated(forRemoval = true, since = "TODO") @Override public String getId() { return this.id; @@ -67,7 +79,7 @@ public class FluidType implements RegistryItem, Keyed { @Override public String toString() { - return getId(); + return id(); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameMode.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameMode.java index 312caa3b5..94b7b7cfe 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameMode.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameMode.java @@ -22,43 +22,21 @@ package com.sk89q.worldedit.world.gamemode; import com.sk89q.worldedit.registry.Keyed; import com.sk89q.worldedit.registry.Registry; -public class GameMode implements Keyed { +public record GameMode(String id) implements Keyed { public static final Registry REGISTRY = new Registry<>("game mode"); - private final String id; - - public GameMode(String id) { - this.id = id; - } - - @Override - public String getId() { - return this.id; - } - /** * Gets the name of this game mode, or the ID if the name cannot be found. * * @return The name, or ID */ public String getName() { - return getId(); + return id(); } @Override public String toString() { - return getId(); + return id(); } - - @Override - public int hashCode() { - return this.id.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof GameMode && this.id.equals(((GameMode) obj).id); - } - } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/ItemMaterial.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/ItemMaterial.java index 19fe653fc..db63b53a4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/ItemMaterial.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/ItemMaterial.java @@ -19,20 +19,53 @@ package com.sk89q.worldedit.world.registry; +import com.sk89q.worldedit.internal.util.DeprecationUtil; +import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility; + public interface ItemMaterial { + /** + * Gets the the maximum quantity of this item that can be in a single stack. + * + * @return the maximum quantity + * @deprecated Use {@link #maxStackSize()} instead. + */ + @Deprecated(forRemoval = true, since = "TODO") + default int getMaxStackSize() { + return maxStackSize(); + } /** * Gets the the maximum quantity of this item that can be in a single stack. * * @return the maximum quantity + * @since TODO */ - int getMaxStackSize(); + @NonAbstractForCompatibility(delegateName = "getMaxStackSize", delegateParams = {}) + default int maxStackSize() { + DeprecationUtil.checkDelegatingOverride(getClass()); + return getMaxStackSize(); + } /** * Gets the the maximum damage this item can take before being broken. * * @return the maximum damage, or 0 if not applicable + * @deprecated Use {@link #maxDamage()} instead. */ - int getMaxDamage(); + @Deprecated(forRemoval = true, since = "TODO") + default int getMaxDamage() { + return maxDamage(); + } + /** + * Gets the the maximum damage this item can take before being broken. + * + * @return the maximum damage, or 0 if not applicable + * @since TODO + */ + @NonAbstractForCompatibility(delegateName = "getMaxDamage", delegateParams = {}) + default int maxDamage() { + DeprecationUtil.checkDelegatingOverride(getClass()); + return getMaxDamage(); + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/PassthroughItemMaterial.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/PassthroughItemMaterial.java index 681add8cc..e5dac8a7f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/PassthroughItemMaterial.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/PassthroughItemMaterial.java @@ -34,13 +34,13 @@ public class PassthroughItemMaterial implements ItemMaterial { } @Override - public int getMaxStackSize() { - return itemMaterial.getMaxStackSize(); + public int maxStackSize() { + return itemMaterial.maxStackSize(); } @Override - public int getMaxDamage() { - return itemMaterial.getMaxDamage(); + public int maxDamage() { + return itemMaterial.maxDamage(); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/SimpleItemMaterial.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/SimpleItemMaterial.java index 40ed03515..9e552e18a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/SimpleItemMaterial.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/SimpleItemMaterial.java @@ -19,24 +19,6 @@ package com.sk89q.worldedit.world.registry; -public class SimpleItemMaterial implements ItemMaterial { - - private final int maxStackSize; - private final int maxDamage; - - public SimpleItemMaterial(int maxStackSize, int maxDamage) { - this.maxStackSize = maxStackSize; - this.maxDamage = maxDamage; - } - - @Override - public int getMaxStackSize() { - return maxStackSize; - } - - @Override - public int getMaxDamage() { - return maxDamage; - } +public record SimpleItemMaterial(int maxStackSize, int maxDamage) implements ItemMaterial { } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherType.java index ea78ee112..4a7b3cd0c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherType.java @@ -22,43 +22,20 @@ package com.sk89q.worldedit.world.weather; import com.sk89q.worldedit.registry.Keyed; import com.sk89q.worldedit.registry.Registry; -public class WeatherType implements Keyed { - +public record WeatherType(String id) implements Keyed { public static final Registry REGISTRY = new Registry<>("weather type"); - private final String id; - - public WeatherType(String id) { - this.id = id; - } - - @Override - public String getId() { - return this.id; - } - /** * Gets the name of this weather, or the ID if the name cannot be found. * * @return The name, or ID */ public String getName() { - return getId(); + return id(); } @Override public String toString() { - return getId(); + return id(); } - - @Override - public int hashCode() { - return this.id.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof WeatherType && this.id.equals(((WeatherType) obj).id); - } - } From a87124821f3922e6f13c809f3291d37197bcf989 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:53:35 +0000 Subject: [PATCH 155/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.2.14 (#2774) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 12c34eeca..bb46a654c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.2.12" +towny = "0.100.2.14" plotsquared = "7.3.8" # Third party From c6e297942f60709cd4ec57e75b26e3bc80bccf3f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 10 Jun 2024 01:54:22 +0000 Subject: [PATCH 156/220] Update dependency paperweight-userdev to v1.20.6-R0.1-20240604.210637-112 (#2775) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts index 43bc53f15..a2b5aa66d 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/ - the().paperDevBundle("1.20.6-R0.1-20240602.222958-106") + the().paperDevBundle("1.20.6-R0.1-20240604.210637-112") compileOnly(libs.paperlib) } From 62297f9479db21ba62a71e31e14f3c29ca28c478 Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 10 Jun 2024 20:11:04 +0200 Subject: [PATCH 157/220] refactor: adjust chunk sending (#2770) - synchronise on the chunk GET object (when available) - kick it off to be run at some point on the main server thread --- .../PaperweightFaweWorldNativeAccess.java | 4 +- .../fawe/v1_19_R3/PaperweightGetBlocks.java | 6 +-- .../v1_19_R3/PaperweightPlatformAdapter.java | 41 +++++++++++-------- .../PaperweightStarlightRelighter.java | 2 +- .../PaperweightFaweWorldNativeAccess.java | 4 +- .../fawe/v1_20_R1/PaperweightGetBlocks.java | 6 +-- .../v1_20_R1/PaperweightPlatformAdapter.java | 37 +++++++++-------- .../PaperweightStarlightRelighter.java | 2 +- .../PaperweightFaweWorldNativeAccess.java | 4 +- .../fawe/v1_20_R2/PaperweightGetBlocks.java | 6 +-- .../v1_20_R2/PaperweightPlatformAdapter.java | 37 +++++++++-------- .../PaperweightStarlightRelighter.java | 2 +- .../PaperweightFaweWorldNativeAccess.java | 4 +- .../fawe/v1_20_R3/PaperweightGetBlocks.java | 9 ++-- .../v1_20_R3/PaperweightPlatformAdapter.java | 37 +++++++++-------- .../PaperweightStarlightRelighter.java | 2 +- .../PaperweightFaweWorldNativeAccess.java | 4 +- .../fawe/v1_20_R4/PaperweightGetBlocks.java | 6 +-- .../v1_20_R4/PaperweightPlatformAdapter.java | 37 +++++++++-------- .../PaperweightStarlightRelighter.java | 2 +- .../bukkit/adapter/BukkitGetBlocks.java | 2 +- .../bukkit/adapter/NMSAdapter.java | 2 +- 22 files changed, 139 insertions(+), 117 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java index dbe0150a9..91fa70546 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java @@ -246,7 +246,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess { + MinecraftServer.getServer().execute(() -> { ClientboundLevelChunkWithLightPacket packet; if (PaperLib.isPaper()) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - true, - false // last false is to not bother with x-ray - ); + synchronized (chunk) { + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null, + true, + false // last false is to not bother with x-ray + ); + } } else { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - true - ); + synchronized (chunk) { + // deprecated on paper - deprecation suppressed + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null, + true + ); + } } nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); }); diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighter.java index 580bbf5a6..b1e0c5772 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighter.java @@ -67,7 +67,7 @@ public class PaperweightStarlightRelighter extends StarlightRelighter { + MinecraftServer.getServer().execute(() -> { ClientboundLevelChunkWithLightPacket packet; if (PaperLib.isPaper()) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - // last false is to not bother with x-ray - ); + synchronized (chunk) { + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null, + false // last false is to not bother with x-ray + ); + } } else { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - ); + synchronized (chunk) { + // deprecated on paper - deprecation suppressed + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null + ); + } } nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); }); diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighter.java index 30df91459..7de83af21 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighter.java @@ -67,7 +67,7 @@ public class PaperweightStarlightRelighter extends StarlightRelighter { + MinecraftServer.getServer().execute(() -> { ClientboundLevelChunkWithLightPacket packet; if (PaperLib.isPaper()) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - // last false is to not bother with x-ray - ); + synchronized (chunk) { + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null, + false // last false is to not bother with x-ray + ); + } } else { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - ); + synchronized (chunk) { + // deprecated on paper - deprecation suppressed + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null + ); + } } nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); }); diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightStarlightRelighter.java index e869046da..addf03867 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightStarlightRelighter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightStarlightRelighter.java @@ -67,7 +67,7 @@ public class PaperweightStarlightRelighter extends StarlightRelighter biomeRegistry; private final IdMap> biomeHolderIdMap; private final ConcurrentHashMap copies = new ConcurrentHashMap<>(); - private final Object sendLock = new Object(); private LevelChunkSection[] sections; private LevelChunk levelChunk; private DataLayer[] blockLight; @@ -808,7 +807,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc nmsChunk.setUnsaved(true); // send to player if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { - this.send(finalMask, finalLightUpdate); + this.send(); } if (finalizer != null) { finalizer.run(); @@ -904,10 +903,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } @Override - public void send(int mask, boolean lighting) { - synchronized (sendLock) { - PaperweightPlatformAdapter.sendChunk(serverLevel, chunkX, chunkZ, lighting); - } + public void send() { + PaperweightPlatformAdapter.sendChunk(this, serverLevel, chunkX, chunkZ); } /** diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java index 23de00ade..2f25bc6f1 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java @@ -26,6 +26,7 @@ import net.minecraft.core.Holder; import net.minecraft.core.IdMap; import net.minecraft.core.Registry; import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.ServerLevel; @@ -332,7 +333,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } @SuppressWarnings("deprecation") - public static void sendChunk(ServerLevel nmsWorld, int chunkX, int chunkZ, boolean lighting) { + public static void sendChunk(Object chunk, ServerLevel nmsWorld, int chunkX, int chunkZ) { ChunkHolder chunkHolder = getPlayerChunk(nmsWorld, chunkX, chunkZ); if (chunkHolder == null) { return; @@ -353,24 +354,28 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { if (levelChunk == null) { return; } - TaskManager.taskManager().task(() -> { + MinecraftServer.getServer().execute(() -> { ClientboundLevelChunkWithLightPacket packet; if (PaperLib.isPaper()) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - // last false is to not bother with x-ray - ); + synchronized (chunk) { + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null, + false // last false is to not bother with x-ray + ); + } } else { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - ); + synchronized (chunk) { + // deprecated on paper - deprecation suppressed + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null + ); + } } nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); }); diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightStarlightRelighter.java index 49f02bf8d..d9109b4df 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightStarlightRelighter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightStarlightRelighter.java @@ -67,7 +67,7 @@ public class PaperweightStarlightRelighter extends StarlightRelighter { + MinecraftServer.getServer().execute(() -> { ClientboundLevelChunkWithLightPacket packet; if (PaperLib.isPaper()) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - // last false is to not bother with x-ray - ); + synchronized (chunk) { + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null, + false // last false is to not bother with x-ray + ); + } } else { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - ); + synchronized (chunk) { + // deprecated on paper - deprecation suppressed + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null + ); + } } nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); }); diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightStarlightRelighter.java index 476978b57..ae09dcc58 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightStarlightRelighter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightStarlightRelighter.java @@ -67,7 +67,7 @@ public class PaperweightStarlightRelighter extends StarlightRelighter Date: Wed, 12 Jun 2024 15:00:40 +0200 Subject: [PATCH 158/220] chore: address deprecations from new records (#2768) * Category should implement Keyed --- .../ext/fawe/v1_19_R3/PaperweightAdapter.java | 8 +-- .../fawe/v1_19_R3/PaperweightFaweAdapter.java | 4 +- .../ext/fawe/v1_20_R1/PaperweightAdapter.java | 8 +-- .../fawe/v1_20_R1/PaperweightFaweAdapter.java | 4 +- .../ext/fawe/v1_20_R2/PaperweightAdapter.java | 8 +-- .../fawe/v1_20_R2/PaperweightFaweAdapter.java | 4 +- .../ext.fawe/v1_20_R3/PaperweightAdapter.java | 8 +-- .../fawe/v1_20_R3/PaperweightFaweAdapter.java | 4 +- .../ext.fawe/v1_20_R4/PaperweightAdapter.java | 8 +-- .../fawe/v1_20_R4/PaperweightFaweAdapter.java | 4 +- .../bukkit/adapter/IBukkitAdapter.java | 12 ++--- .../worldedit/bukkit/BukkitBiomeRegistry.java | 2 +- .../sk89q/worldedit/bukkit/BukkitPlayer.java | 4 +- .../bukkit/BukkitServerInterface.java | 2 +- .../sk89q/worldedit/bukkit/BukkitWorld.java | 2 +- .../sk89q/worldedit/cli/CLIBlockRegistry.java | 2 +- .../com/sk89q/worldedit/cli/CLIPlatform.java | 2 +- .../cli/schematic/ClipboardWorld.java | 2 +- .../core/extent/DisallowedBlocksExtent.java | 4 +- .../core/extent/HistoryExtent.java | 4 +- .../clipboard/io/FastSchematicWriter.java | 4 +- .../io/schematic/MinecraftStructure.java | 4 +- .../processor/lighting/NMSRelighter.java | 22 ++++---- .../core/function/generator/CavesGen.java | 4 +- .../core/function/mask/ABlockMask.java | 2 +- .../core/function/mask/BlockMaskBuilder.java | 6 +-- .../function/pattern/TypeSwapPattern.java | 2 +- .../history/changeset/AbstractChangeSet.java | 2 +- .../core/util/MainUtil.java | 2 +- .../core/util/TextureUtil.java | 6 +-- .../sk89q/worldedit/LocalConfiguration.java | 4 +- .../com/sk89q/worldedit/LocalSession.java | 4 +- .../com/sk89q/worldedit/blocks/BaseItem.java | 2 +- .../worldedit/command/BiomeCommands.java | 4 +- .../worldedit/command/GeneralCommands.java | 4 +- .../worldedit/command/SelectionCommands.java | 4 +- .../command/argument/WorldConverter.java | 4 +- .../command/tool/BlockDataCyler.java | 2 +- .../factory/parser/DefaultBlockParser.java | 50 +++++++++---------- .../pattern/BlockCategoryPatternParser.java | 2 +- .../extension/platform/Platform.java | 2 +- .../worldedit/extent/clipboard/Clipboard.java | 2 +- .../clipboard/io/SpongeSchematicWriter.java | 4 +- .../FlowerPotCompatibilityHandler.java | 2 +- .../Pre13HangingCompatibilityHandler.java | 2 +- .../transform/BlockTransformExtent.java | 2 +- .../function/block/SnowSimulator.java | 4 +- .../changeset/BlockOptimizedHistory.java | 2 +- .../internal/cui/ServerCUIHandler.java | 2 +- .../sk89q/worldedit/registry/Category.java | 7 +-- .../util/PropertiesConfiguration.java | 4 +- .../com/sk89q/worldedit/world/NullWorld.java | 2 +- .../java/com/sk89q/worldedit/world/World.java | 2 +- .../worldedit/world/biome/BiomeTypes.java | 2 +- .../worldedit/world/block/BlockState.java | 2 +- .../world/block/BlockStateHolder.java | 4 +- .../worldedit/world/block/BlockType.java | 14 +++--- .../worldedit/world/block/BlockTypes.java | 4 +- .../worldedit/world/chunk/AnvilChunk13.java | 2 +- .../worldedit/world/chunk/AnvilChunk17.java | 2 +- .../worldedit/world/chunk/AnvilChunk18.java | 2 +- .../world/fluid/FluidCategories.java | 2 +- .../worldedit/world/fluid/FluidTypes.java | 2 +- .../worldedit/world/gamemode/GameModes.java | 2 +- .../sk89q/worldedit/world/item/ItemType.java | 6 +-- .../world/registry/BundledBlockRegistry.java | 8 +-- .../world/registry/BundledItemRegistry.java | 8 +-- .../world/registry/CategoryRegistry.java | 2 +- .../world/registry/NullBiomeRegistry.java | 2 +- .../worldedit/world/weather/WeatherTypes.java | 2 +- 70 files changed, 166 insertions(+), 167 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java index 6d1038677..fa027e567 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java @@ -283,11 +283,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter { - if (itemStack.getType().getId().equalsIgnoreCase(WorldEdit.getInstance().getConfiguration().wandItem)) { + if (itemStack.getType().id().equalsIgnoreCase(WorldEdit.getInstance().getConfiguration().wandItem)) { inv.remove(newItem); } final ItemStack item = player.getInventory().getItemInMainHand(); @@ -267,7 +267,7 @@ public class BukkitPlayer extends AbstractPlayerActor { @Override public void setGameMode(GameMode gameMode) { - player.setGameMode(org.bukkit.GameMode.valueOf(gameMode.getId().toUpperCase(Locale.ROOT))); + player.setGameMode(org.bukkit.GameMode.valueOf(gameMode.id().toUpperCase(Locale.ROOT))); } @Override diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java index 3bf09481e..01d84e8ef 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java @@ -230,7 +230,7 @@ public class BukkitServerInterface extends AbstractPlatform implements MultiUser //FAWE start @Override - public String getId() { + public String id() { return "intellectualsites:bukkit"; } //FAWE end diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index b2fdeead9..66507c151 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -224,7 +224,7 @@ public class BukkitWorld extends AbstractWorld { //FAWE end @Override - public String getId() { + public String id() { return getWorld().getName().replace(" ", "_").toLowerCase(Locale.ROOT); } diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockRegistry.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockRegistry.java index 1fdb97ae6..01ad15c1e 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockRegistry.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockRegistry.java @@ -68,7 +68,7 @@ public class CLIBlockRegistry extends BundledBlockRegistry { @Override public Map> getProperties(BlockType blockType) { Map properties = - CLIWorldEdit.inst.getFileRegistries().getDataFile().blocks.get(blockType.getId()).properties; + CLIWorldEdit.inst.getFileRegistries().getDataFile().blocks.get(blockType.id()).properties; Maps.EntryTransformer> entryTransform = (key, value) -> createProperty(value.type, key, value.values); return ImmutableMap.copyOf(Maps.transformEntries(properties, entryTransform)); diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java index e9a397b73..4895a2922 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java @@ -115,7 +115,7 @@ class CLIPlatform extends AbstractPlatform { @Override public World matchWorld(World world) { return this.worlds.stream() - .filter(w -> w.getId().equals(world.getId())) + .filter(w -> w.id().equals(world.id())) .findAny() .orElse(null); } diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java index a8190234c..e0b4c64f2 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java @@ -85,7 +85,7 @@ public class ClipboardWorld extends AbstractWorld implements Clipboard, CLIWorld //FAWE end @Override - public String getId() { + public String id() { return getName().replace(" ", "_").toLowerCase(Locale.ROOT); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java index f1c523ce3..11f15131f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java @@ -101,7 +101,7 @@ public class DisallowedBlocksExtent extends AbstractDelegateExtent implements IB @SuppressWarnings("unchecked") private > B checkBlock(B block) { if (blockedBlocks != null) { - if (blockedBlocks.contains(block.getBlockType().getId())) { + if (blockedBlocks.contains(block.getBlockType().id())) { return (B) (block instanceof BlockState ? RESERVED : RESERVED.toBaseBlock()); // set to reserved/empty } } @@ -140,7 +140,7 @@ public class DisallowedBlocksExtent extends AbstractDelegateExtent implements IB } BlockState state = BlockTypesCache.states[block]; if (blockedBlocks != null) { - if (blockedBlocks.contains(state.getBlockType().getId())) { + if (blockedBlocks.contains(state.getBlockType().id())) { blocks[i] = BlockTypesCache.ReservedIDs.__RESERVED__; continue; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java index d85594215..daad170da 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java @@ -110,7 +110,7 @@ public class HistoryExtent extends AbstractDelegateExtent { @Override public boolean setBiome(BlockVector3 position, BiomeType newBiome) { BiomeType oldBiome = this.getBiome(position); - if (!oldBiome.getId().equals(newBiome.getId())) { + if (!oldBiome.id().equals(newBiome.id())) { this.changeSet.addBiomeChange(position.x(), position.y(), position.z(), oldBiome, newBiome); return getExtent().setBiome(position, newBiome); } else { @@ -121,7 +121,7 @@ public class HistoryExtent extends AbstractDelegateExtent { @Override public boolean setBiome(int x, int y, int z, BiomeType newBiome) { BiomeType oldBiome = this.getBiome(mutable.setComponents(x, y, z)); - if (!oldBiome.getId().equals(newBiome.getId())) { + if (!oldBiome.id().equals(newBiome.id())) { this.changeSet.addBiomeChange(x, y, z, oldBiome, newBiome); return getExtent().setBiome(x, y, z, newBiome); } else { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java index 5218b1c1e..65a4a0e86 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java @@ -237,7 +237,7 @@ public class FastSchematicWriter implements ClipboardWriter { if (!brokenEntities) { loc = loc.setPosition(loc.add(min.toVector3())); } - values.put("Id", new StringTag(state.getType().getId())); + values.put("Id", new StringTag(state.getType().id())); values.put("Pos", writeVector(loc)); values.put("Rotation", writeRotation(entity.getLocation())); @@ -297,7 +297,7 @@ public class FastSchematicWriter implements ClipboardWriter { for (int i = 0; i < paletteList.size(); i++) { int ordinal = paletteList.get(i); BiomeType state = BiomeTypes.get(ordinal); - out12.writeNamedTag(state.getId(), i); + out12.writeNamedTag(state.id(), i); } }); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java index d52d74b5a..0779418df 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java @@ -183,7 +183,7 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { indexes.put(combined, (Integer) palette.size()); HashMap paletteEntry = new HashMap<>(); - paletteEntry.put("Name", type.getId()); + paletteEntry.put("Name", type.id()); if (block.getInternalId() != type.getInternalId()) { Map properties = null; for (AbstractProperty property : (List>) type.getProperties()) { @@ -239,7 +239,7 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { Map nbtMap = nbt.getValue(); // Replace rotation data nbtMap.put("Rotation", writeRotation(entity.getLocation())); - nbtMap.put("id", new StringTag(state.getType().getId())); + nbtMap.put("id", new StringTag(state.getType().id())); Map entityMap = FaweCache.INSTANCE.asMap("pos", pos, "blockPos", blockPos, "nbt", nbt); entities.add(entityMap); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java index dbe717e49..2ad473130 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java @@ -346,7 +346,7 @@ public class NMSRelighter implements Relighter { } int lightLevel = iChunk.getEmittedLight(node.x() & 15, node.y(), node.z() & 15); BlockState state = this.queue.getBlock(node.x(), node.y(), node.z()); - String id = state.getBlockType().getId().toLowerCase(Locale.ROOT); + String id = state.getBlockType().id().toLowerCase(Locale.ROOT); if (lightLevel <= 1) { continue; } @@ -396,7 +396,7 @@ public class NMSRelighter implements Relighter { if (!(checkStairEast(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) { break east; } - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { this.computeSpreadBlockLight(x + 1, y, z, currentLight, queue, visited); break east; } @@ -449,7 +449,7 @@ public class NMSRelighter implements Relighter { if (!(checkStairWest(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) { break west; } - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { this.computeSpreadBlockLight(x - 1, y, z, currentLight, queue, visited); break west; } @@ -502,7 +502,7 @@ public class NMSRelighter implements Relighter { if (!(checkStairSouth(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) { break south; } - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { this.computeSpreadBlockLight(x, y, z + 1, currentLight, queue, visited); break south; } @@ -555,7 +555,7 @@ public class NMSRelighter implements Relighter { if (!(checkStairNorth(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) { break north; } - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { this.computeSpreadBlockLight(x, y, z - 1, currentLight, queue, visited); break north; } @@ -707,7 +707,7 @@ public class NMSRelighter implements Relighter { } private boolean checkStairNorth(BlockState state) { - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { return true; } Direction direction = getStairDir(state); @@ -725,7 +725,7 @@ public class NMSRelighter implements Relighter { } private boolean checkStairSouth(BlockState state) { - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { return true; } Direction direction = getStairDir(state); @@ -743,7 +743,7 @@ public class NMSRelighter implements Relighter { } private boolean checkStairEast(BlockState state) { - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { return true; } Direction direction = getStairDir(state); @@ -761,7 +761,7 @@ public class NMSRelighter implements Relighter { } private boolean checkStairWest(BlockState state) { - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { return true; } Direction direction = getStairDir(state); @@ -787,11 +787,11 @@ public class NMSRelighter implements Relighter { } private boolean isStairOrTrueTop(BlockState state, boolean top) { - return !state.getBlockType().getId().contains("stair") || state.getState(stairHalf).equals("top") == top; + return !state.getBlockType().id().contains("stair") || state.getState(stairHalf).equals("top") == top; } private boolean isSlabOrTrueValue(BlockState state, String value) { - return !state.getBlockType().getId().contains("slab") || state.getState(slabHalf).equals(value); + return !state.getBlockType().id().contains("slab") || state.getState(slabHalf).equals(value); } private void computeRemoveBlockLight( diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java index b9a403f27..7e4b61514 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java @@ -236,7 +236,7 @@ public class CavesGen extends GenBase { BlockState material = chunk.getBlock(bx + local_x, local_y, bz + local_z); BlockState materialAbove = chunk.getBlock(bx + local_x, local_y + 1, bz + local_z); BlockType blockType = material.getBlockType(); - switch (blockType.getId()) { + switch (blockType.id()) { case "minecraft:mycelium", "minecraft:grass_block" -> grassFound = true; } if (this.isSuitableBlock(material, materialAbove)) { @@ -277,7 +277,7 @@ public class CavesGen extends GenBase { } protected boolean isSuitableBlock(BlockStateHolder material, BlockStateHolder materialAbove) { - return switch (material.getBlockType().getId()) { + return switch (material.getBlockType().id()) { case "minecraft:air", "minecraft:cave_air", "minecraft:void_air", "minecraft:water", "minecraft:lava", "minecraft:bedrock" -> false; default -> true; }; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java index 1f0b88bfa..7fdebdded 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java @@ -40,7 +40,7 @@ public abstract class ABlockMask extends AbstractExtentMask { List all = type.getAllStates(); hasAll = all.stream().map(this::test).reduce(true, (a, b) -> a && b); if (hasAll) { - strings.add(type.getId()); + strings.add(type.id()); } else { for (BlockState state : all) { if (test(state)) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java index 2471ff262..baef7f767 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java @@ -183,7 +183,7 @@ public class BlockMaskBuilder { builders = new ArrayList<>(); Pattern pattern = Pattern.compile("(minecraft:)?" + regex); for (BlockType type : BlockTypesCache.values) { - if (pattern.matcher(type.getId()).find()) { + if (pattern.matcher(type.id()).find()) { blockTypeList.add(type); builders.add(new FuzzyStateAllowingBuilder(type)); add(type); @@ -284,7 +284,7 @@ public class BlockMaskBuilder { } else { boolean success = false; for (BlockType myType : BlockTypesCache.values) { - if (myType.getId().matches("(minecraft:)?" + input)) { + if (myType.id().matches("(minecraft:)?" + input)) { add(myType); success = true; } @@ -571,7 +571,7 @@ public class BlockMaskBuilder { throw new IllegalArgumentException(String.format( "Property %s cannot be applied to block type %s", property.getName(), - type.getId() + type.id() )); } masked.computeIfAbsent(property, k -> new ArrayList<>()).add(index); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/TypeSwapPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/TypeSwapPattern.java index efc122b5d..d222833a7 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/TypeSwapPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/TypeSwapPattern.java @@ -79,7 +79,7 @@ public class TypeSwapPattern extends AbstractExtentPattern { } private BlockState getNewBlock(BlockState existing) { - String oldId = existing.getBlockType().getId(); + String oldId = existing.getBlockType().id(); String newId = oldId; if (inputPattern != null) { newId = inputPattern.matcher(oldId).replaceAll(outputString); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java index e5820fd44..08165577f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java @@ -297,7 +297,7 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { public void add(BlockChange change) { try { BlockVector3 loc = change.getPosition(); - BaseBlock from = change.getPrevious(); + BaseBlock from = change.previous(); BaseBlock to = change.getCurrent(); add(loc, from, to); } catch (Exception e) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java index 117ab8fab..7d7d5d642 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java @@ -444,7 +444,7 @@ public class MainUtil { @Nonnull public static CompoundTag setEntityInfo(@Nonnull CompoundTag tag, @Nonnull Entity entity) { Map map = new HashMap<>(tag.getValue()); - map.put("Id", new StringTag(entity.getState().getType().getId())); + map.put("Id", new StringTag(entity.getState().getType().id())); ListTag pos = (ListTag) map.get("Pos"); if (pos != null) { Location loc = entity.getLocation(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java index f6f896f56..7c4e7137b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java @@ -929,10 +929,10 @@ public class TextureUtil implements TextureHolder { }.getType(); for (BlockType blockType : BlockTypesCache.values) { - if (!blockType.getMaterial().isFullCube() || blockType.getId().toLowerCase().contains("shulker")) { + if (!blockType.getMaterial().isFullCube() || blockType.id().toLowerCase().contains("shulker")) { continue; } - switch (blockType.getId().toLowerCase(Locale.ROOT)) { + switch (blockType.id().toLowerCase(Locale.ROOT)) { case "slime_block": case "honey_block": case "mob_spawner": @@ -940,7 +940,7 @@ public class TextureUtil implements TextureHolder { continue; } int combined = blockType.getInternalId(); - String id = blockType.getId(); + String id = blockType.id(); String[] split = id.split(":", 2); String name = split.length == 1 ? id : split[1]; String nameSpace = split.length == 1 ? "" : split[0]; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java index 7e2ba4549..1301c5bb3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java @@ -196,7 +196,7 @@ public abstract class LocalConfiguration { BlockTypes.BEDROCK FAWE end*/ ); - return blockTypes.stream().filter(Objects::nonNull).map(BlockType::getId).toArray(String[]::new); + return blockTypes.stream().filter(Objects::nonNull).map(BlockType::id).toArray(String[]::new); } /** @@ -277,7 +277,7 @@ public abstract class LocalConfiguration { id = Integer.parseInt(splitter[0]); data = Byte.parseByte(splitter[1]); } - item = LegacyMapper.getInstance().getItemFromLegacy(id, data).getId(); + item = LegacyMapper.getInstance().getItemFromLegacy(id, data).id(); } catch (Throwable ignored) { } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index 5df95414b..7642f3d60 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -1899,7 +1899,7 @@ public class LocalSession implements TextureHolder { */ @Deprecated public String getWandItem() { - return wandItem.getType().getId(); + return wandItem.getType().id(); } /** @@ -1910,7 +1910,7 @@ public class LocalSession implements TextureHolder { */ @Deprecated public String getNavWandItem() { - return navWandItem.getType().getId(); + return navWandItem.getType().id(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java index ac8236297..fe2e1a635 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java @@ -129,7 +129,7 @@ public class BaseItem implements NbtValued { } } - return getType().getId() + nbtString; + return getType().id() + nbtString; } //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java index 0b2bd576d..a60968da1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java @@ -98,7 +98,7 @@ public class BiomeCommands { PaginationBox paginationBox = PaginationBox.fromComponents("Available Biomes", "/biomelist -p %page%", BiomeType.REGISTRY.values().stream() .map(biomeType -> TextComponent.builder() - .append(biomeType.getId()) + .append(biomeType.id()) .append(" (") .append(biomeRegistry.getRichName(biomeType)) .append(")") @@ -166,7 +166,7 @@ public class BiomeCommands { List components = biomes.stream().map(biome -> biomeRegistry.getRichName(biome).hoverEvent( - HoverEvent.showText(TextComponent.of(biome.getId())) + HoverEvent.showText(TextComponent.of(biome.id())) ) ).collect(Collectors.toList()); actor.print(Caption.of(messageKey, TextUtils.join(components, TextComponent.of(", ")))); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java index 0cf5b1a78..3b271a1ec 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java @@ -349,7 +349,7 @@ public class GeneralCommands { if (world == null) { actor.print(Caption.of("worldedit.world.remove")); } else { - actor.print(Caption.of("worldedit.world.set", TextComponent.of(world.getId()))); + actor.print(Caption.of("worldedit.world.set", TextComponent.of(world.id()))); } } @@ -641,7 +641,7 @@ public class GeneralCommands { if (itemsOnly && searchType.hasBlockType()) { continue; } - final String id = searchType.getId(); + final String id = searchType.id(); if (id.contains(idMatch)) { Component name = searchType.getRichName(); results.put(id, TextComponent.builder() diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index d000fcef7..ddca046ff 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -79,8 +79,6 @@ import com.sk89q.worldedit.util.formatting.text.format.TextColor; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockType; -import com.sk89q.worldedit.world.item.ItemType; -import com.sk89q.worldedit.world.item.ItemTypes; import com.sk89q.worldedit.world.storage.ChunkStore; import org.enginehub.piston.annotation.Command; import org.enginehub.piston.annotation.CommandContainer; @@ -841,7 +839,7 @@ public class SelectionCommands { toolTip = TextComponent.of(state.getAsString()); blockName = blockName.append(TextComponent.of("*")); } else { - toolTip = TextComponent.of(blockType.getId()); + toolTip = TextComponent.of(blockType.id()); } blockName = blockName.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, toolTip)); line.append(blockName); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/WorldConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/WorldConverter.java index fd043d440..54492497a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/WorldConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/WorldConverter.java @@ -65,7 +65,7 @@ public class WorldConverter implements ArgumentConverter { @Override public List getSuggestions(String input, InjectedValueAccess context) { return getWorlds() - .map(World::getId) + .map(World::id) .filter(world -> world.startsWith(input)) .collect(Collectors.toList()); } @@ -73,7 +73,7 @@ public class WorldConverter implements ArgumentConverter { @Override public ConversionResult convert(String s, InjectedValueAccess injectedValueAccess) { World result = getWorlds() - .filter(world -> world.getId().equals(s)) + .filter(world -> world.id().equals(s)) .findAny().orElse(null); return result == null ? FailedConversion.from(new IllegalArgumentException( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java index b9a2ee888..2d35b2226 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java @@ -66,7 +66,7 @@ public class BlockDataCyler implements DoubleActionBlockTool { if (!config.allowedDataCycleBlocks.isEmpty() && !player.hasPermission("worldedit.override.data-cycler") - && !config.allowedDataCycleBlocks.contains(block.getBlockType().getId())) { + && !config.allowedDataCycleBlocks.contains(block.getBlockType().id())) { player.print(Caption.of("worldedit.tool.data-cycler.block-not-permitted")); return true; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java index 969216896..03cfb51e3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java @@ -135,42 +135,42 @@ public class DefaultBlockParser extends InputParser { private String woolMapper(String string) { switch (string.toLowerCase(Locale.ROOT)) { case "white": - return BlockTypes.WHITE_WOOL.getId(); + return BlockTypes.WHITE_WOOL.id(); case "black": - return BlockTypes.BLACK_WOOL.getId(); + return BlockTypes.BLACK_WOOL.id(); case "blue": - return BlockTypes.BLUE_WOOL.getId(); + return BlockTypes.BLUE_WOOL.id(); case "brown": - return BlockTypes.BROWN_WOOL.getId(); + return BlockTypes.BROWN_WOOL.id(); case "cyan": - return BlockTypes.CYAN_WOOL.getId(); + return BlockTypes.CYAN_WOOL.id(); case "gray": case "grey": - return BlockTypes.GRAY_WOOL.getId(); + return BlockTypes.GRAY_WOOL.id(); case "green": - return BlockTypes.GREEN_WOOL.getId(); + return BlockTypes.GREEN_WOOL.id(); case "light_blue": case "lightblue": - return BlockTypes.LIGHT_BLUE_WOOL.getId(); + return BlockTypes.LIGHT_BLUE_WOOL.id(); case "light_gray": case "light_grey": case "lightgray": case "lightgrey": - return BlockTypes.LIGHT_GRAY_WOOL.getId(); + return BlockTypes.LIGHT_GRAY_WOOL.id(); case "lime": - return BlockTypes.LIME_WOOL.getId(); + return BlockTypes.LIME_WOOL.id(); case "magenta": - return BlockTypes.MAGENTA_WOOL.getId(); + return BlockTypes.MAGENTA_WOOL.id(); case "orange": - return BlockTypes.ORANGE_WOOL.getId(); + return BlockTypes.ORANGE_WOOL.id(); case "pink": - return BlockTypes.PINK_WOOL.getId(); + return BlockTypes.PINK_WOOL.id(); case "purple": - return BlockTypes.PURPLE_WOOL.getId(); + return BlockTypes.PURPLE_WOOL.id(); case "yellow": - return BlockTypes.YELLOW_WOOL.getId(); + return BlockTypes.YELLOW_WOOL.id(); case "red": - return BlockTypes.RED_WOOL.getId(); + return BlockTypes.RED_WOOL.id(); default: return string; } @@ -194,7 +194,7 @@ public class DefaultBlockParser extends InputParser { if (input.indexOf('[') == -1 && input.indexOf(']') == -1) { continue; } - if (!type.getId().equalsIgnoreCase(input.substring(0, input.indexOf('[')))) { + if (!type.id().equalsIgnoreCase(input.substring(0, input.indexOf('[')))) { continue; } String[] properties = input.substring(input.indexOf('[') + 1, input.indexOf(']')).split(","); @@ -249,10 +249,10 @@ public class DefaultBlockParser extends InputParser { throw new NoMatchException(Caption.of( "worldedit.error.parser.unknown-property", TextComponent.of(parts[0]), - TextComponent.of(type.getId()) + TextComponent.of(type.id()) )); } else { - WorldEdit.logger.debug("Unknown property " + parts[0] + " for block " + type.getId()); + WorldEdit.logger.debug("Unknown property " + parts[0] + " for block " + type.id()); } return Maps.newHashMap(); } @@ -516,20 +516,20 @@ public class DefaultBlockParser extends InputParser { //FAWE start - per-limit disallowed blocks if (actor != null) { if (!actor.hasPermission("worldedit.anyblock") - && worldEdit.getConfiguration().disallowedBlocks.contains(blockType.getId().toLowerCase(Locale.ROOT))) { + && worldEdit.getConfiguration().disallowedBlocks.contains(blockType.id().toLowerCase(Locale.ROOT))) { throw new DisallowedUsageException(Caption.of( "worldedit.error.disallowed-block", - TextComponent.of(blockType.getId()) + TextComponent.of(blockType.id()) )); } FaweLimit limit = actor.getLimit(); if (!limit.isUnlimited()) { // No need to account for blocked states/properties as it will simply return false in the equality check // during contains. - if (limit.DISALLOWED_BLOCKS.contains(blockType.getId().toLowerCase(Locale.ROOT))) { + if (limit.DISALLOWED_BLOCKS.contains(blockType.id().toLowerCase(Locale.ROOT))) { throw new DisallowedUsageException(Caption.of( "fawe.error.limit.disallowed-block", - TextComponent.of(blockType.getId()) + TextComponent.of(blockType.id()) )); } } @@ -559,14 +559,14 @@ public class DefaultBlockParser extends InputParser { if (ent == null) { throw new NoMatchException(Caption.of("worldedit.error.unknown-entity", TextComponent.of(mobName))); } - mobName = ent.getId(); + mobName = ent.id(); if (!worldEdit.getPlatformManager().queryCapability(Capability.USER_COMMANDS).isValidMobType(mobName)) { throw new NoMatchException(Caption.of("worldedit.error.unknown-mob", TextComponent.of(mobName))); } return validate(context, new MobSpawnerBlock(state, mobName)); } else { //noinspection ConstantConditions - return validate(context, new MobSpawnerBlock(state, EntityTypes.PIG.getId())); + return validate(context, new MobSpawnerBlock(state, EntityTypes.PIG.id())); } } else if (blockType == BlockTypes.PLAYER_HEAD || blockType == BlockTypes.PLAYER_WALL_HEAD) { // allow setting type/player/rotation diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java index 36d83eb37..089f2d861 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java @@ -71,7 +71,7 @@ public class BlockCategoryPatternParser extends InputParser implements Set blocks = category.getAll(); if (blocks.isEmpty()) { - throw new InputParseException(Caption.of("worldedit.error.empty-tag", TextComponent.of(category.getId()))); + throw new InputParseException(Caption.of("worldedit.error.empty-tag", TextComponent.of(category.id()))); } if (anyState) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java index f20f3ce9b..472dce93c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java @@ -233,7 +233,7 @@ public interface Platform extends Keyed { */ @NonAbstractForCompatibility(delegateName = "getPlatformName", delegateParams = {}) @Override - default String getId() { + default String id() { return "legacy:" + getPlatformName().toLowerCase(Locale.ROOT).replaceAll("[^a-z_.-]", "_"); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java index 4cd2ead97..cac9f4a7b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java @@ -423,7 +423,7 @@ public interface Clipboard extends Extent, Iterable, Closeable, Fl if (pasteEntities) { for (Entity entity : this.getEntities()) { // skip players on pasting schematic - if (entity.getState() != null && entity.getState().getType().getId() + if (entity.getState() != null && entity.getState().getType().id() .equals("minecraft:player")) { continue; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java index 24860dd3c..dc313b259 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java @@ -223,7 +223,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { BlockVector3 pt = BlockVector3.at(x0, min.y(), z0); BiomeType biome = clipboard.getBiome(pt); - String biomeKey = biome.getId(); + String biomeKey = biome.id(); int biomeId; if (palette.containsKey(biomeKey)) { biomeId = palette.get(biomeKey); @@ -262,7 +262,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { values.putAll(rawData.getValue()); } values.remove("id"); - values.put("Id", new StringTag(state.getType().getId())); + values.put("Id", new StringTag(state.getType().id())); final Location location = e.getLocation(); values.put("Pos", writeVector(location.toVector())); values.put("Rotation", writeRotation(location)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java index 974000762..95d2fb091 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java @@ -84,7 +84,7 @@ public class FlowerPotCompatibilityHandler implements NBTCompatibilityHandler { } else { BlockState plantedWithData = LegacyMapper.getInstance().getBlockFromLegacy(newId, data); if (plantedWithData != null) { - plantedName = plantedWithData.getBlockType().getId().substring(10); // remove "minecraft:" + plantedName = plantedWithData.getBlockType().id().substring(10); // remove "minecraft:" } } if (plantedName != null) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java index 25457042c..346f5f29e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java @@ -29,7 +29,7 @@ public class Pre13HangingCompatibilityHandler implements EntityNBTCompatibilityH @Override public boolean isAffectedEntity(EntityType type, CompoundTag tag) { - if (!type.getId().startsWith("minecraft:")) { + if (!type.id().startsWith("minecraft:")) { return false; } boolean hasLegacyDirection = tag.containsKey("Dir") || tag.containsKey("Direction"); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java index d9effa512..5f434cf9b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java @@ -441,7 +441,7 @@ public class BlockTransformExtent extends ResettableExtent { if (Settings.settings().ENABLED_COMPONENTS.DEBUG) { LOGGER.warn(String.format( "Index outside direction array length found for block:{%s} property:{%s}", - state.getBlockType().getId(), + state.getBlockType().id(), property.getName() )); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java index 4027220b2..962fb3c7d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java @@ -116,7 +116,7 @@ public class SnowSimulator implements LayerFunction { if (!above.getBlockType().getMaterial().isAir() && (!stack || above.getBlockType() != BlockTypes.SNOW)) { return false; //FAWE start - } else if (!block.getBlockType().getId().toLowerCase(Locale.ROOT).contains("ice") && this.extent.getEmittedLight( + } else if (!block.getBlockType().id().toLowerCase(Locale.ROOT).contains("ice") && this.extent.getEmittedLight( abovePosition) > 10) { return false; } else if (!block.getBlockType().getMaterial().isFullCube()) { @@ -132,7 +132,7 @@ public class SnowSimulator implements LayerFunction { return false; } //FAWE end - } else if (!block.getBlockType().getId().toLowerCase(Locale.ROOT).contains("ice") && block + } else if (!block.getBlockType().id().toLowerCase(Locale.ROOT).contains("ice") && block .getBlockType() .getMaterial() .isTranslucent()) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/BlockOptimizedHistory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/BlockOptimizedHistory.java index 2019e3022..f358ebfae 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/BlockOptimizedHistory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/BlockOptimizedHistory.java @@ -56,7 +56,7 @@ public class BlockOptimizedHistory extends ArrayListHistory { BlockChange blockChange = (BlockChange) change; BlockVector3 position = blockChange.getPosition(); if (!previous.containsLocation(position)) { - previous.add(position, blockChange.getPrevious()); + previous.add(position, blockChange.previous()); } current.add(position, blockChange.getCurrent()); } else { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java index 8cc91f969..c30f6fa4d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java @@ -165,7 +165,7 @@ public class ServerCUIHandler { structureTag.putString("mode", "SAVE"); structureTag.putByte("ignoreEntities", (byte) 1); structureTag.putByte("showboundingbox", (byte) 1); - structureTag.putString("id", BlockTypes.STRUCTURE_BLOCK.getId()); + structureTag.putString("id", BlockTypes.STRUCTURE_BLOCK.id()); return BlockTypes.STRUCTURE_BLOCK.getDefaultState().toBaseBlock(structureTag.build()); //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java index fc8a5e895..92a859652 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java @@ -25,7 +25,7 @@ import java.util.HashSet; import java.util.Set; //FAWE start - implements RegistryItem -public abstract class Category implements RegistryItem { +public abstract class Category implements RegistryItem, Keyed { //FAWE end private final Set set = new HashSet<>(); @@ -36,7 +36,8 @@ public abstract class Category implements RegistryItem { this.id = id; } - public final String getId() { + @Override + public final String id() { return this.id; } @@ -81,7 +82,7 @@ public abstract class Category implements RegistryItem { @Override public String toString() { - return getId(); + return id(); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java index 7bec7c2f5..7a52770e3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java @@ -114,7 +114,7 @@ public class PropertiesConfiguration extends LocalConfiguration { registerHelp = getBool("register-help", registerHelp); wandItem = getString("wand-item", wandItem); try { - wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId(); + wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).id(); } catch (Throwable ignored) { } superPickaxeDrop = getBool("super-pickaxe-drop-items", superPickaxeDrop); @@ -124,7 +124,7 @@ public class PropertiesConfiguration extends LocalConfiguration { useInventoryCreativeOverride = getBool("use-inventory-creative-override", useInventoryCreativeOverride); navigationWand = getString("nav-wand-item", navigationWand); try { - navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId(); + navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).id(); } catch (Throwable ignored) { } navigationWandMaxDistance = getInt("nav-wand-distance", navigationWandMaxDistance); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java index ccf8d8535..0e962d746 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java @@ -78,7 +78,7 @@ public class NullWorld extends AbstractWorld { //FAWE end @Override - public String getId() { + public String id() { return "null"; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java index 79822a934..553792599 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java @@ -419,7 +419,7 @@ public interface World extends Extent, Keyed, IChunkCache { } @Override - default String getId() { + default String id() { return getName().replace(" ", "_").toLowerCase(Locale.ROOT); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java index 6fe08a295..e8a5e144a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java @@ -291,7 +291,7 @@ public final class BiomeTypes { } public static BiomeType register(final BiomeType biome) { - return BiomeType.REGISTRY.register(biome.getId(), biome); + return BiomeType.REGISTRY.register(biome.id(), biome); } public static BiomeType getLegacy(int legacyId) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java index 5059c737a..713204843 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java @@ -154,7 +154,7 @@ public class BlockState implements BlockStateHolder, Pattern { String input = key.toString(); throw new SuggestInputParseException(Caption.of("fawe.error.invalid-block-type", TextComponent.of(input)), () -> Stream.of( BlockTypesCache.values) - .map(BlockType::getId) + .map(BlockType::id) .filter(id -> StringMan.blockStateMatches(input, id)) .sorted(StringMan.blockStateComparator(input)) .collect(Collectors.toList()) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java index 5f6667a13..e40482302 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java @@ -204,14 +204,14 @@ public interface BlockStateHolder> extends TileEnt default String getAsString() { if (getStates().isEmpty()) { - return this.getBlockType().getId(); + return this.getBlockType().id(); } else { String properties = getStates().entrySet().stream() .map(entry -> entry.getKey().getName() + "=" + entry.getValue().toString().toLowerCase(Locale.ROOT)) .collect(Collectors.joining(",")); - return this.getBlockType().getId() + "[" + properties + "]"; + return this.getBlockType().id() + "[" + properties + "]"; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java index a2e58a97c..d8b0ae046 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java @@ -124,7 +124,7 @@ public class BlockType implements Keyed, Pattern { * @return The id */ @Override - public String getId() { + public String id() { return this.id; } @@ -135,13 +135,13 @@ public class BlockType implements Keyed, Pattern { //FAWE start public String getNamespace() { - String id = getId(); + String id = id(); int i = id.indexOf(':'); return i == -1 ? "minecraft" : id.substring(0, i); } public String getResource() { - String id = getId(); + String id = id(); return id.substring(id.indexOf(':') + 1); } //FAWE end @@ -156,7 +156,7 @@ public class BlockType implements Keyed, Pattern { public String getName() { String name = this.name.getValue(); if (name == null || name.isEmpty()) { - return getId(); + return id(); } return name; } @@ -180,7 +180,7 @@ public class BlockType implements Keyed, Pattern { LOGGER.error( "Attempted to load blockstate with id {} of type {} outside of state ordinals length. Using default state.", propertyId, - getId() + id() ); return settings.defaultState; } @@ -189,7 +189,7 @@ public class BlockType implements Keyed, Pattern { LOGGER.error( "Attempted to load blockstate with ordinal {} of type {} outside of states length. Using default state. Using default state.", ordinal, - getId() + id() ); return settings.defaultState; } @@ -405,7 +405,7 @@ public class BlockType implements Keyed, Pattern { @Override public String toString() { - return getId(); + return id(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java index 0206cdf92..2667d44f9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java @@ -2235,8 +2235,8 @@ public final class BlockTypes { throw new SuggestInputParseException(Caption.of("fawe.error.invalid-block-type", TextComponent.of(input)), () -> Stream.of( BlockTypesCache.values) - .filter(b -> StringMan.blockStateMatches(inputLower, b.getId())) - .map(BlockType::getId) + .filter(b -> StringMan.blockStateMatches(inputLower, b.id())) + .map(BlockType::id) .sorted(StringMan.blockStateComparator(inputLower)) .collect(Collectors.toList()) ); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java index 31bb7606c..a8c2d63c2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java @@ -125,7 +125,7 @@ public class AnvilChunk13 implements Chunk { } catch (IllegalArgumentException e) { throw new InvalidFormatException("Invalid block state for " + blockState .getBlockType() - .getId() + ", " + property.getName() + ": " + value); + .id() + ", " + property.getName() + ": " + value); } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java index 6d366c295..3789f9a79 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java @@ -133,7 +133,7 @@ public class AnvilChunk17 implements Chunk { } catch (IllegalArgumentException e) { throw new InvalidFormatException("Invalid block state for " + blockState .getBlockType() - .getId() + ", " + property.getName() + ": " + value); + .id() + ", " + property.getName() + ": " + value); } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java index 4fa50629e..1e36938c4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java @@ -146,7 +146,7 @@ public class AnvilChunk18 implements Chunk { } catch (IllegalArgumentException e) { throw new InvalidFormatException("Invalid block state for " + blockState .getBlockType() - .getId() + ", " + property.getName() + ": " + value); + .id() + ", " + property.getName() + ": " + value); } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidCategories.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidCategories.java index 2788fdebe..79569156e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidCategories.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidCategories.java @@ -37,7 +37,7 @@ public final class FluidCategories { } public static FluidCategory register(final FluidCategory tag) { - return FluidCategory.REGISTRY.register(tag.getId(), tag); + return FluidCategory.REGISTRY.register(tag.id(), tag); } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidTypes.java index 18c43d8c8..dd5b0270e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidTypes.java @@ -40,7 +40,7 @@ public final class FluidTypes { } public static FluidType register(final FluidType fluid) { - return FluidType.REGISTRY.register(fluid.getId(), fluid); + return FluidType.REGISTRY.register(fluid.id(), fluid); } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameModes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameModes.java index ce87f9ce7..b6d151ba8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameModes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameModes.java @@ -36,7 +36,7 @@ public final class GameModes { } public static GameMode register(final GameMode gameMode) { - return GameMode.REGISTRY.register(gameMode.getId(), gameMode); + return GameMode.REGISTRY.register(gameMode.id(), gameMode); } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java index 5dc7f9277..e7a72b3c9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java @@ -49,7 +49,7 @@ public class ItemType implements RegistryItem, Keyed { .getRegistries().getItemRegistry().getName(this), "" ); - return name.isEmpty() ? getId() : name; + return name.isEmpty() ? id() : name; }); @SuppressWarnings("this-escape") private transient final LazyReference richName = LazyReference.from(() -> @@ -76,7 +76,7 @@ public class ItemType implements RegistryItem, Keyed { } @Override - public String getId() { + public String id() { return this.id; } @@ -153,7 +153,7 @@ public class ItemType implements RegistryItem, Keyed { @Override public String toString() { - return getId(); + return id(); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockRegistry.java index 3f7181397..11663a4f1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockRegistry.java @@ -41,7 +41,7 @@ public class BundledBlockRegistry implements BlockRegistry { @Override public Component getRichName(BlockType blockType) { - BundledBlockData.BlockEntry blockEntry = BundledBlockData.getInstance().findById(blockType.getId()); + BundledBlockData.BlockEntry blockEntry = BundledBlockData.getInstance().findById(blockType.id()); if (blockEntry != null) { // This is more likely to be "right", but not translated // Some vanilla MC blocks have overrides so we need this name here @@ -50,7 +50,7 @@ public class BundledBlockRegistry implements BlockRegistry { return TextComponent.of(blockEntry.localizedName); } return Caption.of( - TranslationManager.makeTranslationKey("block", blockType.getId()) + TranslationManager.makeTranslationKey("block", blockType.id()) ); } @@ -60,14 +60,14 @@ public class BundledBlockRegistry implements BlockRegistry { // dumb_intellij.jpg - Ok?? @SuppressWarnings("deprecation") public String getName(BlockType blockType) { - BundledBlockData.BlockEntry blockEntry = BundledBlockData.getInstance().findById(blockType.getId()); + BundledBlockData.BlockEntry blockEntry = BundledBlockData.getInstance().findById(blockType.id()); return blockEntry != null ? blockEntry.localizedName : null; } @Nullable @Override public BlockMaterial getMaterial(BlockType blockType) { - return new PassthroughBlockMaterial(BundledBlockData.getInstance().getMaterialById(blockType.getId())); + return new PassthroughBlockMaterial(BundledBlockData.getInstance().getMaterialById(blockType.id())); } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledItemRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledItemRegistry.java index 2e1d42121..53a707821 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledItemRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledItemRegistry.java @@ -34,7 +34,7 @@ import javax.annotation.Nullable; public class BundledItemRegistry implements ItemRegistry { private BundledItemData.ItemEntry getEntryById(ItemType itemType) { - return BundledItemData.getInstance().findById(itemType.getId()); + return BundledItemData.getInstance().findById(itemType.id()); } @Override @@ -48,7 +48,7 @@ public class BundledItemRegistry implements ItemRegistry { return TextComponent.of(itemEntry.localizedName); } return Caption.of( - TranslationManager.makeTranslationKey("item", itemType.getId()) + TranslationManager.makeTranslationKey("item", itemType.id()) ); } @@ -62,7 +62,7 @@ public class BundledItemRegistry implements ItemRegistry { if (itemEntry != null) { String localized = itemEntry.localizedName; if (localized.equals("Air")) { - String id = itemType.getId(); + String id = itemType.id(); int c = id.indexOf(':'); return c < 0 ? id : id.substring(c + 1); } @@ -74,7 +74,7 @@ public class BundledItemRegistry implements ItemRegistry { @Nullable @Override public ItemMaterial getMaterial(ItemType itemType) { - return new PassthroughItemMaterial(BundledItemData.getInstance().getMaterialById(itemType.getId())); + return new PassthroughItemMaterial(BundledItemData.getInstance().getMaterialById(itemType.id())); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/CategoryRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/CategoryRegistry.java index c52c507b9..dade2d193 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/CategoryRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/CategoryRegistry.java @@ -38,7 +38,7 @@ public interface CategoryRegistry { Set getCategorisedByName(String category); default Set getAll(final Category category) { - return getCategorisedByName(category.getId()); + return getCategorisedByName(category.id()); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java index 346c94477..19fdd3b88 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java @@ -41,7 +41,7 @@ public class NullBiomeRegistry implements BiomeRegistry { @Override public Component getRichName(BiomeType biomeType) { return Caption.of( - TranslationManager.makeTranslationKey("biome", biomeType.getId()) + TranslationManager.makeTranslationKey("biome", biomeType.id()) ); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherTypes.java index 404e8d6da..458f17f25 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherTypes.java @@ -35,7 +35,7 @@ public final class WeatherTypes { } public static WeatherType register(WeatherType weather) { - return WeatherType.REGISTRY.register(weather.getId(), weather); + return WeatherType.REGISTRY.register(weather.id(), weather); } @Nullable From 865cc55a0e08ac73e255a1afafb69c7a42081221 Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 13 Jun 2024 20:31:34 +0200 Subject: [PATCH 159/220] feat: add #hotbar mask and pattern (#2769) - closes #2765 --- .../bukkit/BukkitPlayerBlockBag.java | 3 + .../factory/parser/common/HotbarParser.java | 72 +++++++++++++++++++ .../factory/parser/mask/HotbarMaskParser.java | 20 ++++++ .../parser/pattern/HotbarPatternParser.java | 26 +++++++ .../extension/factory/MaskFactory.java | 2 + .../extension/factory/PatternFactory.java | 3 + .../extension/input/ParserContext.java | 15 ++++ .../src/main/resources/lang/strings.json | 2 + 8 files changed, 143 insertions(+) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/common/HotbarParser.java create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/HotbarMaskParser.java create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/HotbarPatternParser.java diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayerBlockBag.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayerBlockBag.java index b060d78f8..2ad20fb6f 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayerBlockBag.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayerBlockBag.java @@ -192,6 +192,9 @@ public class BukkitPlayerBlockBag extends BlockBag implements SlottableBlockBag @Override public BaseItem getItem(int slot) { loadInventory(); + if (items[slot] == null) { + return null; + } return BukkitAdapter.adapt(items[slot]); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/common/HotbarParser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/common/HotbarParser.java new file mode 100644 index 000000000..0fe104990 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/common/HotbarParser.java @@ -0,0 +1,72 @@ +package com.fastasyncworldedit.core.extension.factory.parser.common; + +import com.fastasyncworldedit.core.configuration.Caption; +import com.fastasyncworldedit.core.extent.inventory.SlottableBlockBag; +import com.fastasyncworldedit.core.limit.FaweLimit; +import com.google.common.collect.ImmutableList; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.blocks.BaseItem; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.extension.input.DisallowedUsageException; +import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.input.ParserContext; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.internal.registry.SimpleInputParser; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.world.block.BlockType; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public abstract class HotbarParser extends SimpleInputParser { + + private final List aliases = ImmutableList.of("#hotbar"); + + protected HotbarParser(final WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public List getMatchedAliases() { + return aliases; + } + + protected List getBlockTypes(ParserContext context) { + Player player = context.requirePlayer(); + BlockBag bag = player.getInventoryBlockBag(); + if (!(bag instanceof final SlottableBlockBag slottable)) { + // Matches DefaultBlockParser + throw new InputParseException(Caption.of("fawe.error.unsupported")); + } + List types = new ArrayList<>(); + FaweLimit limit = player.getLimit(); + boolean anyBlock = player.hasPermission("worldedit.anyblock"); + for (int slot = 0; slot < 9; slot++) { + BaseItem item = slottable.getItem(slot); + if (item != null && item.getType().hasBlockType()) { + BlockType type = item.getType().getBlockType(); + if (!anyBlock && worldEdit.getConfiguration().disallowedBlocks.contains(type.id().toLowerCase(Locale.ROOT))) { + throw new DisallowedUsageException(Caption.of( + "worldedit.error.disallowed-block", + TextComponent.of(type.getId()) + )); + } + if (!limit.isUnlimited()) { + if (limit.DISALLOWED_BLOCKS.contains(type.id().toLowerCase(Locale.ROOT))) { + throw new DisallowedUsageException(Caption.of( + "fawe.error.limit.disallowed-block", + TextComponent.of(type.getId()) + )); + } + } + types.add(type); + } + } + if (types.isEmpty()) { + throw new InputParseException(Caption.of("fawe.error.no-valid-on-hotbar")); + } + return types; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/HotbarMaskParser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/HotbarMaskParser.java new file mode 100644 index 000000000..4f56ae109 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/HotbarMaskParser.java @@ -0,0 +1,20 @@ +package com.fastasyncworldedit.core.extension.factory.parser.mask; + +import com.fastasyncworldedit.core.extension.factory.parser.common.HotbarParser; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.input.ParserContext; +import com.sk89q.worldedit.function.mask.BlockTypeMask; +import com.sk89q.worldedit.function.mask.Mask; + +public class HotbarMaskParser extends HotbarParser { + + public HotbarMaskParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public Mask parseFromSimpleInput(String input, ParserContext context) { + return new BlockTypeMask(context.getExtent(), getBlockTypes(context)); + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/HotbarPatternParser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/HotbarPatternParser.java new file mode 100644 index 000000000..2f1db622e --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/HotbarPatternParser.java @@ -0,0 +1,26 @@ +package com.fastasyncworldedit.core.extension.factory.parser.pattern; + +import com.fastasyncworldedit.core.extension.factory.parser.common.HotbarParser; +import com.fastasyncworldedit.core.math.random.TrueRandom; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.input.ParserContext; +import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.function.pattern.RandomPattern; +import com.sk89q.worldedit.world.block.BlockType; + +public class HotbarPatternParser extends HotbarParser { + + public HotbarPatternParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public Pattern parseFromSimpleInput(String input, ParserContext context) { + RandomPattern random = new RandomPattern(new TrueRandom()); + for (BlockType type : getBlockTypes(context)) { + random.add(type, 1); + } + return random; + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java index 5c8ff7d6f..cf126560e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java @@ -25,6 +25,7 @@ import com.fastasyncworldedit.core.extension.factory.parser.mask.AngleMaskParser import com.fastasyncworldedit.core.extension.factory.parser.mask.BesideMaskParser; import com.fastasyncworldedit.core.extension.factory.parser.mask.ExtremaMaskParser; import com.fastasyncworldedit.core.extension.factory.parser.mask.FalseMaskParser; +import com.fastasyncworldedit.core.extension.factory.parser.mask.HotbarMaskParser; import com.fastasyncworldedit.core.extension.factory.parser.mask.LiquidMaskParser; import com.fastasyncworldedit.core.extension.factory.parser.mask.ROCAngleMaskParser; import com.fastasyncworldedit.core.extension.factory.parser.mask.RadiusMaskParser; @@ -110,6 +111,7 @@ public final class MaskFactory extends AbstractFactory { register(new BesideMaskParser(worldEdit)); register(new ExtremaMaskParser(worldEdit)); register(new FalseMaskParser(worldEdit)); + register(new HotbarMaskParser(worldEdit)); register(new LiquidMaskParser(worldEdit)); register(new RadiusMaskParser(worldEdit)); register(new RichOffsetMaskParser(worldEdit)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java index a76759833..b31d801b3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java @@ -20,6 +20,7 @@ package com.sk89q.worldedit.extension.factory; import com.fastasyncworldedit.core.configuration.Caption; +import com.fastasyncworldedit.core.extension.factory.parser.mask.HotbarMaskParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.AngleColorPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.AverageColorPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.BiomePatternParser; @@ -30,6 +31,7 @@ import com.fastasyncworldedit.core.extension.factory.parser.pattern.DarkenPatter import com.fastasyncworldedit.core.extension.factory.parser.pattern.DesaturatePatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.ExistingPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.ExpressionPatternParser; +import com.fastasyncworldedit.core.extension.factory.parser.pattern.HotbarPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.LightenPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.Linear2DPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.Linear3DPatternParser; @@ -116,6 +118,7 @@ public final class PatternFactory extends AbstractFactory { register(new DesaturatePatternParser(worldEdit)); register(new ExistingPatternParser(worldEdit)); register(new ExpressionPatternParser(worldEdit)); + register(new HotbarPatternParser(worldEdit)); register(new LightenPatternParser(worldEdit)); register(new Linear2DPatternParser(worldEdit)); register(new Linear3DPatternParser(worldEdit)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/input/ParserContext.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/input/ParserContext.java index 430280814..989931b0b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/input/ParserContext.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/input/ParserContext.java @@ -23,6 +23,7 @@ import com.fastasyncworldedit.core.configuration.Caption; import com.sk89q.worldedit.IncompleteRegionException; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.factory.MaskFactory; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Capability; @@ -217,6 +218,20 @@ public class ParserContext { return actor; } + /** + * Get the {@link Player} set on this context. + * + * @return a player + * @throws InputParseException thrown if no {@link Actor} is set + */ + public Player requirePlayer() throws InputParseException { + Actor actor = getActor(); + if (!(actor instanceof Player player)) { + throw new InputParseException(Caption.of("worldedit.error.missing-player")); + } + return player; + } + /** * Returns whether there should be restrictions (as a result of * limits or permissions) considered when parsing the input. diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index c67da38d7..a8dddbdcf 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -139,6 +139,7 @@ "fawe.error.occurred-continuing": "Ignorable error occurred during edit: {0}", "fawe.error.limit.max-brush-radius": "Maximum brush radius in limit: {0}", "fawe.error.limit.max-radius": "Maximum radius in limit: {0}", + "fawe.error.no-valid-on-hotbar": "No valid block types on hotbar", "fawe.cancel.count": "Cancelled {0} edits.", "fawe.cancel.reason.confirm": "Use //confirm to execute {0}", "fawe.cancel.reason.confirm.region": "Your selection is large ({0} -> {1}, containing {3} blocks). Use //confirm to execute {2}", @@ -240,6 +241,7 @@ "worldedit.error.missing-session": "No LocalSession is known", "worldedit.error.missing-world": "You need to provide a world (Try //world)", "worldedit.error.missing-actor": "No actor is known", + "worldedit.error.missing-player": "No player is known", "worldedit.error.no-file-selected": "No file selected.", "worldedit.error.file-resolution.outside-root": "Path is outside allowable root", "worldedit.error.file-resolution.resolve-failed": "Failed to resolve path", From 031fdf2efd6c477d4d1b5bdb80db44989d9e99cd Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 13 Jun 2024 20:31:45 +0200 Subject: [PATCH 160/220] fix: ensure config-legacy.yml is created before accessed (#2752) * fix: ensure config-legacy.yml is created before accessed * Stop error attempting to load FAWE config if it doesn't exist --- .../java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java | 8 ++++---- .../com/fastasyncworldedit/core/configuration/Config.java | 3 +++ .../core/configuration/file/YamlConfiguration.java | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index b4556409c..faac1c955 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -137,6 +137,10 @@ public class WorldEditPlugin extends JavaPlugin { //noinspection ResultOfMethodCallIgnored getDataFolder().mkdirs(); + //FAWE start - Migrate from config-legacy to worldedit-config + migrateLegacyConfig(); + //FAWE end + //FAWE start - Modify WorldEdit config name config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "worldedit-config.yml"), true), this); // Load config before we say we've loaded platforms as it is used in listeners of the event @@ -151,10 +155,6 @@ public class WorldEditPlugin extends JavaPlugin { platform = new BukkitServerInterface(this, getServer()); worldEdit.getPlatformManager().register(platform); - //FAWE start - Migrate from config-legacy to worldedit-config - migrateLegacyConfig(); - //FAWE end - //FAWE start - Setup permission attachments permissionAttachmentManager = new BukkitPermissionAttachmentManager(this); //FAWE end diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java index e5185e6d8..d230ab05b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java @@ -100,6 +100,9 @@ public class Config { } public boolean load(File file) { + if (!file.exists()) { + return false; + } existingMigrateNodes = new ArrayList<>(); YamlConfiguration yml = YamlConfiguration.loadConfiguration(file); for (String key : yml.getKeys(true)) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/file/YamlConfiguration.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/file/YamlConfiguration.java index 1e2d5b0c4..f900451b5 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/file/YamlConfiguration.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/file/YamlConfiguration.java @@ -68,6 +68,7 @@ public class YamlConfiguration extends FileConfiguration { LOGGER.error("Could not read {}\n" + "Renamed to {}", file, dest.getAbsolutePath(), ex); } catch (final IOException e) { e.printStackTrace(); + ex.printStackTrace(); } } From 4a5ff8e306151f553764848744cd3a8bcc5e16e3 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 14 Jun 2024 19:18:35 +0100 Subject: [PATCH 161/220] fix: wrap immutable map in MinecraftStructure writer - fixes #2781 --- .../extent/clipboard/io/schematic/MinecraftStructure.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java index 0779418df..c1f129112 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java @@ -236,11 +236,11 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { BaseEntity state = entity.getState(); if (state != null) { CompoundTag nbt = state.getNbtData(); - Map nbtMap = nbt.getValue(); + Map nbtMap = new HashMap<>(nbt.getValue()); // Replace rotation data nbtMap.put("Rotation", writeRotation(entity.getLocation())); nbtMap.put("id", new StringTag(state.getType().id())); - Map entityMap = FaweCache.INSTANCE.asMap("pos", pos, "blockPos", blockPos, "nbt", nbt); + Map entityMap = FaweCache.INSTANCE.asMap("pos", pos, "blockPos", blockPos, "nbt", new CompoundTag(nbtMap)); entities.add(entityMap); } } From 8aba1e6c06e3bf0e3065891e5c2ce0c5e8087e27 Mon Sep 17 00:00:00 2001 From: Jordan Date: Sat, 15 Jun 2024 13:07:29 +0200 Subject: [PATCH 162/220] fix: allow use of quotes to allow spaces to be used as "and" (#2786) * fix: allow use of quotes to allow spaces to be sued as "and" - e.g. `//set "#mask[grass_block& { - private final RichTransformParser richTransformParser; - /** * Create a new factory. * * @param worldEdit the WorldEdit instance */ public TransformFactory(WorldEdit worldEdit) { - super(worldEdit, new NullTransformParser(worldEdit)); - - richTransformParser = new RichTransformParser(worldEdit); + super(worldEdit, new NullTransformParser(worldEdit), new RichTransformParser(worldEdit)); // split and parse each sub-transform register(new RandomTransformParser(worldEdit)); @@ -51,68 +46,7 @@ public class TransformFactory extends AbstractFactory { } @Override - public ResettableExtent parseFromInput(String input, ParserContext context) throws InputParseException { - List transforms = new ArrayList<>(); - - for (String component : input.split(" ")) { - if (component.isEmpty()) { - continue; - } - - ResettableExtent match = richTransformParser.parseFromInput(component, context); - if (match != null) { - transforms.add(match); - continue; - } - parseFromParsers(context, transforms, component); - } - - return getResettableExtent(input, transforms); - } - - private void parseFromParsers( - final ParserContext context, - final List transforms, - final String component - ) { - ResettableExtent match = null; - for (InputParser parser : getParsers()) { - match = parser.parseFromInput(component, context); - - if (match != null) { - break; - } - } - if (match == null) { - throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component))); - } - transforms.add(match); - } - - /** - * Parses a transform without considering parsing through the {@link RichTransformParser}, therefore not accepting - * "richer" parsing where & and , are used. Exists to prevent stack overflows. - * - * @param input input string - * @param context input context - * @return parsed result - * @throws InputParseException if no result found - */ - public ResettableExtent parseWithoutRich(String input, ParserContext context) throws InputParseException { - List transforms = new ArrayList<>(); - - for (String component : input.split(" ")) { - if (component.isEmpty()) { - continue; - } - - parseFromParsers(context, transforms, component); - } - - return getResettableExtent(input, transforms); - } - - private ResettableExtent getResettableExtent(final String input, final List transforms) { + protected ResettableExtent getParsed(final String input, final List transforms) { switch (transforms.size()) { case 0: throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input))); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/FaweParser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/FaweParser.java index 11d33ef67..08dd05ad1 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/FaweParser.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/FaweParser.java @@ -37,14 +37,14 @@ public abstract class FaweParser extends InputParser implements AliasedPar for (int i = 0; i < toParse.length(); i++) { char c = toParse.charAt(i); switch (c) { - case ',', '&' -> { + case ',', '&', ' ' -> { if (expression) { continue; } String result = toParse.substring(last, i); if (!result.isEmpty()) { inputs.add(result); - and.add(c == '&'); + and.add(c == '&' || c == ' '); } else { throw new InputParseException(Caption.of("fawe.error.parse.invalid-dangling-character", c)); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java index 14ecb48f1..f436ce576 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java @@ -23,11 +23,16 @@ import com.sk89q.util.StringUtil; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.factory.parser.DefaultBlockParser; import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.input.NoMatchException; import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.internal.registry.AbstractFactory; +import com.sk89q.worldedit.internal.registry.InputParser; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.world.block.BaseBlock; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -67,4 +72,21 @@ public class BlockFactory extends AbstractFactory { return blocks; } + //FAWE start + @Override + public BaseBlock parseFromInput(String input, ParserContext context) throws InputParseException { + BaseBlock match; + + for (InputParser parser : parsers) { + match = parser.parseFromInput(input, context); + + if (match != null) { + return match; + } + } + + throw new NoMatchException(TranslatableComponent.of("worldedit.error.no-match", TextComponent.of(input))); + } + //FAWE end + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/ItemFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/ItemFactory.java index b1858a12d..8c907f42a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/ItemFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/ItemFactory.java @@ -22,7 +22,13 @@ package com.sk89q.worldedit.extension.factory; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.extension.factory.parser.DefaultItemParser; +import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.input.NoMatchException; +import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.internal.registry.AbstractFactory; +import com.sk89q.worldedit.internal.registry.InputParser; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; public class ItemFactory extends AbstractFactory { @@ -35,4 +41,21 @@ public class ItemFactory extends AbstractFactory { super(worldEdit, new DefaultItemParser(worldEdit)); } + //FAWE start + @Override + public BaseItem parseFromInput(String input, ParserContext context) throws InputParseException { + BaseItem match; + + for (InputParser parser : parsers) { + match = parser.parseFromInput(input, context); + + if (match != null) { + return match; + } + } + + throw new NoMatchException(TranslatableComponent.of("worldedit.error.no-match", TextComponent.of(input))); + } + //FAWE end + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java index cf126560e..3440b009c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java @@ -53,16 +53,13 @@ import com.sk89q.worldedit.extension.factory.parser.mask.NoiseMaskParser; import com.sk89q.worldedit.extension.factory.parser.mask.OffsetMaskParser; import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser; import com.sk89q.worldedit.extension.factory.parser.mask.SolidMaskParser; -import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.NoMatchException; import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.MaskIntersection; import com.sk89q.worldedit.internal.registry.AbstractFactory; -import com.sk89q.worldedit.internal.registry.InputParser; import com.sk89q.worldedit.util.formatting.text.TextComponent; -import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -75,21 +72,13 @@ import java.util.stream.Collectors; */ public final class MaskFactory extends AbstractFactory { - //FAWE start - rich mask parsing - private final RichMaskParser richMaskParser; - //FAWE end - /** * Create a new mask registry. * * @param worldEdit the WorldEdit instance */ public MaskFactory(WorldEdit worldEdit) { - super(worldEdit, new BlocksMaskParser(worldEdit)); - - //FAWE start - rich mask parsing - richMaskParser = new RichMaskParser(worldEdit); - //FAWE end + super(worldEdit, new BlocksMaskParser(worldEdit), new RichMaskParser(worldEdit)); register(new ExistingMaskParser(worldEdit)); register(new AirMaskParser(worldEdit)); @@ -125,7 +114,6 @@ public final class MaskFactory extends AbstractFactory { register(new ZAxisMaskParser(worldEdit)); register(new SurfaceAngleMaskParser(worldEdit)); //FAWE end - } @Override @@ -133,85 +121,24 @@ public final class MaskFactory extends AbstractFactory { final String[] split = input.split(" "); if (split.length > 1) { String prev = input.substring(0, input.lastIndexOf(" ")) + " "; - return super.getSuggestions(split[split.length - 1], parserContext).stream().map(s -> prev + s).collect(Collectors.toList()); + return super + .getSuggestions(split[split.length - 1], parserContext) + .stream() + .map(s -> prev + s) + .collect(Collectors.toList()); } return super.getSuggestions(input, parserContext); } - @Override - public Mask parseFromInput(String input, ParserContext context) throws InputParseException { - List masks = new ArrayList<>(); - - for (String component : input.split(" ")) { - if (component.isEmpty()) { - continue; - } - - //FAWE start - rich mask parsing - Mask match = richMaskParser.parseFromInput(component, context); - if (match != null) { - masks.add(match); - continue; - } - parseFromParsers(context, masks, component); - //FAWE end - } - - return getMask(input, masks); - } - //FAWE start - rich mask parsing - private void parseFromParsers( - final ParserContext context, - final List masks, - final String component - ) { - Mask match = null; - for (InputParser parser : getParsers()) { - match = parser.parseFromInput(component, context); - if (match != null) { - break; - } - } - if (match == null) { - throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component))); - } - masks.add(match); - } - - /** - * Parses a mask without considering parsing through the {@link RichMaskParser}, therefore not accepting - * "richer" parsing where & and , are used. Exists to prevent stack overflows. - * - * @param input input string - * @param context input context - * @return parsed result - * @throws InputParseException if no result found - */ - public Mask parseWithoutRich(String input, ParserContext context) throws InputParseException { - List masks = new ArrayList<>(); - - for (String component : input.split(" ")) { - if (component.isEmpty()) { - continue; - } - - parseFromParsers(context, masks, component); - } - - return getMask(input, masks); - } - - private Mask getMask(final String input, final List masks) { - switch (masks.size()) { - case 0: - throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input))); - case 1: - return masks.get(0).optimize(); - default: - return new MaskIntersection(masks).optimize(); - } + @Override + protected Mask getParsed(final String input, final List masks) { + return switch (masks.size()) { + case 0 -> throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input))); + case 1 -> masks.get(0).optimize(); + default -> new MaskIntersection(masks).optimize(); + }; } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java index b31d801b3..25955adee 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java @@ -20,7 +20,6 @@ package com.sk89q.worldedit.extension.factory; import com.fastasyncworldedit.core.configuration.Caption; -import com.fastasyncworldedit.core.extension.factory.parser.mask.HotbarMaskParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.AngleColorPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.AverageColorPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.BiomePatternParser; @@ -44,8 +43,6 @@ import com.fastasyncworldedit.core.extension.factory.parser.pattern.OffsetPatter import com.fastasyncworldedit.core.extension.factory.parser.pattern.PerlinPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.RandomFullClipboardPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.RandomOffsetPatternParser; -import com.fastasyncworldedit.core.extension.factory.parser.pattern.TypeSwapPatternParser; -import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.RelativePatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.RichPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.RidgedMultiFractalPatternParser; @@ -53,24 +50,22 @@ import com.fastasyncworldedit.core.extension.factory.parser.pattern.SaturatePatt import com.fastasyncworldedit.core.extension.factory.parser.pattern.SimplexPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.SolidRandomOffsetPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.SurfaceRandomOffsetPatternParser; +import com.fastasyncworldedit.core.extension.factory.parser.pattern.TypeSwapPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.VoronoiPatternParser; import com.fastasyncworldedit.core.math.random.TrueRandom; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.factory.parser.pattern.BlockCategoryPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser; +import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.RandomStatePatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.SingleBlockPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.TypeOrStateApplyingPatternParser; -import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.NoMatchException; -import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.RandomPattern; import com.sk89q.worldedit.internal.registry.AbstractFactory; -import com.sk89q.worldedit.internal.registry.InputParser; import com.sk89q.worldedit.util.formatting.text.TextComponent; -import java.util.ArrayList; import java.util.List; /** @@ -82,20 +77,14 @@ import java.util.List; */ public final class PatternFactory extends AbstractFactory { - //FAWE start - rich pattern parsing - private final RichPatternParser richPatternParser; - //FAWE end - /** * Create a new instance. * * @param worldEdit the WorldEdit instance */ public PatternFactory(WorldEdit worldEdit) { - super(worldEdit, new SingleBlockPatternParser(worldEdit)); - //FAWE start - rich pattern parsing - richPatternParser = new RichPatternParser(worldEdit); + super(worldEdit, new SingleBlockPatternParser(worldEdit), new RichPatternParser(worldEdit)); //FAWE end // split and parse each sub-pattern @@ -139,75 +128,10 @@ public final class PatternFactory extends AbstractFactory { register(new SurfaceRandomOffsetPatternParser(worldEdit)); register(new TypeSwapPatternParser(worldEdit)); register(new VoronoiPatternParser(worldEdit)); - //FAWE end } @Override - public Pattern parseFromInput(String input, ParserContext context) throws InputParseException { - List patterns = new ArrayList<>(); - - for (String component : input.split(" ")) { - if (component.isEmpty()) { - continue; - } - - //FAWE start - rich pattern parsing - Pattern match = richPatternParser.parseFromInput(component, context); - if (match != null) { - patterns.add(match); - continue; - } - parseFromParsers(context, patterns, component); - //FAWE end - } - - return getPattern(input, patterns); - } - - //FAWE start - rich pattern parsing - private void parseFromParsers( - final ParserContext context, - final List patterns, - final String component - ) { - Pattern match = null; - for (InputParser parser : getParsers()) { - match = parser.parseFromInput(component, context); - - if (match != null) { - break; - } - } - if (match == null) { - throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component))); - } - patterns.add(match); - } - - /** - * Parses a pattern without considering parsing through the {@link RichPatternParser}, therefore not accepting - * "richer" parsing where & and , are used. Exists to prevent stack overflows. - * - * @param input input string - * @param context input context - * @return parsed result - * @throws InputParseException if no result found - */ - public Pattern parseWithoutRich(String input, ParserContext context) throws InputParseException { - List patterns = new ArrayList<>(); - - for (String component : input.split(" ")) { - if (component.isEmpty()) { - continue; - } - - parseFromParsers(context, patterns, component); - } - - return getPattern(input, patterns); - } - - private Pattern getPattern(final String input, final List patterns) { + protected Pattern getParsed(final String input, final List patterns) { switch (patterns.size()) { case 0: throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input))); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java index 237dd1c4c..0934627b9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java @@ -21,6 +21,9 @@ package com.sk89q.worldedit.internal.registry; import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.extension.factory.parser.AliasedParser; +import com.fastasyncworldedit.core.extension.factory.parser.FaweParser; +import com.fastasyncworldedit.core.extension.factory.parser.pattern.RichPatternParser; +import com.sk89q.util.StringUtil; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.NoMatchException; @@ -43,7 +46,10 @@ import static com.google.common.base.Preconditions.checkNotNull; public abstract class AbstractFactory { protected final WorldEdit worldEdit; - private final List> parsers = new ArrayList<>(); + //FAWE start + protected final List> parsers = new ArrayList<>(); + private final FaweParser richParser; + //FWAE end /** * Create a new factory. @@ -52,11 +58,26 @@ public abstract class AbstractFactory { * @param defaultParser the parser to fall back to */ protected AbstractFactory(WorldEdit worldEdit, InputParser defaultParser) { + //FAWE start + this(worldEdit, defaultParser, null); + } + + /** + * Create a new factory with a given rich parser for FAWE rich parsing + * + * @param worldEdit the WorldEdit instance + * @param defaultParser the parser to fall back to + * @param richParser the rich parser + * @since TODO + */ + protected AbstractFactory(WorldEdit worldEdit, InputParser defaultParser, FaweParser richParser) { checkNotNull(worldEdit); checkNotNull(defaultParser); this.worldEdit = worldEdit; this.parsers.add(defaultParser); + this.richParser = richParser; } + //FAWE end /** * Gets an immutable list of parsers. @@ -71,7 +92,7 @@ public abstract class AbstractFactory { return Collections.unmodifiableList(parsers); } - //FAWE start - javadoc + //FAWE start /** * Parse a string and context to each {@link InputParser} added to this factory. If no result found, throws {@link InputParseException} @@ -81,20 +102,26 @@ public abstract class AbstractFactory { * @return parsed result * @throws InputParseException if no result found */ - //FAWE end public E parseFromInput(String input, ParserContext context) throws InputParseException { - E match; - - for (InputParser parser : parsers) { - match = parser.parseFromInput(input, context); - - if (match != null) { - return match; + List parsed = new ArrayList<>(); + for (String component : StringUtil.split(input,' ', '[', ']')) { + if (component.isEmpty()) { + continue; } + + if (richParser != null) { + E match = richParser.parseFromInput(component, context); + if (match != null) { + parsed.add(match); + continue; + } + } + parseFromParsers(context, parsed, component); } - throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input))); + return getParsed(input, parsed); } + //FAWE end @Deprecated public List getSuggestions(String input) { @@ -133,4 +160,48 @@ public abstract class AbstractFactory { }); } + //FAWE start + protected void parseFromParsers(final ParserContext context, final List parsed, final String component) { + E match = null; + for (InputParser parser : getParsers()) { + match = parser.parseFromInput(component, context); + + if (match != null) { + break; + } + } + if (match == null) { + throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component))); + } + parsed.add(match); + } + + /** + * Parses a pattern without considering parsing through the {@link RichPatternParser}, therefore not accepting + * "richer" parsing where & and , are used. Exists to prevent stack overflows. + * + * @param input input string + * @param context input context + * @return parsed result + * @throws InputParseException if no result found + */ + public E parseWithoutRich(String input, ParserContext context) throws InputParseException { + List parsed = new ArrayList<>(); + + for (String component : StringUtil.split(input, ' ', '[', ']')) { + if (component.isEmpty()) { + continue; + } + + parseFromParsers(context, parsed, component); + } + + return getParsed(input, parsed); + } + + protected E getParsed(final String input, final List parsed) { + return parsed.isEmpty() ? null : parsed.get(0); + } + //FAWE end + } From af83b2f9c9a1a2fca87715b10d34367b8377cb45 Mon Sep 17 00:00:00 2001 From: Jordan Date: Sat, 15 Jun 2024 13:08:42 +0200 Subject: [PATCH 163/220] fix: improve biome setting to avoid writing directly to chunk (#2757) * fix: improve biome setting to avoid writing directly to chunk - Removes possibility of writing to the LevelChunkSection biomes PalettedContainer whilst it is being read for sending packets - I believe this occured mostly on clipboard operations where blocks are written before biomes, so chunks are being sent whilst writing biomes - This would explain why the error reported in the below issue (and others) is/was so rare - Of course I could be completely wrong about all of this, but given the line in LevelChunkSection#write that the error seems to consistently occur on is when writing biomes to the packet, and that the only place I can find in FAWE where we write to a "live" PalettedContainer is for biomes, I am reasonably confident that this is the cause - Should address #2729 * Remove self-refraction-check --- .../fawe/v1_19_R3/PaperweightGetBlocks.java | 49 ++++++------ .../v1_19_R3/PaperweightPlatformAdapter.java | 14 +++- .../fawe/v1_20_R1/PaperweightGetBlocks.java | 49 ++++++------ .../v1_20_R1/PaperweightPlatformAdapter.java | 18 +++-- .../fawe/v1_20_R2/PaperweightGetBlocks.java | 76 +++++++++++------- .../v1_20_R2/PaperweightPlatformAdapter.java | 18 +++-- .../fawe/v1_20_R3/PaperweightGetBlocks.java | 76 +++++++++++------- .../v1_20_R3/PaperweightPlatformAdapter.java | 17 ++-- .../fawe/v1_20_R4/PaperweightGetBlocks.java | 80 ++++++++++++------- .../v1_20_R4/PaperweightPlatformAdapter.java | 19 +++-- 10 files changed, 252 insertions(+), 164 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java index abf0aa9f0..4d979fd0e 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java @@ -511,7 +511,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } } } else { - setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes()); + PalettedContainer> paletteBiomes = setBiomesToPalettedContainer( + biomes, + setSectionIndex, + existingSection.getBiomes() + ); + if (paletteBiomes != null) { + PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); + } } } } @@ -553,11 +560,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), PalettedContainer.Strategy.SECTION_BIOMES, null ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); @@ -625,15 +628,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc existingSection.getBiomes() ); - newSection = - PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData - ); + newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + this::loadPrivately, + setArr, + adapter, + biomeRegistry, + biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() + ); if (!PaperweightPlatformAdapter.setSectionAtomic( levelChunkSections, existingSection, @@ -845,7 +847,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } if (callback == null) { if (finalizer != null) { - finalizer.run(); + queueHandler.async(finalizer, null); } return null; } else { @@ -1103,9 +1105,13 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc final int sectionIndex, final PalettedContainerRO> data ) { + BiomeType[] sectionBiomes; + if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { + return null; + } PalettedContainer> biomeData; if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer; + biomeData = palettedContainer.copy(); } else { LOGGER.warn( "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + @@ -1115,10 +1121,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc ); biomeData = data.recreate(); } - BiomeType[] sectionBiomes; - if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return biomeData; - } for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { @@ -1130,10 +1132,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc x, y, z, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)) + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) ); } } diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java index 0a7453578..ccd6ed982 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java @@ -98,7 +98,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final Field fieldTickingFluidCount; private static final Field fieldTickingBlockCount; - private static final Field fieldNonEmptyBlockCount; + private static final Field fieldBiomes; private static final MethodHandle methodGetVisibleChunk; @@ -139,8 +139,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "g")); fieldTickingBlockCount.setAccessible(true); - fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "f")); - fieldNonEmptyBlockCount.setAccessible(true); + fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "j")); + fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( "getVisibleChunkIfPresent", @@ -502,6 +502,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return new LevelChunkSection(layer, dataPaletteBlocks, biomes); } + public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { + try { + fieldBiomes.set(section, biomes); + } catch (IllegalAccessException e) { + LOGGER.error("Could not set biomes to chunk section", e); + } + } + /** * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. */ diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java index e0232f996..cc329c16a 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java @@ -510,7 +510,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } } } else { - setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes()); + PalettedContainer> paletteBiomes = setBiomesToPalettedContainer( + biomes, + setSectionIndex, + existingSection.getBiomes() + ); + if (paletteBiomes != null) { + PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); + } } } } @@ -552,11 +559,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), PalettedContainer.Strategy.SECTION_BIOMES ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); newSection = PaperweightPlatformAdapter.newChunkSection( @@ -623,15 +626,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc existingSection.getBiomes() ); - newSection = - PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData - ); + newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + this::loadPrivately, + setArr, + adapter, + biomeRegistry, + biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() + ); if (!PaperweightPlatformAdapter.setSectionAtomic( levelChunkSections, existingSection, @@ -843,7 +845,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } if (callback == null) { if (finalizer != null) { - finalizer.run(); + queueHandler.async(finalizer, null); } return null; } else { @@ -1100,9 +1102,13 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc final int sectionIndex, final PalettedContainerRO> data ) { + BiomeType[] sectionBiomes; + if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { + return null; + } PalettedContainer> biomeData; if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer; + biomeData = palettedContainer.copy(); } else { LOGGER.warn( "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + @@ -1112,10 +1118,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc ); biomeData = data.recreate(); } - BiomeType[] sectionBiomes; - if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return biomeData; - } for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { @@ -1127,10 +1129,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc x, y, z, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)) + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) ); } } diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java index 74eec9195..999dd3646 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java @@ -62,7 +62,6 @@ import net.minecraft.world.level.entity.PersistentEntitySectionManager; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_20_R1.CraftChunk; -import sun.misc.Unsafe; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -102,7 +101,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final Field fieldTickingFluidCount; private static final Field fieldTickingBlockCount; - private static final Field fieldNonEmptyBlockCount; private static final MethodHandle methodGetVisibleChunk; @@ -111,6 +109,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final MethodHandle methodRemoveGameEventListener; private static final MethodHandle methodremoveTickingBlockEntity; + private static final Field fieldBiomes; private static final Field fieldOffers; private static final MerchantOffers OFFERS = new MerchantOffers(); @@ -149,8 +148,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e")); - fieldNonEmptyBlockCount.setAccessible(true); + fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i")); + fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( "getVisibleChunkIfPresent", @@ -417,7 +416,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @Nullable PalettedContainer> biomes ) { if (set == null) { - return newChunkSection(layer, biomeRegistry, biomes); + return newChunkSection(biomeRegistry, biomes); } final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); @@ -507,7 +506,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @SuppressWarnings("deprecation") // Only deprecated in paper private static LevelChunkSection newChunkSection( - int layer, Registry biomeRegistry, @Nullable PalettedContainer> biomes ) { @@ -522,6 +520,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return new LevelChunkSection(dataPaletteBlocks, biomes); } + public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { + try { + fieldBiomes.set(section, biomes); + } catch (IllegalAccessException e) { + LOGGER.error("Could not set biomes to chunk section", e); + } + } + /** * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. */ diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java index 08ba39b10..f5492fccb 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java @@ -29,7 +29,11 @@ import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; import io.papermc.lib.PaperLib; import io.papermc.paper.event.block.BeaconDeactivatedEvent; -import net.minecraft.core.*; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.IdMap; +import net.minecraft.core.Registry; +import net.minecraft.core.SectionPos; import net.minecraft.nbt.IntTag; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvents; @@ -42,7 +46,14 @@ import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.entity.BeaconBlockEntity; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.*; +import net.minecraft.world.level.chunk.DataLayer; +import net.minecraft.world.level.chunk.HashMapPalette; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.LinearPalette; +import net.minecraft.world.level.chunk.Palette; +import net.minecraft.world.level.chunk.PalettedContainer; +import net.minecraft.world.level.chunk.PalettedContainerRO; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.lighting.LevelLightEngine; import org.apache.logging.log4j.Logger; @@ -52,7 +63,17 @@ import org.bukkit.craftbukkit.v1_20_R2.block.CraftBlock; import org.bukkit.event.entity.CreatureSpawnEvent; import javax.annotation.Nonnull; -import java.util.*; +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; @@ -497,7 +518,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } } } else { - setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes()); + PalettedContainer> paletteBiomes = setBiomesToPalettedContainer( + biomes, + setSectionIndex, + existingSection.getBiomes() + ); + if (paletteBiomes != null) { + PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); + } } } } @@ -539,11 +567,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), PalettedContainer.Strategy.SECTION_BIOMES ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); newSection = PaperweightPlatformAdapter.newChunkSection( @@ -610,15 +634,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc existingSection.getBiomes() ); - newSection = - PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData - ); + newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + this::loadPrivately, + setArr, + adapter, + biomeRegistry, + biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() + ); if (!PaperweightPlatformAdapter.setSectionAtomic( levelChunkSections, existingSection, @@ -830,7 +853,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } if (callback == null) { if (finalizer != null) { - finalizer.run(); + queueHandler.async(finalizer, null); } return null; } else { @@ -1087,9 +1110,13 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc final int sectionIndex, final PalettedContainerRO> data ) { + BiomeType[] sectionBiomes; + if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { + return null; + } PalettedContainer> biomeData; if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer; + biomeData = palettedContainer.copy(); } else { LOGGER.warn( "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + @@ -1099,10 +1126,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc ); biomeData = data.recreate(); } - BiomeType[] sectionBiomes; - if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return biomeData; - } for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { @@ -1114,10 +1137,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc x, y, z, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)) + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) ); } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java index 29d7278a5..721758c3e 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java @@ -59,7 +59,6 @@ import net.minecraft.world.level.entity.PersistentEntitySectionManager; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_20_R2.CraftChunk; -import sun.misc.Unsafe; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -99,7 +98,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final Field fieldTickingFluidCount; private static final Field fieldTickingBlockCount; - private static final Field fieldNonEmptyBlockCount; private static final MethodHandle methodGetVisibleChunk; @@ -108,6 +106,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final MethodHandle methodRemoveGameEventListener; private static final MethodHandle methodremoveTickingBlockEntity; + private static final Field fieldBiomes; /* * This is a workaround for the changes from https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/1fddefce1cdce44010927b888432bf70c0e88cde#src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -143,8 +142,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e")); - fieldNonEmptyBlockCount.setAccessible(true); + fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i")); + fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( "getVisibleChunkIfPresent", @@ -408,7 +407,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @Nullable PalettedContainer> biomes ) { if (set == null) { - return newChunkSection(layer, biomeRegistry, biomes); + return newChunkSection(biomeRegistry, biomes); } final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); @@ -498,7 +497,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @SuppressWarnings("deprecation") // Only deprecated in paper private static LevelChunkSection newChunkSection( - int layer, Registry biomeRegistry, @Nullable PalettedContainer> biomes ) { @@ -513,6 +511,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return new LevelChunkSection(dataPaletteBlocks, biomes); } + public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { + try { + fieldBiomes.set(section, biomes); + } catch (IllegalAccessException e) { + LOGGER.error("Could not set biomes to chunk section", e); + } + } + /** * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. */ diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java index a52f7909f..2a4d1fec4 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java @@ -29,7 +29,11 @@ import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; import io.papermc.lib.PaperLib; import io.papermc.paper.event.block.BeaconDeactivatedEvent; -import net.minecraft.core.*; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.IdMap; +import net.minecraft.core.Registry; +import net.minecraft.core.SectionPos; import net.minecraft.nbt.IntTag; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundEvents; @@ -42,7 +46,14 @@ import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.entity.BeaconBlockEntity; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.*; +import net.minecraft.world.level.chunk.DataLayer; +import net.minecraft.world.level.chunk.HashMapPalette; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.LinearPalette; +import net.minecraft.world.level.chunk.Palette; +import net.minecraft.world.level.chunk.PalettedContainer; +import net.minecraft.world.level.chunk.PalettedContainerRO; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.lighting.LevelLightEngine; import org.apache.logging.log4j.Logger; @@ -52,7 +63,17 @@ import org.bukkit.craftbukkit.v1_20_R3.block.CraftBlock; import org.bukkit.event.entity.CreatureSpawnEvent; import javax.annotation.Nonnull; -import java.util.*; +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; @@ -496,7 +517,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } } } else { - setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes()); + PalettedContainer> paletteBiomes = setBiomesToPalettedContainer( + biomes, + setSectionIndex, + existingSection.getBiomes() + ); + if (paletteBiomes != null) { + PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); + } } } } @@ -538,11 +566,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), PalettedContainer.Strategy.SECTION_BIOMES ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); newSection = PaperweightPlatformAdapter.newChunkSection( @@ -609,15 +633,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc existingSection.getBiomes() ); - newSection = - PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData - ); + newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + this::loadPrivately, + setArr, + adapter, + biomeRegistry, + biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() + ); if (!PaperweightPlatformAdapter.setSectionAtomic( levelChunkSections, existingSection, @@ -829,7 +852,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } if (callback == null) { if (finalizer != null) { - finalizer.run(); + queueHandler.async(finalizer, null); } return null; } else { @@ -1084,9 +1107,13 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc final int sectionIndex, final PalettedContainerRO> data ) { + BiomeType[] sectionBiomes; + if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { + return null; + } PalettedContainer> biomeData; if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer; + biomeData = palettedContainer.copy(); } else { LOGGER.warn( "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + @@ -1096,10 +1123,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc ); biomeData = data.recreate(); } - BiomeType[] sectionBiomes; - if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return biomeData; - } for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { @@ -1111,10 +1134,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc x, y, z, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)) + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) ); } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java index 2f25bc6f1..fb655322b 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java @@ -98,7 +98,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final Field fieldTickingFluidCount; private static final Field fieldTickingBlockCount; - private static final Field fieldNonEmptyBlockCount; + private static final Field fieldBiomes; private static final MethodHandle methodGetVisibleChunk; @@ -142,8 +142,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e")); - fieldNonEmptyBlockCount.setAccessible(true); + fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i")); + fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( "getVisibleChunkIfPresent", @@ -407,7 +407,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @Nullable PalettedContainer> biomes ) { if (set == null) { - return newChunkSection(layer, biomeRegistry, biomes); + return newChunkSection(biomeRegistry, biomes); } final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); @@ -497,7 +497,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @SuppressWarnings("deprecation") // Only deprecated in paper private static LevelChunkSection newChunkSection( - int layer, Registry biomeRegistry, @Nullable PalettedContainer> biomes ) { @@ -512,6 +511,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return new LevelChunkSection(dataPaletteBlocks, biomes); } + public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { + try { + fieldBiomes.set(section, biomes); + } catch (IllegalAccessException e) { + LOGGER.error("Could not set biomes to chunk section", e); + } + } + /** * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. */ diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java index 2c0a46bb3..063829c0d 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java @@ -29,7 +29,11 @@ import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; import io.papermc.lib.PaperLib; import io.papermc.paper.event.block.BeaconDeactivatedEvent; -import net.minecraft.core.*; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.IdMap; +import net.minecraft.core.Registry; +import net.minecraft.core.SectionPos; import net.minecraft.nbt.IntTag; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.level.ServerLevel; @@ -43,7 +47,14 @@ import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.entity.BeaconBlockEntity; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.*; +import net.minecraft.world.level.chunk.DataLayer; +import net.minecraft.world.level.chunk.HashMapPalette; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.LinearPalette; +import net.minecraft.world.level.chunk.Palette; +import net.minecraft.world.level.chunk.PalettedContainer; +import net.minecraft.world.level.chunk.PalettedContainerRO; import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.lighting.LevelLightEngine; import org.apache.logging.log4j.Logger; @@ -53,7 +64,17 @@ import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.event.entity.CreatureSpawnEvent; import javax.annotation.Nonnull; -import java.util.*; +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Future; @@ -499,7 +520,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } } } else { - setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes()); + PalettedContainer> paletteBiomes = setBiomesToPalettedContainer( + biomes, + setSectionIndex, + existingSection.getBiomes() + ); + if (paletteBiomes != null) { + PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); + } } } } @@ -541,11 +569,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), PalettedContainer.Strategy.SECTION_BIOMES ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); newSection = PaperweightPlatformAdapter.newChunkSection( @@ -612,18 +636,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc existingSection.getBiomes() ); - newSection = - PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData - ); - if (!PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - existingSection, + newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + this::loadPrivately, + setArr, + adapter, + biomeRegistry, + biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() + ); + if (!PaperweightPlatformAdapter.setSectionAtomic(levelChunkSections, existingSection, newSection, getSectionIndex )) { @@ -832,7 +853,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } if (callback == null) { if (finalizer != null) { - finalizer.run(); + queueHandler.async(finalizer, null); } return null; } else { @@ -1089,9 +1110,13 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc final int sectionIndex, final PalettedContainerRO> data ) { + BiomeType[] sectionBiomes; + if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { + return null; + } PalettedContainer> biomeData; if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer; + biomeData = palettedContainer.copy(); } else { LOGGER.warn( "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + @@ -1101,10 +1126,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc ); biomeData = data.recreate(); } - BiomeType[] sectionBiomes; - if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return biomeData; - } for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { @@ -1116,10 +1137,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc x, y, z, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)) + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) ); } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java index 76a7a9025..6c0f72590 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java @@ -10,7 +10,6 @@ import com.fastasyncworldedit.core.math.BitArrayUnstretched; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.ReflectionUtils; import com.fastasyncworldedit.core.util.TaskManager; -import com.mojang.datafixers.util.Either; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.Refraction; @@ -77,7 +76,6 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; @@ -98,7 +96,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final Field fieldTickingFluidCount; private static final Field fieldTickingBlockCount; - private static final Field fieldNonEmptyBlockCount; + private static final Field fieldBiomes; private static final MethodHandle methodGetVisibleChunk; @@ -142,8 +140,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e")); - fieldNonEmptyBlockCount.setAccessible(true); + fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i")); + fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( "getVisibleChunkIfPresent", @@ -405,7 +403,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @Nullable PalettedContainer> biomes ) { if (set == null) { - return newChunkSection(layer, biomeRegistry, biomes); + return newChunkSection(biomeRegistry, biomes); } final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); @@ -495,7 +493,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @SuppressWarnings("deprecation") // Only deprecated in paper private static LevelChunkSection newChunkSection( - int layer, Registry biomeRegistry, @Nullable PalettedContainer> biomes ) { @@ -510,6 +507,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return new LevelChunkSection(dataPaletteBlocks, biomes); } + public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { + try { + fieldBiomes.set(section, biomes); + } catch (IllegalAccessException e) { + LOGGER.error("Could not set biomes to chunk section", e); + } + } + /** * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. */ From 3761b5184c8d25b6158e172c9491e50b067b5fc2 Mon Sep 17 00:00:00 2001 From: Jordan Date: Sat, 15 Jun 2024 15:52:11 +0200 Subject: [PATCH 164/220] fix: correctly create Minecraft Structure format schematics (#2787) - fixes #2784 - fixes #2785 --- .../io/schematic/MinecraftStructure.java | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java index c1f129112..91fb75495 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java @@ -19,7 +19,6 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.registry.state.AbstractProperty; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.block.BaseBlock; @@ -174,27 +173,23 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { ArrayList> palette = new ArrayList<>(); for (BlockVector3 point : region) { BlockState block = clipboard.getBlock(point); - int combined = block.getInternalId(); + char ordinal = block.getOrdinalChar(); BlockType type = block.getBlockType(); - if (type == BlockTypes.STRUCTURE_VOID || indexes.containsKey(combined)) { + if (type == BlockTypes.STRUCTURE_VOID || indexes.containsKey(ordinal)) { continue; } - indexes.put(combined, (Integer) palette.size()); + indexes.put(ordinal, palette.size()); HashMap paletteEntry = new HashMap<>(); paletteEntry.put("Name", type.id()); if (block.getInternalId() != type.getInternalId()) { Map properties = null; - for (AbstractProperty property : (List>) type.getProperties()) { - int propIndex = property.getIndex(block.getInternalId()); - if (propIndex != 0) { - if (properties == null) { - properties = new HashMap<>(); - } - Object value = property.getValues().get(propIndex); - properties.put(property.getName(), value.toString()); + for (Map.Entry, Object> entry : block.getStates().entrySet()) { + if (properties == null) { + properties = new HashMap<>(); } + properties.put(entry.getKey().getName(), entry.getValue().toString()); } if (properties != null) { paletteEntry.put("Properties", properties); @@ -211,16 +206,23 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { for (BlockVector3 point : region) { BaseBlock block = clipboard.getFullBlock(point); if (block.getBlockType() != BlockTypes.STRUCTURE_VOID) { - int combined = block.getInternalId(); - int index = indexes.get(combined); - List pos = Arrays.asList(point.x() - min.x(), - point.y() - min.y(), point.z() - min.z() + char ordinal = block.getOrdinalChar(); + int index = indexes.get(ordinal); + List pos = Arrays.asList( + point.x() - min.x(), + point.y() - min.y(), + point.z() - min.z() ); if (!block.hasNbtData()) { blocks.add(FaweCache.INSTANCE.asMap("state", index, "pos", pos)); } else { + Map tag = new HashMap<>(block.getNbtData().getValue()); + tag.remove("x"); + tag.remove("y"); + tag.remove("z"); + CompoundTag cTag = new CompoundTag(tag); blocks.add( - FaweCache.INSTANCE.asMap("state", index, "pos", pos, "nbt", block.getNbtData())); + FaweCache.INSTANCE.asMap("state", index, "pos", pos, "nbt", cTag)); } } } @@ -231,8 +233,16 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { ArrayList> entities = new ArrayList<>(); for (Entity entity : clipboard.getEntities()) { Location loc = entity.getLocation(); - List pos = Arrays.asList(loc.x(), loc.y(), loc.z()); - List blockPos = Arrays.asList(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + List pos = Arrays.asList( + loc.x() - min.x(), + loc.y() - min.y(), + loc.z() - min.z() + ); + List blockPos = Arrays.asList( + loc.getBlockX() - min.x(), + loc.getBlockY() - min.y(), + loc.getBlockZ() - min.z() + ); BaseEntity state = entity.getState(); if (state != null) { CompoundTag nbt = state.getNbtData(); From 49ac08d5b4e6b60dec435f0e768dad708eaa9c85 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sat, 15 Jun 2024 20:53:01 +0100 Subject: [PATCH 165/220] Revert "Remove self-refraction-check" This reverts commit 2eb6b5a12306cc2dc7cfc35e8c03f38ac8f7067c. --- .../impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java | 9 ++++++++- .../impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java | 9 ++++++++- .../impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java | 9 ++++++++- .../impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java | 9 ++++++++- .../impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java | 9 ++++++++- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java index ccd6ed982..334289b08 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java @@ -139,7 +139,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "g")); fieldTickingBlockCount.setAccessible(true); - fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "j")); + Field tmpFieldBiomes; + try { + // It seems to actually be biomes, but is apparently obfuscated to "j" + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); + } catch (NoSuchFieldException ignored) { + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("j"); + } + fieldBiomes = tmpFieldBiomes; fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java index 999dd3646..05c0b58f9 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java @@ -148,7 +148,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i")); + Field tmpFieldBiomes; + try { + // It seems to actually be biomes, but is apparently obfuscated to "i" + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); + } catch (NoSuchFieldException ignored) { + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("i"); + } + fieldBiomes = tmpFieldBiomes; fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java index 721758c3e..91dcfe24e 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java @@ -142,7 +142,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i")); + Field tmpFieldBiomes; + try { + // It seems to actually be biomes, but is apparently obfuscated to "i" + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); + } catch (NoSuchFieldException ignored) { + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("i"); + } + fieldBiomes = tmpFieldBiomes; fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java index fb655322b..f2f78eb7d 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java @@ -142,7 +142,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i")); + Field tmpFieldBiomes; + try { + // It seems to actually be biomes, but is apparently obfuscated to "i" + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); + } catch (NoSuchFieldException ignored) { + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("i"); + } + fieldBiomes = tmpFieldBiomes; fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java index 6c0f72590..e19e33524 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java @@ -140,7 +140,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i")); + Field tmpFieldBiomes; + try { + // It seems to actually be biomes, but is apparently obfuscated to "i" + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); + } catch (NoSuchFieldException ignored) { + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("i"); + } + fieldBiomes = tmpFieldBiomes; fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( From 5ab79a3f6156a7025a2d8b52e582781fb44b5af0 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sun, 16 Jun 2024 09:24:54 +0100 Subject: [PATCH 166/220] ref: biomes refrection works on 1.20.6 --- .../impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java index e19e33524..6c0f72590 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java @@ -140,14 +140,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - Field tmpFieldBiomes; - try { - // It seems to actually be biomes, but is apparently obfuscated to "i" - tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); - } catch (NoSuchFieldException ignored) { - tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("i"); - } - fieldBiomes = tmpFieldBiomes; + fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i")); fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( From 7c7118ce26d471fa9b204b768fdd50a9fa9a2f52 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 01:44:06 +0000 Subject: [PATCH 167/220] Update dependency paperweight-userdev to v1.20.6-R0.1-20240615.211816-120 (#2794) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts index a2b5aa66d..4fca485af 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/ - the().paperDevBundle("1.20.6-R0.1-20240604.210637-112") + the().paperDevBundle("1.20.6-R0.1-20240615.211816-120") compileOnly(libs.paperlib) } From c7d6c907f187d374c2bc6444d5dc0a0a0ecbed26 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 01:44:30 +0000 Subject: [PATCH 168/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.3.0 (#2793) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bb46a654c..50e1a1757 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.2.14" +towny = "0.100.3.0" plotsquared = "7.3.8" # Third party From 6a54c5bcb53ee5a4b2b7dea832c413dd2bbea506 Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 17 Jun 2024 17:40:59 +0200 Subject: [PATCH 169/220] fix: recover from trimmed chunk (#2771) - It's theoretically possible for the section FULL to return a null layer due to race condition with a trim operation - Locally cache result and if null, recover - I just had the error from #1592 again - This seems to have stopped the error, but adding logging did not log, so possibly some bigger bytecode changes? - Oh well --- .../queue/implementation/blocks/CharBlocks.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java index 6eae2db5b..047394322 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java @@ -17,13 +17,23 @@ public abstract class CharBlocks implements IBlocks { protected static final Section FULL = new Section() { @Override public char[] get(CharBlocks blocks, int layer) { - return blocks.blocks[layer]; + char[] arr = blocks.blocks[layer]; + if (arr == null) { + // Chunk probably trimmed mid-operations, but do nothing about it to avoid other issues + return EMPTY.get(blocks, layer, false); + } + return arr; } // Ignore aggressive switch here. @Override public char[] get(CharBlocks blocks, int layer, boolean aggressive) { - return blocks.blocks[layer]; + char[] arr = blocks.blocks[layer]; + if (arr == null) { + // Chunk probably trimmed mid-operations, but do nothing about it to avoid other issues + return EMPTY.get(blocks, layer, false); + } + return arr; } @Override From eaeb3a633aa3a42c0824da33fe77fc995427c52d Mon Sep 17 00:00:00 2001 From: Jordan Date: Wed, 19 Jun 2024 07:38:33 +0200 Subject: [PATCH 170/220] fix: always init ChunkFilterBlock to the chunk (#2788) - rename initFilterBlock from init to create - remove where we now needlessly init filter blocks - fixes #2662 --- .../core/queue/IQueueExtent.java | 14 +++++++++++--- .../queue/implementation/ParallelQueueExtent.java | 7 +++++-- .../implementation/SingleThreadQueueExtent.java | 2 +- .../core/regions/PolyhedralRegion.java | 2 +- .../fastasyncworldedit/core/regions/Triangle.java | 14 +++++++++++++- .../com/sk89q/worldedit/extent/MaskingExtent.java | 3 ++- .../com/sk89q/worldedit/regions/CuboidRegion.java | 1 - .../sk89q/worldedit/regions/EllipsoidRegion.java | 2 -- .../java/com/sk89q/worldedit/regions/Region.java | 1 - 9 files changed, 33 insertions(+), 13 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueExtent.java index c13373d9a..3f104b35d 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueExtent.java @@ -115,7 +115,7 @@ public interface IQueueExtent extends Flushable, Trimable, ICh * A filter block is used to iterate over blocks / positions. Essentially combines BlockVector3, * Extent and BlockState functions in a way that avoids lookups. */ - ChunkFilterBlock initFilterBlock(); + ChunkFilterBlock createFilterBlock(); /** * Returns the number of chunks in this queue. @@ -129,7 +129,14 @@ public interface IQueueExtent extends Flushable, Trimable, ICh */ boolean isEmpty(); - default ChunkFilterBlock apply(ChunkFilterBlock block, Filter filter, Region region, int chunkX, int chunkZ, boolean full) { + default ChunkFilterBlock apply( + @Nullable ChunkFilterBlock block, + Filter filter, + Region region, + int chunkX, + int chunkZ, + boolean full + ) { if (!filter.appliesChunk(chunkX, chunkZ)) { return block; } @@ -139,8 +146,9 @@ public interface IQueueExtent extends Flushable, Trimable, ICh if (newChunk != null) { chunk = newChunk; if (block == null) { - block = this.initFilterBlock(); + block = this.createFilterBlock(); } + block.initChunk(chunkX, chunkZ); chunk.filterBlocks(filter, block, region, full); } this.submit(chunk); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java index 38546ed1b..1b56afdbc 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java @@ -28,6 +28,7 @@ import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Countable; import com.sk89q.worldedit.world.World; @@ -133,14 +134,16 @@ public class ParallelQueueExtent extends PassthroughExtent { final int size = Math.min(chunks.size(), Settings.settings().QUEUE.PARALLEL_THREADS); if (size <= 1) { // if PQE is ever used with PARALLEL_THREADS = 1, or only one chunk is edited, just run sequentially + ChunkFilterBlock block = null; while (chunksIter.hasNext()) { BlockVector2 pos = chunksIter.next(); - getExtent().apply(null, filter, region, pos.x(), pos.z(), full); + block = getExtent().apply(block, filter, region, pos.x(), pos.z(), full); } } else { final ForkJoinTask[] tasks = IntStream.range(0, size).mapToObj(i -> handler.submit(() -> { try { final Filter newFilter = filter.fork(); + final Region newRegion = region.clone(); // Create a chunk that we will reuse/reset for each operation final SingleThreadQueueExtent queue = (SingleThreadQueueExtent) getNewQueue(); queue.setFastMode(fastmode); @@ -162,7 +165,7 @@ public class ParallelQueueExtent extends PassthroughExtent { chunkX = pos.x(); chunkZ = pos.z(); } - block = queue.apply(block, newFilter, region, chunkX, chunkZ, full); + block = queue.apply(block, newFilter, newRegion, chunkX, chunkZ, full); } queue.flush(); } catch (Throwable t) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java index 789547d83..b0239a5a3 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java @@ -473,7 +473,7 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen } @Override - public ChunkFilterBlock initFilterBlock() { + public ChunkFilterBlock createFilterBlock() { return new CharFilterBlock(this); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java index dbfe840c8..a1471c9d8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java @@ -71,7 +71,7 @@ public class PolyhedralRegion extends AbstractRegion { public PolyhedralRegion(PolyhedralRegion region) { this(region.world); vertices.addAll(region.vertices); - triangles.addAll(region.triangles); + region.triangles.forEach(triangle -> triangles.add(triangle.clone())); vertexBacklog.addAll(region.vertexBacklog); minimumPoint = region.minimumPoint; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/Triangle.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/Triangle.java index 2bb9fc5ac..1d96d5f95 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/Triangle.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/Triangle.java @@ -7,10 +7,14 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.regions.polyhedron.Edge; -public class Triangle { +public class Triangle implements Cloneable { public static double RADIUS = 0.5; + private final BlockVector3 pos1; + private final BlockVector3 pos2; + private final BlockVector3 pos3; + private final double[][] verts = new double[3][3]; private final double[] center = new double[3]; private final double[] radius = new double[3]; @@ -28,6 +32,9 @@ public class Triangle { private final double b; public Triangle(BlockVector3 pos1, BlockVector3 pos2, BlockVector3 pos3) { + this.pos1 = pos1; + this.pos2 = pos2; + this.pos3 = pos3; verts[0] = new double[]{pos1.x(), pos1.y(), pos1.z()}; verts[1] = new double[]{pos2.x(), pos2.y(), pos2.z()}; verts[2] = new double[]{pos3.x(), pos3.y(), pos3.z()}; @@ -290,4 +297,9 @@ public class Triangle { return dot(normal, vmax) >= 0.0f; } + @Override + public Triangle clone() { + return new Triangle(pos1, pos2, pos3); + } + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java index 64b6eecc3..0abc80153 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java @@ -106,7 +106,8 @@ public class MaskingExtent extends AbstractDelegateExtent implements IBatchProce @Override public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { final ChunkFilterBlock filter = getOrCreateFilterBlock.apply(Thread.currentThread().getId()); - return filter.filter(chunk, get, set, MaskingExtent.this); + filter.initChunk(chunk.getX(), chunk.getZ()); + return filter.filter(chunk, get, set, this); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java index 8e4da9214..4b0894d91 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java @@ -755,7 +755,6 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { ) { int chunkX = chunk.getX(); int chunkZ = chunk.getZ(); - block = block.initChunk(chunkX, chunkZ); //Chunk entry is an "interior chunk" in regards to the entire region, so filter the chunk whole instead of partially if ((minX + 15) >> 4 <= chunkX && (maxX - 15) >> 4 >= chunkX && (minZ + 15) >> 4 <= chunkZ && (maxZ - 15) >> 4 >= chunkZ) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java index 944e7a14c..1bc13ed43 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java @@ -412,8 +412,6 @@ public class EllipsoidRegion extends AbstractRegion { return; } - block = block.initChunk(chunk.getX(), chunk.getZ()); - // Get the solid layers int cy = center.y(); int diffYFull = MathMan.usqrt(diffY2); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java index e8c6da179..08f2ee00c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java @@ -268,7 +268,6 @@ public interface Region extends Iterable, Cloneable, IBatchProcess ) { int minSection = Math.max(get.getMinSectionPosition(), getMinimumY() >> 4); int maxSection = Math.min(get.getMaxSectionPosition(), getMaximumY() >> 4); - block = block.initChunk(chunk.getX(), chunk.getZ()); for (int layer = minSection; layer <= maxSection; layer++) { if ((!full && !get.hasSection(layer)) || !filter.appliesLayer(chunk, layer)) { return; From d69dc979587a534334b86de1bfabeda16cc83a1a Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 20 Jun 2024 18:24:41 +0200 Subject: [PATCH 171/220] fix: take confirm-large from default limit for unlimited, add option to override (#2782) - fixes #2706 --- .../src/main/java/com/fastasyncworldedit/core/Fawe.java | 3 +++ .../com/fastasyncworldedit/core/configuration/Settings.java | 5 +++++ .../java/com/fastasyncworldedit/core/limit/FaweLimit.java | 4 +++- .../java/com/sk89q/worldedit/command/WorldEditCommands.java | 4 ++++ 4 files changed, 15 insertions(+), 1 deletion(-) 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 ff2f69486..829f29da6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/Fawe.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/Fawe.java @@ -2,6 +2,7 @@ package com.fastasyncworldedit.core; import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.internal.exception.FaweException; +import com.fastasyncworldedit.core.limit.FaweLimit; import com.fastasyncworldedit.core.queue.implementation.QueueHandler; import com.fastasyncworldedit.core.util.CachedTextureUtil; import com.fastasyncworldedit.core.util.CleanTextureUtil; @@ -105,6 +106,8 @@ public class Fawe { * Implementation dependent stuff */ this.setupConfigs(); + FaweLimit.MAX.CONFIRM_LARGE = + Settings.settings().LIMITS.get("default").CONFIRM_LARGE || Settings.settings().GENERAL.LIMIT_UNLIMITED_CONFIRMS; TaskManager.IMP = this.implementation.getTaskManager(); TaskManager.taskManager().async(() -> { 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 cf0ba6f35..d069e62a1 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 @@ -791,6 +791,11 @@ public class Settings extends Config { }) public boolean UNSTUCK_ON_GENERATE = true; + @Comment({ + "If unlimited limits should still require /confirm on large. Defaults to limits.default.confirm-large otherwise." + }) + public boolean LIMIT_UNLIMITED_CONFIRMS = true; + } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java index 5ecc89d44..e30ee4db6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java @@ -1,6 +1,7 @@ package com.fastasyncworldedit.core.limit; import com.fastasyncworldedit.core.FaweCache; +import com.fastasyncworldedit.core.configuration.Settings; import java.util.Collections; import java.util.Set; @@ -121,7 +122,8 @@ public class FaweLimit { MAX.SCHEM_FILE_SIZE_LIMIT = Integer.MAX_VALUE; MAX.MAX_EXPRESSION_MS = 50; MAX.FAST_PLACEMENT = true; - MAX.CONFIRM_LARGE = true; + MAX.CONFIRM_LARGE = + Settings.settings().LIMITS.get("default").CONFIRM_LARGE || Settings.settings().GENERAL.LIMIT_UNLIMITED_CONFIRMS; MAX.RESTRICT_HISTORY_TO_REGIONS = false; MAX.STRIP_NBT = Collections.emptySet(); MAX.UNIVERSAL_DISALLOWED_BLOCKS = false; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java index db611b75c..04274a79a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java @@ -22,6 +22,8 @@ package com.sk89q.worldedit.command; import com.fastasyncworldedit.core.Fawe; import com.fastasyncworldedit.core.FaweVersion; import com.fastasyncworldedit.core.configuration.Caption; +import com.fastasyncworldedit.core.configuration.Settings; +import com.fastasyncworldedit.core.limit.FaweLimit; import com.fastasyncworldedit.core.util.UpdateNotification; import com.intellectualsites.paster.IncendoPaster; import com.sk89q.worldedit.LocalSession; @@ -97,6 +99,8 @@ public class WorldEditCommands { .getConfiguration())); //FAWE start Fawe.instance().setupConfigs(); + FaweLimit.MAX.CONFIRM_LARGE = + Settings.settings().LIMITS.get("default").CONFIRM_LARGE || Settings.settings().GENERAL.LIMIT_UNLIMITED_CONFIRMS; //FAWE end actor.print(Caption.of("worldedit.reload.config")); } From 705df34c12eac4e872a73e15e1ec97a0db2550df Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 20 Jun 2024 20:49:16 +0200 Subject: [PATCH 172/220] fix: create new biome paletted container when writing (#2791) - resizing a paletted container copy alters the original paletted container - copy is not clone - fixes #2790 --- .../fawe/v1_19_R3/PaperweightGetBlocks.java | 30 +++++++------------ .../v1_19_R3/PaperweightGetBlocks_Copy.java | 13 +++++--- .../fawe/v1_20_R1/PaperweightGetBlocks.java | 30 +++++++------------ .../v1_20_R1/PaperweightGetBlocks_Copy.java | 13 +++++--- .../fawe/v1_20_R2/PaperweightGetBlocks.java | 30 +++++++------------ .../v1_20_R2/PaperweightGetBlocks_Copy.java | 13 +++++--- .../fawe/v1_20_R3/PaperweightGetBlocks.java | 30 +++++++------------ .../v1_20_R3/PaperweightGetBlocks_Copy.java | 13 +++++--- .../fawe/v1_20_R4/PaperweightGetBlocks.java | 30 +++++++------------ .../v1_20_R4/PaperweightGetBlocks_Copy.java | 13 +++++--- 10 files changed, 95 insertions(+), 120 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java index 4d979fd0e..470378715 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java @@ -824,7 +824,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc nmsChunk.mustNotSave = false; nmsChunk.setUnsaved(true); // send to player - if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { + if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) { this.send(); } if (finalizer != null) { @@ -1109,31 +1109,21 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { return null; } - PalettedContainer> biomeData; - if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer.copy(); - } else { - LOGGER.warn( - "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + - "type {} but got {}", - PalettedContainer.class.getSimpleName(), - data.getClass().getSimpleName() - ); - biomeData = data.recreate(); - } + PalettedContainer> biomeData = data.recreate(); for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { BiomeType biomeType = sectionBiomes[index]; if (biomeType == null) { - continue; + biomeData.set(x, y, z, data.get(x, y, z)); + } else { + biomeData.set( + x, + y, + z, + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) + ); } - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) - ); } } } diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java index 7e908c74c..dd1787868 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java @@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final int maxHeight; final ServerLevel serverLevel; final LevelChunk levelChunk; - private PalettedContainer>[] biomes = null; + private Holder[][] biomes = null; protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.levelChunk = levelChunk; @@ -144,7 +144,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { @Override public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); + Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; return PaperweightPlatformAdapter.adapt(biome, serverLevel); } @@ -173,10 +173,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { if (biomes == null) { - biomes = new PalettedContainer[getSectionCount()]; + biomes = new Holder[getSectionCount()][]; + } + if (biomes[layer] == null) { + biomes[layer] = new Holder[64]; } if (biomeData instanceof PalettedContainer> palettedContainer) { - biomes[layer] = palettedContainer.copy(); + for (int i = 0; i < 64; i++) { + biomes[layer][i] = palettedContainer.get(i); + } } else { LOGGER.error( "Cannot correctly save biomes to history. Expected class type {} but got {}", diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java index cc329c16a..b26a42e74 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java @@ -822,7 +822,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc nmsChunk.mustNotSave = false; nmsChunk.setUnsaved(true); // send to player - if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { + if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) { this.send(); } if (finalizer != null) { @@ -1106,31 +1106,21 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { return null; } - PalettedContainer> biomeData; - if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer.copy(); - } else { - LOGGER.warn( - "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + - "type {} but got {}", - PalettedContainer.class.getSimpleName(), - data.getClass().getSimpleName() - ); - biomeData = data.recreate(); - } + PalettedContainer> biomeData = data.recreate(); for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { BiomeType biomeType = sectionBiomes[index]; if (biomeType == null) { - continue; + biomeData.set(x, y, z, data.get(x, y, z)); + } else { + biomeData.set( + x, + y, + z, + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) + ); } - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) - ); } } } diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java index a3ca91376..d2412b98f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java @@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final int maxHeight; final ServerLevel serverLevel; final LevelChunk levelChunk; - private PalettedContainer>[] biomes = null; + private Holder[][] biomes = null; protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.levelChunk = levelChunk; @@ -144,7 +144,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { @Override public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); + Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; return PaperweightPlatformAdapter.adapt(biome, serverLevel); } @@ -173,10 +173,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { if (biomes == null) { - biomes = new PalettedContainer[getSectionCount()]; + biomes = new Holder[getSectionCount()][]; + } + if (biomes[layer] == null) { + biomes[layer] = new Holder[64]; } if (biomeData instanceof PalettedContainer> palettedContainer) { - biomes[layer] = palettedContainer.copy(); + for (int i = 0; i < 64; i++) { + biomes[layer][i] = palettedContainer.get(i); + } } else { LOGGER.error( "Cannot correctly save biomes to history. Expected class type {} but got {}", diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java index f5492fccb..58d53d037 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java @@ -830,7 +830,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc nmsChunk.mustNotSave = false; nmsChunk.setUnsaved(true); // send to player - if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { + if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) { this.send(); } if (finalizer != null) { @@ -1114,31 +1114,21 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { return null; } - PalettedContainer> biomeData; - if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer.copy(); - } else { - LOGGER.warn( - "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + - "type {} but got {}", - PalettedContainer.class.getSimpleName(), - data.getClass().getSimpleName() - ); - biomeData = data.recreate(); - } + PalettedContainer> biomeData = data.recreate(); for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { BiomeType biomeType = sectionBiomes[index]; if (biomeType == null) { - continue; + biomeData.set(x, y, z, data.get(x, y, z)); + } else { + biomeData.set( + x, + y, + z, + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) + ); } - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) - ); } } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks_Copy.java index 1c1130764..b6f4c7d94 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks_Copy.java @@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final int maxHeight; final ServerLevel serverLevel; final LevelChunk levelChunk; - private PalettedContainer>[] biomes = null; + private Holder[][] biomes = null; protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.levelChunk = levelChunk; @@ -144,7 +144,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { @Override public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); + Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; return PaperweightPlatformAdapter.adapt(biome, serverLevel); } @@ -173,10 +173,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { if (biomes == null) { - biomes = new PalettedContainer[getSectionCount()]; + biomes = new Holder[getSectionCount()][]; + } + if (biomes[layer] == null) { + biomes[layer] = new Holder[64]; } if (biomeData instanceof PalettedContainer> palettedContainer) { - biomes[layer] = palettedContainer.copy(); + for (int i = 0; i < 64; i++) { + biomes[layer][i] = palettedContainer.get(i); + } } else { LOGGER.error( "Cannot correctly save biomes to history. Expected class type {} but got {}", diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java index 2a4d1fec4..afdd64baa 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java @@ -829,7 +829,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc nmsChunk.mustNotSave = false; nmsChunk.setUnsaved(true); // send to player - if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { + if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) { this.send(); } if (finalizer != null) { @@ -1111,31 +1111,21 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { return null; } - PalettedContainer> biomeData; - if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer.copy(); - } else { - LOGGER.warn( - "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + - "type {} but got {}", - PalettedContainer.class.getSimpleName(), - data.getClass().getSimpleName() - ); - biomeData = data.recreate(); - } + PalettedContainer> biomeData = data.recreate(); for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { BiomeType biomeType = sectionBiomes[index]; if (biomeType == null) { - continue; + biomeData.set(x, y, z, data.get(x, y, z)); + } else { + biomeData.set( + x, + y, + z, + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) + ); } - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) - ); } } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks_Copy.java index 92d9ec801..23c882284 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks_Copy.java @@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final int maxHeight; final ServerLevel serverLevel; final LevelChunk levelChunk; - private PalettedContainer>[] biomes = null; + private Holder[][] biomes = null; protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.levelChunk = levelChunk; @@ -144,7 +144,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { @Override public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); + Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; return PaperweightPlatformAdapter.adapt(biome, serverLevel); } @@ -173,10 +173,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { if (biomes == null) { - biomes = new PalettedContainer[getSectionCount()]; + biomes = new Holder[getSectionCount()][]; + } + if (biomes[layer] == null) { + biomes[layer] = new Holder[64]; } if (biomeData instanceof PalettedContainer> palettedContainer) { - biomes[layer] = palettedContainer.copy(); + for (int i = 0; i < 64; i++) { + biomes[layer][i] = palettedContainer.get(i); + } } else { LOGGER.error( "Cannot correctly save biomes to history. Expected class type {} but got {}", diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java index 063829c0d..bd2873b7f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java @@ -830,7 +830,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc nmsChunk.mustNotSave = false; nmsChunk.setUnsaved(true); // send to player - if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { + if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) { this.send(); } if (finalizer != null) { @@ -1114,31 +1114,21 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { return null; } - PalettedContainer> biomeData; - if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer.copy(); - } else { - LOGGER.warn( - "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + - "type {} but got {}", - PalettedContainer.class.getSimpleName(), - data.getClass().getSimpleName() - ); - biomeData = data.recreate(); - } + PalettedContainer> biomeData = data.recreate(); for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { BiomeType biomeType = sectionBiomes[index]; if (biomeType == null) { - continue; + biomeData.set(x, y, z, data.get(x, y, z)); + } else { + biomeData.set( + x, + y, + z, + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) + ); } - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) - ); } } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java index c0a7bda52..146760020 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java @@ -46,7 +46,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final int maxHeight; final ServerLevel serverLevel; final LevelChunk levelChunk; - private PalettedContainer>[] biomes = null; + private Holder[][] biomes = null; protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.levelChunk = levelChunk; @@ -145,7 +145,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { @Override public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); + Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; return PaperweightPlatformAdapter.adapt(biome, serverLevel); } @@ -174,10 +174,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { if (biomes == null) { - biomes = new PalettedContainer[getSectionCount()]; + biomes = new Holder[getSectionCount()][]; + } + if (biomes[layer] == null) { + biomes[layer] = new Holder[64]; } if (biomeData instanceof PalettedContainer> palettedContainer) { - biomes[layer] = palettedContainer.copy(); + for (int i = 0; i < 64; i++) { + biomes[layer][i] = palettedContainer.get(i); + } } else { LOGGER.error( "Cannot correctly save biomes to history. Expected class type {} but got {}", From 4fe9c6bd7433117c9cade8be73925a404d7ba15b Mon Sep 17 00:00:00 2001 From: Jordan Date: Fri, 21 Jun 2024 08:49:09 +0200 Subject: [PATCH 173/220] fix: correctly process chunks when using worldguard region blacklists (#2789) - fixes #2399 --- .../fastasyncworldedit/bukkit/regions/WorldGuardFeature.java | 4 ++++ .../src/main/java/com/sk89q/worldedit/regions/Region.java | 2 +- .../java/com/sk89q/worldedit/regions/RegionIntersection.java | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java index c847a8688..6a055de05 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java @@ -1,5 +1,6 @@ package com.fastasyncworldedit.bukkit.regions; +import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.regions.FaweMask; import com.fastasyncworldedit.core.regions.RegionWrapper; import com.sk89q.worldedit.bukkit.BukkitAdapter; @@ -158,6 +159,9 @@ public class WorldGuardFeature extends BukkitMaskManager implements Listener { @Override public FaweMask getMask(com.sk89q.worldedit.entity.Player wePlayer, MaskType type, boolean isWhitelist) { + if (isWhitelist && Settings.settings().REGION_RESTRICTIONS_OPTIONS.WORLDGUARD_REGION_BLACKLIST) { + return new FaweMask(RegionWrapper.GLOBAL()); + } final Player player = BukkitAdapter.adapt(wePlayer); final LocalPlayer localplayer = this.worldguard.wrapPlayer(player); final Location location = player.getLocation(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java index 08f2ee00c..085274772 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java @@ -482,7 +482,7 @@ public interface Region extends Iterable, Cloneable, IBatchProcess } return set; } else { - return null; + return set; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java index c1a81834c..4312e50fa 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java @@ -205,7 +205,7 @@ public class RegionIntersection extends AbstractRegion { BlockVector3 regMin = region.getMinimumPoint(); BlockVector3 regMax = region.getMaximumPoint(); if (tx >= regMin.x() && bx <= regMax.x() && tz >= regMin.z() && bz <= regMax.z()) { - return region.processSet(chunk, get, set, true); + set = region.processSet(chunk, get, set, true); } } return set; // default return set as no "blacklist" regions contained the chunk From 5708eb7aa0cdf46d0b0a538c7785d76518c139e0 Mon Sep 17 00:00:00 2001 From: Jordan Date: Sun, 23 Jun 2024 22:33:36 +0200 Subject: [PATCH 174/220] fix: correct y index addition in biome history (#2797) --- .../core/history/changeset/FaweStreamChangeSet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/FaweStreamChangeSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/FaweStreamChangeSet.java index 71232a31c..ad7c82c9f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/FaweStreamChangeSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/FaweStreamChangeSet.java @@ -353,7 +353,7 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet { os.write((byte) (z)); // only need to store biomes in the 4x4x4 chunks so only need one byte for y still (signed byte -128 -> 127) // means -512 -> 508. Add 128 to avoid negative value casting. - os.write((byte) (y + 32)); + os.write((byte) (y + 128)); os.writeVarInt(from.getInternalId()); os.writeVarInt(to.getInternalId()); } catch (IOException e) { From 3aa4a4b482293fc17b522414bb56e535269e3561 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 01:39:12 +0000 Subject: [PATCH 175/220] Update dependency paperweight-userdev to v1.20.6-R0.1-20240617.192752-122 (#2799) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts index 4fca485af..34e3569eb 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/ - the().paperDevBundle("1.20.6-R0.1-20240615.211816-120") + the().paperDevBundle("1.20.6-R0.1-20240617.192752-122") compileOnly(libs.paperlib) } From 06bf7104cc8867f81c0e2c4ca8e28f30303ea20c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Jun 2024 01:39:43 +0000 Subject: [PATCH 176/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.3.2 (#2798) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 50e1a1757..70a4116a6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.3.0" +towny = "0.100.3.2" plotsquared = "7.3.8" # Third party From 75af797d4c7462b445461cc96590ac0f59fd841c Mon Sep 17 00:00:00 2001 From: Jordan Date: Wed, 26 Jun 2024 17:32:36 +0200 Subject: [PATCH 177/220] fix: extract new config option for deleting disk history on logout (#2772) * fix: extract new config option for deleting disk history on logout - fixes #2663 * Copyto is nullable --- .../core/configuration/Config.java | 78 +++++++++++++++---- .../core/configuration/Settings.java | 3 + .../com/sk89q/worldedit/entity/Player.java | 8 +- 3 files changed, 69 insertions(+), 20 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java index d230ab05b..2a1a5a5ef 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java @@ -6,6 +6,7 @@ import com.sk89q.util.StringUtil; import com.sk89q.worldedit.internal.util.LogManagerCompat; import org.apache.logging.log4j.Logger; +import javax.annotation.Nullable; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.PrintWriter; @@ -18,6 +19,7 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -31,10 +33,15 @@ public class Config { private static final Logger LOGGER = LogManagerCompat.getLogger(); private final Map removedKeyVals = new HashMap<>(); + @Nullable + private Map> copyTo = new HashMap<>(); + private boolean performCopyTo = false; private List existingMigrateNodes = null; public Config() { - save(new PrintWriter(new ByteArrayOutputStream(0)), getClass(), this, 0); + // This is now definitely required as the save -> load -> save order means the @CopiedFrom annotated fields work + save(new PrintWriter(new ByteArrayOutputStream(0)), getClass(), this, 0, null); + performCopyTo = true; } /** @@ -60,11 +67,12 @@ public class Config { /** * Set the value of a specific node. Probably throws some error if you supply non existing keys or invalid values. + * This should only be called during loading of a config file * * @param key config node * @param value value */ - private void set(String key, Object value, Class root) { + private void setLoadedNode(String key, Object value, Class root) { String[] split = key.split("\\."); Object instance = getInstance(split, root); if (instance != null) { @@ -74,8 +82,18 @@ public class Config { if (field.getAnnotation(Final.class) != null) { return; } + if (copyTo != null) { + copyTo.remove(key); // Remove if the config field is already written + final Object finalValue = value; + copyTo.replaceAll((copyToNode, entry) -> { + if (!key.equals(entry.getKey())) { + return entry; + } + return new AbstractMap.SimpleEntry<>(key, finalValue); + }); + } Migrate migrate = field.getAnnotation(Migrate.class); - if (existingMigrateNodes != null && migrate != null) { + if (migrate != null) { existingMigrateNodes.add(migrate.value()); } if (field.getType() == String.class && !(value instanceof String)) { @@ -90,8 +108,9 @@ public class Config { } } removedKeyVals.put(key, value); - LOGGER.error( - "Failed to set config option: {}: {} | {} | {}.yml. This is likely because it was removed.", + LOGGER.warn( + "Failed to set config option: {}: {} | {} | {}.yml. This is likely because it was removed or was set with an " + + "invalid value.", key, value, instance, @@ -110,7 +129,7 @@ public class Config { if (value instanceof MemorySection) { continue; } - set(key, value, getClass()); + setLoadedNode(key, value, getClass()); } for (String node : existingMigrateNodes) { removedKeyVals.remove(node); @@ -133,7 +152,7 @@ public class Config { } PrintWriter writer = new PrintWriter(file); Object instance = this; - save(writer, getClass(), instance, 0); + save(writer, getClass(), instance, 0, null); writer.close(); } catch (Throwable e) { LOGGER.error("Failed to save config file: {}", file, e); @@ -190,7 +209,7 @@ public class Config { } /** - * Indicates that a field should be instantiated / created. + * Indicates that a field should be migrated from a node that is deleted * * @since 2.10.0 */ @@ -202,6 +221,19 @@ public class Config { } + /** + * Indicates that a field's default value should match another input if the config is otherwise already generated + * + * @since TODO + */ + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.FIELD}) + public @interface CopiedFrom { + + String value(); + + } + @Ignore // This is not part of the config public static class ConfigBlock { @@ -254,7 +286,7 @@ public class Config { return value != null ? value.toString() : "null"; } - private void save(PrintWriter writer, Class clazz, final Object instance, int indent) { + private void save(PrintWriter writer, Class clazz, final Object instance, int indent, String parentNode) { try { String CTRF = System.lineSeparator(); String spacing = StringMan.repeat(" ", indent); @@ -274,7 +306,7 @@ public class Config { } if (current == ConfigBlock.class) { current = (Class) ((ParameterizedType) (field.getGenericType())).getActualTypeArguments()[0]; - handleConfigBlockSave(writer, instance, indent, field, spacing, CTRF, current); + handleConfigBlockSave(writer, instance, indent, field, spacing, CTRF, current, parentNode); continue; } else if (!removedKeyVals.isEmpty()) { Migrate migrate = field.getAnnotation(Migrate.class); @@ -283,6 +315,17 @@ public class Config { field.set(instance, value); } } + CopiedFrom copiedFrom; + if (copyTo != null && (copiedFrom = field.getAnnotation(CopiedFrom.class)) != null) { + String node = toNodeName(field.getName()); + node = parentNode == null ? node : parentNode + "." + node; + Map.Entry entry = copyTo.remove(node); + if (entry == null) { + copyTo.put(node,new AbstractMap.SimpleEntry<>(copiedFrom.value(), null)); + } else { + field.set(instance, entry.getValue()); + } + } Create create = field.getAnnotation(Create.class); if (create != null) { Object value = field.get(instance); @@ -296,11 +339,12 @@ public class Config { writer.write(spacing + "# " + commentLine + CTRF); } } - writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF); + String node = toNodeName(current.getSimpleName()); + writer.write(spacing + node + ":" + CTRF); if (value == null) { field.set(instance, value = current.getDeclaredConstructor().newInstance()); } - save(writer, current, value, indent + 2); + save(writer, current, value, indent + 2, parentNode == null ? node : parentNode + "." + node); } else { writer.write(spacing + toNodeName(field.getName() + ": ") + toYamlString( field.get(instance), @@ -311,6 +355,10 @@ public class Config { } catch (Throwable e) { LOGGER.error("Failed to save config file", e); } + if (parentNode == null && performCopyTo) { + performCopyTo = false; + copyTo = null; + } } private void handleConfigBlockSave( @@ -320,7 +368,8 @@ public class Config { Field field, String spacing, String CTRF, - Class current + Class current, + String parentNode ) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException { Comment comment = current.getAnnotation(Comment.class); if (comment != null) { @@ -330,6 +379,7 @@ public class Config { } BlockName blockNames = current.getAnnotation(BlockName.class); if (blockNames != null) { + String node = toNodeName(current.getSimpleName()); writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF); ConfigBlock configBlock = (ConfigBlock) field.get(instance); if (configBlock == null || configBlock.getInstances().isEmpty()) { @@ -343,7 +393,7 @@ public class Config { for (Map.Entry entry : configBlock.getRaw().entrySet()) { String key = entry.getKey(); writer.write(spacing + " " + toNodeName(key) + ":" + CTRF); - save(writer, current, entry.getValue(), indent + 4); + save(writer, current, entry.getValue(), indent + 4, parentNode == null ? node : parentNode + "." + node); } } } 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 d069e62a1..5a10ad344 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 @@ -518,6 +518,9 @@ public class Settings extends Config { public int DELETE_AFTER_DAYS = 7; @Comment("Delete history in memory on logout (does not effect disk)") public boolean DELETE_ON_LOGOUT = true; + @Comment("Delete history on disk on logout") + @CopiedFrom("history.delete-on-logout") + public boolean DELETE_DISK_ON_LOGOUT = false; @Comment({ "If history should be enabled by default for plugins using WorldEdit:", " - It is faster to have disabled", 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 277d755b1..cc203190b 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 @@ -22,19 +22,15 @@ package com.sk89q.worldedit.entity; 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; import com.sk89q.worldedit.IncompleteRegionException; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.extension.platform.Actor; -import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; -import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.internal.util.DeprecationUtil; @@ -43,7 +39,6 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.RegionSelector; -import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.HandSide; import com.sk89q.worldedit.util.Location; @@ -432,7 +427,8 @@ public interface Player extends Entity, Actor { } else if (Settings.settings().CLIPBOARD.DELETE_ON_LOGOUT) { session.setClipboard(null); } - if (Settings.settings().HISTORY.DELETE_ON_LOGOUT) { + if (!Settings.settings().HISTORY.USE_DISK && Settings.settings().HISTORY.DELETE_ON_LOGOUT + || Settings.settings().HISTORY.USE_DISK && Settings.settings().HISTORY.DELETE_DISK_ON_LOGOUT) { session.clearHistory(); } } From 6dd779f90bef02f2e23e8ed9b1f292e7a4d899d4 Mon Sep 17 00:00:00 2001 From: Jordan Date: Wed, 26 Jun 2024 21:12:36 +0200 Subject: [PATCH 178/220] fix: only write copied value if non null (#2802) - fixes #2801 --- .../com/fastasyncworldedit/core/configuration/Config.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java index 2a1a5a5ef..1d6f8d146 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java @@ -320,10 +320,11 @@ public class Config { String node = toNodeName(field.getName()); node = parentNode == null ? node : parentNode + "." + node; Map.Entry entry = copyTo.remove(node); + Object copiedVal; if (entry == null) { - copyTo.put(node,new AbstractMap.SimpleEntry<>(copiedFrom.value(), null)); - } else { - field.set(instance, entry.getValue()); + copyTo.put(node, new AbstractMap.SimpleEntry<>(copiedFrom.value(), null)); + } else if ((copiedVal = entry.getValue()) != null) { + field.set(instance, copiedVal); } } Create create = field.getAnnotation(Create.class); From ad5739e014e26dd0f6308ce270762783107eec88 Mon Sep 17 00:00:00 2001 From: Jordan Date: Wed, 26 Jun 2024 21:55:47 +0200 Subject: [PATCH 179/220] ref: switch from adventure NBT to LinBus (#2778) * Switch from adventure NBT to LinBus * Cleanup * Clean * Reimplement NumberTag behaviour * Use 0.1.0 release * Fix build, remove fawe tags --------- Co-authored-by: Octavia Togami --- buildSrc/src/main/kotlin/LibsConfig.kt | 30 ++- gradle/libs.versions.toml | 7 +- .../ext/fawe/v1_19_R3/PaperweightAdapter.java | 157 +++++------ .../v1_19_R3/PaperweightDataConverters.java | 30 +-- .../PaperweightWorldNativeAccess.java | 18 +- .../fawe/v1_19_R3/PaperweightFaweAdapter.java | 20 +- .../PaperweightFaweWorldNativeAccess.java | 6 +- .../fawe/v1_19_R3/PaperweightGetBlocks.java | 2 +- .../nbt/PaperweightLazyCompoundTag.java | 14 +- .../ext/fawe/v1_20_R1/PaperweightAdapter.java | 155 +++++------ .../v1_20_R1/PaperweightDataConverters.java | 30 +-- .../PaperweightWorldNativeAccess.java | 18 +- .../fawe/v1_20_R1/PaperweightFaweAdapter.java | 20 +- .../PaperweightFaweWorldNativeAccess.java | 9 +- .../fawe/v1_20_R1/PaperweightGetBlocks.java | 2 +- .../nbt/PaperweightLazyCompoundTag.java | 14 +- .../ext/fawe/v1_20_R2/PaperweightAdapter.java | 151 +++++------ .../v1_20_R2/PaperweightDataConverters.java | 30 +-- .../PaperweightWorldNativeAccess.java | 6 +- .../fawe/v1_20_R2/PaperweightFaweAdapter.java | 20 +- .../PaperweightFaweWorldNativeAccess.java | 9 +- .../fawe/v1_20_R2/PaperweightGetBlocks.java | 2 +- .../nbt/PaperweightLazyCompoundTag.java | 14 +- .../ext.fawe/v1_20_R3/PaperweightAdapter.java | 151 +++++------ .../v1_20_R3/PaperweightDataConverters.java | 31 +-- .../PaperweightWorldNativeAccess.java | 18 +- .../fawe/v1_20_R3/PaperweightFaweAdapter.java | 20 +- .../PaperweightFaweWorldNativeAccess.java | 8 +- .../fawe/v1_20_R3/PaperweightGetBlocks.java | 2 +- .../nbt/PaperweightLazyCompoundTag.java | 14 +- .../ext.fawe/v1_20_R4/PaperweightAdapter.java | 153 +++++------ .../v1_20_R4/PaperweightDataConverters.java | 31 +-- .../PaperweightWorldNativeAccess.java | 6 +- .../fawe/v1_20_R4/PaperweightFaweAdapter.java | 20 +- .../PaperweightFaweWorldNativeAccess.java | 8 +- .../fawe/v1_20_R4/PaperweightGetBlocks.java | 2 +- .../nbt/PaperweightLazyCompoundTag.java | 14 +- worldedit-bukkit/build.gradle.kts | 3 - .../adapter/IDelegateBukkitImplAdapter.java | 15 +- .../FaweDelegateSchematicHandler.java | 4 +- .../sk89q/worldedit/bukkit/BukkitPlayer.java | 4 +- .../bukkit/adapter/BukkitImplAdapter.java | 20 +- worldedit-core/build.gradle.kts | 3 +- .../worldedit/blocks/MobSpawnerBlock.java | 4 +- .../com/sk89q/worldedit/blocks/SignBlock.java | 8 +- .../sk89q/worldedit/blocks/SkullBlock.java | 6 +- .../fastasyncworldedit/core/FaweCache.java | 2 +- .../core/entity/LazyBaseEntity.java | 10 +- .../core/extent/StripNBTExtent.java | 10 +- .../clipboard/CPUOptimizedClipboard.java | 4 +- .../clipboard/DiskOptimizedClipboard.java | 4 +- .../extent/clipboard/LinearClipboard.java | 2 +- .../clipboard/MemoryOptimizedClipboard.java | 2 +- .../clipboard/io/FastSchematicReader.java | 18 +- .../clipboard/io/FastSchematicWriter.java | 4 +- .../io/schematic/MinecraftStructure.java | 14 +- .../history/change/MutableEntityChange.java | 5 +- .../history/changeset/BlockBagChangeSet.java | 2 +- .../core/jnbt/CompressedCompoundTag.java | 6 +- .../core/jnbt/JSON2NBT.java | 3 +- .../core/jnbt/NumberTag.java | 7 +- .../core/queue/IChunkExtent.java | 2 +- .../core/util/BrushCache.java | 5 +- .../core/util/MainUtil.java | 4 +- .../core/util/NbtUtils.java | 45 ++-- .../core/util/gson/BaseItemAdapter.java | 16 +- .../com/sk89q/jnbt/AdventureNBTConverter.java | 110 -------- .../java/com/sk89q/jnbt/ByteArrayTag.java | 27 +- .../src/main/java/com/sk89q/jnbt/ByteTag.java | 25 +- .../main/java/com/sk89q/jnbt/CompoundTag.java | 124 +++++---- .../com/sk89q/jnbt/CompoundTagBuilder.java | 22 +- .../main/java/com/sk89q/jnbt/DoubleTag.java | 23 +- .../src/main/java/com/sk89q/jnbt/EndTag.java | 17 +- .../main/java/com/sk89q/jnbt/FloatTag.java | 24 +- .../main/java/com/sk89q/jnbt/IntArrayTag.java | 25 +- .../src/main/java/com/sk89q/jnbt/IntTag.java | 24 +- .../java/com/sk89q/jnbt/LazyCompoundTag.java | 10 +- .../java/com/sk89q/jnbt/LinBusConverter.java | 140 ++++++++++ .../src/main/java/com/sk89q/jnbt/ListTag.java | 193 ++++++-------- .../java/com/sk89q/jnbt/ListTagBuilder.java | 52 ++-- .../java/com/sk89q/jnbt/LongArrayTag.java | 25 +- .../src/main/java/com/sk89q/jnbt/LongTag.java | 25 +- .../java/com/sk89q/jnbt/NBTConstants.java | 53 ++-- .../java/com/sk89q/jnbt/NBTInputStream.java | 7 +- .../java/com/sk89q/jnbt/NBTOutputStream.java | 18 +- .../main/java/com/sk89q/jnbt/NBTUtils.java | 80 +++--- .../main/java/com/sk89q/jnbt/NamedTag.java | 6 +- .../main/java/com/sk89q/jnbt/ShortTag.java | 25 +- .../main/java/com/sk89q/jnbt/StringTag.java | 25 +- .../src/main/java/com/sk89q/jnbt/Tag.java | 29 +- .../com/sk89q/worldedit/LocalSession.java | 13 +- .../com/sk89q/worldedit/blocks/BaseItem.java | 67 ++--- .../sk89q/worldedit/blocks/BaseItemStack.java | 28 +- .../sk89q/worldedit/entity/BaseEntity.java | 10 +- .../factory/parser/DefaultItemParser.java | 24 +- .../extent/clipboard/BlockArrayClipboard.java | 2 +- .../clipboard/io/BuiltInClipboardFormat.java | 2 +- .../clipboard/io/MCEditSchematicReader.java | 230 ++++++---------- .../clipboard/io/NBTSchematicReader.java | 8 +- .../clipboard/io/SpongeSchematicReader.java | 49 ++-- .../clipboard/io/SpongeSchematicWriter.java | 18 +- .../BannerBlockCompatibilityHandler.java | 142 ++++------ .../BedBlockCompatibilityHandler.java | 144 ++++------ .../EntityNBTCompatibilityHandler.java | 40 ++- .../FlowerPotCompatibilityHandler.java | 79 +++--- .../legacycompat/NBTCompatibilityHandler.java | 69 ++++- .../NoteBlockCompatibilityHandler.java | 37 ++- .../Pre13HangingCompatibilityHandler.java | 34 +-- .../SignCompatibilityHandler.java | 74 +++--- .../SkullBlockCompatibilityHandler.java | 112 ++++---- .../transform/BlockTransformExtent.java | 2 +- .../extent/world/SurvivalModeExtent.java | 6 +- .../function/block/ExtentBlockCopy.java | 19 +- .../internal/cui/ServerCUIHandler.java | 7 +- .../internal/wna/WorldNativeAccess.java | 25 +- .../com/sk89q/worldedit/world/DataFixer.java | 18 +- .../com/sk89q/worldedit/world/NbtValued.java | 20 +- .../worldedit/world/block/BaseBlock.java | 37 ++- .../worldedit/world/block/BlockState.java | 4 +- .../world/block/BlockStateHolder.java | 9 +- .../worldedit/world/chunk/AnvilChunk.java | 130 ++++----- .../worldedit/world/chunk/AnvilChunk13.java | 161 ++++++----- .../worldedit/world/chunk/AnvilChunk15.java | 15 +- .../worldedit/world/chunk/AnvilChunk16.java | 6 +- .../worldedit/world/chunk/AnvilChunk17.java | 121 ++++----- .../worldedit/world/chunk/AnvilChunk18.java | 251 ++++-------------- .../sk89q/worldedit/world/chunk/OldChunk.java | 87 +++--- .../world/snapshot/SnapshotRestore.java | 23 +- .../experimental/SnapshotRestore.java | 24 +- .../world/storage/ChunkStoreHelper.java | 20 +- .../world/storage/NBTConversions.java | 35 ++- .../fabric/internal/NBTConverter.java | 4 +- .../forge/internal/NBTConverter.java | 4 +- worldedit-libs/core/build.gradle.kts | 7 +- 134 files changed, 2258 insertions(+), 2542 deletions(-) delete mode 100644 worldedit-core/src/main/java/com/sk89q/jnbt/AdventureNBTConverter.java create mode 100644 worldedit-core/src/main/java/com/sk89q/jnbt/LinBusConverter.java diff --git a/buildSrc/src/main/kotlin/LibsConfig.kt b/buildSrc/src/main/kotlin/LibsConfig.kt index 2c957880a..4bf9ffca2 100644 --- a/buildSrc/src/main/kotlin/LibsConfig.kt +++ b/buildSrc/src/main/kotlin/LibsConfig.kt @@ -40,8 +40,7 @@ fun Project.applyLibrariesConfiguration() { val relocations = mapOf( "net.kyori.text" to "com.sk89q.worldedit.util.formatting.text", - "net.kyori.minecraft" to "com.sk89q.worldedit.util.kyori", - "net.kyori.adventure.nbt" to "com.sk89q.worldedit.util.nbt" + "net.kyori.minecraft" to "com.sk89q.worldedit.util.kyori" ) @@ -53,9 +52,14 @@ fun Project.applyLibrariesConfiguration() { exclude(dependency("com.google.guava:guava")) exclude(dependency("com.google.code.gson:gson")) exclude(dependency("com.google.errorprone:error_prone_annotations")) + exclude(dependency("com.google.guava:failureaccess")) exclude(dependency("org.checkerframework:checker-qual")) + exclude(dependency("org.jetbrains:annotations")) exclude(dependency("org.apache.logging.log4j:log4j-api")) exclude(dependency("com.google.code.findbugs:jsr305")) + exclude { + it.moduleGroup == "org.jetbrains.kotlin" + } } relocations.forEach { (from, to) -> @@ -67,11 +71,19 @@ fun Project.applyLibrariesConfiguration() { .filterIsInstance() .map { it.copy() } .map { dependency -> - dependency.artifact { - name = dependency.name - type = artifactType - extension = "jar" - classifier = artifactType + val category = dependency.attributes.getAttribute(Category.CATEGORY_ATTRIBUTE)?.name + if (category == Category.REGULAR_PLATFORM || category == Category.ENFORCED_PLATFORM) { + return@map dependency + } + try { + dependency.artifact { + name = dependency.name + type = artifactType + extension = "jar" + classifier = artifactType + } + } catch (e: Exception) { + throw RuntimeException("Failed to add artifact to dependency: $dependency", e) } dependency } @@ -85,6 +97,10 @@ fun Project.applyLibrariesConfiguration() { from({ altConfigFiles("sources") }) + + // Yeet module-info's + exclude("module-info.java") + relocations.forEach { (from, to) -> val filePattern = Regex("(.*)${from.replace('.', '/')}((?:/|$).*)") val textPattern = Regex.fromLiteral(from) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 70a4116a6..4f64aa273 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,6 +40,7 @@ paperlib = "1.0.8" paster = "1.1.6" vault = "1.7.1" serverlib = "2.3.6" +linbus = "0.1.0" ## Internal text-adapter = "3.0.6" text = "3.0.4" @@ -78,7 +79,6 @@ bstatsBase = { group = "org.bstats", name = "bstats-base", version.ref = "bstats bstatsBukkit = { group = "org.bstats", name = "bstats-bukkit", version.ref = "bstats" } sparsebitset = { group = "com.zaxxer", name = "SparseBitSet", version.ref = "sparsebitset" } parallelgzip = { group = "org.anarres", name = "parallelgzip", version.ref = "parallelgzip" } -adventureNbt = { group = "net.kyori", name = "adventure-nbt", version.ref = "adventure" } truezip = { group = "de.schlichtherle", name = "truezip", version.ref = "truezip" } autoValueAnnotations = { group = "com.google.auto.value", name = "auto-value-annotations", version.ref = "auto-value" } autoValue = { group = "com.google.auto.value", name = "auto-value", version.ref = "auto-value" } @@ -101,6 +101,11 @@ paster = { group = "com.intellectualsites.paster", name = "Paster", version.ref vault = { group = "com.github.MilkBowl", name = "VaultAPI", version.ref = "vault" } serverlib = { group = "dev.notmyfault.serverlib", name = "ServerLib", version.ref = "serverlib" } checkerqual = { group = "org.checkerframework", name = "checker-qual", version.ref = "checkerqual" } +linBus-bom = { group = "org.enginehub.lin-bus", name = "lin-bus-bom", version.ref = "linbus" } +linBus-common = { group = "org.enginehub.lin-bus", name = "lin-bus-common" } +linBus-stream = { group = "org.enginehub.lin-bus", name = "lin-bus-stream" } +linBus-tree = { group = "org.enginehub.lin-bus", name = "lin-bus-tree" } +linBus-format-snbt = { group = "org.enginehub.lin-bus.format", name = "lin-bus-format-snbt" } # Internal ## Text diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java index fa027e567..a5c3da0e1 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java @@ -55,20 +55,6 @@ import com.sk89q.worldedit.util.concurrency.LazyReference; import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.ByteArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.ByteBinaryTag; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.DoubleBinaryTag; -import com.sk89q.worldedit.util.nbt.EndBinaryTag; -import com.sk89q.worldedit.util.nbt.FloatBinaryTag; -import com.sk89q.worldedit.util.nbt.IntArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.IntBinaryTag; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; -import com.sk89q.worldedit.util.nbt.LongArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.LongBinaryTag; -import com.sk89q.worldedit.util.nbt.ShortBinaryTag; -import com.sk89q.worldedit.util.nbt.StringBinaryTag; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.RegenOptions; import com.sk89q.worldedit.world.biome.BiomeType; @@ -134,9 +120,26 @@ import org.bukkit.craftbukkit.v1_19_R3.util.CraftMagicNumbers; import org.bukkit.entity.Player; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.generator.ChunkGenerator; +import org.enginehub.linbus.common.LinTagId; +import org.enginehub.linbus.tree.LinByteArrayTag; +import org.enginehub.linbus.tree.LinByteTag; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinDoubleTag; +import org.enginehub.linbus.tree.LinEndTag; +import org.enginehub.linbus.tree.LinFloatTag; +import org.enginehub.linbus.tree.LinIntArrayTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinLongArrayTag; +import org.enginehub.linbus.tree.LinLongTag; +import org.enginehub.linbus.tree.LinShortTag; +import org.enginehub.linbus.tree.LinStringTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; import org.spigotmc.SpigotConfig; import org.spigotmc.WatchdogThread; +import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -158,14 +161,13 @@ import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; public final class PaperweightAdapter implements BukkitImplAdapter { - private final Logger LOGGER = Logger.getLogger(getClass().getCanonicalName()); + private final Logger logger = Logger.getLogger(getClass().getCanonicalName()); private final Field serverWorldsField; private final Method getChunkFutureMethod; @@ -347,7 +349,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter (CompoundBinaryTag) toNativeBinary(tag)) + LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)) ); } @@ -443,9 +445,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) + __ -> (net.minecraft.nbt.CompoundTag) fromNativeLin(nbtData) )); } @@ -558,7 +560,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter toNativeLin(net.minecraft.nbt.Tag foreign) { if (foreign == null) { return null; } if (foreign instanceof net.minecraft.nbt.CompoundTag) { - Map values = new HashMap<>(); + Map> values = new HashMap<>(); Set foreignKeys = ((net.minecraft.nbt.CompoundTag) foreign).getAllKeys(); for (String str : foreignKeys) { net.minecraft.nbt.Tag base = ((net.minecraft.nbt.CompoundTag) foreign).get(str); - values.put(str, toNativeBinary(base)); + values.put(str, toNativeLin(base)); } - return CompoundBinaryTag.from(values); + return LinCompoundTag.of(values); } else if (foreign instanceof net.minecraft.nbt.ByteTag) { - return ByteBinaryTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); + return LinByteTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); } else if (foreign instanceof net.minecraft.nbt.ByteArrayTag) { - return ByteArrayBinaryTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); + return LinByteArrayTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); } else if (foreign instanceof net.minecraft.nbt.DoubleTag) { - return DoubleBinaryTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); + return LinDoubleTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); } else if (foreign instanceof net.minecraft.nbt.FloatTag) { - return FloatBinaryTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); + return LinFloatTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); } else if (foreign instanceof net.minecraft.nbt.IntTag) { - return IntBinaryTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); + return LinIntTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); } else if (foreign instanceof net.minecraft.nbt.IntArrayTag) { - return IntArrayBinaryTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); + return LinIntArrayTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); } else if (foreign instanceof net.minecraft.nbt.LongArrayTag) { - return LongArrayBinaryTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); + return LinLongArrayTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); } else if (foreign instanceof net.minecraft.nbt.ListTag) { try { - return toNativeList((net.minecraft.nbt.ListTag) foreign); + return toNativeLinList((net.minecraft.nbt.ListTag) foreign); } catch (Throwable e) { - LOGGER.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); - return ListBinaryTag.empty(); + logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); } } else if (foreign instanceof net.minecraft.nbt.LongTag) { - return LongBinaryTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); + return LinLongTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); } else if (foreign instanceof net.minecraft.nbt.ShortTag) { - return ShortBinaryTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); + return LinShortTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); } else if (foreign instanceof net.minecraft.nbt.StringTag) { - return StringBinaryTag.of(foreign.getAsString()); + return LinStringTag.of(foreign.getAsString()); } else if (foreign instanceof net.minecraft.nbt.EndTag) { - return EndBinaryTag.get(); - } else { - throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); + return LinEndTag.instance(); } + throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); } /** @@ -871,14 +871,16 @@ public final class PaperweightAdapter implements BukkitImplAdapter toNativeLinList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException { + LinListTag.Builder> builder = LinListTag.builder( + LinTagType.fromId(LinTagId.fromId(foreign.getElementType())) + ); for (net.minecraft.nbt.Tag tag : foreign) { - values.add(toNativeBinary(tag)); + builder.add(toNativeLin(tag)); } - return values.build(); + return builder.build(); } /** @@ -888,44 +890,43 @@ public final class PaperweightAdapter implements BukkitImplAdapter foreign) { if (foreign == null) { return null; } - if (foreign instanceof CompoundBinaryTag) { + if (foreign instanceof LinCompoundTag compoundTag) { net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - for (String key : ((CompoundBinaryTag) foreign).keySet()) { - tag.put(key, fromNativeBinary(((CompoundBinaryTag) foreign).get(key))); + for (var entry : compoundTag.value().entrySet()) { + tag.put(entry.getKey(), fromNativeLin(entry.getValue())); } return tag; - } else if (foreign instanceof ByteBinaryTag) { - return net.minecraft.nbt.ByteTag.valueOf(((ByteBinaryTag) foreign).value()); - } else if (foreign instanceof ByteArrayBinaryTag) { - return new net.minecraft.nbt.ByteArrayTag(((ByteArrayBinaryTag) foreign).value()); - } else if (foreign instanceof DoubleBinaryTag) { - return net.minecraft.nbt.DoubleTag.valueOf(((DoubleBinaryTag) foreign).value()); - } else if (foreign instanceof FloatBinaryTag) { - return net.minecraft.nbt.FloatTag.valueOf(((FloatBinaryTag) foreign).value()); - } else if (foreign instanceof IntBinaryTag) { - return net.minecraft.nbt.IntTag.valueOf(((IntBinaryTag) foreign).value()); - } else if (foreign instanceof IntArrayBinaryTag) { - return new net.minecraft.nbt.IntArrayTag(((IntArrayBinaryTag) foreign).value()); - } else if (foreign instanceof LongArrayBinaryTag) { - return new net.minecraft.nbt.LongArrayTag(((LongArrayBinaryTag) foreign).value()); - } else if (foreign instanceof ListBinaryTag) { + } else if (foreign instanceof LinByteTag byteTag) { + return net.minecraft.nbt.ByteTag.valueOf(byteTag.valueAsByte()); + } else if (foreign instanceof LinByteArrayTag byteArrayTag) { + return new net.minecraft.nbt.ByteArrayTag(byteArrayTag.value()); + } else if (foreign instanceof LinDoubleTag doubleTag) { + return net.minecraft.nbt.DoubleTag.valueOf(doubleTag.valueAsDouble()); + } else if (foreign instanceof LinFloatTag floatTag) { + return net.minecraft.nbt.FloatTag.valueOf(floatTag.valueAsFloat()); + } else if (foreign instanceof LinIntTag intTag) { + return net.minecraft.nbt.IntTag.valueOf(intTag.valueAsInt()); + } else if (foreign instanceof LinIntArrayTag intArrayTag) { + return new net.minecraft.nbt.IntArrayTag(intArrayTag.value()); + } else if (foreign instanceof LinLongArrayTag longArrayTag) { + return new net.minecraft.nbt.LongArrayTag(longArrayTag.value()); + } else if (foreign instanceof LinListTag listTag) { net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); - ListBinaryTag foreignList = (ListBinaryTag) foreign; - for (BinaryTag t : foreignList) { - tag.add(fromNativeBinary(t)); + for (var t : listTag.value()) { + tag.add(fromNativeLin(t)); } return tag; - } else if (foreign instanceof LongBinaryTag) { - return net.minecraft.nbt.LongTag.valueOf(((LongBinaryTag) foreign).value()); - } else if (foreign instanceof ShortBinaryTag) { - return net.minecraft.nbt.ShortTag.valueOf(((ShortBinaryTag) foreign).value()); - } else if (foreign instanceof StringBinaryTag) { - return net.minecraft.nbt.StringTag.valueOf(((StringBinaryTag) foreign).value()); - } else if (foreign instanceof EndBinaryTag) { + } else if (foreign instanceof LinLongTag longTag) { + return net.minecraft.nbt.LongTag.valueOf(longTag.valueAsLong()); + } else if (foreign instanceof LinShortTag shortTag) { + return net.minecraft.nbt.ShortTag.valueOf(shortTag.valueAsShort()); + } else if (foreign instanceof LinStringTag stringTag) { + return net.minecraft.nbt.StringTag.valueOf(stringTag.value()); + } else if (foreign instanceof LinEndTag) { return net.minecraft.nbt.EndTag.INSTANCE; } else { throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName()); @@ -964,7 +965,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter T fixUp(FixType type, T original, int srcVer) { if (type == FixTypes.CHUNK) { - return (T) fixChunk((CompoundBinaryTag) original, srcVer); + return (T) fixChunk((LinCompoundTag) original, srcVer); } else if (type == FixTypes.BLOCK_ENTITY) { - return (T) fixBlockEntity((CompoundBinaryTag) original, srcVer); + return (T) fixBlockEntity((LinCompoundTag) original, srcVer); } else if (type == FixTypes.ENTITY) { - return (T) fixEntity((CompoundBinaryTag) original, srcVer); + return (T) fixEntity((LinCompoundTag) original, srcVer); } else if (type == FixTypes.BLOCK_STATE) { return (T) fixBlockState((String) original, srcVer); } else if (type == FixTypes.ITEM_TYPE) { @@ -98,24 +97,23 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return original; } - private CompoundBinaryTag fixChunk(CompoundBinaryTag originalChunk, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(originalChunk); + private LinCompoundTag fixChunk(LinCompoundTag originalChunk, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(originalChunk); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.CHUNK, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - private CompoundBinaryTag fixBlockEntity(CompoundBinaryTag origTileEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origTileEnt); + private LinCompoundTag fixBlockEntity(LinCompoundTag origTileEnt, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origTileEnt); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.BLOCK_ENTITY, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - private CompoundBinaryTag fixEntity(CompoundBinaryTag origEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origEnt); + private LinCompoundTag fixEntity(LinCompoundTag origEnt, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origEnt); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.ENTITY, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - //FAWE end private String fixBlockState(String blockState, int srcVer) { net.minecraft.nbt.CompoundTag stateNBT = stateToNBT(blockState); diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java index 22d9f917b..7923c9e69 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java @@ -19,25 +19,28 @@ package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_19_R3; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.internal.block.BlockStateIdAccess; import com.sk89q.worldedit.internal.wna.WorldNativeAccess; import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.block.BlockState; import net.minecraft.core.BlockPos; +import net.minecraft.nbt.Tag; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.LevelChunk; import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; import org.bukkit.event.block.BlockPhysicsEvent; +import org.enginehub.linbus.tree.LinCompoundTag; +import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.util.Objects; -import javax.annotation.Nullable; public class PaperweightWorldNativeAccess implements WorldNativeAccess { private static final int UPDATE = 1; @@ -101,8 +104,15 @@ public class PaperweightWorldNativeAccess implements WorldNativeAccess saveTag = () -> { + Supplier saveTag = () -> { final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag(); PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag); //add Id for AbstractChangeSet to work - final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag); - final Map tags = NbtUtils.getCompoundBinaryTagValues(tag); - tags.put("Id", StringBinaryTag.of(id)); - return CompoundBinaryTag.from(tags); + final LinCompoundTag tag = (LinCompoundTag) toNativeLin(minecraftTag); + final Map> tags = NbtUtils.getLinCompoundTagValues(tag); + tags.put("Id", LinStringTag.of(id)); + return LinCompoundTag.of(tags); }; return new LazyBaseEntity(type, saveTag); } else { @@ -514,7 +514,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter iterator = entities.iterator(); while (iterator.hasNext()) { final CompoundTag nativeTag = iterator.next(); - final Map entityTagMap = nativeTag.getValue(); + final Map> entityTagMap = nativeTag.getValue(); final StringTag idTag = (StringTag) entityTagMap.get("Id"); final ListTag posTag = (ListTag) entityTagMap.get("Pos"); final ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/nbt/PaperweightLazyCompoundTag.java index 7db487c3f..0026c4c67 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/nbt/PaperweightLazyCompoundTag.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/nbt/PaperweightLazyCompoundTag.java @@ -6,8 +6,8 @@ import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import net.minecraft.nbt.NumericTag; +import org.enginehub.linbus.tree.LinCompoundTag; import java.util.ArrayList; import java.util.Collections; @@ -36,7 +36,7 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { @Override @SuppressWarnings("unchecked") - public Map getValue() { + public Map> getValue() { if (compoundTag == null) { compoundTag = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(compoundTagSupplier.get()); } @@ -44,9 +44,9 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @Override - public CompoundBinaryTag asBinaryTag() { + public LinCompoundTag toLinTag() { getValue(); - return compoundTag.asBinaryTag(); + return compoundTag.toLinTag(); } public boolean containsKey(String key) { @@ -94,10 +94,10 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @SuppressWarnings("unchecked") - public List getList(String key) { + public List> getList(String key) { net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); if (tag instanceof net.minecraft.nbt.ListTag nbtList) { - ArrayList list = new ArrayList<>(); + ArrayList> list = new ArrayList<>(); for (net.minecraft.nbt.Tag elem : nbtList) { if (elem instanceof net.minecraft.nbt.CompoundTag compoundTag) { list.add(new PaperweightLazyCompoundTag(compoundTag)); @@ -120,7 +120,7 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @SuppressWarnings("unchecked") - public List getList(String key, Class listType) { + public > List getList(String key, Class listType) { ListTag listTag = getListTag(key); if (listTag.getType().equals(listType)) { return (List) listTag.getValue(); diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java index 519620061..f0ba19c6d 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java @@ -55,20 +55,6 @@ import com.sk89q.worldedit.util.concurrency.LazyReference; import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.ByteArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.ByteBinaryTag; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.DoubleBinaryTag; -import com.sk89q.worldedit.util.nbt.EndBinaryTag; -import com.sk89q.worldedit.util.nbt.FloatBinaryTag; -import com.sk89q.worldedit.util.nbt.IntArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.IntBinaryTag; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; -import com.sk89q.worldedit.util.nbt.LongArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.LongBinaryTag; -import com.sk89q.worldedit.util.nbt.ShortBinaryTag; -import com.sk89q.worldedit.util.nbt.StringBinaryTag; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.RegenOptions; import com.sk89q.worldedit.world.biome.BiomeType; @@ -135,6 +121,22 @@ import org.bukkit.craftbukkit.v1_20_R1.util.CraftMagicNumbers; import org.bukkit.entity.Player; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.generator.ChunkGenerator; +import org.enginehub.linbus.common.LinTagId; +import org.enginehub.linbus.tree.LinByteArrayTag; +import org.enginehub.linbus.tree.LinByteTag; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinDoubleTag; +import org.enginehub.linbus.tree.LinEndTag; +import org.enginehub.linbus.tree.LinFloatTag; +import org.enginehub.linbus.tree.LinIntArrayTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinLongArrayTag; +import org.enginehub.linbus.tree.LinLongTag; +import org.enginehub.linbus.tree.LinShortTag; +import org.enginehub.linbus.tree.LinStringTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; import org.spigotmc.SpigotConfig; import org.spigotmc.WatchdogThread; @@ -166,7 +168,7 @@ import static com.google.common.base.Preconditions.checkState; public final class PaperweightAdapter implements BukkitImplAdapter { - private final Logger LOGGER = Logger.getLogger(getClass().getCanonicalName()); + private final Logger logger = Logger.getLogger(getClass().getCanonicalName()); private final Field serverWorldsField; private final Method getChunkFutureMethod; @@ -348,7 +350,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter (CompoundBinaryTag) toNativeBinary(tag)) + LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)) ); } @@ -483,9 +485,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) + __ -> (net.minecraft.nbt.CompoundTag) fromNativeLin(nbtData) )); } @@ -609,7 +611,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter toNativeLin(net.minecraft.nbt.Tag foreign) { if (foreign == null) { return null; } if (foreign instanceof net.minecraft.nbt.CompoundTag) { - Map values = new HashMap<>(); + Map> values = new HashMap<>(); Set foreignKeys = ((net.minecraft.nbt.CompoundTag) foreign).getAllKeys(); for (String str : foreignKeys) { net.minecraft.nbt.Tag base = ((net.minecraft.nbt.CompoundTag) foreign).get(str); - values.put(str, toNativeBinary(base)); + values.put(str, toNativeLin(base)); } - return CompoundBinaryTag.from(values); + return LinCompoundTag.of(values); } else if (foreign instanceof net.minecraft.nbt.ByteTag) { - return ByteBinaryTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); + return LinByteTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); } else if (foreign instanceof net.minecraft.nbt.ByteArrayTag) { - return ByteArrayBinaryTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); + return LinByteArrayTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); } else if (foreign instanceof net.minecraft.nbt.DoubleTag) { - return DoubleBinaryTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); + return LinDoubleTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); } else if (foreign instanceof net.minecraft.nbt.FloatTag) { - return FloatBinaryTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); + return LinFloatTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); } else if (foreign instanceof net.minecraft.nbt.IntTag) { - return IntBinaryTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); + return LinIntTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); } else if (foreign instanceof net.minecraft.nbt.IntArrayTag) { - return IntArrayBinaryTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); + return LinIntArrayTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); } else if (foreign instanceof net.minecraft.nbt.LongArrayTag) { - return LongArrayBinaryTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); + return LinLongArrayTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); } else if (foreign instanceof net.minecraft.nbt.ListTag) { try { - return toNativeList((net.minecraft.nbt.ListTag) foreign); + return toNativeLinList((net.minecraft.nbt.ListTag) foreign); } catch (Throwable e) { - LOGGER.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); - return ListBinaryTag.empty(); + logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); } } else if (foreign instanceof net.minecraft.nbt.LongTag) { - return LongBinaryTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); + return LinLongTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); } else if (foreign instanceof net.minecraft.nbt.ShortTag) { - return ShortBinaryTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); + return LinShortTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); } else if (foreign instanceof net.minecraft.nbt.StringTag) { - return StringBinaryTag.of(foreign.getAsString()); + return LinStringTag.of(foreign.getAsString()); } else if (foreign instanceof net.minecraft.nbt.EndTag) { - return EndBinaryTag.get(); - } else { - throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); + return LinEndTag.instance(); } + throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); } /** @@ -934,14 +934,16 @@ public final class PaperweightAdapter implements BukkitImplAdapter toNativeLinList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException { + LinListTag.Builder> builder = LinListTag.builder( + LinTagType.fromId(LinTagId.fromId(foreign.getElementType())) + ); for (net.minecraft.nbt.Tag tag : foreign) { - values.add(toNativeBinary(tag)); + builder.add(toNativeLin(tag)); } - return values.build(); + return builder.build(); } /** @@ -951,44 +953,43 @@ public final class PaperweightAdapter implements BukkitImplAdapter foreign) { if (foreign == null) { return null; } - if (foreign instanceof CompoundBinaryTag) { + if (foreign instanceof LinCompoundTag compoundTag) { net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - for (String key : ((CompoundBinaryTag) foreign).keySet()) { - tag.put(key, fromNativeBinary(((CompoundBinaryTag) foreign).get(key))); + for (var entry : compoundTag.value().entrySet()) { + tag.put(entry.getKey(), fromNativeLin(entry.getValue())); } return tag; - } else if (foreign instanceof ByteBinaryTag) { - return net.minecraft.nbt.ByteTag.valueOf(((ByteBinaryTag) foreign).value()); - } else if (foreign instanceof ByteArrayBinaryTag) { - return new net.minecraft.nbt.ByteArrayTag(((ByteArrayBinaryTag) foreign).value()); - } else if (foreign instanceof DoubleBinaryTag) { - return net.minecraft.nbt.DoubleTag.valueOf(((DoubleBinaryTag) foreign).value()); - } else if (foreign instanceof FloatBinaryTag) { - return net.minecraft.nbt.FloatTag.valueOf(((FloatBinaryTag) foreign).value()); - } else if (foreign instanceof IntBinaryTag) { - return net.minecraft.nbt.IntTag.valueOf(((IntBinaryTag) foreign).value()); - } else if (foreign instanceof IntArrayBinaryTag) { - return new net.minecraft.nbt.IntArrayTag(((IntArrayBinaryTag) foreign).value()); - } else if (foreign instanceof LongArrayBinaryTag) { - return new net.minecraft.nbt.LongArrayTag(((LongArrayBinaryTag) foreign).value()); - } else if (foreign instanceof ListBinaryTag) { + } else if (foreign instanceof LinByteTag byteTag) { + return net.minecraft.nbt.ByteTag.valueOf(byteTag.valueAsByte()); + } else if (foreign instanceof LinByteArrayTag byteArrayTag) { + return new net.minecraft.nbt.ByteArrayTag(byteArrayTag.value()); + } else if (foreign instanceof LinDoubleTag doubleTag) { + return net.minecraft.nbt.DoubleTag.valueOf(doubleTag.valueAsDouble()); + } else if (foreign instanceof LinFloatTag floatTag) { + return net.minecraft.nbt.FloatTag.valueOf(floatTag.valueAsFloat()); + } else if (foreign instanceof LinIntTag intTag) { + return net.minecraft.nbt.IntTag.valueOf(intTag.valueAsInt()); + } else if (foreign instanceof LinIntArrayTag intArrayTag) { + return new net.minecraft.nbt.IntArrayTag(intArrayTag.value()); + } else if (foreign instanceof LinLongArrayTag longArrayTag) { + return new net.minecraft.nbt.LongArrayTag(longArrayTag.value()); + } else if (foreign instanceof LinListTag listTag) { net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); - ListBinaryTag foreignList = (ListBinaryTag) foreign; - for (BinaryTag t : foreignList) { - tag.add(fromNativeBinary(t)); + for (var t : listTag.value()) { + tag.add(fromNativeLin(t)); } return tag; - } else if (foreign instanceof LongBinaryTag) { - return net.minecraft.nbt.LongTag.valueOf(((LongBinaryTag) foreign).value()); - } else if (foreign instanceof ShortBinaryTag) { - return net.minecraft.nbt.ShortTag.valueOf(((ShortBinaryTag) foreign).value()); - } else if (foreign instanceof StringBinaryTag) { - return net.minecraft.nbt.StringTag.valueOf(((StringBinaryTag) foreign).value()); - } else if (foreign instanceof EndBinaryTag) { + } else if (foreign instanceof LinLongTag longTag) { + return net.minecraft.nbt.LongTag.valueOf(longTag.valueAsLong()); + } else if (foreign instanceof LinShortTag shortTag) { + return net.minecraft.nbt.ShortTag.valueOf(shortTag.valueAsShort()); + } else if (foreign instanceof LinStringTag stringTag) { + return net.minecraft.nbt.StringTag.valueOf(stringTag.value()); + } else if (foreign instanceof LinEndTag) { return net.minecraft.nbt.EndTag.INSTANCE; } else { throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName()); @@ -1027,7 +1028,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter T fixUp(FixType type, T original, int srcVer) { if (type == FixTypes.CHUNK) { - return (T) fixChunk((CompoundBinaryTag) original, srcVer); + return (T) fixChunk((LinCompoundTag) original, srcVer); } else if (type == FixTypes.BLOCK_ENTITY) { - return (T) fixBlockEntity((CompoundBinaryTag) original, srcVer); + return (T) fixBlockEntity((LinCompoundTag) original, srcVer); } else if (type == FixTypes.ENTITY) { - return (T) fixEntity((CompoundBinaryTag) original, srcVer); + return (T) fixEntity((LinCompoundTag) original, srcVer); } else if (type == FixTypes.BLOCK_STATE) { return (T) fixBlockState((String) original, srcVer); } else if (type == FixTypes.ITEM_TYPE) { @@ -98,24 +97,23 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return original; } - private CompoundBinaryTag fixChunk(CompoundBinaryTag originalChunk, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(originalChunk); + private LinCompoundTag fixChunk(LinCompoundTag originalChunk, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(originalChunk); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.CHUNK, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - private CompoundBinaryTag fixBlockEntity(CompoundBinaryTag origTileEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origTileEnt); + private LinCompoundTag fixBlockEntity(LinCompoundTag origTileEnt, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origTileEnt); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.BLOCK_ENTITY, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - private CompoundBinaryTag fixEntity(CompoundBinaryTag origEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origEnt); + private LinCompoundTag fixEntity(LinCompoundTag origEnt, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origEnt); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.ENTITY, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - //FAWE end private String fixBlockState(String blockState, int srcVer) { net.minecraft.nbt.CompoundTag stateNBT = stateToNBT(blockState); diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java index dc44a165a..c7f3d3f3c 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java @@ -19,7 +19,7 @@ package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R1; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.internal.block.BlockStateIdAccess; import com.sk89q.worldedit.internal.wna.WorldNativeAccess; @@ -27,17 +27,20 @@ import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.world.block.BlockState; import net.minecraft.core.BlockPos; +import net.minecraft.nbt.Tag; import net.minecraft.server.level.FullChunkStatus; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.LevelChunk; import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData; import org.bukkit.event.block.BlockPhysicsEvent; +import org.enginehub.linbus.tree.LinCompoundTag; +import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.util.Objects; -import javax.annotation.Nullable; public class PaperweightWorldNativeAccess implements WorldNativeAccess { private static final int UPDATE = 1; @@ -101,8 +104,15 @@ public class PaperweightWorldNativeAccess implements WorldNativeAccess saveTag = () -> { + Supplier saveTag = () -> { final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag(); PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag); //add Id for AbstractChangeSet to work - final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag); - final Map tags = NbtUtils.getCompoundBinaryTagValues(tag); - tags.put("Id", StringBinaryTag.of(id)); - return CompoundBinaryTag.from(tags); + final LinCompoundTag tag = (LinCompoundTag) toNativeLin(minecraftTag); + final Map> tags = NbtUtils.getLinCompoundTagValues(tag); + tags.put("Id", LinStringTag.of(id)); + return LinCompoundTag.of(tags); }; return new LazyBaseEntity(type, saveTag); } else { @@ -514,7 +514,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter iterator = entities.iterator(); while (iterator.hasNext()) { final CompoundTag nativeTag = iterator.next(); - final Map entityTagMap = nativeTag.getValue(); + final Map> entityTagMap = nativeTag.getValue(); final StringTag idTag = (StringTag) entityTagMap.get("Id"); final ListTag posTag = (ListTag) entityTagMap.get("Pos"); final ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/nbt/PaperweightLazyCompoundTag.java index dbdece689..f2a694a2f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/nbt/PaperweightLazyCompoundTag.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/nbt/PaperweightLazyCompoundTag.java @@ -6,8 +6,8 @@ import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import net.minecraft.nbt.NumericTag; +import org.enginehub.linbus.tree.LinCompoundTag; import java.util.ArrayList; import java.util.Collections; @@ -36,7 +36,7 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { @Override @SuppressWarnings("unchecked") - public Map getValue() { + public Map> getValue() { if (compoundTag == null) { compoundTag = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(compoundTagSupplier.get()); } @@ -44,9 +44,9 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @Override - public CompoundBinaryTag asBinaryTag() { + public LinCompoundTag toLinTag() { getValue(); - return compoundTag.asBinaryTag(); + return compoundTag.toLinTag(); } public boolean containsKey(String key) { @@ -94,10 +94,10 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @SuppressWarnings("unchecked") - public List getList(String key) { + public List> getList(String key) { net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); if (tag instanceof net.minecraft.nbt.ListTag nbtList) { - ArrayList list = new ArrayList<>(); + ArrayList> list = new ArrayList<>(); for (net.minecraft.nbt.Tag elem : nbtList) { if (elem instanceof net.minecraft.nbt.CompoundTag compoundTag) { list.add(new PaperweightLazyCompoundTag(compoundTag)); @@ -120,7 +120,7 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @SuppressWarnings("unchecked") - public List getList(String key, Class listType) { + public > List getList(String key, Class listType) { ListTag listTag = getListTag(key); if (listTag.getType().equals(listType)) { return (List) listTag.getValue(); diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java index f695876cc..e30bb2b2a 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java @@ -54,20 +54,6 @@ import com.sk89q.worldedit.util.concurrency.LazyReference; import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.ByteArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.ByteBinaryTag; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.DoubleBinaryTag; -import com.sk89q.worldedit.util.nbt.EndBinaryTag; -import com.sk89q.worldedit.util.nbt.FloatBinaryTag; -import com.sk89q.worldedit.util.nbt.IntArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.IntBinaryTag; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; -import com.sk89q.worldedit.util.nbt.LongArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.LongBinaryTag; -import com.sk89q.worldedit.util.nbt.ShortBinaryTag; -import com.sk89q.worldedit.util.nbt.StringBinaryTag; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.RegenOptions; import com.sk89q.worldedit.world.biome.BiomeType; @@ -134,9 +120,26 @@ import org.bukkit.craftbukkit.v1_20_R2.util.CraftMagicNumbers; import org.bukkit.entity.Player; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.generator.ChunkGenerator; +import org.enginehub.linbus.common.LinTagId; +import org.enginehub.linbus.tree.LinByteArrayTag; +import org.enginehub.linbus.tree.LinByteTag; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinDoubleTag; +import org.enginehub.linbus.tree.LinEndTag; +import org.enginehub.linbus.tree.LinFloatTag; +import org.enginehub.linbus.tree.LinIntArrayTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinLongArrayTag; +import org.enginehub.linbus.tree.LinLongTag; +import org.enginehub.linbus.tree.LinShortTag; +import org.enginehub.linbus.tree.LinStringTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; import org.spigotmc.SpigotConfig; import org.spigotmc.WatchdogThread; +import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -158,7 +161,6 @@ import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; @@ -345,7 +347,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter (CompoundBinaryTag) toNativeBinary(tag)) + LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)) ); } @@ -443,9 +445,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) + __ -> (net.minecraft.nbt.CompoundTag) fromNativeLin(nbtData) )); } @@ -558,7 +560,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter toNativeLin(net.minecraft.nbt.Tag foreign) { if (foreign == null) { return null; } if (foreign instanceof net.minecraft.nbt.CompoundTag) { - Map values = new HashMap<>(); + Map> values = new HashMap<>(); Set foreignKeys = ((net.minecraft.nbt.CompoundTag) foreign).getAllKeys(); for (String str : foreignKeys) { net.minecraft.nbt.Tag base = ((net.minecraft.nbt.CompoundTag) foreign).get(str); - values.put(str, toNativeBinary(base)); + values.put(str, toNativeLin(base)); } - return CompoundBinaryTag.from(values); + return LinCompoundTag.of(values); } else if (foreign instanceof net.minecraft.nbt.ByteTag) { - return ByteBinaryTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); + return LinByteTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); } else if (foreign instanceof net.minecraft.nbt.ByteArrayTag) { - return ByteArrayBinaryTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); + return LinByteArrayTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); } else if (foreign instanceof net.minecraft.nbt.DoubleTag) { - return DoubleBinaryTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); + return LinDoubleTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); } else if (foreign instanceof net.minecraft.nbt.FloatTag) { - return FloatBinaryTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); + return LinFloatTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); } else if (foreign instanceof net.minecraft.nbt.IntTag) { - return IntBinaryTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); + return LinIntTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); } else if (foreign instanceof net.minecraft.nbt.IntArrayTag) { - return IntArrayBinaryTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); + return LinIntArrayTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); } else if (foreign instanceof net.minecraft.nbt.LongArrayTag) { - return LongArrayBinaryTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); + return LinLongArrayTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); } else if (foreign instanceof net.minecraft.nbt.ListTag) { try { - return toNativeList((net.minecraft.nbt.ListTag) foreign); + return toNativeLinList((net.minecraft.nbt.ListTag) foreign); } catch (Throwable e) { logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); - return ListBinaryTag.empty(); } } else if (foreign instanceof net.minecraft.nbt.LongTag) { - return LongBinaryTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); + return LinLongTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); } else if (foreign instanceof net.minecraft.nbt.ShortTag) { - return ShortBinaryTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); + return LinShortTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); } else if (foreign instanceof net.minecraft.nbt.StringTag) { - return StringBinaryTag.of(foreign.getAsString()); + return LinStringTag.of(foreign.getAsString()); } else if (foreign instanceof net.minecraft.nbt.EndTag) { - return EndBinaryTag.get(); - } else { - throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); + return LinEndTag.instance(); } + throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); } /** @@ -872,14 +872,16 @@ public final class PaperweightAdapter implements BukkitImplAdapter toNativeLinList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException { + LinListTag.Builder> builder = LinListTag.builder( + LinTagType.fromId(LinTagId.fromId(foreign.getElementType())) + ); for (net.minecraft.nbt.Tag tag : foreign) { - values.add(toNativeBinary(tag)); + builder.add(toNativeLin(tag)); } - return values.build(); + return builder.build(); } /** @@ -889,44 +891,43 @@ public final class PaperweightAdapter implements BukkitImplAdapter foreign) { if (foreign == null) { return null; } - if (foreign instanceof CompoundBinaryTag) { + if (foreign instanceof LinCompoundTag compoundTag) { net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - for (String key : ((CompoundBinaryTag) foreign).keySet()) { - tag.put(key, fromNativeBinary(((CompoundBinaryTag) foreign).get(key))); + for (var entry : compoundTag.value().entrySet()) { + tag.put(entry.getKey(), fromNativeLin(entry.getValue())); } return tag; - } else if (foreign instanceof ByteBinaryTag) { - return net.minecraft.nbt.ByteTag.valueOf(((ByteBinaryTag) foreign).value()); - } else if (foreign instanceof ByteArrayBinaryTag) { - return new net.minecraft.nbt.ByteArrayTag(((ByteArrayBinaryTag) foreign).value()); - } else if (foreign instanceof DoubleBinaryTag) { - return net.minecraft.nbt.DoubleTag.valueOf(((DoubleBinaryTag) foreign).value()); - } else if (foreign instanceof FloatBinaryTag) { - return net.minecraft.nbt.FloatTag.valueOf(((FloatBinaryTag) foreign).value()); - } else if (foreign instanceof IntBinaryTag) { - return net.minecraft.nbt.IntTag.valueOf(((IntBinaryTag) foreign).value()); - } else if (foreign instanceof IntArrayBinaryTag) { - return new net.minecraft.nbt.IntArrayTag(((IntArrayBinaryTag) foreign).value()); - } else if (foreign instanceof LongArrayBinaryTag) { - return new net.minecraft.nbt.LongArrayTag(((LongArrayBinaryTag) foreign).value()); - } else if (foreign instanceof ListBinaryTag) { + } else if (foreign instanceof LinByteTag byteTag) { + return net.minecraft.nbt.ByteTag.valueOf(byteTag.valueAsByte()); + } else if (foreign instanceof LinByteArrayTag byteArrayTag) { + return new net.minecraft.nbt.ByteArrayTag(byteArrayTag.value()); + } else if (foreign instanceof LinDoubleTag doubleTag) { + return net.minecraft.nbt.DoubleTag.valueOf(doubleTag.valueAsDouble()); + } else if (foreign instanceof LinFloatTag floatTag) { + return net.minecraft.nbt.FloatTag.valueOf(floatTag.valueAsFloat()); + } else if (foreign instanceof LinIntTag intTag) { + return net.minecraft.nbt.IntTag.valueOf(intTag.valueAsInt()); + } else if (foreign instanceof LinIntArrayTag intArrayTag) { + return new net.minecraft.nbt.IntArrayTag(intArrayTag.value()); + } else if (foreign instanceof LinLongArrayTag longArrayTag) { + return new net.minecraft.nbt.LongArrayTag(longArrayTag.value()); + } else if (foreign instanceof LinListTag listTag) { net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); - ListBinaryTag foreignList = (ListBinaryTag) foreign; - for (BinaryTag t : foreignList) { - tag.add(fromNativeBinary(t)); + for (var t : listTag.value()) { + tag.add(fromNativeLin(t)); } return tag; - } else if (foreign instanceof LongBinaryTag) { - return net.minecraft.nbt.LongTag.valueOf(((LongBinaryTag) foreign).value()); - } else if (foreign instanceof ShortBinaryTag) { - return net.minecraft.nbt.ShortTag.valueOf(((ShortBinaryTag) foreign).value()); - } else if (foreign instanceof StringBinaryTag) { - return net.minecraft.nbt.StringTag.valueOf(((StringBinaryTag) foreign).value()); - } else if (foreign instanceof EndBinaryTag) { + } else if (foreign instanceof LinLongTag longTag) { + return net.minecraft.nbt.LongTag.valueOf(longTag.valueAsLong()); + } else if (foreign instanceof LinShortTag shortTag) { + return net.minecraft.nbt.ShortTag.valueOf(shortTag.valueAsShort()); + } else if (foreign instanceof LinStringTag stringTag) { + return net.minecraft.nbt.StringTag.valueOf(stringTag.value()); + } else if (foreign instanceof LinEndTag) { return net.minecraft.nbt.EndTag.INSTANCE; } else { throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName()); diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightDataConverters.java index f7be01738..be25d079a 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightDataConverters.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightDataConverters.java @@ -35,7 +35,6 @@ import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.DataFixerBuilder; import com.mojang.datafixers.schemas.Schema; import com.mojang.serialization.Dynamic; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import net.minecraft.core.Direction; import net.minecraft.nbt.NbtOps; import net.minecraft.network.chat.Component; @@ -48,7 +47,9 @@ import net.minecraft.util.datafix.fixes.References; import net.minecraft.world.item.DyeColor; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.enginehub.linbus.tree.LinCompoundTag; +import javax.annotation.Nullable; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.EnumMap; @@ -62,7 +63,6 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.Executor; import java.util.stream.Collectors; -import javax.annotation.Nullable; /** * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2) @@ -78,16 +78,15 @@ import javax.annotation.Nullable; @SuppressWarnings({ "rawtypes", "unchecked" }) public class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.worldedit.world.DataFixer { - //FAWE start - BinaryTag @SuppressWarnings("unchecked") @Override public T fixUp(FixType type, T original, int srcVer) { if (type == FixTypes.CHUNK) { - return (T) fixChunk((CompoundBinaryTag) original, srcVer); + return (T) fixChunk((LinCompoundTag) original, srcVer); } else if (type == FixTypes.BLOCK_ENTITY) { - return (T) fixBlockEntity((CompoundBinaryTag) original, srcVer); + return (T) fixBlockEntity((LinCompoundTag) original, srcVer); } else if (type == FixTypes.ENTITY) { - return (T) fixEntity((CompoundBinaryTag) original, srcVer); + return (T) fixEntity((LinCompoundTag) original, srcVer); } else if (type == FixTypes.BLOCK_STATE) { return (T) fixBlockState((String) original, srcVer); } else if (type == FixTypes.ITEM_TYPE) { @@ -98,24 +97,23 @@ public class PaperweightDataConverters extends DataFixerBuilder implements com.s return original; } - private CompoundBinaryTag fixChunk(CompoundBinaryTag originalChunk, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(originalChunk); + private LinCompoundTag fixChunk(LinCompoundTag originalChunk, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(originalChunk); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.CHUNK, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - private CompoundBinaryTag fixBlockEntity(CompoundBinaryTag origTileEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origTileEnt); + private LinCompoundTag fixBlockEntity(LinCompoundTag origTileEnt, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origTileEnt); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.BLOCK_ENTITY, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - private CompoundBinaryTag fixEntity(CompoundBinaryTag origEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origEnt); + private LinCompoundTag fixEntity(LinCompoundTag origEnt, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origEnt); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.ENTITY, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - //FAWE end private String fixBlockState(String blockState, int srcVer) { net.minecraft.nbt.CompoundTag stateNBT = stateToNBT(blockState); diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightWorldNativeAccess.java index 9e69e4a31..95ecae72a 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightWorldNativeAccess.java @@ -24,7 +24,6 @@ import com.sk89q.worldedit.internal.block.BlockStateIdAccess; import com.sk89q.worldedit.internal.wna.WorldNativeAccess; import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.block.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.server.level.FullChunkStatus; @@ -34,10 +33,11 @@ import net.minecraft.world.level.chunk.LevelChunk; import org.bukkit.craftbukkit.v1_20_R2.CraftWorld; import org.bukkit.craftbukkit.v1_20_R2.block.data.CraftBlockData; import org.bukkit.event.block.BlockPhysicsEvent; +import org.enginehub.linbus.tree.LinCompoundTag; +import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.util.Objects; -import javax.annotation.Nullable; public class PaperweightWorldNativeAccess implements WorldNativeAccess { private static final int UPDATE = 1; @@ -101,7 +101,7 @@ public class PaperweightWorldNativeAccess implements WorldNativeAccess saveTag = () -> { + Supplier saveTag = () -> { final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag(); readEntityIntoTag(mcEntity, minecraftTag); //add Id for AbstractChangeSet to work - final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag); - final Map tags = NbtUtils.getCompoundBinaryTagValues(tag); - tags.put("Id", StringBinaryTag.of(id)); - return CompoundBinaryTag.from(tags); + final LinCompoundTag tag = (LinCompoundTag) toNativeLin(minecraftTag); + final Map> tags = NbtUtils.getLinCompoundTagValues(tag); + tags.put("Id", LinStringTag.of(id)); + return LinCompoundTag.of(tags); }; return new LazyBaseEntity(type, saveTag); } else { @@ -517,7 +517,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter iterator = entities.iterator(); while (iterator.hasNext()) { final CompoundTag nativeTag = iterator.next(); - final Map entityTagMap = nativeTag.getValue(); + final Map> entityTagMap = nativeTag.getValue(); final StringTag idTag = (StringTag) entityTagMap.get("Id"); final ListTag posTag = (ListTag) entityTagMap.get("Pos"); final ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/nbt/PaperweightLazyCompoundTag.java index 911da046a..68dbc6b8e 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/nbt/PaperweightLazyCompoundTag.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/nbt/PaperweightLazyCompoundTag.java @@ -6,8 +6,8 @@ import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import net.minecraft.nbt.NumericTag; +import org.enginehub.linbus.tree.LinCompoundTag; import java.util.ArrayList; import java.util.Collections; @@ -36,7 +36,7 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { @Override @SuppressWarnings("unchecked") - public Map getValue() { + public Map> getValue() { if (compoundTag == null) { compoundTag = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(compoundTagSupplier.get()); } @@ -44,9 +44,9 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @Override - public CompoundBinaryTag asBinaryTag() { + public LinCompoundTag toLinTag() { getValue(); - return compoundTag.asBinaryTag(); + return compoundTag.toLinTag(); } public boolean containsKey(String key) { @@ -94,10 +94,10 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @SuppressWarnings("unchecked") - public List getList(String key) { + public List> getList(String key) { net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); if (tag instanceof net.minecraft.nbt.ListTag nbtList) { - ArrayList list = new ArrayList<>(); + ArrayList> list = new ArrayList<>(); for (net.minecraft.nbt.Tag elem : nbtList) { if (elem instanceof net.minecraft.nbt.CompoundTag compoundTag) { list.add(new PaperweightLazyCompoundTag(compoundTag)); @@ -120,7 +120,7 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @SuppressWarnings("unchecked") - public List getList(String key, Class listType) { + public > List getList(String key, Class listType) { ListTag listTag = getListTag(key); if (listTag.getType().equals(listType)) { return (List) listTag.getValue(); diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java index aa3920ccd..0bc5ba09c 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java @@ -54,20 +54,6 @@ import com.sk89q.worldedit.util.concurrency.LazyReference; import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.ByteArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.ByteBinaryTag; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.DoubleBinaryTag; -import com.sk89q.worldedit.util.nbt.EndBinaryTag; -import com.sk89q.worldedit.util.nbt.FloatBinaryTag; -import com.sk89q.worldedit.util.nbt.IntArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.IntBinaryTag; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; -import com.sk89q.worldedit.util.nbt.LongArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.LongBinaryTag; -import com.sk89q.worldedit.util.nbt.ShortBinaryTag; -import com.sk89q.worldedit.util.nbt.StringBinaryTag; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.RegenOptions; import com.sk89q.worldedit.world.biome.BiomeType; @@ -134,9 +120,26 @@ import org.bukkit.craftbukkit.v1_20_R3.util.CraftMagicNumbers; import org.bukkit.entity.Player; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.generator.ChunkGenerator; +import org.enginehub.linbus.common.LinTagId; +import org.enginehub.linbus.tree.LinByteArrayTag; +import org.enginehub.linbus.tree.LinByteTag; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinDoubleTag; +import org.enginehub.linbus.tree.LinEndTag; +import org.enginehub.linbus.tree.LinFloatTag; +import org.enginehub.linbus.tree.LinIntArrayTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinLongArrayTag; +import org.enginehub.linbus.tree.LinLongTag; +import org.enginehub.linbus.tree.LinShortTag; +import org.enginehub.linbus.tree.LinStringTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; import org.spigotmc.SpigotConfig; import org.spigotmc.WatchdogThread; +import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -158,7 +161,6 @@ import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; @@ -345,7 +347,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter (CompoundBinaryTag) toNativeBinary(tag)) + LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)) ); } @@ -443,9 +445,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) + __ -> (net.minecraft.nbt.CompoundTag) fromNativeLin(nbtData) )); } @@ -558,7 +560,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter toNativeLin(net.minecraft.nbt.Tag foreign) { if (foreign == null) { return null; } if (foreign instanceof net.minecraft.nbt.CompoundTag) { - Map values = new HashMap<>(); + Map> values = new HashMap<>(); Set foreignKeys = ((net.minecraft.nbt.CompoundTag) foreign).getAllKeys(); for (String str : foreignKeys) { net.minecraft.nbt.Tag base = ((net.minecraft.nbt.CompoundTag) foreign).get(str); - values.put(str, toNativeBinary(base)); + values.put(str, toNativeLin(base)); } - return CompoundBinaryTag.from(values); + return LinCompoundTag.of(values); } else if (foreign instanceof net.minecraft.nbt.ByteTag) { - return ByteBinaryTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); + return LinByteTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); } else if (foreign instanceof net.minecraft.nbt.ByteArrayTag) { - return ByteArrayBinaryTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); + return LinByteArrayTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); } else if (foreign instanceof net.minecraft.nbt.DoubleTag) { - return DoubleBinaryTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); + return LinDoubleTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); } else if (foreign instanceof net.minecraft.nbt.FloatTag) { - return FloatBinaryTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); + return LinFloatTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); } else if (foreign instanceof net.minecraft.nbt.IntTag) { - return IntBinaryTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); + return LinIntTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); } else if (foreign instanceof net.minecraft.nbt.IntArrayTag) { - return IntArrayBinaryTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); + return LinIntArrayTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); } else if (foreign instanceof net.minecraft.nbt.LongArrayTag) { - return LongArrayBinaryTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); + return LinLongArrayTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); } else if (foreign instanceof net.minecraft.nbt.ListTag) { try { - return toNativeList((net.minecraft.nbt.ListTag) foreign); + return toNativeLinList((net.minecraft.nbt.ListTag) foreign); } catch (Throwable e) { logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); - return ListBinaryTag.empty(); } } else if (foreign instanceof net.minecraft.nbt.LongTag) { - return LongBinaryTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); + return LinLongTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); } else if (foreign instanceof net.minecraft.nbt.ShortTag) { - return ShortBinaryTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); + return LinShortTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); } else if (foreign instanceof net.minecraft.nbt.StringTag) { - return StringBinaryTag.of(foreign.getAsString()); + return LinStringTag.of(foreign.getAsString()); } else if (foreign instanceof net.minecraft.nbt.EndTag) { - return EndBinaryTag.get(); - } else { - throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); + return LinEndTag.instance(); } + throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); } /** @@ -872,14 +872,16 @@ public final class PaperweightAdapter implements BukkitImplAdapter toNativeLinList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException { + LinListTag.Builder> builder = LinListTag.builder( + LinTagType.fromId(LinTagId.fromId(foreign.getElementType())) + ); for (net.minecraft.nbt.Tag tag : foreign) { - values.add(toNativeBinary(tag)); + builder.add(toNativeLin(tag)); } - return values.build(); + return builder.build(); } /** @@ -889,44 +891,43 @@ public final class PaperweightAdapter implements BukkitImplAdapter foreign) { if (foreign == null) { return null; } - if (foreign instanceof CompoundBinaryTag) { + if (foreign instanceof LinCompoundTag compoundTag) { net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - for (String key : ((CompoundBinaryTag) foreign).keySet()) { - tag.put(key, fromNativeBinary(((CompoundBinaryTag) foreign).get(key))); + for (var entry : compoundTag.value().entrySet()) { + tag.put(entry.getKey(), fromNativeLin(entry.getValue())); } return tag; - } else if (foreign instanceof ByteBinaryTag) { - return net.minecraft.nbt.ByteTag.valueOf(((ByteBinaryTag) foreign).value()); - } else if (foreign instanceof ByteArrayBinaryTag) { - return new net.minecraft.nbt.ByteArrayTag(((ByteArrayBinaryTag) foreign).value()); - } else if (foreign instanceof DoubleBinaryTag) { - return net.minecraft.nbt.DoubleTag.valueOf(((DoubleBinaryTag) foreign).value()); - } else if (foreign instanceof FloatBinaryTag) { - return net.minecraft.nbt.FloatTag.valueOf(((FloatBinaryTag) foreign).value()); - } else if (foreign instanceof IntBinaryTag) { - return net.minecraft.nbt.IntTag.valueOf(((IntBinaryTag) foreign).value()); - } else if (foreign instanceof IntArrayBinaryTag) { - return new net.minecraft.nbt.IntArrayTag(((IntArrayBinaryTag) foreign).value()); - } else if (foreign instanceof LongArrayBinaryTag) { - return new net.minecraft.nbt.LongArrayTag(((LongArrayBinaryTag) foreign).value()); - } else if (foreign instanceof ListBinaryTag) { + } else if (foreign instanceof LinByteTag byteTag) { + return net.minecraft.nbt.ByteTag.valueOf(byteTag.valueAsByte()); + } else if (foreign instanceof LinByteArrayTag byteArrayTag) { + return new net.minecraft.nbt.ByteArrayTag(byteArrayTag.value()); + } else if (foreign instanceof LinDoubleTag doubleTag) { + return net.minecraft.nbt.DoubleTag.valueOf(doubleTag.valueAsDouble()); + } else if (foreign instanceof LinFloatTag floatTag) { + return net.minecraft.nbt.FloatTag.valueOf(floatTag.valueAsFloat()); + } else if (foreign instanceof LinIntTag intTag) { + return net.minecraft.nbt.IntTag.valueOf(intTag.valueAsInt()); + } else if (foreign instanceof LinIntArrayTag intArrayTag) { + return new net.minecraft.nbt.IntArrayTag(intArrayTag.value()); + } else if (foreign instanceof LinLongArrayTag longArrayTag) { + return new net.minecraft.nbt.LongArrayTag(longArrayTag.value()); + } else if (foreign instanceof LinListTag listTag) { net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); - ListBinaryTag foreignList = (ListBinaryTag) foreign; - for (BinaryTag t : foreignList) { - tag.add(fromNativeBinary(t)); + for (var t : listTag.value()) { + tag.add(fromNativeLin(t)); } return tag; - } else if (foreign instanceof LongBinaryTag) { - return net.minecraft.nbt.LongTag.valueOf(((LongBinaryTag) foreign).value()); - } else if (foreign instanceof ShortBinaryTag) { - return net.minecraft.nbt.ShortTag.valueOf(((ShortBinaryTag) foreign).value()); - } else if (foreign instanceof StringBinaryTag) { - return net.minecraft.nbt.StringTag.valueOf(((StringBinaryTag) foreign).value()); - } else if (foreign instanceof EndBinaryTag) { + } else if (foreign instanceof LinLongTag longTag) { + return net.minecraft.nbt.LongTag.valueOf(longTag.valueAsLong()); + } else if (foreign instanceof LinShortTag shortTag) { + return net.minecraft.nbt.ShortTag.valueOf(shortTag.valueAsShort()); + } else if (foreign instanceof LinStringTag stringTag) { + return net.minecraft.nbt.StringTag.valueOf(stringTag.value()); + } else if (foreign instanceof LinEndTag) { return net.minecraft.nbt.EndTag.INSTANCE; } else { throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName()); diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightDataConverters.java index 175174b75..3a80b6a3a 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightDataConverters.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightDataConverters.java @@ -35,8 +35,6 @@ import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.DataFixerBuilder; import com.mojang.datafixers.schemas.Schema; import com.mojang.serialization.Dynamic; -import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R3.PaperweightAdapter; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import net.minecraft.core.Direction; import net.minecraft.nbt.NbtOps; import net.minecraft.network.chat.Component; @@ -49,7 +47,9 @@ import net.minecraft.util.datafix.fixes.References; import net.minecraft.world.item.DyeColor; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.enginehub.linbus.tree.LinCompoundTag; +import javax.annotation.Nullable; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.EnumMap; @@ -63,7 +63,6 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.Executor; import java.util.stream.Collectors; -import javax.annotation.Nullable; /** * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2) @@ -79,16 +78,15 @@ import javax.annotation.Nullable; @SuppressWarnings({ "rawtypes", "unchecked" }) public class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.worldedit.world.DataFixer { - //FAWE start - BinaryTag @SuppressWarnings("unchecked") @Override public T fixUp(FixType type, T original, int srcVer) { if (type == FixTypes.CHUNK) { - return (T) fixChunk((CompoundBinaryTag) original, srcVer); + return (T) fixChunk((LinCompoundTag) original, srcVer); } else if (type == FixTypes.BLOCK_ENTITY) { - return (T) fixBlockEntity((CompoundBinaryTag) original, srcVer); + return (T) fixBlockEntity((LinCompoundTag) original, srcVer); } else if (type == FixTypes.ENTITY) { - return (T) fixEntity((CompoundBinaryTag) original, srcVer); + return (T) fixEntity((LinCompoundTag) original, srcVer); } else if (type == FixTypes.BLOCK_STATE) { return (T) fixBlockState((String) original, srcVer); } else if (type == FixTypes.ITEM_TYPE) { @@ -99,24 +97,23 @@ public class PaperweightDataConverters extends DataFixerBuilder implements com.s return original; } - private CompoundBinaryTag fixChunk(CompoundBinaryTag originalChunk, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(originalChunk); + private LinCompoundTag fixChunk(LinCompoundTag originalChunk, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(originalChunk); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.CHUNK, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - private CompoundBinaryTag fixBlockEntity(CompoundBinaryTag origTileEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origTileEnt); + private LinCompoundTag fixBlockEntity(LinCompoundTag origTileEnt, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origTileEnt); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.BLOCK_ENTITY, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - private CompoundBinaryTag fixEntity(CompoundBinaryTag origEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origEnt); + private LinCompoundTag fixEntity(LinCompoundTag origEnt, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origEnt); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.ENTITY, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - //FAWE end private String fixBlockState(String blockState, int srcVer) { net.minecraft.nbt.CompoundTag stateNBT = stateToNBT(blockState); diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightWorldNativeAccess.java index b50ead936..7e5a171f6 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightWorldNativeAccess.java @@ -19,25 +19,28 @@ package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R3; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.internal.block.BlockStateIdAccess; import com.sk89q.worldedit.internal.wna.WorldNativeAccess; import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.block.BlockState; import net.minecraft.core.BlockPos; +import net.minecraft.nbt.Tag; import net.minecraft.server.level.FullChunkStatus; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.LevelChunk; import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; import org.bukkit.craftbukkit.v1_20_R3.block.data.CraftBlockData; import org.bukkit.event.block.BlockPhysicsEvent; +import org.enginehub.linbus.tree.LinCompoundTag; +import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.util.Objects; -import javax.annotation.Nullable; public class PaperweightWorldNativeAccess implements WorldNativeAccess { private static final int UPDATE = 1; @@ -101,8 +104,15 @@ public class PaperweightWorldNativeAccess implements WorldNativeAccess saveTag = () -> { + Supplier saveTag = () -> { final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag(); readEntityIntoTag(mcEntity, minecraftTag); //add Id for AbstractChangeSet to work - final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag); - final Map tags = NbtUtils.getCompoundBinaryTagValues(tag); - tags.put("Id", StringBinaryTag.of(id)); - return CompoundBinaryTag.from(tags); + final LinCompoundTag tag = (LinCompoundTag) toNativeLin(minecraftTag); + final Map> tags = NbtUtils.getLinCompoundTagValues(tag); + tags.put("Id", LinStringTag.of(id)); + return LinCompoundTag.of(tags); }; return new LazyBaseEntity(type, saveTag); } else { @@ -517,7 +517,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter iterator = entities.iterator(); while (iterator.hasNext()) { final CompoundTag nativeTag = iterator.next(); - final Map entityTagMap = nativeTag.getValue(); + final Map> entityTagMap = nativeTag.getValue(); final StringTag idTag = (StringTag) entityTagMap.get("Id"); final ListTag posTag = (ListTag) entityTagMap.get("Pos"); final ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/nbt/PaperweightLazyCompoundTag.java index 9a8a51896..1d27f17a7 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/nbt/PaperweightLazyCompoundTag.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/nbt/PaperweightLazyCompoundTag.java @@ -6,8 +6,8 @@ import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import net.minecraft.nbt.NumericTag; +import org.enginehub.linbus.tree.LinCompoundTag; import java.util.ArrayList; import java.util.Collections; @@ -36,7 +36,7 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { @Override @SuppressWarnings("unchecked") - public Map getValue() { + public Map> getValue() { if (compoundTag == null) { compoundTag = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(compoundTagSupplier.get()); } @@ -44,9 +44,9 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @Override - public CompoundBinaryTag asBinaryTag() { + public LinCompoundTag toLinTag() { getValue(); - return compoundTag.asBinaryTag(); + return compoundTag.toLinTag(); } public boolean containsKey(String key) { @@ -94,10 +94,10 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @SuppressWarnings("unchecked") - public List getList(String key) { + public List> getList(String key) { net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); if (tag instanceof net.minecraft.nbt.ListTag nbtList) { - ArrayList list = new ArrayList<>(); + ArrayList> list = new ArrayList<>(); for (net.minecraft.nbt.Tag elem : nbtList) { if (elem instanceof net.minecraft.nbt.CompoundTag compoundTag) { list.add(new PaperweightLazyCompoundTag(compoundTag)); @@ -120,7 +120,7 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @SuppressWarnings("unchecked") - public List getList(String key, Class listType) { + public > List getList(String key, Class listType) { ListTag listTag = getListTag(key); if (listTag.getType().equals(listType)) { return (List) listTag.getValue(); diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java index 964be1398..503330ad5 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java @@ -54,20 +54,6 @@ import com.sk89q.worldedit.util.concurrency.LazyReference; import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.ByteArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.ByteBinaryTag; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.DoubleBinaryTag; -import com.sk89q.worldedit.util.nbt.EndBinaryTag; -import com.sk89q.worldedit.util.nbt.FloatBinaryTag; -import com.sk89q.worldedit.util.nbt.IntArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.IntBinaryTag; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; -import com.sk89q.worldedit.util.nbt.LongArrayBinaryTag; -import com.sk89q.worldedit.util.nbt.LongBinaryTag; -import com.sk89q.worldedit.util.nbt.ShortBinaryTag; -import com.sk89q.worldedit.util.nbt.StringBinaryTag; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.RegenOptions; import com.sk89q.worldedit.world.biome.BiomeType; @@ -139,9 +125,26 @@ import org.bukkit.craftbukkit.util.CraftMagicNumbers; import org.bukkit.entity.Player; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.generator.ChunkGenerator; +import org.enginehub.linbus.common.LinTagId; +import org.enginehub.linbus.tree.LinByteArrayTag; +import org.enginehub.linbus.tree.LinByteTag; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinDoubleTag; +import org.enginehub.linbus.tree.LinEndTag; +import org.enginehub.linbus.tree.LinFloatTag; +import org.enginehub.linbus.tree.LinIntArrayTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinLongArrayTag; +import org.enginehub.linbus.tree.LinLongTag; +import org.enginehub.linbus.tree.LinShortTag; +import org.enginehub.linbus.tree.LinStringTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; import org.spigotmc.SpigotConfig; import org.spigotmc.WatchdogThread; +import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -163,7 +166,6 @@ import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; @@ -375,7 +377,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter (CompoundBinaryTag) toNativeBinary(tag)) + LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)) ); } @@ -473,9 +475,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) + (blockEntity, registryAccess) -> (net.minecraft.nbt.CompoundTag) fromNativeLin(nbtData) )); } @@ -619,7 +621,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter (CompoundBinaryTag) toNativeBinary(tag)), + LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)), itemStack.getAmount() ); } @@ -811,7 +813,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter toNativeLin(net.minecraft.nbt.Tag foreign) { if (foreign == null) { return null; } if (foreign instanceof net.minecraft.nbt.CompoundTag) { - Map values = new HashMap<>(); + Map> values = new HashMap<>(); Set foreignKeys = ((net.minecraft.nbt.CompoundTag) foreign).getAllKeys(); for (String str : foreignKeys) { net.minecraft.nbt.Tag base = ((net.minecraft.nbt.CompoundTag) foreign).get(str); - values.put(str, toNativeBinary(base)); + values.put(str, toNativeLin(base)); } - return CompoundBinaryTag.from(values); + return LinCompoundTag.of(values); } else if (foreign instanceof net.minecraft.nbt.ByteTag) { - return ByteBinaryTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); + return LinByteTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); } else if (foreign instanceof net.minecraft.nbt.ByteArrayTag) { - return ByteArrayBinaryTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); + return LinByteArrayTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); } else if (foreign instanceof net.minecraft.nbt.DoubleTag) { - return DoubleBinaryTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); + return LinDoubleTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); } else if (foreign instanceof net.minecraft.nbt.FloatTag) { - return FloatBinaryTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); + return LinFloatTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); } else if (foreign instanceof net.minecraft.nbt.IntTag) { - return IntBinaryTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); + return LinIntTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); } else if (foreign instanceof net.minecraft.nbt.IntArrayTag) { - return IntArrayBinaryTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); + return LinIntArrayTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); } else if (foreign instanceof net.minecraft.nbt.LongArrayTag) { - return LongArrayBinaryTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); + return LinLongArrayTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); } else if (foreign instanceof net.minecraft.nbt.ListTag) { try { - return toNativeList((net.minecraft.nbt.ListTag) foreign); + return toNativeLinList((net.minecraft.nbt.ListTag) foreign); } catch (Throwable e) { logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); - return ListBinaryTag.empty(); } } else if (foreign instanceof net.minecraft.nbt.LongTag) { - return LongBinaryTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); + return LinLongTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); } else if (foreign instanceof net.minecraft.nbt.ShortTag) { - return ShortBinaryTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); + return LinShortTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); } else if (foreign instanceof net.minecraft.nbt.StringTag) { - return StringBinaryTag.of(foreign.getAsString()); + return LinStringTag.of(foreign.getAsString()); } else if (foreign instanceof net.minecraft.nbt.EndTag) { - return EndBinaryTag.get(); - } else { - throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); + return LinEndTag.instance(); } + throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); } /** @@ -946,17 +946,19 @@ public final class PaperweightAdapter implements BukkitImplAdapter toNativeLinList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException { + LinListTag.Builder> builder = LinListTag.builder( + LinTagType.fromId(LinTagId.fromId(foreign.getElementType())) + ); for (net.minecraft.nbt.Tag tag : foreign) { - values.add(toNativeBinary(tag)); + builder.add(toNativeLin(tag)); } - return values.build(); + return builder.build(); } /** @@ -966,44 +968,43 @@ public final class PaperweightAdapter implements BukkitImplAdapter foreign) { if (foreign == null) { return null; } - if (foreign instanceof CompoundBinaryTag) { + if (foreign instanceof LinCompoundTag compoundTag) { net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - for (String key : ((CompoundBinaryTag) foreign).keySet()) { - tag.put(key, fromNativeBinary(((CompoundBinaryTag) foreign).get(key))); + for (var entry : compoundTag.value().entrySet()) { + tag.put(entry.getKey(), fromNativeLin(entry.getValue())); } return tag; - } else if (foreign instanceof ByteBinaryTag) { - return net.minecraft.nbt.ByteTag.valueOf(((ByteBinaryTag) foreign).value()); - } else if (foreign instanceof ByteArrayBinaryTag) { - return new net.minecraft.nbt.ByteArrayTag(((ByteArrayBinaryTag) foreign).value()); - } else if (foreign instanceof DoubleBinaryTag) { - return net.minecraft.nbt.DoubleTag.valueOf(((DoubleBinaryTag) foreign).value()); - } else if (foreign instanceof FloatBinaryTag) { - return net.minecraft.nbt.FloatTag.valueOf(((FloatBinaryTag) foreign).value()); - } else if (foreign instanceof IntBinaryTag) { - return net.minecraft.nbt.IntTag.valueOf(((IntBinaryTag) foreign).value()); - } else if (foreign instanceof IntArrayBinaryTag) { - return new net.minecraft.nbt.IntArrayTag(((IntArrayBinaryTag) foreign).value()); - } else if (foreign instanceof LongArrayBinaryTag) { - return new net.minecraft.nbt.LongArrayTag(((LongArrayBinaryTag) foreign).value()); - } else if (foreign instanceof ListBinaryTag) { + } else if (foreign instanceof LinByteTag byteTag) { + return net.minecraft.nbt.ByteTag.valueOf(byteTag.valueAsByte()); + } else if (foreign instanceof LinByteArrayTag byteArrayTag) { + return new net.minecraft.nbt.ByteArrayTag(byteArrayTag.value()); + } else if (foreign instanceof LinDoubleTag doubleTag) { + return net.minecraft.nbt.DoubleTag.valueOf(doubleTag.valueAsDouble()); + } else if (foreign instanceof LinFloatTag floatTag) { + return net.minecraft.nbt.FloatTag.valueOf(floatTag.valueAsFloat()); + } else if (foreign instanceof LinIntTag intTag) { + return net.minecraft.nbt.IntTag.valueOf(intTag.valueAsInt()); + } else if (foreign instanceof LinIntArrayTag intArrayTag) { + return new net.minecraft.nbt.IntArrayTag(intArrayTag.value()); + } else if (foreign instanceof LinLongArrayTag longArrayTag) { + return new net.minecraft.nbt.LongArrayTag(longArrayTag.value()); + } else if (foreign instanceof LinListTag listTag) { net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); - ListBinaryTag foreignList = (ListBinaryTag) foreign; - for (BinaryTag t : foreignList) { - tag.add(fromNativeBinary(t)); + for (var t : listTag.value()) { + tag.add(fromNativeLin(t)); } return tag; - } else if (foreign instanceof LongBinaryTag) { - return net.minecraft.nbt.LongTag.valueOf(((LongBinaryTag) foreign).value()); - } else if (foreign instanceof ShortBinaryTag) { - return net.minecraft.nbt.ShortTag.valueOf(((ShortBinaryTag) foreign).value()); - } else if (foreign instanceof StringBinaryTag) { - return net.minecraft.nbt.StringTag.valueOf(((StringBinaryTag) foreign).value()); - } else if (foreign instanceof EndBinaryTag) { + } else if (foreign instanceof LinLongTag longTag) { + return net.minecraft.nbt.LongTag.valueOf(longTag.valueAsLong()); + } else if (foreign instanceof LinShortTag shortTag) { + return net.minecraft.nbt.ShortTag.valueOf(shortTag.valueAsShort()); + } else if (foreign instanceof LinStringTag stringTag) { + return net.minecraft.nbt.StringTag.valueOf(stringTag.value()); + } else if (foreign instanceof LinEndTag) { return net.minecraft.nbt.EndTag.INSTANCE; } else { throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName()); diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightDataConverters.java index 39807b86d..c566f0ae8 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightDataConverters.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightDataConverters.java @@ -35,8 +35,6 @@ import com.mojang.datafixers.DataFixer; import com.mojang.datafixers.DataFixerBuilder; import com.mojang.datafixers.schemas.Schema; import com.mojang.serialization.Dynamic; -import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4.PaperweightAdapter; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import net.minecraft.core.Direction; import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.StringTag; @@ -51,7 +49,9 @@ import net.minecraft.util.datafix.fixes.References; import net.minecraft.world.item.DyeColor; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.enginehub.linbus.tree.LinCompoundTag; +import javax.annotation.Nullable; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.EnumMap; @@ -65,7 +65,6 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.Executor; import java.util.stream.Collectors; -import javax.annotation.Nullable; /** * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2) @@ -81,16 +80,15 @@ import javax.annotation.Nullable; @SuppressWarnings({ "rawtypes", "unchecked" }) public class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.worldedit.world.DataFixer { - //FAWE start - BinaryTag @SuppressWarnings("unchecked") @Override public T fixUp(FixType type, T original, int srcVer) { if (type == FixTypes.CHUNK) { - return (T) fixChunk((CompoundBinaryTag) original, srcVer); + return (T) fixChunk((LinCompoundTag) original, srcVer); } else if (type == FixTypes.BLOCK_ENTITY) { - return (T) fixBlockEntity((CompoundBinaryTag) original, srcVer); + return (T) fixBlockEntity((LinCompoundTag) original, srcVer); } else if (type == FixTypes.ENTITY) { - return (T) fixEntity((CompoundBinaryTag) original, srcVer); + return (T) fixEntity((LinCompoundTag) original, srcVer); } else if (type == FixTypes.BLOCK_STATE) { return (T) fixBlockState((String) original, srcVer); } else if (type == FixTypes.ITEM_TYPE) { @@ -101,24 +99,23 @@ public class PaperweightDataConverters extends DataFixerBuilder implements com.s return original; } - private CompoundBinaryTag fixChunk(CompoundBinaryTag originalChunk, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(originalChunk); + private LinCompoundTag fixChunk(LinCompoundTag originalChunk, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(originalChunk); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.CHUNK, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - private CompoundBinaryTag fixBlockEntity(CompoundBinaryTag origTileEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origTileEnt); + private LinCompoundTag fixBlockEntity(LinCompoundTag origTileEnt, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origTileEnt); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.BLOCK_ENTITY, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - private CompoundBinaryTag fixEntity(CompoundBinaryTag origEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeBinary(origEnt); + private LinCompoundTag fixEntity(LinCompoundTag origEnt, int srcVer) { + net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origEnt); net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.ENTITY, tag, srcVer); - return (CompoundBinaryTag) adapter.toNativeBinary(fixed); + return (LinCompoundTag) adapter.toNativeLin(fixed); } - //FAWE end private String fixBlockState(String blockState, int srcVer) { net.minecraft.nbt.CompoundTag stateNBT = stateToNBT(blockState); diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightWorldNativeAccess.java index f7e5cee3f..4b82a2eb0 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightWorldNativeAccess.java @@ -24,7 +24,6 @@ import com.sk89q.worldedit.internal.block.BlockStateIdAccess; import com.sk89q.worldedit.internal.wna.WorldNativeAccess; import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.block.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.server.level.FullChunkStatus; @@ -34,10 +33,11 @@ import net.minecraft.world.level.chunk.LevelChunk; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.event.block.BlockPhysicsEvent; +import org.enginehub.linbus.tree.LinCompoundTag; +import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.util.Objects; -import javax.annotation.Nullable; public class PaperweightWorldNativeAccess implements WorldNativeAccess { private static final int UPDATE = 1; @@ -101,7 +101,7 @@ public class PaperweightWorldNativeAccess implements WorldNativeAccess saveTag = () -> { + Supplier saveTag = () -> { final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag(); readEntityIntoTag(mcEntity, minecraftTag); //add Id for AbstractChangeSet to work - final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag); - final Map tags = NbtUtils.getCompoundBinaryTagValues(tag); - tags.put("Id", StringBinaryTag.of(id)); - return CompoundBinaryTag.from(tags); + final LinCompoundTag tag = (LinCompoundTag) toNativeLin(minecraftTag); + final Map> tags = NbtUtils.getLinCompoundTagValues(tag); + tags.put("Id", LinStringTag.of(id)); + return LinCompoundTag.of(tags); }; return new LazyBaseEntity(type, saveTag); } else { @@ -538,7 +538,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter (CompoundBinaryTag) toNativeBinary(tag)), + LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)), itemStack.getAmount() ); } diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweWorldNativeAccess.java index d66057313..8d33efb0f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweWorldNativeAccess.java @@ -9,15 +9,14 @@ import com.sk89q.worldedit.internal.block.BlockStateIdAccess; import com.sk89q.worldedit.internal.wna.WorldNativeAccess; import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.block.BlockState; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.MinecraftServer; import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.FullChunkStatus; +import net.minecraft.server.level.ServerChunkCache; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; @@ -25,6 +24,7 @@ import net.minecraft.world.level.chunk.LevelChunk; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.event.block.BlockPhysicsEvent; +import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nullable; import java.lang.ref.WeakReference; @@ -133,14 +133,14 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess iterator = entities.iterator(); while (iterator.hasNext()) { final CompoundTag nativeTag = iterator.next(); - final Map entityTagMap = nativeTag.getValue(); + final Map> entityTagMap = nativeTag.getValue(); final StringTag idTag = (StringTag) entityTagMap.get("Id"); final ListTag posTag = (ListTag) entityTagMap.get("Pos"); final ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/nbt/PaperweightLazyCompoundTag.java index 11d3c940a..52111a4fd 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/nbt/PaperweightLazyCompoundTag.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/nbt/PaperweightLazyCompoundTag.java @@ -6,8 +6,8 @@ import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import net.minecraft.nbt.NumericTag; +import org.enginehub.linbus.tree.LinCompoundTag; import java.util.ArrayList; import java.util.Collections; @@ -36,7 +36,7 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { @Override @SuppressWarnings("unchecked") - public Map getValue() { + public Map> getValue() { if (compoundTag == null) { compoundTag = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(compoundTagSupplier.get()); } @@ -44,9 +44,9 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @Override - public CompoundBinaryTag asBinaryTag() { + public LinCompoundTag toLinTag() { getValue(); - return compoundTag.asBinaryTag(); + return compoundTag.toLinTag(); } public boolean containsKey(String key) { @@ -94,10 +94,10 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @SuppressWarnings("unchecked") - public List getList(String key) { + public List> getList(String key) { net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); if (tag instanceof net.minecraft.nbt.ListTag nbtList) { - ArrayList list = new ArrayList<>(); + ArrayList> list = new ArrayList<>(); for (net.minecraft.nbt.Tag elem : nbtList) { if (elem instanceof net.minecraft.nbt.CompoundTag compoundTag) { list.add(new PaperweightLazyCompoundTag(compoundTag)); @@ -120,7 +120,7 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { } @SuppressWarnings("unchecked") - public List getList(String key, Class listType) { + public > List getList(String key, Class listType) { ListTag listTag = getListTag(key); if (listTag.getType().equals(listType)) { return (List) listTag.getValue(); diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index ce6c9d1b1..258d9b83e 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -178,9 +178,6 @@ tasks.named("shadowJar") { relocate("org.lz4", "com.fastasyncworldedit.core.lz4") { include(dependency("org.lz4:lz4-java:1.8.0")) } - relocate("net.kyori", "com.fastasyncworldedit.core.adventure") { - include(dependency("net.kyori:adventure-nbt:4.17.0")) - } relocate("com.zaxxer", "com.fastasyncworldedit.core.math") { include(dependency("com.zaxxer:SparseBitSet:1.3")) } diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java index e0d13a36b..5cbc0f6b8 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java @@ -12,11 +12,8 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; @@ -33,6 +30,8 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinTag; import javax.annotation.Nullable; import java.util.Map; @@ -81,7 +80,7 @@ public interface IDelegateBukkitImplAdapter extends BukkitImplAdapter { } @Override - default void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) { + default void sendFakeNBT(Player player, BlockVector3 pos, LinCompoundTag nbtData) { getParent().sendFakeNBT(player, pos, nbtData); } @@ -131,8 +130,8 @@ public interface IDelegateBukkitImplAdapter extends BukkitImplAdapter { } @Override - default BinaryTag toNativeBinary(T foreign) { - return getParent().toNativeBinary(foreign); + default LinTag toNativeLin(T foreign) { + return getParent().toNativeLin(foreign); } @Override @@ -141,8 +140,8 @@ public interface IDelegateBukkitImplAdapter extends BukkitImplAdapter { } @Override - default T fromNativeBinary(BinaryTag foreign) { - return getParent().fromNativeBinary(foreign); + default T fromNativeLin(LinTag foreign) { + return getParent().fromNativeLin(foreign); } @Override diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java index 792f3937e..4b798981e 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java @@ -194,7 +194,7 @@ public class FaweDelegateSchematicHandler { } else { try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new ParallelGZIPOutputStream(stream))) { - Map map = tag.getValue(); + Map> map = tag.getValue(); output.writeNamedTag("Schematic", map.getOrDefault("Schematic", tag)); } } @@ -226,7 +226,7 @@ public class FaweDelegateSchematicHandler { try { try (ParallelGZIPOutputStream gzip = new ParallelGZIPOutputStream(output)) { try (NBTOutputStream nos = new NBTOutputStream(gzip)) { - Map map = weTag.getValue(); + Map> map = weTag.getValue(); nos.writeNamedTag("Schematic", map.getOrDefault("Schematic", weTag)); } } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index 44918557e..4ced1a680 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -45,7 +45,6 @@ import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.util.formatting.text.adapter.bukkit.TextAdapter; import com.sk89q.worldedit.util.formatting.text.event.ClickEvent; import com.sk89q.worldedit.util.formatting.text.format.TextColor; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; @@ -61,6 +60,7 @@ import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.permissions.PermissionAttachment; +import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -430,7 +430,7 @@ public class BukkitPlayer extends AbstractPlayerActor { BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); if (adapter != null) { if (block.getBlockType() == BlockTypes.STRUCTURE_BLOCK && block instanceof BaseBlock) { - CompoundBinaryTag nbt = ((BaseBlock) block).getNbt(); + LinCompoundTag nbt = ((BaseBlock) block).getNbt(); if (nbt != null) { adapter.sendFakeNBT(player, pos, nbt); adapter.sendFakeOP(player); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java index a34494ce5..d656e874a 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java @@ -27,7 +27,7 @@ import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket; -import com.sk89q.jnbt.AdventureNBTConverter; +import com.sk89q.jnbt.LinBusConverter; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; @@ -41,8 +41,6 @@ import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.RegenOptions; import com.sk89q.worldedit.world.biome.BiomeType; @@ -61,6 +59,8 @@ import org.bukkit.block.data.BlockData; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinTag; import javax.annotation.Nullable; import java.util.Arrays; @@ -183,7 +183,7 @@ public interface BukkitImplAdapter extends IBukkitAdapter { * @param pos The position * @param nbtData The NBT Data */ - void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData); + void sendFakeNBT(Player player, BlockVector3 pos, LinCompoundTag nbtData); /** * Make the client think it has operator status. @@ -291,11 +291,11 @@ public interface BukkitImplAdapter extends IBukkitAdapter { @Deprecated default Tag toNative(T foreign) { - return AdventureNBTConverter.fromAdventure(toNativeBinary(foreign)); + return LinBusConverter.toJnbtTag(toNativeLin(foreign)); } - default BinaryTag toNativeBinary(T foreign) { - return toNative(foreign).asBinaryTag(); + default LinTag toNativeLin(T foreign) { + return toNative(foreign).toLinTag(); } @Deprecated @@ -303,14 +303,14 @@ public interface BukkitImplAdapter extends IBukkitAdapter { if (foreign == null) { return null; } - return fromNativeBinary(foreign.asBinaryTag()); + return fromNativeLin(foreign.toLinTag()); } - default T fromNativeBinary(BinaryTag foreign) { + default T fromNativeLin(LinTag foreign) { if (foreign == null) { return null; } - return fromNative(AdventureNBTConverter.fromAdventure(foreign)); + return fromNative(LinBusConverter.toJnbtTag(foreign)); } @Nullable diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index d9794d9f6..d5839d99f 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -46,7 +46,6 @@ dependencies { implementation(libs.findbugs) implementation(libs.rhino) compileOnly(libs.adventureApi) - compileOnlyApi(libs.adventureNbt) compileOnlyApi(libs.adventureMiniMessage) implementation(libs.zstd) { isTransitive = false } compileOnly(libs.paster) @@ -56,10 +55,10 @@ dependencies { antlr(libs.antlr4) implementation(libs.antlr4Runtime) implementation(libs.jsonSimple) { isTransitive = false } + implementation(platform(libs.linBus.bom)) // Tests testRuntimeOnly(libs.log4jCore) - testImplementation(libs.adventureNbt) testImplementation(libs.parallelgzip) } diff --git a/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java b/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java index 0420d0994..1f0efe7a1 100644 --- a/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java +++ b/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/MobSpawnerBlock.java @@ -125,7 +125,7 @@ public class MobSpawnerBlock extends BaseBlock { @Override public CompoundTag getNbtData() { - Map values = new HashMap<>(); + Map> values = new HashMap<>(); values.put("Delay", new ShortTag(delay)); values.put("SpawnCount", new ShortTag(spawnCount)); values.put("SpawnRange", new ShortTag(spawnRange)); @@ -170,7 +170,7 @@ public class MobSpawnerBlock extends BaseBlock { return; } - Map values = rootTag.getValue(); + Map> values = rootTag.getValue(); Tag t = values.get("id"); if (!(t instanceof StringTag) || !((StringTag) t).getValue().equals(getNbtId())) { diff --git a/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SignBlock.java b/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SignBlock.java index 333c3336b..bf9adfa38 100644 --- a/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SignBlock.java +++ b/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SignBlock.java @@ -104,7 +104,7 @@ public class SignBlock extends BaseBlock { @Override public CompoundTag getNbtData() { - Map values = new HashMap<>(); + Map> values = new HashMap<>(); if (isLegacy()) { values.put("Text1", new StringTag(text[0])); values.put("Text2", new StringTag(text[1])); @@ -112,7 +112,7 @@ public class SignBlock extends BaseBlock { values.put("Text4", new StringTag(text[3])); } else { ListTag messages = new ListTag(StringTag.class, Arrays.stream(text).map(StringTag::new).collect(Collectors.toList())); - Map frontTextTag = new HashMap<>(); + Map> frontTextTag = new HashMap<>(); frontTextTag.put("messages", messages); values.put("front_text", new CompoundTag(frontTextTag)); } @@ -125,9 +125,9 @@ public class SignBlock extends BaseBlock { return; } - Map values = rootTag.getValue(); + Map> values = rootTag.getValue(); - Tag t; + Tag t; text = new String[]{EMPTY, EMPTY, EMPTY, EMPTY}; diff --git a/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SkullBlock.java b/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SkullBlock.java index a60ffbc09..a5b405f47 100644 --- a/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SkullBlock.java +++ b/worldedit-core/src/legacy/java/com/sk89q/worldedit/blocks/SkullBlock.java @@ -100,8 +100,8 @@ public class SkullBlock extends BaseBlock { @Override public CompoundTag getNbtData() { - Map values = new HashMap<>(); - Map inner = new HashMap<>(); + Map> values = new HashMap<>(); + Map> inner = new HashMap<>(); inner.put("Name", new StringTag(owner)); values.put(DeprecationUtil.getHeadOwnerKey(), new CompoundTag(inner)); return new CompoundTag(values); @@ -113,7 +113,7 @@ public class SkullBlock extends BaseBlock { return; } - Map values = rootTag.getValue(); + Map> values = rootTag.getValue(); Tag t; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java index 46a3a1574..526570296 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java @@ -532,7 +532,7 @@ public enum FaweCache implements Trimable { } public CompoundTag asTag(Map value) { - HashMap map = new HashMap<>(); + HashMap> map = new HashMap<>(); for (Map.Entry entry : value.entrySet()) { Object child = entry.getValue(); Tag tag = asTag(child); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/entity/LazyBaseEntity.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/entity/LazyBaseEntity.java index f591cf826..325cd4191 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/entity/LazyBaseEntity.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/entity/LazyBaseEntity.java @@ -3,25 +3,25 @@ package com.fastasyncworldedit.core.entity; import com.fastasyncworldedit.core.Fawe; import com.fastasyncworldedit.core.util.TaskManager; import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.entity.EntityType; +import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nullable; import java.util.function.Supplier; public class LazyBaseEntity extends BaseEntity { - private Supplier saveTag; + private Supplier saveTag; - public LazyBaseEntity(EntityType type, Supplier saveTag) { + public LazyBaseEntity(EntityType type, Supplier saveTag) { super(type); this.saveTag = saveTag; } @Nullable @Override - public CompoundBinaryTag getNbt() { - Supplier tmp = saveTag; + public LinCompoundTag getNbt() { + Supplier tmp = saveTag; if (tmp != null) { saveTag = null; if (Fawe.isMainThread()) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/StripNBTExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/StripNBTExtent.java index ded96d5aa..c0b49c333 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/StripNBTExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/StripNBTExtent.java @@ -29,8 +29,6 @@ import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @@ -81,7 +79,7 @@ public class StripNBTExtent extends AbstractDelegateExtent implements IBatchProc return block; } CompoundTag nbt = localBlock.getNbtData(); - Map value = new HashMap<>(nbt.getValue()); + Map> value = new HashMap<>(nbt.getValue()); for (String key : strip) { value.remove(key); } @@ -93,7 +91,7 @@ public class StripNBTExtent extends AbstractDelegateExtent implements IBatchProc return entity; } CompoundTag nbt = entity.getNbtData(); - Map value = new HashMap<>(nbt.getValue()); + Map> value = new HashMap<>(nbt.getValue()); for (String key : strip) { value.remove(key); } @@ -110,7 +108,7 @@ public class StripNBTExtent extends AbstractDelegateExtent implements IBatchProc } boolean isBv3ChunkMap = tiles instanceof BlockVector3ChunkMap; for (final Map.Entry entry : tiles.entrySet()) { - ImmutableMap.Builder map = ImmutableMap.builder(); + ImmutableMap.Builder> map = ImmutableMap.builder(); final AtomicBoolean isStripped = new AtomicBoolean(false); entry.getValue().getValue().forEach((k, v) -> { if (strip.contains(k.toLowerCase())) { @@ -132,7 +130,7 @@ public class StripNBTExtent extends AbstractDelegateExtent implements IBatchProc Iterator iterator = entities.iterator(); while (iterator.hasNext()) { CompoundTag entity = iterator.next(); - ImmutableMap.Builder map = ImmutableMap.builder(); + ImmutableMap.Builder> map = ImmutableMap.builder(); final AtomicBoolean isStripped = new AtomicBoolean(false); entity.getValue().forEach((k, v) -> { if (strip.contains(k.toUpperCase(Locale.ROOT))) { 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 6a306fc44..77447ac4c 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 @@ -152,7 +152,7 @@ public class CPUOptimizedClipboard extends LinearClipboard { public Collection getTileEntities() { convertTilesToIndex(); nbtMapIndex.replaceAll((index, tag) -> { - Map values = new HashMap<>(tag.getValue()); + Map> values = new HashMap<>(tag.getValue()); if (!values.containsKey("x")) { int y = index / getArea(); index -= y * getArea(); @@ -176,7 +176,7 @@ public class CPUOptimizedClipboard extends LinearClipboard { } private boolean setTile(int index, CompoundTag tag) { - final Map values = new HashMap<>(tag.getValue()); + final Map> values = new HashMap<>(tag.getValue()); values.remove("x"); values.remove("y"); values.remove("z"); 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 f42cdbbff..dc7193394 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 @@ -586,7 +586,7 @@ public class DiskOptimizedClipboard extends LinearClipboard { for (BlockArrayClipboard.ClipboardEntity entity : entities) { if (entity.getState() != null && entity.getState().getNbtData() != null) { CompoundTag data = entity.getState().getNbtData(); - HashMap value = new HashMap<>(data.getValue()); + HashMap> value = new HashMap<>(data.getValue()); List pos = new ArrayList<>(3); pos.add(new DoubleTag(entity.getLocation().x())); pos.add(new DoubleTag(entity.getLocation().x())); @@ -710,7 +710,7 @@ public class DiskOptimizedClipboard extends LinearClipboard { @Override public boolean setTile(int x, int y, int z, CompoundTag tag) { - final Map values = new HashMap<>(tag.getValue()); + final Map> values = new HashMap<>(tag.getValue()); values.put("x", new IntTag(x)); values.put("y", new IntTag(y)); values.put("z", new IntTag(z)); 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 143168504..2e65f59ca 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 @@ -106,7 +106,7 @@ public abstract class LinearClipboard extends SimpleClipboard { @Nullable @Override public Entity createEntity(Location location, BaseEntity entity, UUID uuid) { - Map map = new HashMap<>(entity.getNbtData().getValue()); + Map> map = new HashMap<>(entity.getNbtData().getValue()); NBTUtils.addUUIDToMap(map, uuid); entity.setNbtData(new CompoundTag(map)); BlockArrayClipboard.ClipboardEntity ret = new BlockArrayClipboard.ClipboardEntity(location, entity); 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 6c7a910f2..426cbc32a 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 @@ -254,7 +254,7 @@ public class MemoryOptimizedClipboard extends LinearClipboard { @Override public boolean setTile(int x, int y, int z, CompoundTag tag) { - final Map values = new HashMap<>(tag.getValue()); + final Map> values = new HashMap<>(tag.getValue()); values.put("x", new IntTag(x)); values.put("y", new IntTag(y)); values.put("z", new IntTag(z)); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java index 156e38544..b32d42c04 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java @@ -9,7 +9,7 @@ import com.fastasyncworldedit.core.internal.io.FaweInputStream; import com.fastasyncworldedit.core.internal.io.FaweOutputStream; import com.fastasyncworldedit.core.jnbt.streamer.StreamDelegate; import com.fastasyncworldedit.core.jnbt.streamer.ValueReader; -import com.sk89q.jnbt.AdventureNBTConverter; +import com.sk89q.jnbt.LinBusConverter; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.IntTag; import com.sk89q.jnbt.NBTInputStream; @@ -109,10 +109,10 @@ public class FastSchematicReader extends NBTSchematicReader { if (fixer == null || dataVersion == -1) { return tag; } - //FAWE start - BinaryTag - return (CompoundTag) AdventureNBTConverter.fromAdventure(fixer.fixUp( + //FAWE start - LinTag + return (CompoundTag) LinBusConverter.fromLinBus(fixer.fixUp( DataFixer.FixTypes.BLOCK_ENTITY, - tag.asBinaryTag(), + tag.toLinTag(), dataVersion )); //FAWE end @@ -122,10 +122,10 @@ public class FastSchematicReader extends NBTSchematicReader { if (fixer == null || dataVersion == -1) { return tag; } - //FAWE start - BinaryTag - return (CompoundTag) AdventureNBTConverter.fromAdventure(fixer.fixUp( + //FAWE start - LinTag + return (CompoundTag) LinBusConverter.fromLinBus(fixer.fixUp( DataFixer.FixTypes.ENTITY, - tag.asBinaryTag(), + tag.toLinTag(), dataVersion )); //FAWE end @@ -344,7 +344,7 @@ public class FastSchematicReader extends NBTSchematicReader { y = pos[1]; z = pos[2]; } - Map values = new HashMap<>(tile.getValue()); + Map> values = new HashMap<>(tile.getValue()); Tag id = values.get("Id"); if (id != null) { values.put("x", new IntTag(x)); @@ -371,7 +371,7 @@ public class FastSchematicReader extends NBTSchematicReader { // entities if (entities != null && !entities.isEmpty()) { for (Map entRaw : entities) { - Map value = new HashMap<>(FaweCache.INSTANCE.asTag(entRaw).getValue()); + Map> value = new HashMap<>(FaweCache.INSTANCE.asTag(entRaw).getValue()); StringTag id = (StringTag) value.get("Id"); if (id == null) { id = (StringTag) value.get("id"); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java index 65a4a0e86..ac86fb249 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java @@ -149,7 +149,7 @@ public class FastSchematicWriter implements ClipboardWriter { BaseBlock block = pos.getFullBlock(finalClipboard); CompoundTag nbt = block.getNbtData(); if (nbt != null) { - Map values = new HashMap<>(nbt.getValue()); + Map> values = new HashMap<>(nbt.getValue()); // Positions are kept in NBT, we don't want that. values.remove("x"); @@ -223,7 +223,7 @@ public class FastSchematicWriter implements ClipboardWriter { BaseEntity state = entity.getState(); if (state != null) { - Map values = new HashMap<>(); + Map> values = new HashMap<>(); // Put NBT provided data CompoundTag rawTag = state.getNbtData(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java index 91fb75495..0915766cc 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java @@ -70,7 +70,7 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { throw new IOException("Root tag has name - are you sure this is a structure?"); } - Map tags = ((CompoundTag) rootTag.getTag()).getValue(); + Map> tags = ((CompoundTag) rootTag.getTag()).getValue(); ListTag size = (ListTag) tags.get("size"); int width = size.getInt(0); @@ -89,13 +89,13 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { BlockState[] combinedArray = new BlockState[palette.size()]; for (int i = 0; i < palette.size(); i++) { CompoundTag compound = palette.get(i); - Map map = compound.getValue(); + Map> map = compound.getValue(); String name = ((StringTag) map.get("Name")).getValue(); BlockType type = BlockTypes.get(name); BlockState state = type.getDefaultState(); CompoundTag properties = (CompoundTag) map.get("Properties"); if (properties != null) { - for (Map.Entry entry : properties.getValue().entrySet()) { + for (Map.Entry> entry : properties.getValue().entrySet()) { String key = entry.getKey(); String value = ((StringTag) entry.getValue()).getValue(); Property property = type.getProperty(key); @@ -108,7 +108,7 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { List blocksList = (List) tags.get("blocks").getValue(); try { for (CompoundTag compound : blocksList) { - Map blockMap = compound.getValue(); + Map> blockMap = compound.getValue(); IntTag stateTag = (IntTag) blockMap.get("state"); ListTag posTag = (ListTag) blockMap.get("pos"); BlockState state = combinedArray[stateTag.getValue()]; @@ -136,7 +136,7 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { if (entities != null) { List entityList = (List) (List) entities.getValue(); for (CompoundTag entityEntry : entityList) { - Map entityEntryMap = entityEntry.getValue(); + Map> entityEntryMap = entityEntry.getValue(); ListTag posTag = (ListTag) entityEntryMap.get("pos"); CompoundTag nbtTag = (CompoundTag) entityEntryMap.get("nbt"); String id = nbtTag.getString("Id"); @@ -216,7 +216,7 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { if (!block.hasNbtData()) { blocks.add(FaweCache.INSTANCE.asMap("state", index, "pos", pos)); } else { - Map tag = new HashMap<>(block.getNbtData().getValue()); + Map> tag = new HashMap<>(block.getNbtData().getValue()); tag.remove("x"); tag.remove("y"); tag.remove("z"); @@ -246,7 +246,7 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { BaseEntity state = entity.getState(); if (state != null) { CompoundTag nbt = state.getNbtData(); - Map nbtMap = new HashMap<>(nbt.getValue()); + Map> nbtMap = new HashMap<>(nbt.getValue()); // Replace rotation data nbtMap.put("Rotation", writeRotation(entity.getLocation())); nbtMap.put("id", new StringTag(state.getType().id())); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/change/MutableEntityChange.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/change/MutableEntityChange.java index 7fa4ddc6d..b56ebc3eb 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/change/MutableEntityChange.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/change/MutableEntityChange.java @@ -3,7 +3,6 @@ package com.fastasyncworldedit.core.history.change; import com.fastasyncworldedit.core.util.MathMan; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.DoubleTag; -import com.sk89q.jnbt.LongTag; import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.entity.BaseEntity; @@ -52,7 +51,7 @@ public class MutableEntityChange implements Change { @SuppressWarnings({"unchecked"}) public void delete(UndoContext context) { - Map map = tag.getValue(); + Map> map = tag.getValue(); UUID uuid = tag.getUUID(); if (uuid == null) { LOGGER.info("Skipping entity without uuid."); @@ -66,7 +65,7 @@ public class MutableEntityChange implements Change { } public void create(UndoContext context) { - Map map = tag.getValue(); + Map> map = tag.getValue(); Tag posTag = map.get("Pos"); if (posTag == null) { LOGGER.warn("Missing pos tag: {}", tag); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/BlockBagChangeSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/BlockBagChangeSet.java index c0dc9756c..e17a78765 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/BlockBagChangeSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/BlockBagChangeSet.java @@ -112,7 +112,7 @@ public class BlockBagChangeSet extends AbstractDelegateChangeSet { @Override public void addTileCreate(CompoundTag nbt) { if (nbt.containsKey("items")) { - Map map = new HashMap<>(nbt.getValue()); + Map> map = new HashMap<>(nbt.getValue()); map.remove("items"); } super.addTileCreate(nbt); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/CompressedCompoundTag.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/CompressedCompoundTag.java index 85bdddf09..efed01376 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/CompressedCompoundTag.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/CompressedCompoundTag.java @@ -19,7 +19,7 @@ public abstract class CompressedCompoundTag extends CompoundTag { } @Override - public Map getValue() { + public Map> getValue() { if (in != null) { decompress(); } @@ -36,8 +36,8 @@ public abstract class CompressedCompoundTag extends CompoundTag { try (NBTInputStream nbtIn = new NBTInputStream(adapt(in))) { in = null; CompoundTag tag = (CompoundTag) nbtIn.readTag(); - Map value = tag.getValue(); - Map raw = super.getValue(); + Map> value = tag.getValue(); + Map> raw = super.getValue(); raw.putAll(value); } catch (IOException e) { throw new RuntimeException(e); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/JSON2NBT.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/JSON2NBT.java index 8b942895d..6cdef3dda 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/JSON2NBT.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/JSON2NBT.java @@ -17,7 +17,6 @@ import com.sk89q.jnbt.Tag; import java.util.ArrayList; import java.util.HashMap; -import java.util.Iterator; import java.util.Stack; import java.util.regex.Pattern; @@ -409,7 +408,7 @@ public class JSON2NBT { } public Tag parse() throws NBTException { - HashMap map = new HashMap<>(); + HashMap> map = new HashMap<>(); for (Any JSON2NBT$any : this.tagList) { map.put(JSON2NBT$any.json, JSON2NBT$any.parse()); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/NumberTag.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/NumberTag.java index db1984bb3..5931069c6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/NumberTag.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/NumberTag.java @@ -1,11 +1,16 @@ package com.fastasyncworldedit.core.jnbt; import com.sk89q.jnbt.Tag; +import org.enginehub.linbus.tree.LinTag; /** * A numerical {@link Tag} */ -public abstract class NumberTag extends Tag { +public abstract class NumberTag> extends Tag { + + protected NumberTag(LT linTag) { + super(linTag); + } @Override public abstract Number getValue(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkExtent.java index a56fe27d5..534a96fac 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkExtent.java @@ -124,7 +124,7 @@ public interface IChunkExtent extends Extent { @Override default Entity createEntity(Location location, BaseEntity entity, UUID uuid) { final IChunk chunk = getOrCreateChunk(location.getBlockX() >> 4, location.getBlockZ() >> 4); - Map map = new HashMap<>(entity.getNbtData().getValue()); //do not modify original entity data + Map> map = new HashMap<>(entity.getNbtData().getValue()); //do not modify original entity data map.put("Id", new StringTag(entity.getType().getName())); //Set pos diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/BrushCache.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/BrushCache.java index afab331a7..762929400 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/BrushCache.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/BrushCache.java @@ -82,7 +82,7 @@ public final class BrushCache { } CompoundTag nbt = item.getNbtData(); - Map map; + Map> map; if (nbt == null) { if (tool == null) { item.setNbtData(null); @@ -92,9 +92,10 @@ public final class BrushCache { } else { map = nbt.getValue(); } + item.setNbtData(nbt); brushCache.remove(getKey(item)); CompoundTag display = (CompoundTag) map.get("display"); - Map displayMap; + Map> displayMap; return tool; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java index 7d7d5d642..6b693162e 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java @@ -427,7 +427,7 @@ public class MainUtil { */ @Nonnull public static CompoundTag setPosition(@Nonnull CompoundTag tag, int x, int y, int z) { - Map value = new HashMap<>(tag.getValue()); + Map> value = new HashMap<>(tag.getValue()); value.put("x", new IntTag(x)); value.put("y", new IntTag(y)); value.put("z", new IntTag(z)); @@ -443,7 +443,7 @@ public class MainUtil { */ @Nonnull public static CompoundTag setEntityInfo(@Nonnull CompoundTag tag, @Nonnull Entity entity) { - Map map = new HashMap<>(tag.getValue()); + Map> map = new HashMap<>(tag.getValue()); map.put("Id", new StringTag(entity.getState().getType().id())); ListTag pos = (ListTag) map.get("Pos"); if (pos != null) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/NbtUtils.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/NbtUtils.java index 7abb51284..07157e820 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/NbtUtils.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/NbtUtils.java @@ -1,13 +1,12 @@ package com.fastasyncworldedit.core.util; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.BinaryTagType; -import com.sk89q.worldedit.util.nbt.BinaryTagTypes; -import com.sk89q.worldedit.util.nbt.ByteBinaryTag; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.IntBinaryTag; -import com.sk89q.worldedit.util.nbt.ShortBinaryTag; import com.sk89q.worldedit.world.storage.InvalidFormatException; +import org.enginehub.linbus.tree.LinByteTag; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinShortTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; import java.util.HashMap; import java.util.Map; @@ -23,9 +22,9 @@ public class NbtUtils { * @return child tag * @throws InvalidFormatException if the format of the items is invalid */ - public static T getChildTag(CompoundBinaryTag tag, String key, BinaryTagType expected) throws + public static T getChildTag(LinCompoundTag tag, String key, LinTagType expected) throws InvalidFormatException { - BinaryTag childTag = tag.get(key); + LinTag childTag = tag.value().get(key); if (childTag == null) { throw new InvalidFormatException("Missing a \"" + key + "\" tag"); } @@ -48,35 +47,35 @@ public class NbtUtils { * @throws InvalidFormatException if the format of the items is invalid * @since 2.1.0 */ - public static int getInt(CompoundBinaryTag tag, String key) throws InvalidFormatException { - BinaryTag childTag = tag.get(key); + public static int getInt(LinCompoundTag tag, String key) throws InvalidFormatException { + LinTag childTag = tag.value().get(key); if (childTag == null) { throw new InvalidFormatException("Missing a \"" + key + "\" tag"); } - BinaryTagType type = childTag.type(); - if (type == BinaryTagTypes.INT) { - return ((IntBinaryTag) childTag).intValue(); + LinTagType type = childTag.type(); + if (type == LinTagType.intTag()) { + return ((LinIntTag) childTag).value(); } - if (type == BinaryTagTypes.BYTE) { - return ((ByteBinaryTag) childTag).intValue(); + if (type == LinTagType.byteTag()) { + return ((LinByteTag) childTag).value(); } - if (type == BinaryTagTypes.SHORT) { - return ((ShortBinaryTag) childTag).intValue(); + if (type == LinTagType.shortTag()) { + return ((LinShortTag) childTag).value(); } throw new InvalidFormatException(key + " tag is not of int, short or byte tag type."); } /** - * Get a mutable map of the values stored inside a {@link CompoundBinaryTag} + * Get a mutable map of the values stored inside a {@link LinCompoundTag} * - * @param tag {@link CompoundBinaryTag} to get values for + * @param tag {@link LinCompoundTag} to get values for * @return Mutable map of values * @since 2.1.0 */ - public static Map getCompoundBinaryTagValues(CompoundBinaryTag tag) { - Map value = new HashMap<>(); - tag.forEach((e) -> value.put(e.getKey(), e.getValue())); + public static Map> getLinCompoundTagValues(LinCompoundTag tag) { + Map> value = new HashMap<>(); + value.putAll(tag.value()); return value; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/BaseItemAdapter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/BaseItemAdapter.java index 859ed9194..9fbdd88bd 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/BaseItemAdapter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/gson/BaseItemAdapter.java @@ -10,9 +10,10 @@ import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.nbt.TagStringIO; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemTypes; +import org.enginehub.linbus.format.snbt.LinStringIO; +import org.enginehub.linbus.tree.LinCompoundTag; import java.io.IOException; import java.lang.reflect.Type; @@ -36,7 +37,10 @@ public final class BaseItemAdapter implements JsonDeserializer, JsonSe return new BaseItem(itemType); } try { - return new BaseItem(itemType, LazyReference.computed(TagStringIO.get().asCompound(nbt.getAsString()))); + return new BaseItem( + itemType, + LazyReference.computed(LinCompoundTag.readFrom(LinStringIO.readFromString(nbt.getAsString()))) + ); } catch (IOException e) { throw new JsonParseException("Could not deserialize BaseItem", e); } @@ -50,12 +54,8 @@ public final class BaseItemAdapter implements JsonDeserializer, JsonSe ) { JsonObject obj = new JsonObject(); obj.add("itemType", jsonSerializationContext.serialize(baseItem.getType())); - try { - obj.add("nbt", baseItem.getNbt() == null ? null : new JsonPrimitive(TagStringIO.get().asString(baseItem.getNbt()))); - return obj; - } catch (IOException e) { - throw new JsonParseException("Could not deserialize BaseItem", e); - } + obj.add("nbt", baseItem.getNbt() == null ? null : new JsonPrimitive(LinStringIO.writeToString(baseItem.getNbt()))); + return obj; } } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/AdventureNBTConverter.java b/worldedit-core/src/main/java/com/sk89q/jnbt/AdventureNBTConverter.java deleted file mode 100644 index 1e9d36178..000000000 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/AdventureNBTConverter.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.jnbt; - -import com.google.common.collect.BiMap; -import com.google.common.collect.ImmutableBiMap; -import com.google.common.collect.ImmutableMap; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.BinaryTagType; -import com.sk89q.worldedit.util.nbt.BinaryTagTypes; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.Map; -import java.util.Objects; -import java.util.function.Function; - -/** - * Converts between JNBT and Adventure-NBT classes. - * - * @deprecated JNBT is being removed in WE8. - */ -@Deprecated(forRemoval = true) -public class AdventureNBTConverter { - - private static final BiMap, BinaryTagType> TAG_TYPES = - new ImmutableBiMap.Builder, BinaryTagType>() - .put(ByteArrayTag.class, BinaryTagTypes.BYTE_ARRAY) - .put(ByteTag.class, BinaryTagTypes.BYTE) - .put(CompoundTag.class, BinaryTagTypes.COMPOUND) - .put(DoubleTag.class, BinaryTagTypes.DOUBLE) - .put(EndTag.class, BinaryTagTypes.END) - .put(FloatTag.class, BinaryTagTypes.FLOAT) - .put(IntArrayTag.class, BinaryTagTypes.INT_ARRAY) - .put(IntTag.class, BinaryTagTypes.INT) - .put(ListTag.class, BinaryTagTypes.LIST) - .put(LongArrayTag.class, BinaryTagTypes.LONG_ARRAY) - .put(LongTag.class, BinaryTagTypes.LONG) - .put(ShortTag.class, BinaryTagTypes.SHORT) - .put(StringTag.class, BinaryTagTypes.STRING) - .build(); - - private static final Map, Function> CONVERSION; - - static { - ImmutableMap.Builder, Function> conversion = - ImmutableMap.builder(); - - for (Map.Entry, BinaryTagType> tag : TAG_TYPES.entrySet()) { - Constructor[] constructors = tag.getKey().getConstructors(); - for (Constructor c : constructors) { - if (c.getParameterCount() == 1 && BinaryTag.class.isAssignableFrom(c.getParameterTypes()[0])) { - conversion.put(tag.getValue(), binaryTag -> { - try { - return (Tag) c.newInstance(binaryTag); - } catch (InstantiationException | IllegalAccessException e) { - throw new IllegalStateException(e); - } catch (InvocationTargetException e) { - // I assume this is always a RuntimeException since we control the ctor - throw (RuntimeException) e.getCause(); - } - }); - break; - } - } - } - - CONVERSION = conversion.build(); - } - - public static BinaryTagType getAdventureType(Class type) { - return Objects.requireNonNull(TAG_TYPES.get(type), () -> "Missing entry for " + type); - } - - public static Class getJNBTType(BinaryTagType type) { - return Objects.requireNonNull(TAG_TYPES.inverse().get(type), () -> "Missing entry for " + type); - } - - private AdventureNBTConverter() { - } - - public static Tag fromAdventure(BinaryTag other) { - if (other == null) { - return null; - } - Function conversion = CONVERSION.get(other.type()); - if (conversion == null) { - throw new IllegalArgumentException("Can't convert other of type " + other.getClass().getCanonicalName()); - } - return conversion.apply(other); - } - -} diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/ByteArrayTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/ByteArrayTag.java index 094a7c9bb..4889235eb 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/ByteArrayTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/ByteArrayTag.java @@ -19,41 +19,26 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.ByteArrayBinaryTag; +import org.enginehub.linbus.tree.LinByteArrayTag; /** * The {@code TAG_Byte_Array} tag. * - * @deprecated Use {@link ByteArrayBinaryTag}. + * @deprecated Use {@link LinByteArrayTag}. */ @Deprecated -public final class ByteArrayTag extends Tag { - - private final ByteArrayBinaryTag innerTag; - +public final class ByteArrayTag extends Tag { /** * Creates the tag with an empty name. * * @param value the value of the tag */ public ByteArrayTag(byte[] value) { - super(); - this.innerTag = ByteArrayBinaryTag.of(value); + this(LinByteArrayTag.of(value)); } - public ByteArrayTag(ByteArrayBinaryTag adventureTag) { - super(); - this.innerTag = adventureTag; - } - - @Override - public byte[] getValue() { - return innerTag.value(); - } - - @Override - public ByteArrayBinaryTag asBinaryTag() { - return innerTag; + public ByteArrayTag(LinByteArrayTag tag) { + super(tag); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/ByteTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/ByteTag.java index 6068b2af0..6b3d3d153 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/ByteTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/ByteTag.java @@ -19,41 +19,32 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.ByteBinaryTag; +import com.fastasyncworldedit.core.jnbt.NumberTag; +import org.enginehub.linbus.tree.LinByteTag; /** * The {@code TAG_Byte} tag. * - * @deprecated Use {@link ByteBinaryTag}. + * @deprecated Use {@link LinByteTag}. */ @Deprecated -public final class ByteTag extends Tag { - - private final ByteBinaryTag innerTag; - +public final class ByteTag extends NumberTag { /** * Creates the tag with an empty name. * * @param value the value of the tag */ public ByteTag(byte value) { - super(); - this.innerTag = ByteBinaryTag.of(value); + this(LinByteTag.of(value)); } - public ByteTag(ByteBinaryTag adventureTag) { - super(); - this.innerTag = adventureTag; + public ByteTag(LinByteTag tag) { + super(tag); } @Override public Byte getValue() { - return innerTag.value(); - } - - @Override - public ByteBinaryTag asBinaryTag() { - return innerTag; + return linTag.value(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java index d91aea8fe..10e9adf08 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTag.java @@ -25,10 +25,11 @@ import com.google.common.collect.Maps; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.BinaryTagLike; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.NumberBinaryTag; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinNumberTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; import java.util.Collections; import java.util.HashMap; @@ -39,26 +40,24 @@ import java.util.UUID; /** * The {@code TAG_Compound} tag. * - * @deprecated Use {@link com.sk89q.worldedit.util.nbt.CompoundBinaryTag}. + * @deprecated Use {@link LinCompoundTag}. */ @Deprecated -public class CompoundTag extends Tag { - - private final CompoundBinaryTag innerTag; +//FAWE start - nonfinal +public class CompoundTag extends Tag { + //FAWE end /** * Creates the tag with an empty name. * * @param value the value of the tag */ - public CompoundTag(Map value) { - this(CompoundBinaryTag.builder() - .put(Maps.transformValues(value, BinaryTagLike::asBinaryTag)) - .build()); + public CompoundTag(Map> value) { + this(LinCompoundTag.of(Maps.transformValues(value, Tag::toLinTag))); } - public CompoundTag(CompoundBinaryTag adventureTag) { - this.innerTag = adventureTag; + public CompoundTag(LinCompoundTag tag) { + super(tag); } /** @@ -68,16 +67,16 @@ public class CompoundTag extends Tag { * @return true if the tag contains the given key */ public boolean containsKey(String key) { - return innerTag.keySet().contains(key); + return linTag.value().containsKey(key); } + @SuppressWarnings({ "unchecked", "rawtypes" }) @Override - public Map getValue() { - ImmutableMap.Builder map = ImmutableMap.builder(); - for (String key : innerTag.keySet()) { - map.put(key, AdventureNBTConverter.fromAdventure(innerTag.get(key))); - } - return map.build(); + public Map> getValue() { + return ImmutableMap.copyOf(Maps.transformValues( + linTag.value(), + tag -> (Tag) LinBusConverter.toJnbtTag((LinTag) tag) + )); } /** @@ -86,7 +85,7 @@ public class CompoundTag extends Tag { * @param value the value * @return the new compound tag */ - public CompoundTag setValue(Map value) { + public CompoundTag setValue(Map> value) { return new CompoundTag(value); } @@ -96,7 +95,7 @@ public class CompoundTag extends Tag { * @return the builder */ public CompoundTagBuilder createBuilder() { - return new CompoundTagBuilder(innerTag); + return new CompoundTagBuilder(linTag); } /** @@ -109,7 +108,8 @@ public class CompoundTag extends Tag { * @return a byte array */ public byte[] getByteArray(String key) { - return this.innerTag.getByteArray(key); + var tag = linTag.findTag(key, LinTagType.byteArrayTag()); + return tag == null ? new byte[0] : tag.value(); } /** @@ -122,7 +122,8 @@ public class CompoundTag extends Tag { * @return a byte */ public byte getByte(String key) { - return this.innerTag.getByte(key); + var tag = linTag.findTag(key, LinTagType.byteTag()); + return tag == null ? 0 : tag.value(); } /** @@ -135,7 +136,8 @@ public class CompoundTag extends Tag { * @return a double */ public double getDouble(String key) { - return this.innerTag.getDouble(key); + var tag = linTag.findTag(key, LinTagType.doubleTag()); + return tag == null ? 0 : tag.value(); } /** @@ -149,9 +151,10 @@ public class CompoundTag extends Tag { * @return a double */ public double asDouble(String key) { - BinaryTag tag = this.innerTag.get(key); - if (tag instanceof NumberBinaryTag) { - return ((NumberBinaryTag) tag).doubleValue(); + var tag = linTag.value().get(key); + if (tag instanceof LinNumberTag numberTag) { + Number value = numberTag.value(); + return value.doubleValue(); } return 0; } @@ -166,7 +169,8 @@ public class CompoundTag extends Tag { * @return a float */ public float getFloat(String key) { - return this.innerTag.getFloat(key); + var tag = linTag.findTag(key, LinTagType.floatTag()); + return tag == null ? 0 : tag.value(); } /** @@ -179,7 +183,8 @@ public class CompoundTag extends Tag { * @return an int array */ public int[] getIntArray(String key) { - return this.innerTag.getIntArray(key); + var tag = linTag.findTag(key, LinTagType.intArrayTag()); + return tag == null ? new int[0] : tag.value(); } /** @@ -192,7 +197,8 @@ public class CompoundTag extends Tag { * @return an int */ public int getInt(String key) { - return this.innerTag.getInt(key); + var tag = linTag.findTag(key, LinTagType.intTag()); + return tag == null ? 0 : tag.value(); } /** @@ -206,9 +212,10 @@ public class CompoundTag extends Tag { * @return an int */ public int asInt(String key) { - BinaryTag tag = this.innerTag.get(key); - if (tag instanceof NumberBinaryTag) { - return ((NumberBinaryTag) tag).intValue(); + var tag = linTag.value().get(key); + if (tag instanceof LinNumberTag numberTag) { + Number value = numberTag.value(); + return value.intValue(); } return 0; } @@ -222,7 +229,7 @@ public class CompoundTag extends Tag { * @param key the key * @return a list of tags */ - public List getList(String key) { + public List> getList(String key) { return getListTag(key).getValue(); } @@ -235,8 +242,15 @@ public class CompoundTag extends Tag { * @param key the key * @return a tag list instance */ - public ListTag getListTag(String key) { - return new ListTag(this.innerTag.getList(key)); + public > ListTag getListTag(String key) { + LinListTag tag = linTag.findTag(key, LinTagType.listTag()); + if (tag == null) { + // This is actually hella unsafe. But eh. + @SuppressWarnings("unchecked") + LinTagType endGenerically = (LinTagType) LinTagType.endTag(); + return new ListTag<>(LinListTag.empty(endGenerically)); + } + return new ListTag<>(tag); } /** @@ -253,8 +267,8 @@ public class CompoundTag extends Tag { * @return a list of tags */ @SuppressWarnings("unchecked") - public List getList(String key, Class listType) { - ListTag listTag = getListTag(key); + public > List getList(String key, Class listType) { + ListTag listTag = getListTag(key); if (listTag.getType().equals(listType)) { return (List) listTag.getValue(); } else { @@ -272,7 +286,8 @@ public class CompoundTag extends Tag { * @return an int array */ public long[] getLongArray(String key) { - return this.innerTag.getLongArray(key); + var tag = linTag.findTag(key, LinTagType.longArrayTag()); + return tag == null ? new long[0] : tag.value(); } /** @@ -285,7 +300,8 @@ public class CompoundTag extends Tag { * @return a long */ public long getLong(String key) { - return this.innerTag.getLong(key); + var tag = linTag.findTag(key, LinTagType.longTag()); + return tag == null ? 0 : tag.value(); } /** @@ -299,9 +315,10 @@ public class CompoundTag extends Tag { * @return a long */ public long asLong(String key) { - BinaryTag tag = this.innerTag.get(key); - if (tag instanceof NumberBinaryTag) { - return ((NumberBinaryTag) tag).longValue(); + var tag = linTag.value().get(key); + if (tag instanceof LinNumberTag numberTag) { + Number value = numberTag.value(); + return value.longValue(); } return 0; } @@ -316,7 +333,8 @@ public class CompoundTag extends Tag { * @return a short */ public short getShort(String key) { - return this.innerTag.getShort(key); + var tag = linTag.findTag(key, LinTagType.shortTag()); + return tag == null ? 0 : tag.value(); } /** @@ -329,12 +347,8 @@ public class CompoundTag extends Tag { * @return a string */ public String getString(String key) { - return this.innerTag.getString(key); - } - - @Override - public CompoundBinaryTag asBinaryTag() { - return this.innerTag; + var tag = linTag.findTag(key, LinTagType.stringTag()); + return tag == null ? "" : tag.value(); } @@ -357,7 +371,7 @@ public class CompoundTag extends Tag { } public Vector3 getEntityPosition() { - List posTags = getList("Pos"); + List> posTags = getList("Pos"); double x = ((NumberTag) posTags.get(0)).getValue().doubleValue(); double y = ((NumberTag) posTags.get(1)).getValue().doubleValue(); double z = ((NumberTag) posTags.get(2)).getValue().doubleValue(); @@ -365,7 +379,7 @@ public class CompoundTag extends Tag { } public Location getEntityLocation(Extent extent) { - List rotTag = getList("Rotation"); + List> rotTag = getList("Rotation"); float yaw = ((NumberTag) rotTag.get(0)).getValue().floatValue(); float pitch = ((NumberTag) rotTag.get(1)).getValue().floatValue(); return new Location(extent, getEntityPosition(), yaw, pitch); @@ -382,7 +396,7 @@ public class CompoundTag extends Tag { if (this.getValue().isEmpty()) { return raw; } - for (Map.Entry entry : getValue().entrySet()) { + for (Map.Entry> entry : getValue().entrySet()) { raw.put(entry.getKey(), entry.getValue().toRaw()); } return raw; diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTagBuilder.java b/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTagBuilder.java index f21bdb8cc..535722b74 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTagBuilder.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/CompoundTagBuilder.java @@ -19,27 +19,27 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; +import org.enginehub.linbus.tree.LinCompoundTag; import java.util.Map; -import java.util.Objects; import static com.google.common.base.Preconditions.checkNotNull; /** * Helps create compound tags. * - * @deprecated Use {@link com.sk89q.worldedit.util.nbt.CompoundBinaryTag.Builder}. + * @deprecated Use {@link LinCompoundTag.Builder}. */ @Deprecated public class CompoundTagBuilder { - private final CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder(); + private final LinCompoundTag.Builder builder; /** * Create a new instance. */ CompoundTagBuilder() { + this.builder = LinCompoundTag.builder(); } /** @@ -47,11 +47,9 @@ public class CompoundTagBuilder { * * @param source the value */ - CompoundTagBuilder(CompoundBinaryTag source) { + CompoundTagBuilder(LinCompoundTag source) { checkNotNull(source); - for (String key : source.keySet()) { - this.builder.put(key, Objects.requireNonNull(source.get(key))); - } + this.builder = source.toBuilder(); } /** @@ -61,10 +59,10 @@ public class CompoundTagBuilder { * @param value the value * @return this object */ - public CompoundTagBuilder put(String key, Tag value) { + public CompoundTagBuilder put(String key, Tag value) { checkNotNull(key); checkNotNull(value); - this.builder.put(key, value.asBinaryTag()); + this.builder.put(key, value.toLinTag()); return this; } @@ -215,9 +213,9 @@ public class CompoundTagBuilder { * @param value the map of tags * @return this object */ - public CompoundTagBuilder putAll(Map value) { + public CompoundTagBuilder putAll(Map> value) { checkNotNull(value); - for (Map.Entry entry : value.entrySet()) { + for (Map.Entry> entry : value.entrySet()) { put(entry.getKey(), entry.getValue()); } return this; diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/DoubleTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/DoubleTag.java index da0890ea6..6dad5186b 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/DoubleTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/DoubleTag.java @@ -20,17 +20,15 @@ package com.sk89q.jnbt; import com.fastasyncworldedit.core.jnbt.NumberTag; -import com.sk89q.worldedit.util.nbt.DoubleBinaryTag; +import org.enginehub.linbus.tree.LinDoubleTag; /** * The {@code TAG_Double} tag. * - * @deprecated Use {@link DoubleBinaryTag}. + * @deprecated Use {@link LinDoubleTag}. */ @Deprecated -public final class DoubleTag extends NumberTag { - - private final DoubleBinaryTag innerTag; +public final class DoubleTag extends NumberTag { /** * Creates the tag with an empty name. @@ -38,23 +36,16 @@ public final class DoubleTag extends NumberTag { * @param value the value of the tag */ public DoubleTag(double value) { - super(); - this.innerTag = DoubleBinaryTag.of(value); + this(LinDoubleTag.of(value)); } - public DoubleTag(DoubleBinaryTag adventureTag) { - super(); - this.innerTag = adventureTag; - } - - @Override - public DoubleBinaryTag asBinaryTag() { - return this.innerTag; + public DoubleTag(LinDoubleTag tag) { + super(tag); } @Override public Double getValue() { - return innerTag.value(); + return linTag.value(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/EndTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/EndTag.java index 18347d928..523fcf79e 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/EndTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/EndTag.java @@ -19,24 +19,17 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.EndBinaryTag; +import org.enginehub.linbus.tree.LinEndTag; /** * The {@code TAG_End} tag. * - * @deprecated Use {@link com.sk89q.worldedit.util.nbt.EndBinaryTag}. + * @deprecated Use {@link LinEndTag}. */ @Deprecated -public final class EndTag extends Tag { - - @Override - public Object getValue() { - return null; - } - - @Override - public EndBinaryTag asBinaryTag() { - return EndBinaryTag.get(); +public final class EndTag extends Tag { + public EndTag() { + super(LinEndTag.instance()); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/FloatTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/FloatTag.java index 2e1533827..128e36014 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/FloatTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/FloatTag.java @@ -20,17 +20,14 @@ package com.sk89q.jnbt; import com.fastasyncworldedit.core.jnbt.NumberTag; -import com.sk89q.worldedit.util.nbt.FloatBinaryTag; +import org.enginehub.linbus.tree.LinFloatTag; /** * The {@code TAG_Float} tag. * - * @deprecated Use {@link FloatBinaryTag}. + * @deprecated Use {@link LinFloatTag}. */ -@Deprecated -public final class FloatTag extends NumberTag { - - private final FloatBinaryTag innerTag; +public final class FloatTag extends NumberTag { /** * Creates the tag with an empty name. @@ -38,23 +35,16 @@ public final class FloatTag extends NumberTag { * @param value the value of the tag */ public FloatTag(float value) { - super(); - this.innerTag = FloatBinaryTag.of(value); + this(LinFloatTag.of(value)); } - public FloatTag(FloatBinaryTag adventureTag) { - super(); - this.innerTag = adventureTag; - } - - @Override - public FloatBinaryTag asBinaryTag() { - return this.innerTag; + public FloatTag(LinFloatTag tag) { + super(tag); } @Override public Float getValue() { - return innerTag.value(); + return linTag.value(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/IntArrayTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/IntArrayTag.java index 76d8fac74..0e3536eed 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/IntArrayTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/IntArrayTag.java @@ -19,44 +19,33 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.IntArrayBinaryTag; +import org.enginehub.linbus.tree.LinIntArrayTag; import static com.google.common.base.Preconditions.checkNotNull; /** * The {@code TAG_Int_Array} tag. * - * @deprecated Use {@link IntArrayBinaryTag}. + * @deprecated Use {@link LinIntArrayTag}. */ @Deprecated -public final class IntArrayTag extends Tag { - - private final IntArrayBinaryTag innerTag; - +public final class IntArrayTag extends Tag { /** * Creates the tag with an empty name. * * @param value the value of the tag */ public IntArrayTag(int[] value) { - super(); - checkNotNull(value); - this.innerTag = IntArrayBinaryTag.of(value); + this(LinIntArrayTag.of(checkNotNull(value))); } - public IntArrayTag(IntArrayBinaryTag adventureTag) { - super(); - this.innerTag = adventureTag; - } - - @Override - public IntArrayBinaryTag asBinaryTag() { - return this.innerTag; + public IntArrayTag(LinIntArrayTag tag) { + super(tag); } @Override public int[] getValue() { - return innerTag.value(); + return linTag.value(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/IntTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/IntTag.java index c6ff80252..c4c90889b 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/IntTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/IntTag.java @@ -19,17 +19,16 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.IntBinaryTag; +import com.fastasyncworldedit.core.jnbt.NumberTag; +import org.enginehub.linbus.tree.LinIntTag; /** * The {@code TAG_Int} tag. * - * @deprecated Use {@link IntBinaryTag}. + * @deprecated Use {@link LinIntTag}. */ @Deprecated -public final class IntTag extends Tag { - - private final IntBinaryTag innerTag; +public final class IntTag extends NumberTag { /** * Creates the tag with an empty name. @@ -37,23 +36,16 @@ public final class IntTag extends Tag { * @param value the value of the tag */ public IntTag(int value) { - super(); - this.innerTag = IntBinaryTag.of(value); + this(LinIntTag.of(value)); } - public IntTag(IntBinaryTag adventureTag) { - super(); - this.innerTag = adventureTag; - } - - @Override - public IntBinaryTag asBinaryTag() { - return this.innerTag; + public IntTag(LinIntTag tag) { + super(tag); } @Override public Integer getValue() { - return innerTag.value(); + return linTag.value(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/LazyCompoundTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/LazyCompoundTag.java index 00b5aeb9a..4ce6febd6 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/LazyCompoundTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/LazyCompoundTag.java @@ -20,27 +20,27 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; +import org.enginehub.linbus.tree.LinCompoundTag; import java.util.Map; /** * Allows detection of the version-specific LazyCompoundTag classes. * - * @deprecated Use {@link CompoundBinaryTag}. + * @deprecated Use {@link LinCompoundTag}. */ @Deprecated public abstract class LazyCompoundTag extends CompoundTag { - public LazyCompoundTag(Map value) { + public LazyCompoundTag(Map> value) { super(value); } - public LazyCompoundTag(CompoundBinaryTag adventureTag) { + public LazyCompoundTag(LinCompoundTag adventureTag) { super(adventureTag); } @Override - public abstract CompoundBinaryTag asBinaryTag(); + public abstract LinCompoundTag toLinTag(); } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/LinBusConverter.java b/worldedit-core/src/main/java/com/sk89q/jnbt/LinBusConverter.java new file mode 100644 index 000000000..52b30f599 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/LinBusConverter.java @@ -0,0 +1,140 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.jnbt; + +import com.google.common.collect.BiMap; +import com.google.common.collect.ImmutableBiMap; +import com.google.common.collect.ImmutableMap; +import org.enginehub.linbus.tree.LinByteArrayTag; +import org.enginehub.linbus.tree.LinByteTag; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinDoubleTag; +import org.enginehub.linbus.tree.LinFloatTag; +import org.enginehub.linbus.tree.LinIntArrayTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinLongArrayTag; +import org.enginehub.linbus.tree.LinLongTag; +import org.enginehub.linbus.tree.LinShortTag; +import org.enginehub.linbus.tree.LinStringTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; + +/** + * Converts between JNBT and Adventure-NBT classes. + * + * @deprecated JNBT is being removed in WE8. + */ +@Deprecated(forRemoval = true) +public class LinBusConverter { + + private static final BiMap, LinTagType> TAG_TYPES = + new ImmutableBiMap.Builder, LinTagType>() + .put(ByteArrayTag.class, LinTagType.byteArrayTag()) + .put(ByteTag.class, LinTagType.byteTag()) + .put(CompoundTag.class, LinTagType.compoundTag()) + .put(DoubleTag.class, LinTagType.doubleTag()) + .put(EndTag.class, LinTagType.endTag()) + .put(FloatTag.class, LinTagType.floatTag()) + .put(IntArrayTag.class, LinTagType.intArrayTag()) + .put(IntTag.class, LinTagType.intTag()) + .put(ListTag.class, LinTagType.listTag()) + .put(LongArrayTag.class, LinTagType.longArrayTag()) + .put(LongTag.class, LinTagType.longTag()) + .put(ShortTag.class, LinTagType.shortTag()) + .put(StringTag.class, LinTagType.stringTag()) + .build(); + + private static final Map, Function> CONVERSION; + + static { + ImmutableMap.Builder, Function> conversion = + ImmutableMap.builder(); + + for (Map.Entry, LinTagType> tag : TAG_TYPES.entrySet()) { + Constructor[] constructors = tag.getKey().getConstructors(); + for (Constructor c : constructors) { + if (c.getParameterCount() == 1 && LinTag.class.isAssignableFrom(c.getParameterTypes()[0])) { + conversion.put(tag.getValue(), linTag -> { + try { + return (Tag) c.newInstance(linTag); + } catch (InstantiationException | IllegalAccessException e) { + throw new IllegalStateException(e); + } catch (InvocationTargetException e) { + // I assume this is always a RuntimeException since we control the ctor + throw (RuntimeException) e.getCause(); + } + }); + break; + } + } + } + + CONVERSION = conversion.build(); + } + + public static LinTagType getAdventureType(Class type) { + return Objects.requireNonNull(TAG_TYPES.get(type), () -> "Missing entry for " + type); + } + + public static Class getJNBTType(LinTagType type) { + return Objects.requireNonNull(TAG_TYPES.inverse().get(type), () -> "Missing entry for " + type); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static > Tag toJnbtTag(LT tag) { + return (Tag) switch (tag.type().id()) { + case BYTE_ARRAY -> new ByteArrayTag((LinByteArrayTag) tag); + case BYTE -> new ByteTag((LinByteTag) tag); + case COMPOUND -> new CompoundTag((LinCompoundTag) tag); + case DOUBLE -> new DoubleTag((LinDoubleTag) tag); + case END -> new EndTag(); + case FLOAT -> new FloatTag((LinFloatTag) tag); + case INT_ARRAY -> new IntArrayTag((LinIntArrayTag) tag); + case INT -> new IntTag((LinIntTag) tag); + case LIST -> new ListTag((LinListTag) tag); + case LONG_ARRAY -> new LongArrayTag((LinLongArrayTag) tag); + case LONG -> new LongTag((LinLongTag) tag); + case SHORT -> new ShortTag((LinShortTag) tag); + case STRING -> new StringTag((LinStringTag) tag); + }; + } + + private LinBusConverter() { + } + + public static Tag fromLinBus(LinTag other) { + if (other == null) { + return null; + } + Function conversion = CONVERSION.get(other.type()); + if (conversion == null) { + throw new IllegalArgumentException("Can't convert other of type " + other.getClass().getCanonicalName()); + } + return conversion.apply(other); + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/ListTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/ListTag.java index 879a0d4a3..d3c330d4d 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/ListTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/ListTag.java @@ -19,10 +19,20 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.BinaryTagLike; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; -import com.sk89q.worldedit.util.nbt.NumberBinaryTag; +import org.enginehub.linbus.common.LinTagId; +import org.enginehub.linbus.tree.LinByteArrayTag; +import org.enginehub.linbus.tree.LinByteTag; +import org.enginehub.linbus.tree.LinDoubleTag; +import org.enginehub.linbus.tree.LinFloatTag; +import org.enginehub.linbus.tree.LinIntArrayTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinLongTag; +import org.enginehub.linbus.tree.LinNumberTag; +import org.enginehub.linbus.tree.LinShortTag; +import org.enginehub.linbus.tree.LinStringTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; import javax.annotation.Nullable; import java.util.Collections; @@ -34,12 +44,10 @@ import java.util.stream.Collectors; /** * The {@code TAG_List} tag. * - * @deprecated Use {@link com.sk89q.worldedit.util.nbt.ListBinaryTag}. + * @deprecated Use {@link LinListTag}. */ @Deprecated -public final class ListTag extends Tag { - - private final ListBinaryTag innerTag; +public final class ListTag> extends Tag> { /** * Creates the tag with an empty name. @@ -47,20 +55,15 @@ public final class ListTag extends Tag { * @param type the type of tag * @param value the value of the tag */ - public ListTag(Class type, List value) { - this(ListBinaryTag.of( - AdventureNBTConverter.getAdventureType(type), - value.stream().map(BinaryTagLike::asBinaryTag).collect(Collectors.toList()) + public ListTag(Class> type, List> value) { + this(LinListTag.of( + LinTagType.fromId(LinTagId.fromId(NBTUtils.getTypeCode(type))), + value.stream().map(Tag::toLinTag).collect(Collectors.toList()) )); } - public ListTag(ListBinaryTag adventureTag) { - this.innerTag = adventureTag; - } - - @Override - public ListBinaryTag asBinaryTag() { - return this.innerTag; + public ListTag(LinListTag tag) { + super(tag); } /** @@ -68,15 +71,14 @@ public final class ListTag extends Tag { * * @return The type of item in this list. */ - public Class getType() { - return AdventureNBTConverter.getJNBTType(this.innerTag.elementType()); + @SuppressWarnings("unchecked") + public Class> getType() { + return (Class>) NBTUtils.getTypeClass(linTag.elementType().id().id()); } @Override - public List getValue() { - return this.innerTag.stream() - .map(AdventureNBTConverter::fromAdventure) - .collect(Collectors.toList()); + public List> getValue() { + return linTag.value().stream().map(LinBusConverter::toJnbtTag).toList(); } /** @@ -85,17 +87,31 @@ public final class ListTag extends Tag { * @param list the new list * @return a new list tag */ - public ListTag setValue(List list) { - return new ListTag(getType(), list); + public ListTag setValue(List> list) { + return new ListTag<>(getType(), list); } private T accessIfExists(int index, Supplier defaultValue, IntFunction accessor) { - if (index >= this.innerTag.size()) { + if (index >= this.linTag.value().size()) { return defaultValue.get(); } return accessor.apply(index); } + @SuppressWarnings("unchecked") + private > T extractViaValue( + int index, Class requiredType, Supplier defaultValue + ) { + if (index >= this.linTag.value().size()) { + return defaultValue.get(); + } + E value = this.linTag.get(index); + if (!requiredType.isInstance(value)) { + return defaultValue.get(); + } + return (T) value.value(); + } + /** * Get the tag if it exists at the given index. * @@ -103,11 +119,11 @@ public final class ListTag extends Tag { * @return the tag or null */ @Nullable - public Tag getIfExists(int index) { + public Tag getIfExists(int index) { return accessIfExists( - index, - () -> null, - i -> AdventureNBTConverter.fromAdventure(this.innerTag.get(i)) + index, + () -> null, + i -> LinBusConverter.toJnbtTag(this.linTag.get(i)) ); } @@ -121,11 +137,7 @@ public final class ListTag extends Tag { * @return a byte array */ public byte[] getByteArray(int index) { - return accessIfExists( - index, - () -> new byte[0], - this.innerTag::getByteArray - ); + return extractViaValue(index, LinByteArrayTag.class, () -> new byte[0]); } /** @@ -138,11 +150,7 @@ public final class ListTag extends Tag { * @return a byte */ public byte getByte(int index) { - return accessIfExists( - index, - () -> (byte) 0, - this.innerTag::getByte - ); + return extractViaValue(index, LinByteTag.class, () -> (byte) 0); } /** @@ -155,11 +163,7 @@ public final class ListTag extends Tag { * @return a double */ public double getDouble(int index) { - return accessIfExists( - index, - () -> 0.0, - this.innerTag::getDouble - ); + return extractViaValue(index, LinDoubleTag.class, () -> 0.0); } /** @@ -174,15 +178,11 @@ public final class ListTag extends Tag { */ public double asDouble(int index) { return accessIfExists( - index, - () -> 0.0, - i -> { - BinaryTag tag = this.innerTag.get(i); - if (tag instanceof NumberBinaryTag) { - return ((NumberBinaryTag) tag).doubleValue(); - } - return 0.0; - } + index, + () -> 0.0, + i -> this.linTag.get(i) instanceof LinNumberTag tag + ? tag.value().doubleValue() + : 0.0 ); } @@ -196,11 +196,7 @@ public final class ListTag extends Tag { * @return a float */ public float getFloat(int index) { - return accessIfExists( - index, - () -> 0.0f, - this.innerTag::getFloat - ); + return extractViaValue(index, LinFloatTag.class, () -> 0f); } /** @@ -213,11 +209,7 @@ public final class ListTag extends Tag { * @return an int array */ public int[] getIntArray(int index) { - return accessIfExists( - index, - () -> new int[0], - this.innerTag::getIntArray - ); + return extractViaValue(index, LinIntArrayTag.class, () -> new int[0]); } /** @@ -230,11 +222,7 @@ public final class ListTag extends Tag { * @return an int */ public int getInt(int index) { - return accessIfExists( - index, - () -> 0, - this.innerTag::getInt - ); + return extractViaValue(index, LinIntTag.class, () -> 0); } /** @@ -249,15 +237,11 @@ public final class ListTag extends Tag { */ public int asInt(int index) { return accessIfExists( - index, - () -> 0, - i -> { - BinaryTag tag = this.innerTag.get(i); - if (tag instanceof NumberBinaryTag) { - return ((NumberBinaryTag) tag).intValue(); - } - return 0; - } + index, + () -> 0, + i -> this.linTag.get(i) instanceof LinNumberTag tag + ? tag.value().intValue() + : 0 ); } @@ -270,7 +254,7 @@ public final class ListTag extends Tag { * @param index the index * @return a list of tags */ - public List getList(int index) { + public List> getList(int index) { return getListTag(index).getValue(); } @@ -283,11 +267,12 @@ public final class ListTag extends Tag { * @param index the index * @return a tag list instance */ - public ListTag getListTag(int index) { - return new ListTag(accessIfExists( - index, - ListBinaryTag::empty, - this.innerTag::getList + @SuppressWarnings("unchecked") + public ListTag getListTag(int index) { + return new ListTag<>(extractViaValue( + index, + LinListTag.class, + () -> LinListTag.empty(LinTagType.endTag()) )); } @@ -305,8 +290,8 @@ public final class ListTag extends Tag { * @return a list of tags */ @SuppressWarnings("unchecked") - public List getList(int index, Class listType) { - ListTag listTag = getListTag(index); + public > List getList(int index, Class listType) { + ListTag listTag = getListTag(index); if (listTag.getType().equals(listType)) { return (List) listTag.getValue(); } else { @@ -324,11 +309,7 @@ public final class ListTag extends Tag { * @return a long */ public long getLong(int index) { - return accessIfExists( - index, - () -> 0L, - this.innerTag::getLong - ); + return extractViaValue(index, LinLongTag.class, () -> 0L); } /** @@ -343,15 +324,11 @@ public final class ListTag extends Tag { */ public long asLong(int index) { return accessIfExists( - index, - () -> 0L, - i -> { - BinaryTag tag = this.innerTag.get(i); - if (tag instanceof NumberBinaryTag) { - return ((NumberBinaryTag) tag).longValue(); - } - return 0L; - } + index, + () -> 0L, + i -> this.linTag.get(i) instanceof LinNumberTag tag + ? tag.value().longValue() + : 0L ); } @@ -365,11 +342,7 @@ public final class ListTag extends Tag { * @return a short */ public short getShort(int index) { - return accessIfExists( - index, - () -> (short) 0, - this.innerTag::getShort - ); + return extractViaValue(index, LinShortTag.class, () -> (short) 0); } /** @@ -382,11 +355,7 @@ public final class ListTag extends Tag { * @return a string */ public String getString(int index) { - return accessIfExists( - index, - () -> "", - this.innerTag::getString - ); + return extractViaValue(index, LinStringTag.class, () -> ""); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/ListTagBuilder.java b/worldedit-core/src/main/java/com/sk89q/jnbt/ListTagBuilder.java index 78a8b6401..18aab079c 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/ListTagBuilder.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/ListTagBuilder.java @@ -19,11 +19,11 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.BinaryTagType; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; +import org.enginehub.linbus.common.LinTagId; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; -import java.util.Arrays; import java.util.Collection; import static com.google.common.base.Preconditions.checkNotNull; @@ -31,12 +31,12 @@ import static com.google.common.base.Preconditions.checkNotNull; /** * Helps create list tags. * - * @deprecated Use {@link com.sk89q.worldedit.util.nbt.ListBinaryTag.Builder}. + * @deprecated Use {@link LinListTag.Builder}. */ @Deprecated -public class ListTagBuilder { +public class ListTagBuilder> { - private final ListBinaryTag.Builder builder; + private final LinListTag.Builder builder; /** * Create a new instance. @@ -44,11 +44,11 @@ public class ListTagBuilder { * @param type of tag contained in this list */ @SuppressWarnings("unchecked") - ListTagBuilder(Class type) { + ListTagBuilder(Class> type) { checkNotNull(type); - this.builder = type != EndTag.class - ? ListBinaryTag.builder((BinaryTagType) AdventureNBTConverter.getAdventureType(type)) - : ListBinaryTag.builder(); + this.builder = (LinListTag.Builder) LinListTag.builder(LinTagType.fromId(LinTagId.fromId( + NBTUtils.getTypeCode(type) + ))); } /** @@ -57,9 +57,9 @@ public class ListTagBuilder { * @param value the tag * @return this object */ - public ListTagBuilder add(Tag value) { + public ListTagBuilder add(Tag value) { checkNotNull(value); - builder.add(value.asBinaryTag()); + builder.add(value.toLinTag()); return this; } @@ -69,9 +69,9 @@ public class ListTagBuilder { * @param value a list of tags * @return this object */ - public ListTagBuilder addAll(Collection value) { + public ListTagBuilder addAll(Collection> value) { checkNotNull(value); - for (Tag v : value) { + for (Tag v : value) { add(v); } return this; @@ -82,8 +82,8 @@ public class ListTagBuilder { * * @return the new list tag */ - public ListTag build() { - return new ListTag(this.builder.build()); + public ListTag build() { + return new ListTag<>(this.builder.build()); } /** @@ -91,8 +91,8 @@ public class ListTagBuilder { * * @return a new builder */ - public static ListTagBuilder create(Class type) { - return new ListTagBuilder(type); + public static > ListTagBuilder create(Class> type) { + return new ListTagBuilder<>(type); } /** @@ -100,22 +100,24 @@ public class ListTagBuilder { * * @return a new builder */ - public static ListTagBuilder createWith(Tag... entries) { + @SafeVarargs + public static > ListTagBuilder createWith(Tag... entries) { checkNotNull(entries); if (entries.length == 0) { throw new IllegalArgumentException("This method needs an array of at least one entry"); } - Class type = entries[0].getClass(); - for (int i = 1; i < entries.length; i++) { - if (!type.isInstance(entries[i])) { + @SuppressWarnings("unchecked") + Class> type = (Class>) entries[0].getClass(); + ListTagBuilder builder = new ListTagBuilder<>(type); + for (Tag entry : entries) { + if (!type.isInstance(entry)) { throw new IllegalArgumentException("An array of different tag types was provided"); } + builder.add(entry); } - ListTagBuilder builder = new ListTagBuilder(type); - builder.addAll(Arrays.asList(entries)); return builder; } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/LongArrayTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/LongArrayTag.java index 81c6e3376..968019b7e 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/LongArrayTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/LongArrayTag.java @@ -19,44 +19,33 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.LongArrayBinaryTag; +import org.enginehub.linbus.tree.LinLongArrayTag; import static com.google.common.base.Preconditions.checkNotNull; /** * The {@code TAG_Long_Array} tag. * - * @deprecated Use {@link LongArrayBinaryTag}. + * @deprecated Use {@link LinLongArrayTag}. */ @Deprecated -public class LongArrayTag extends Tag { - - private final LongArrayBinaryTag innerTag; - +public class LongArrayTag extends Tag { /** * Creates the tag with an empty name. * * @param value the value of the tag */ public LongArrayTag(long[] value) { - super(); - checkNotNull(value); - this.innerTag = LongArrayBinaryTag.of(value); + this(LinLongArrayTag.of(checkNotNull(value))); } - public LongArrayTag(LongArrayBinaryTag adventureTag) { - super(); - this.innerTag = adventureTag; - } - - @Override - public LongArrayBinaryTag asBinaryTag() { - return this.innerTag; + public LongArrayTag(LinLongArrayTag tag) { + super(tag); } @Override public long[] getValue() { - return innerTag.value(); + return linTag.value(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/LongTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/LongTag.java index 84a443746..b8632b752 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/LongTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/LongTag.java @@ -19,41 +19,32 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.LongBinaryTag; +import com.fastasyncworldedit.core.jnbt.NumberTag; +import org.enginehub.linbus.tree.LinLongTag; /** * The {@code TAG_Long} tag. * - * @deprecated Use {@link LongBinaryTag}. + * @deprecated Use {@link LinLongTag}. */ @Deprecated -public final class LongTag extends Tag { - - private final LongBinaryTag innerTag; - +public final class LongTag extends NumberTag { /** * Creates the tag with an empty name. * * @param value the value of the tag */ public LongTag(long value) { - super(); - this.innerTag = LongBinaryTag.of(value); + this(LinLongTag.of(value)); } - public LongTag(LongBinaryTag adventureTag) { - super(); - this.innerTag = adventureTag; - } - - @Override - public LongBinaryTag asBinaryTag() { - return this.innerTag; + public LongTag(LinLongTag tag) { + super(tag); } @Override public Long getValue() { - return innerTag.value(); + return linTag.value(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTConstants.java b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTConstants.java index 54746fc49..3ab1923c1 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTConstants.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTConstants.java @@ -50,7 +50,6 @@ public final class NBTConstants { * Default private constructor. */ private NBTConstants() { - } /** @@ -60,37 +59,27 @@ public final class NBTConstants { * @return tag class * @throws IllegalArgumentException thrown if the tag ID is not valid */ - public static Class getClassFromType(int id) { - switch (id) { - case TYPE_END: - return EndTag.class; - case TYPE_BYTE: - return ByteTag.class; - case TYPE_SHORT: - return ShortTag.class; - case TYPE_INT: - return IntTag.class; - case TYPE_LONG: - return LongTag.class; - case TYPE_FLOAT: - return FloatTag.class; - case TYPE_DOUBLE: - return DoubleTag.class; - case TYPE_BYTE_ARRAY: - return ByteArrayTag.class; - case TYPE_STRING: - return StringTag.class; - case TYPE_LIST: - return ListTag.class; - case TYPE_COMPOUND: - return CompoundTag.class; - case TYPE_INT_ARRAY: - return IntArrayTag.class; - case TYPE_LONG_ARRAY: - return LongArrayTag.class; - default: - throw new IllegalArgumentException("Unknown tag type ID of " + id); - } + public static Class> getClassFromType(int id) { + return switch (id) { + case TYPE_END -> EndTag.class; + case TYPE_BYTE -> ByteTag.class; + case TYPE_SHORT -> ShortTag.class; + case TYPE_INT -> IntTag.class; + case TYPE_LONG -> LongTag.class; + case TYPE_FLOAT -> FloatTag.class; + case TYPE_DOUBLE -> DoubleTag.class; + case TYPE_BYTE_ARRAY -> ByteArrayTag.class; + case TYPE_STRING -> StringTag.class; + case TYPE_LIST -> { + @SuppressWarnings("unchecked") + var aClass = (Class>) (Class) ListTag.class; + yield aClass; + } + case TYPE_COMPOUND -> CompoundTag.class; + case TYPE_INT_ARRAY -> IntArrayTag.class; + case TYPE_LONG_ARRAY -> LongArrayTag.class; + default -> throw new IllegalArgumentException("Unknown tag type ID of " + id); + }; } } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java index fca025212..806168327 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java @@ -21,6 +21,7 @@ package com.sk89q.jnbt; import com.fastasyncworldedit.core.jnbt.streamer.StreamDelegate; import com.fastasyncworldedit.core.jnbt.streamer.ValueReader; +import org.enginehub.linbus.stream.LinBinaryIO; import java.io.Closeable; import java.io.DataInputStream; @@ -44,8 +45,9 @@ import java.util.Map; * https://minecraft.gamepedia.com/NBT_format. *

    * - * @deprecated JNBT is being removed for adventure-nbt in WorldEdit 8. + * @deprecated JNBT is being removed for lin-bus in WorldEdit 8, use {@link LinBinaryIO} instead */ +@SuppressWarnings("removal") @Deprecated(forRemoval = true) public final class NBTInputStream implements Closeable { @@ -77,7 +79,6 @@ public final class NBTInputStream implements Closeable { * Reads an NBT tag from the stream. * * @return The tag that was read. - * @throws IOException if an I/O error occurs. */ public NamedTag readNamedTag() throws IOException { return readNamedTag(0); @@ -617,7 +618,7 @@ public final class NBTInputStream implements Closeable { return new ListTag(NBTUtils.getTypeClass(childType), tagList); case NBTConstants.TYPE_COMPOUND: - Map tagMap = new HashMap<>(); + Map> tagMap = new HashMap<>(); while (true) { NamedTag namedTag = readNamedTag(depth + 1); Tag tag = namedTag.getTag(); diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTOutputStream.java b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTOutputStream.java index 6342455eb..b466e6de2 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTOutputStream.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTOutputStream.java @@ -20,6 +20,7 @@ package com.sk89q.jnbt; import com.fastasyncworldedit.core.internal.io.LittleEndianOutputStream; +import org.enginehub.linbus.stream.LinBinaryIO; import java.io.Closeable; import java.io.DataOutput; @@ -44,8 +45,9 @@ import static com.google.common.base.Preconditions.checkNotNull; * https://minecraft.gamepedia.com/NBT_format. *

    * - * @deprecated JNBT is being removed for adventure-nbt in WorldEdit 8. + * @deprecated JNBT is being removed for lin-bus in WorldEdit 8, use {@link LinBinaryIO} instead */ +@SuppressWarnings("removal") @Deprecated(forRemoval = true) public final class NBTOutputStream extends OutputStream implements Closeable, DataOutput { @@ -61,7 +63,7 @@ public final class NBTOutputStream extends OutputStream implements Closeable, Da * @param os The output stream. * @throws IOException if an I/O error occurs. */ - public NBTOutputStream(OutputStream os) throws IOException { + public NBTOutputStream(OutputStream os) { this(os instanceof DataOutput ? (DataOutput) os : new DataOutputStream(os)); } @@ -91,11 +93,11 @@ public final class NBTOutputStream extends OutputStream implements Closeable, Da * @param tag The tag to write. * @throws IOException if an I/O error occurs. */ - public void writeNamedTag(String name, Tag tag) throws IOException { + public void writeNamedTag(String name, Tag tag) throws IOException { checkNotNull(name); checkNotNull(tag); - int type = NBTUtils.getTypeCode(tag.getClass()); + int type = tag.getTypeCode(); writeNamedTagName(name, type); if (type == NBTConstants.TYPE_END) { @@ -196,7 +198,7 @@ public final class NBTOutputStream extends OutputStream implements Closeable, Da } public void writeTag(Tag tag) throws IOException { - int type = NBTUtils.getTypeCode(tag.getClass()); + int type = tag.getTypeCode(); os.writeByte(type); writeTagPayload(tag); } @@ -212,7 +214,7 @@ public final class NBTOutputStream extends OutputStream implements Closeable, Da * @throws IOException if an I/O error occurs. */ public void writeTagPayload(Tag tag) throws IOException { - int type = NBTUtils.getTypeCode(tag.getClass()); + int type = tag.getTypeCode(); switch (type) { case NBTConstants.TYPE_END: writeEndTagPayload((EndTag) tag); @@ -287,7 +289,7 @@ public final class NBTOutputStream extends OutputStream implements Closeable, Da * @throws IOException if an I/O error occurs. */ private void writeCompoundTagPayload(CompoundTag tag) throws IOException { - for (Map.Entry entry : tag.getValue().entrySet()) { + for (Map.Entry> entry : tag.getValue().entrySet()) { writeNamedTag(entry.getKey(), entry.getValue()); } os.writeByte((byte) 0); // end tag - better way? @@ -300,7 +302,7 @@ public final class NBTOutputStream extends OutputStream implements Closeable, Da * @throws IOException if an I/O error occurs. */ private void writeListTagPayload(ListTag tag) throws IOException { - Class clazz = tag.getType(); + Class> clazz = tag.getType(); if (clazz == null) { clazz = CompoundTag.class; } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTUtils.java b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTUtils.java index c899ba07b..b742cb6f8 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTUtils.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTUtils.java @@ -20,7 +20,6 @@ package com.sk89q.jnbt; import com.sk89q.worldedit.math.Vector3; -import com.sk89q.worldedit.util.nbt.BinaryTagTypes; import com.sk89q.worldedit.world.storage.InvalidFormatException; import java.util.Map; @@ -33,6 +32,7 @@ import static com.google.common.base.Preconditions.checkNotNull; * * @deprecated JNBT is being removed for adventure-nbt in WorldEdit 8. */ +@SuppressWarnings("ALL") @Deprecated public final class NBTUtils { @@ -48,7 +48,7 @@ public final class NBTUtils { * @param clazz the tag class * @return The type name. */ - public static String getTypeName(Class clazz) { + public static String getTypeName(Class> clazz) { if (clazz.equals(ByteArrayTag.class)) { return "TAG_Byte_Array"; } else if (clazz.equals(ByteTag.class)) { @@ -77,7 +77,7 @@ public final class NBTUtils { return "TAG_Long_Array"; } else { throw new IllegalArgumentException("Invalid tag class (" - + clazz.getName() + ")."); + + clazz.getName() + ")."); } } @@ -88,11 +88,35 @@ public final class NBTUtils { * @return The type code. * @throws IllegalArgumentException if the tag class is invalid. */ - public static int getTypeCode(Class clazz) { - if (LazyCompoundTag.class.isAssignableFrom(clazz)) { - return BinaryTagTypes.COMPOUND.id(); + public static int getTypeCode(Class> clazz) { + if (clazz == ByteArrayTag.class) { + return NBTConstants.TYPE_BYTE_ARRAY; + } else if (clazz == ByteTag.class) { + return NBTConstants.TYPE_BYTE; + } else if (clazz == CompoundTag.class) { + return NBTConstants.TYPE_COMPOUND; + } else if (clazz == DoubleTag.class) { + return NBTConstants.TYPE_DOUBLE; + } else if (clazz == EndTag.class) { + return NBTConstants.TYPE_END; + } else if (clazz == FloatTag.class) { + return NBTConstants.TYPE_FLOAT; + } else if (clazz == IntArrayTag.class) { + return NBTConstants.TYPE_INT_ARRAY; + } else if (clazz == IntTag.class) { + return NBTConstants.TYPE_INT; + } else if (clazz.equals(ListTag.class) /* I hate this, it wouldn't do == b/c generics */) { + return NBTConstants.TYPE_LIST; + } else if (clazz == LongArrayTag.class) { + return NBTConstants.TYPE_LONG_ARRAY; + } else if (clazz == LongTag.class) { + return NBTConstants.TYPE_LONG; + } else if (clazz == ShortTag.class) { + return NBTConstants.TYPE_SHORT; + } else if (clazz == StringTag.class) { + return NBTConstants.TYPE_STRING; } - return AdventureNBTConverter.getAdventureType(clazz).id(); + throw new IllegalArgumentException("Invalid tag class (" + clazz.getName() + ")"); } /** @@ -102,38 +126,8 @@ public final class NBTUtils { * @return The class. * @throws IllegalArgumentException if the tag type is invalid. */ - public static Class getTypeClass(int type) { - switch (type) { - case NBTConstants.TYPE_END: - return EndTag.class; - case NBTConstants.TYPE_BYTE: - return ByteTag.class; - case NBTConstants.TYPE_SHORT: - return ShortTag.class; - case NBTConstants.TYPE_INT: - return IntTag.class; - case NBTConstants.TYPE_LONG: - return LongTag.class; - case NBTConstants.TYPE_FLOAT: - return FloatTag.class; - case NBTConstants.TYPE_DOUBLE: - return DoubleTag.class; - case NBTConstants.TYPE_BYTE_ARRAY: - return ByteArrayTag.class; - case NBTConstants.TYPE_STRING: - return StringTag.class; - case NBTConstants.TYPE_LIST: - return ListTag.class; - case NBTConstants.TYPE_COMPOUND: - return CompoundTag.class; - case NBTConstants.TYPE_INT_ARRAY: - return IntArrayTag.class; - case NBTConstants.TYPE_LONG_ARRAY: - return LongArrayTag.class; - default: - throw new IllegalArgumentException("Invalid tag type : " + type - + "."); - } + public static Class> getTypeClass(int type) { + return NBTConstants.getClassFromType(type); } /** @@ -145,7 +139,7 @@ public final class NBTUtils { * @param listTag the list tag * @return a vector */ - public static Vector3 toVector(ListTag listTag) { + public static Vector3 toVector(ListTag listTag) { checkNotNull(listTag); return Vector3.at(listTag.asDouble(0), listTag.asDouble(1), listTag.asDouble(2)); } @@ -159,12 +153,12 @@ public final class NBTUtils { * @return child tag * @throws InvalidFormatException if the format of the items is invalid */ - public static T getChildTag(Map items, String key, Class expected) throws + public static > T getChildTag(Map> items, String key, Class expected) throws InvalidFormatException { if (!items.containsKey(key)) { throw new InvalidFormatException("Missing a \"" + key + "\" tag"); } - Tag tag = items.get(key); + Tag tag = items.get(key); if (!expected.isInstance(tag)) { throw new InvalidFormatException(key + " tag is not of tag type " + expected.getName()); } @@ -179,7 +173,7 @@ public final class NBTUtils { * @param uuid {@link UUID} to add * @since 2.4.0 */ - public static void addUUIDToMap(Map map, UUID uuid) { + public static void addUUIDToMap(Map> map, UUID uuid) { int[] uuidArray = new int[4]; uuidArray[0] = (int) (uuid.getMostSignificantBits() >> 32); uuidArray[1] = (int) uuid.getMostSignificantBits(); diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NamedTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/NamedTag.java index c7e2f9f28..e83f135de 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NamedTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/NamedTag.java @@ -30,7 +30,7 @@ import static com.google.common.base.Preconditions.checkNotNull; public class NamedTag { private final String name; - private final Tag tag; + private final Tag tag; /** * Create a new named tag. @@ -38,7 +38,7 @@ public class NamedTag { * @param name the name * @param tag the tag */ - public NamedTag(String name, Tag tag) { + public NamedTag(String name, Tag tag) { checkNotNull(name); checkNotNull(tag); this.name = name; @@ -59,7 +59,7 @@ public class NamedTag { * * @return the tag */ - public Tag getTag() { + public Tag getTag() { return tag; } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/ShortTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/ShortTag.java index abbd06b3f..d0b9590fa 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/ShortTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/ShortTag.java @@ -19,41 +19,32 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.ShortBinaryTag; +import com.fastasyncworldedit.core.jnbt.NumberTag; +import org.enginehub.linbus.tree.LinShortTag; /** * The {@code TAG_Short} tag. * - * @deprecated Use {@link ShortBinaryTag}. + * @deprecated Use {@link LinShortTag}. */ @Deprecated -public final class ShortTag extends Tag { - - private final ShortBinaryTag innerTag; - +public final class ShortTag extends NumberTag { /** * Creates the tag with an empty name. * * @param value the value of the tag */ public ShortTag(short value) { - super(); - this.innerTag = ShortBinaryTag.of(value); + super(LinShortTag.of(value)); } - public ShortTag(ShortBinaryTag adventureTag) { - super(); - this.innerTag = adventureTag; - } - - @Override - public ShortBinaryTag asBinaryTag() { - return this.innerTag; + public ShortTag(LinShortTag tag) { + super(tag); } @Override public Short getValue() { - return innerTag.value(); + return linTag.value(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/StringTag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/StringTag.java index 483263752..2bc78f141 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/StringTag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/StringTag.java @@ -19,44 +19,33 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.StringBinaryTag; +import org.enginehub.linbus.tree.LinStringTag; import static com.google.common.base.Preconditions.checkNotNull; /** * The {@code TAG_String} tag. * - * @deprecated Use {@link StringBinaryTag}. + * @deprecated Use {@link LinStringTag}. */ @Deprecated -public final class StringTag extends Tag { - - private final StringBinaryTag innerTag; - +public final class StringTag extends Tag { /** * Creates the tag with an empty name. * * @param value the value of the tag */ public StringTag(String value) { - super(); - checkNotNull(value); - this.innerTag = StringBinaryTag.of(value); + super(LinStringTag.of(checkNotNull(value))); } - public StringTag(StringBinaryTag adventureTag) { - super(); - this.innerTag = adventureTag; - } - - @Override - public StringBinaryTag asBinaryTag() { - return this.innerTag; + public StringTag(LinStringTag tag) { + super(tag); } @Override public String getValue() { - return innerTag.value(); + return linTag.value(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/Tag.java b/worldedit-core/src/main/java/com/sk89q/jnbt/Tag.java index 6327f4133..80df4c1cb 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/Tag.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/Tag.java @@ -19,26 +19,43 @@ package com.sk89q.jnbt; -import com.sk89q.worldedit.util.nbt.BinaryTagLike; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.ToLinTag; + +import javax.annotation.Nonnull; /** * Represents a NBT tag. * - * @deprecated JNBT is being removed for adventure-nbt in WorldEdit 8. + * @deprecated JNBT is being removed for lin-bus in WorldEdit 8, use {@link LinTag} instead */ -@Deprecated(forRemoval = true) -public abstract class Tag implements BinaryTagLike { +@Deprecated +public abstract class Tag> implements ToLinTag { + + protected final LT linTag; + + protected Tag(LT linTag) { + this.linTag = linTag; + } /** * Gets the value of this tag. * * @return the value */ - public abstract Object getValue(); + public V getValue() { + return linTag.value(); + } @Override public String toString() { - return asBinaryTag().toString(); + return toLinTag().toString(); + } + + @Override + @Nonnull + public LT toLinTag() { + return linTag; } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index 7642f3d60..be1740dc4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -76,7 +76,6 @@ import com.sk89q.worldedit.util.Countable; import com.sk89q.worldedit.util.HandSide; import com.sk89q.worldedit.util.Identifiable; import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; @@ -84,6 +83,8 @@ import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.snapshot.experimental.Snapshot; import com.zaxxer.sparsebits.SparseBitSet; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinTagType; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -1513,13 +1514,13 @@ public class LocalSession implements TextureHolder { BaseBlock block = ServerCUIHandler.createStructureBlock(player); if (block != null) { - CompoundBinaryTag tags = Objects.requireNonNull( - block.getNbt(), "createStructureBlock should return nbt" + LinCompoundTag tags = Objects.requireNonNull( + block.getNbt(), "createStructureBlock should return nbt" ); BlockVector3 tempCuiTemporaryBlock = BlockVector3.at( - tags.getInt("x"), - tags.getInt("y"), - tags.getInt("z") + tags.getTag("x", LinTagType.intTag()).valueAsInt(), + tags.getTag("y", LinTagType.intTag()).valueAsInt(), + tags.getTag("z", LinTagType.intTag()).valueAsInt() ); // If it's null, we don't need to do anything. The old was already removed. if (cuiTemporaryBlock != null && !tempCuiTemporaryBlock.equals(cuiTemporaryBlock)) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java index fe2e1a635..552dc6f56 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java @@ -20,15 +20,13 @@ package com.sk89q.worldedit.blocks; import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.TagStringIO; import com.sk89q.worldedit.world.NbtValued; import com.sk89q.worldedit.world.item.ItemType; +import org.enginehub.linbus.format.snbt.LinStringIO; +import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nullable; -import java.io.IOException; import static com.google.common.base.Preconditions.checkNotNull; @@ -42,9 +40,7 @@ public class BaseItem implements NbtValued { private ItemType itemType; @Nullable - //FAWE start - Use LR & CBT over CompoundTag - private LazyReference nbtData; - //FAWE end + private LazyReference nbtData; /** * Construct the object. @@ -56,6 +52,29 @@ public class BaseItem implements NbtValued { this.itemType = itemType; } + /** + * Construct the object. + * + * @param itemType Type of the item + * @param nbtData NBT Compound tag + */ + @Deprecated + public BaseItem(ItemType itemType, @Nullable CompoundTag nbtData) { + this(itemType, nbtData == null ? null : LazyReference.from(nbtData::toLinTag)); + } + + /** + * Construct the object. + * + * @param itemType Type of the item + * @param tag NBT Compound tag + */ + public BaseItem(ItemType itemType, @Nullable LazyReference tag) { + checkNotNull(itemType); + this.itemType = itemType; + this.nbtData = tag; + } + /** * Get the type of item. * @@ -77,29 +96,6 @@ public class BaseItem implements NbtValued { //FAWE start - /** - * Construct the object. - * - * @param itemType Type of the item - * @param nbtData NBT Compound tag - */ - @Deprecated - public BaseItem(ItemType itemType, @Nullable CompoundTag nbtData) { - this(itemType, nbtData == null ? null : LazyReference.from(nbtData::asBinaryTag)); - } - - /** - * Construct the object. - * - * @param itemType Type of the item - * @param tag NBT Compound tag - */ - public BaseItem(ItemType itemType, @Nullable LazyReference tag) { - checkNotNull(itemType); - this.itemType = itemType; - this.nbtData = tag; - } - @Deprecated @Nullable public Object getNativeItem() { @@ -108,25 +104,20 @@ public class BaseItem implements NbtValued { @Nullable @Override - public LazyReference getNbtReference() { + public LazyReference getNbtReference() { return this.nbtData; } @Override - public void setNbtReference(@Nullable LazyReference nbtData) { + public void setNbtReference(@Nullable LazyReference nbtData) { this.nbtData = nbtData; } @Override public String toString() { String nbtString = ""; - LazyReference nbtData = this.nbtData; if (nbtData != null) { - try { - nbtString = TagStringIO.get().asString(nbtData.getValue()); - } catch (IOException e) { - WorldEdit.logger.error("Failed to serialize NBT of Item", e); - } + nbtString = LinStringIO.writeToString(nbtData.getValue()); } return getType().id() + nbtString; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItemStack.java b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItemStack.java index 07a9aa147..b83efe24a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItemStack.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItemStack.java @@ -24,8 +24,8 @@ import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.util.concurrency.LazyReference; import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.item.ItemType; +import org.enginehub.linbus.tree.LinCompoundTag; /** * Represents a stack of BaseItems. @@ -70,6 +70,18 @@ public class BaseItemStack extends BaseItem { this.amount = amount; } + /** + * Construct the object. + * + * @param id The item type + * @param tag Tag value + * @param amount amount in the stack + */ + public BaseItemStack(ItemType id, LazyReference tag, int amount) { + super(id, tag); + this.amount = amount; + } + /** * Get the number of items in the stack. * @@ -93,18 +105,4 @@ public class BaseItemStack extends BaseItem { .getRegistries().getItemRegistry().getRichName(this); } - //FAWE start - - /** - * Construct the object. - * - * @param id The item type - * @param tag Tag value - * @param amount amount in the stack - */ - public BaseItemStack(ItemType id, LazyReference tag, int amount) { - super(id, tag); - this.amount = amount; - } - //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java index 235cdf761..b369ddd87 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java @@ -21,10 +21,10 @@ package com.sk89q.worldedit.entity; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.NbtValued; import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.entity.EntityTypes; +import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nullable; @@ -47,7 +47,7 @@ public class BaseEntity implements NbtValued { private final EntityType type; @Nullable - private LazyReference nbtData; + private LazyReference nbtData; /** * Create a new base entity. @@ -69,7 +69,7 @@ public class BaseEntity implements NbtValued { * @param type the entity type * @param nbtData NBT data */ - public BaseEntity(EntityType type, LazyReference nbtData) { + public BaseEntity(EntityType type, LazyReference nbtData) { this(type); setNbtReference(nbtData); } @@ -97,12 +97,12 @@ public class BaseEntity implements NbtValued { @Nullable @Override - public LazyReference getNbtReference() { + public LazyReference getNbtReference() { return nbtData; } @Override - public void setNbtReference(@Nullable LazyReference nbtData) { + public void setNbtReference(@Nullable LazyReference nbtData) { this.nbtData = nbtData; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultItemParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultItemParser.java index b889d4dca..2eb4fbfe3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultItemParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultItemParser.java @@ -20,7 +20,6 @@ package com.sk89q.worldedit.extension.factory.parser; import com.fastasyncworldedit.core.configuration.Caption; -import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; @@ -35,13 +34,13 @@ import com.sk89q.worldedit.util.HandSide; import com.sk89q.worldedit.util.concurrency.LazyReference; import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.TagStringIO; import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemTypes; import com.sk89q.worldedit.world.registry.LegacyMapper; +import org.enginehub.linbus.format.snbt.LinStringIO; +import org.enginehub.linbus.stream.exception.NbtParseException; +import org.enginehub.linbus.tree.LinCompoundTag; -import java.io.IOException; import java.util.Locale; import java.util.stream.Stream; @@ -59,7 +58,7 @@ public class DefaultItemParser extends InputParser { @Override public BaseItem parseFromInput(String input, ParserContext context) throws InputParseException { ItemType itemType; - CompoundBinaryTag itemNbtData = null; + LinCompoundTag itemNbtData = null; BaseItem item = null; @@ -128,20 +127,21 @@ public class DefaultItemParser extends InputParser { } if (nbtString != null) { + LinCompoundTag otherTag; try { - CompoundBinaryTag otherTag = TagStringIO.get().asCompound(nbtString); - if (itemNbtData == null) { - itemNbtData = otherTag; - } else { - itemNbtData.put(NbtUtils.getCompoundBinaryTagValues(otherTag)); - } - } catch (IOException e) { + otherTag = LinStringIO.readFromStringUsing(nbtString, LinCompoundTag::readFrom); + } catch (NbtParseException e) { throw new NoMatchException(TranslatableComponent.of( "worldedit.error.invalid-nbt", TextComponent.of(input), TextComponent.of(e.getMessage()) )); } + if (itemNbtData == null) { + itemNbtData = otherTag; + } else { + itemNbtData = itemNbtData.toBuilder().putAll(otherTag.value()).build(); + } } item = new BaseItem(itemType, itemNbtData == null ? null : LazyReference.computed(itemNbtData)); 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 b861dbd6b..cf4623739 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 @@ -186,7 +186,7 @@ public class BlockArrayClipboard implements Clipboard { } @Override - public > boolean setBlock(BlockVector3 position, B block) throws WorldEditException { + public > boolean setBlock(BlockVector3 position, B block) { if (region.contains(position)) { //FAWE - get points final int x = position.x(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java index 5aafa220e..1fd9dda9a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java @@ -153,7 +153,7 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { CompoundTag schematicTag = (CompoundTag) rootTag.getTag(); // Check - Map schematic = schematicTag.getValue(); + Map> schematic = schematicTag.getValue(); if (!schematic.containsKey("Version")) { return false; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java index aebef3e9a..945cd6981 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/MCEditSchematicReader.java @@ -20,17 +20,7 @@ package com.sk89q.worldedit.extent.clipboard.io; import com.google.common.collect.ImmutableList; -import com.sk89q.jnbt.AdventureNBTConverter; -import com.sk89q.jnbt.ByteArrayTag; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.IntTag; -import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.NBTInputStream; -import com.sk89q.jnbt.NamedTag; -import com.sk89q.jnbt.ShortTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard; @@ -49,7 +39,7 @@ import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.collection.BlockMap; -import com.sk89q.worldedit.world.DataFixer; +import com.sk89q.worldedit.util.concurrency.LazyReference; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.entity.EntityType; @@ -57,27 +47,25 @@ import com.sk89q.worldedit.world.entity.EntityTypes; import com.sk89q.worldedit.world.registry.LegacyMapper; import com.sk89q.worldedit.world.storage.NBTConversions; import org.apache.logging.log4j.Logger; +import org.enginehub.linbus.tree.LinByteArrayTag; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinRootEntry; +import org.enginehub.linbus.tree.LinTagType; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; +import java.io.UncheckedIOException; import java.util.HashSet; import java.util.List; import java.util.Locale; -import java.util.Map; -import java.util.Optional; import java.util.Set; -import static com.google.common.base.Preconditions.checkNotNull; - /** * Reads schematic files that are compatible with MCEdit and other editors. */ public class MCEditSchematicReader extends NBTSchematicReader { private static final Logger LOGGER = LogManagerCompat.getLogger(); - private final NBTInputStream inputStream; - private final DataFixer fixer; + private final LinRootEntry root; private static final ImmutableList COMPATIBILITY_HANDLERS = ImmutableList.of( new SignCompatibilityHandler(), @@ -98,30 +86,30 @@ public class MCEditSchematicReader extends NBTSchematicReader { * @param inputStream the input stream to read from */ public MCEditSchematicReader(NBTInputStream inputStream) { - checkNotNull(inputStream); - this.inputStream = inputStream; - this.fixer = null; - //com.sk89q.worldedit.WorldEdit.getInstance().getPlatformManager().queryCapability( - //com.sk89q.worldedit.extension.platform.Capability.WORLD_EDITING).getDataFixer(); + try { + var tag = inputStream.readNamedTag(); + this.root = new LinRootEntry(tag.getName(), (LinCompoundTag) tag.getTag().toLinTag()); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + MCEditSchematicReader(LinRootEntry root) { + this.root = root; } @Override public Clipboard read() throws IOException { // Schematic tag - NamedTag rootTag = inputStream.readNamedTag(); - if (!rootTag.getName().equals("Schematic")) { + if (!root.name().equals("Schematic")) { throw new IOException("Tag 'Schematic' does not exist or is not first"); } - CompoundTag schematicTag = (CompoundTag) rootTag.getTag(); + var schematicTag = root.value(); - // Check - Map schematic = schematicTag.getValue(); - if (!schematic.containsKey("Blocks")) { + if (!schematicTag.value().containsKey("Blocks")) { throw new IOException("Schematic file is missing a 'Blocks' tag"); } - - // Check type of Schematic - String materials = requireTag(schematic, "Materials", StringTag.class).getValue(); + String materials = schematicTag.getTag("Materials", LinTagType.stringTag()).value(); if (!materials.equals("Alpha")) { throw new IOException("Schematic file is not an Alpha schematic"); } @@ -134,42 +122,38 @@ public class MCEditSchematicReader extends NBTSchematicReader { Region region; // Get information - short width = requireTag(schematic, "Width", ShortTag.class).getValue(); - short height = requireTag(schematic, "Height", ShortTag.class).getValue(); - short length = requireTag(schematic, "Length", ShortTag.class).getValue(); + short width = schematicTag.getTag("Width", LinTagType.shortTag()).valueAsShort(); + short height = schematicTag.getTag("Height", LinTagType.shortTag()).valueAsShort(); + short length = schematicTag.getTag("Length", LinTagType.shortTag()).valueAsShort(); - try { - int originX = requireTag(schematic, "WEOriginX", IntTag.class).getValue(); - int originY = requireTag(schematic, "WEOriginY", IntTag.class).getValue(); - int originZ = requireTag(schematic, "WEOriginZ", IntTag.class).getValue(); - BlockVector3 min = BlockVector3.at(originX, originY, originZ); + int originX = schematicTag.getTag("WEOriginX", LinTagType.intTag()).valueAsInt(); + int originY = schematicTag.getTag("WEOriginY", LinTagType.intTag()).valueAsInt(); + int originZ = schematicTag.getTag("WEOriginZ", LinTagType.intTag()).valueAsInt(); + BlockVector3 min = BlockVector3.at(originX, originY, originZ); - int offsetX = requireTag(schematic, "WEOffsetX", IntTag.class).getValue(); - int offsetY = requireTag(schematic, "WEOffsetY", IntTag.class).getValue(); - int offsetZ = requireTag(schematic, "WEOffsetZ", IntTag.class).getValue(); - BlockVector3 offset = BlockVector3.at(offsetX, offsetY, offsetZ); + int offsetX = schematicTag.getTag("WEOffsetX", LinTagType.intTag()).valueAsInt(); + int offsetY = schematicTag.getTag("WEOffsetY", LinTagType.intTag()).valueAsInt(); + int offsetZ = schematicTag.getTag("WEOffsetZ", LinTagType.intTag()).valueAsInt(); + BlockVector3 offset = BlockVector3.at(offsetX, offsetY, offsetZ); - origin = min.subtract(offset); - region = new CuboidRegion(min, min.add(width, height, length).subtract(BlockVector3.ONE)); - } catch (IOException ignored) { - origin = BlockVector3.ZERO; - region = new CuboidRegion(origin, origin.add(width, height, length).subtract(BlockVector3.ONE)); - } + origin = min.subtract(offset); + region = new CuboidRegion(min, min.add(width, height, length).subtract(BlockVector3.ONE)); // ==================================================================== // Blocks // ==================================================================== // Get blocks - byte[] blockId = requireTag(schematic, "Blocks", ByteArrayTag.class).getValue(); - byte[] blockData = requireTag(schematic, "Data", ByteArrayTag.class).getValue(); + byte[] blockId = schematicTag.getTag("Blocks", LinTagType.byteArrayTag()).value(); + byte[] blockData = schematicTag.getTag("Data", LinTagType.byteArrayTag()).value(); byte[] addId = new byte[0]; short[] blocks = new short[blockId.length]; // Have to later combine IDs // We support 4096 block IDs using the same method as vanilla Minecraft, where // the highest 4 bits are stored in a separate byte array. - if (schematic.containsKey("AddBlocks")) { - addId = requireTag(schematic, "AddBlocks", ByteArrayTag.class).getValue(); + LinByteArrayTag addBlocks = schematicTag.findTag("AddBlocks", LinTagType.byteArrayTag()); + if (addBlocks != null) { + addId = addBlocks.value(); } // Combine the AddBlocks data with the first 8-bit block ID @@ -186,21 +170,17 @@ public class MCEditSchematicReader extends NBTSchematicReader { } // Need to pull out tile entities - final ListTag tileEntityTag = getTag(schematic, "TileEntities", ListTag.class); - List tileEntities = tileEntityTag == null ? new ArrayList<>() : tileEntityTag.getValue(); + var tileEntityTag = schematicTag.findListTag("TileEntities", LinTagType.compoundTag()); + List tileEntities = tileEntityTag == null ? List.of() : tileEntityTag.value(); BlockMap tileEntityBlocks = BlockMap.createForBaseBlock(); - for (Tag tag : tileEntities) { - if (!(tag instanceof CompoundTag)) { - continue; - } - CompoundTag t = (CompoundTag) tag; - Map values = new HashMap<>(t.getValue()); - String id = t.getString("id"); - values.put("id", new StringTag(convertBlockEntityId(id))); - int x = t.getInt("x"); - int y = t.getInt("y"); - int z = t.getInt("z"); + for (LinCompoundTag tag : tileEntities) { + var newTag = tag.toBuilder(); + String id = tag.getTag("id", LinTagType.stringTag()).value(); + newTag.putString("id", convertBlockEntityId(id)); + int x = tag.getTag("x", LinTagType.intTag()).valueAsInt(); + int y = tag.getTag("y", LinTagType.intTag()).valueAsInt(); + int z = tag.getTag("z", LinTagType.intTag()).valueAsInt(); int index = y * width * length + z * width + x; //FAWE start - tile entity safety - perhaps caused by the old issue with tile entities created in the wrong @@ -211,44 +191,17 @@ public class MCEditSchematicReader extends NBTSchematicReader { } BlockState block = getBlockState(blocks[index], blockData[index]); - BlockState newBlock = block; - if (newBlock != null) { - for (NBTCompatibilityHandler handler : COMPATIBILITY_HANDLERS) { - if (handler.isAffectedBlock(newBlock)) { - newBlock = handler.updateNBT(block, values).toImmutableState(); - if (newBlock == null || values.isEmpty()) { - break; - } - } + if (block == null) { + continue; + } + var updatedBlock = block.toBaseBlock(LazyReference.from(newTag::build)); + for (NBTCompatibilityHandler handler : COMPATIBILITY_HANDLERS) { + updatedBlock = handler.updateNbt(updatedBlock); + if (updatedBlock.getNbtReference() == null) { + break; } } - if (values.isEmpty()) { - t = null; - } else { - t = new CompoundTag(values); - } - - if (fixer != null && t != null) { - //FAWE start - BinaryTag - t = (CompoundTag) AdventureNBTConverter.fromAdventure(fixer.fixUp( - DataFixer.FixTypes.BLOCK_ENTITY, - t.asBinaryTag(), - -1 - )); - //FAWE end - } - - BlockVector3 vec = BlockVector3.at(x, y, z); - // Insert into the map if we have changed the block or have a tag - BlockState blockToInsert = newBlock != null - ? newBlock - : (t != null ? block : null); - if (blockToInsert != null) { - BaseBlock baseBlock = t != null - ? blockToInsert.toBaseBlock(new CompoundTag(t.getValue())) - : blockToInsert.toBaseBlock(); - tileEntityBlocks.put(vec, baseBlock); - } + tileEntityBlocks.put(BlockVector3.at(x, y, z), updatedBlock); } BlockArrayClipboard clipboard = new BlockArrayClipboard(region); @@ -261,16 +214,10 @@ public class MCEditSchematicReader extends NBTSchematicReader { for (int z = 0; z < length; ++z) { int index = y * width * length + z * width + x; BlockVector3 pt = BlockVector3.at(x, y, z); - BaseBlock state = Optional.ofNullable(tileEntityBlocks.get(pt)) - .orElseGet(() -> { - BlockState blockState = getBlockState(blocks[index], blockData[index]); - return blockState == null ? null : blockState.toBaseBlock(); - }); - - try { - if (state != null) { - clipboard.setBlock(region.getMinimumPoint().add(pt), state); - } else { + BaseBlock state = tileEntityBlocks.get(pt); + if (state == null) { + BlockState blockState = getBlockState(blocks[index], blockData[index]); + if (blockState == null) { short block = blocks[index]; byte data = blockData[index]; int combined = block << 8 | data; @@ -278,9 +225,12 @@ public class MCEditSchematicReader extends NBTSchematicReader { LOGGER.warn("Unknown block when loading schematic: {} {}. This is most likely a" + "bad schematic.", block, data); } + continue; } - } catch (WorldEditException ignored) { // BlockArrayClipboard won't throw this + state = blockState.toBaseBlock(); } + + clipboard.setBlock(region.getMinimumPoint().add(pt), state); } } } @@ -289,40 +239,25 @@ public class MCEditSchematicReader extends NBTSchematicReader { // Entities // ==================================================================== - ListTag entityList = getTag(schematic, "Entities", ListTag.class); + var entityList = schematicTag.findListTag("Entities", LinTagType.compoundTag()); if (entityList != null) { - List entityTags = entityList.getValue(); - for (Tag tag : entityTags) { - if (tag instanceof CompoundTag) { - CompoundTag compound = (CompoundTag) tag; - if (fixer != null) { - //FAWE start - BinaryTag - compound = (CompoundTag) AdventureNBTConverter.fromAdventure(fixer.fixUp( - DataFixer.FixTypes.ENTITY, - compound.asBinaryTag(), - -1 - )); - //FAWE end - } - String id = convertEntityId(compound.getString("id")); - Location location = NBTConversions.toLocation( - clipboard, - compound.getListTag("Pos"), - compound.getListTag("Rotation") - ); - if (!id.isEmpty()) { - EntityType entityType = EntityTypes.get(id.toLowerCase(Locale.ROOT)); - if (entityType != null) { - for (EntityNBTCompatibilityHandler compatibilityHandler : ENTITY_COMPATIBILITY_HANDLERS) { - if (compatibilityHandler.isAffectedEntity(entityType, compound)) { - compound = compatibilityHandler.updateNBT(entityType, compound); - } - } - BaseEntity state = new BaseEntity(entityType, compound); - clipboard.createEntity(location, state); - } else { - LOGGER.warn("Unknown entity when pasting schematic: " + id.toLowerCase(Locale.ROOT)); + for (LinCompoundTag tag : entityList.value()) { + String id = convertEntityId(tag.getTag("id", LinTagType.stringTag()).value()); + Location location = NBTConversions.toLocation( + clipboard, + tag.getListTag("Pos", LinTagType.doubleTag()), + tag.getListTag("Rotation", LinTagType.floatTag()) + ); + if (!id.isEmpty()) { + EntityType entityType = EntityTypes.get(id.toLowerCase(Locale.ROOT)); + if (entityType != null) { + for (EntityNBTCompatibilityHandler compatibilityHandler : ENTITY_COMPATIBILITY_HANDLERS) { + tag = compatibilityHandler.updateNbt(entityType, tag); } + BaseEntity state = new BaseEntity(entityType, LazyReference.computed(tag)); + clipboard.createEntity(location, state); + } else { + LOGGER.warn("Unknown entity when pasting schematic: " + id.toLowerCase(Locale.ROOT)); } } } @@ -494,7 +429,6 @@ public class MCEditSchematicReader extends NBTSchematicReader { @Override public void close() throws IOException { - inputStream.close(); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/NBTSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/NBTSchematicReader.java index 0328b1c76..a6b9c1400 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/NBTSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/NBTSchematicReader.java @@ -30,13 +30,13 @@ import java.util.Map; */ public abstract class NBTSchematicReader implements ClipboardReader { - protected static T requireTag(Map items, String key, Class expected) throws IOException { + protected static > T requireTag(Map> items, String key, Class expected) throws IOException { if (!items.containsKey(key)) { throw new IOException("Schematic file is missing a \"" + key + "\" tag of type " + expected.getName()); } - Tag tag = items.get(key); + Tag tag = items.get(key); if (!expected.isInstance(tag)) { throw new IOException(key + " tag is not of tag type " + expected.getName() + ", got " + tag.getClass().getName() + " instead"); @@ -46,12 +46,12 @@ public abstract class NBTSchematicReader implements ClipboardReader { } @Nullable - protected static T getTag(Map items, String key, Class expected) { + protected static > T getTag(Map> items, String key, Class expected) { if (!items.containsKey(key)) { return null; } - Tag test = items.get(key); + Tag test = items.get(key); if (!expected.isInstance(test)) { return null; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java index a140b666a..ec82be228 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java @@ -21,7 +21,7 @@ package com.sk89q.worldedit.extent.clipboard.io; import com.fastasyncworldedit.core.configuration.Caption; import com.google.common.collect.Maps; -import com.sk89q.jnbt.AdventureNBTConverter; +import com.sk89q.jnbt.LinBusConverter; import com.sk89q.jnbt.ByteArrayTag; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.IntArrayTag; @@ -64,7 +64,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.OptionalInt; -import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkNotNull; @@ -97,7 +96,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { @Override public Clipboard read() throws IOException { CompoundTag schematicTag = getBaseTag(); - Map schematic = schematicTag.getValue(); + Map> schematic = schematicTag.getValue(); final Platform platform = WorldEdit.getInstance().getPlatformManager() .queryCapability(Capability.WORLD_EDITING); @@ -147,7 +146,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { public OptionalInt getDataVersion() { try { CompoundTag schematicTag = getBaseTag(); - Map schematic = schematicTag.getValue(); + Map> schematic = schematicTag.getValue(); if (schematicVersion == 1) { return OptionalInt.of(Constants.DATA_VERSION_MC_1_13_2); } else if (schematicVersion == 2) { @@ -168,7 +167,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { CompoundTag schematicTag = (CompoundTag) rootTag.getTag(); // Check - Map schematic = schematicTag.getValue(); + Map> schematic = schematicTag.getValue(); // Be lenient about the specific nesting level of the Schematic tag // Also allows checking the version from newer versions of the specification @@ -184,7 +183,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { private BlockArrayClipboard readVersion1(CompoundTag schematicTag) throws IOException { BlockVector3 origin; Region region; - Map schematic = schematicTag.getValue(); + Map> schematic = schematicTag.getValue(); int width = requireTag(schematic, "Width", ShortTag.class).getValue(); int height = requireTag(schematic, "Height", ShortTag.class).getValue(); @@ -206,7 +205,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { CompoundTag metadataTag = getTag(schematic, "Metadata", CompoundTag.class); if (metadataTag != null && metadataTag.containsKey("WEOffsetX")) { // We appear to have WorldEdit Metadata - Map metadata = metadataTag.getValue(); + Map> metadata = metadataTag.getValue(); int offsetX = requireTag(metadata, "WEOffsetX", IntTag.class).getValue(); int offsetY = requireTag(metadata, "WEOffsetY", IntTag.class).getValue(); int offsetZ = requireTag(metadata, "WEOffsetZ", IntTag.class).getValue(); @@ -219,7 +218,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { } IntTag paletteMaxTag = getTag(schematic, "PaletteMax", IntTag.class); - Map paletteObject = requireTag(schematic, "Palette", CompoundTag.class).getValue(); + Map> paletteObject = requireTag(schematic, "Palette", CompoundTag.class).getValue(); if (paletteMaxTag != null && paletteObject.size() != paletteMaxTag.getValue()) { throw new IOException("Block palette size does not match expected size."); } @@ -248,21 +247,17 @@ public class SpongeSchematicReader extends NBTSchematicReader { byte[] blocks = requireTag(schematic, "BlockData", ByteArrayTag.class).getValue(); - Map> tileEntitiesMap = new HashMap<>(); + Map>> tileEntitiesMap = new HashMap<>(); ListTag tileEntities = getTag(schematic, "BlockEntities", ListTag.class); if (tileEntities == null) { tileEntities = getTag(schematic, "TileEntities", ListTag.class); } if (tileEntities != null) { - List> tileEntityTags = tileEntities.getValue().stream() - .map(tag -> (CompoundTag) tag) - .map(CompoundTag::getValue) - .collect(Collectors.toList()); - - for (Map tileEntity : tileEntityTags) { + for (Object tileTag : tileEntities.getValue()) { + Map> tileEntity = ((CompoundTag) tileTag).getValue(); int[] pos = requireTag(tileEntity, "Pos", IntArrayTag.class).getValue(); final BlockVector3 pt = BlockVector3.at(pos[0], pos[1], pos[2]); - Map values = Maps.newHashMap(tileEntity); + Map> values = Maps.newHashMap(tileEntity); values.put("x", new IntTag(pt.x())); values.put("y", new IntTag(pt.y())); values.put("z", new IntTag(pt.z())); @@ -279,10 +274,10 @@ public class SpongeSchematicReader extends NBTSchematicReader { values.remove("Id"); values.remove("Pos"); if (fixer != null) { - //FAWE start - BinaryTag - tileEntity = ((CompoundTag) AdventureNBTConverter.fromAdventure(fixer.fixUp( + //FAWE start - LinTag + tileEntity = ((CompoundTag) LinBusConverter.fromLinBus(fixer.fixUp( DataFixer.FixTypes.BLOCK_ENTITY, - new CompoundTag(values).asBinaryTag(), + new CompoundTag(values).toLinTag(), dataVersion ))).getValue(); //FAWE end @@ -341,7 +336,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { } private Clipboard readVersion2(BlockArrayClipboard version1, CompoundTag schematicTag) throws IOException { - Map schematic = schematicTag.getValue(); + Map> schematic = schematicTag.getValue(); if (schematic.containsKey("BiomeData")) { readBiomes(version1, schematic); } @@ -351,7 +346,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { return version1; } - private void readBiomes(BlockArrayClipboard clipboard, Map schematic) throws IOException { + private void readBiomes(BlockArrayClipboard clipboard, Map> schematic) throws IOException { ByteArrayTag dataTag = requireTag(schematic, "BiomeData", ByteArrayTag.class); IntTag maxTag = requireTag(schematic, "BiomePaletteMax", IntTag.class); CompoundTag paletteTag = requireTag(schematic, "BiomePalette", CompoundTag.class); @@ -361,7 +356,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { throw new IOException("Biome palette size does not match expected size."); } - for (Entry palettePart : paletteTag.getValue().entrySet()) { + for (Entry> palettePart : paletteTag.getValue().entrySet()) { String key = palettePart.getKey(); if (fixer != null) { key = fixer.fixUp(DataFixer.FixTypes.BIOME, key, dataVersion); @@ -411,7 +406,7 @@ public class SpongeSchematicReader extends NBTSchematicReader { } } - private void readEntities(BlockArrayClipboard clipboard, Map schematic) throws IOException { + private void readEntities(BlockArrayClipboard clipboard, Map> schematic) throws IOException { List entList = requireTag(schematic, "Entities", ListTag.class).getValue(); if (entList.isEmpty()) { return; @@ -421,15 +416,15 @@ public class SpongeSchematicReader extends NBTSchematicReader { continue; } CompoundTag entityTag = (CompoundTag) et; - Map tags = entityTag.getValue(); + Map> tags = entityTag.getValue(); String id = requireTag(tags, "Id", StringTag.class).getValue(); entityTag = entityTag.createBuilder().putString("id", id).remove("Id").build(); if (fixer != null) { - //FAWE start - BinaryTag - entityTag = (CompoundTag) AdventureNBTConverter.fromAdventure(fixer.fixUp( + //FAWE start - LinTag + entityTag = (CompoundTag) LinBusConverter.fromLinBus(fixer.fixUp( DataFixer.FixTypes.ENTITY, - entityTag.asBinaryTag(), + entityTag.toLinTag(), dataVersion )); //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java index dc313b259..38c0115e5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java @@ -92,7 +92,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { * @param clipboard The clipboard * @return The schematic map */ - private Map write2(Clipboard clipboard) { + private Map> write2(Clipboard clipboard) { Region region = clipboard.getRegion(); BlockVector3 origin = clipboard.getOrigin(); BlockVector3 min = region.getMinimumPoint(); @@ -111,12 +111,12 @@ public class SpongeSchematicWriter implements ClipboardWriter { throw new IllegalArgumentException("Length of region too large for a .schematic"); } - Map schematic = new HashMap<>(); + Map> schematic = new HashMap<>(); schematic.put("Version", new IntTag(CURRENT_VERSION)); schematic.put("DataVersion", new IntTag( WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion())); - Map metadata = new HashMap<>(); + Map> metadata = new HashMap<>(); metadata.put("WEOffsetX", new IntTag(offset.x())); metadata.put("WEOffsetY", new IntTag(offset.y())); metadata.put("WEOffsetZ", new IntTag(offset.z())); @@ -151,7 +151,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { BlockVector3 point = BlockVector3.at(x0, y0, z0); BaseBlock block = clipboard.getFullBlock(point); if (block.getNbtData() != null) { - Map values = new HashMap<>(block.getNbtData().getValue()); + Map> values = new HashMap<>(block.getNbtData().getValue()); values.remove("id"); // Remove 'id' if it exists. We want 'Id' @@ -187,7 +187,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { schematic.put("PaletteMax", new IntTag(paletteMax)); - Map paletteTag = new HashMap<>(); + Map> paletteTag = new HashMap<>(); palette.forEach((key, value) -> paletteTag.put(key, new IntTag(value))); schematic.put("Palette", new CompoundTag(paletteTag)); @@ -206,7 +206,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { return schematic; } - private void writeBiomes(Clipboard clipboard, Map schematic) { + private void writeBiomes(Clipboard clipboard, Map> schematic) { BlockVector3 min = clipboard.getMinimumPoint(); int width = clipboard.getRegion().getWidth(); int length = clipboard.getRegion().getLength(); @@ -243,20 +243,20 @@ public class SpongeSchematicWriter implements ClipboardWriter { schematic.put("BiomePaletteMax", new IntTag(paletteMax)); - Map paletteTag = new HashMap<>(); + Map> paletteTag = new HashMap<>(); palette.forEach((key, value) -> paletteTag.put(key, new IntTag(value))); schematic.put("BiomePalette", new CompoundTag(paletteTag)); schematic.put("BiomeData", new ByteArrayTag(buffer.toByteArray())); } - private void writeEntities(Clipboard clipboard, Map schematic) { + private void writeEntities(Clipboard clipboard, Map> schematic) { List entities = clipboard.getEntities().stream().map(e -> { BaseEntity state = e.getState(); if (state == null) { return null; } - Map values = Maps.newHashMap(); + Map> values = Maps.newHashMap(); CompoundTag rawData = state.getNbtData(); if (rawData != null) { values.putAll(rawData.getValue()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BannerBlockCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BannerBlockCompatibilityHandler.java index 826967400..d4b7347f2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BannerBlockCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BannerBlockCompatibilityHandler.java @@ -19,21 +19,16 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.CompoundTagBuilder; -import com.sk89q.jnbt.IntTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Direction; +import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinTagType; public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler { @@ -55,17 +50,19 @@ public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler } @Override - public > boolean isAffectedBlock(B block) { - return block.getBlockType() == BlockTypes.WHITE_BANNER - || block.getBlockType() == BlockTypes.WHITE_WALL_BANNER; - } - - @Override - public > BlockStateHolder updateNBT(B block, Map values) { - Tag typeTag = values.get("Base"); - if (typeTag instanceof IntTag) { + public BaseBlock updateNbt(BaseBlock block) { + var blockType = block.getBlockType(); + if (blockType != BlockTypes.WHITE_BANNER && blockType != BlockTypes.WHITE_WALL_BANNER) { + return block; + } + var nbt = block.getNbt(); + if (nbt == null) { + return block; + } + LinIntTag typeTag = nbt.findTag("Base", LinTagType.intTag()); + if (typeTag != null) { boolean isWall = block.getBlockType() == BlockTypes.WHITE_WALL_BANNER; - String bannerType = convertBannerType(((IntTag) typeTag).getValue(), isWall); + String bannerType = convertBannerType(typeTag.valueAsInt(), isWall); if (bannerType != null) { BlockType type = BlockTypes.get("minecraft:" + bannerType); if (type != null) { @@ -79,29 +76,25 @@ public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler state = state.with(rotationProp, block.getState(RotationProperty)); } - values.remove("Base"); + var nbtBuilder = nbt.toBuilder(); + nbtBuilder.remove("Base"); - Tag patternsTag = values.get("Patterns"); - if (patternsTag instanceof ListTag) { - List tempList = new ArrayList<>(); - for (Tag pattern : ((ListTag) patternsTag).getValue()) { - if (pattern instanceof CompoundTag) { - Map patternMap = ((CompoundTag) pattern).getValue(); - Tag colorTag = patternMap.get("Color"); - - CompoundTagBuilder builder = CompoundTagBuilder.create(); - builder.putAll(patternMap); - if (colorTag instanceof IntTag) { - builder.putInt("Color", 15 - ((IntTag) colorTag).getValue()); - } - tempList.add(builder.build()); + var patternsTag = nbt.findListTag("Patterns", LinTagType.compoundTag()); + if (patternsTag != null) { + var newPatterns = LinListTag.builder(LinTagType.compoundTag()); + for (LinCompoundTag pattern : patternsTag.value()) { + LinIntTag color = pattern.findTag("Color", LinTagType.intTag()); + if (color != null) { + newPatterns.add(pattern.toBuilder() + .putInt("Color", 15 - color.valueAsInt()) + .build()); } else { - tempList.add(pattern); + newPatterns.add(pattern); } } - values.put("Patterns", new ListTag(((ListTag) patternsTag).getType(), tempList)); + nbtBuilder.put("Patterns", newPatterns.build()); } - return state; + return state.toBaseBlock(nbtBuilder.build()); } } } @@ -109,58 +102,27 @@ public class BannerBlockCompatibilityHandler implements NBTCompatibilityHandler } private static String convertBannerType(int oldType, boolean isWall) { - String color; - switch (oldType) { - case 0: - color = "black"; - break; - case 1: - color = "red"; - break; - case 2: - color = "green"; - break; - case 3: - color = "brown"; - break; - case 4: - color = "blue"; - break; - case 5: - color = "purple"; - break; - case 6: - color = "cyan"; - break; - case 7: - color = "light_gray"; - break; - case 8: - color = "gray"; - break; - case 9: - color = "pink"; - break; - case 10: - color = "lime"; - break; - case 11: - color = "yellow"; - break; - case 12: - color = "light_blue"; - break; - case 13: - color = "magenta"; - break; - case 14: - color = "orange"; - break; - case 15: - color = "white"; - break; - default: - return null; + String color = switch (oldType) { + case 0 -> "black"; + case 1 -> "red"; + case 2 -> "green"; + case 3 -> "brown"; + case 4 -> "blue"; + case 5 -> "purple"; + case 6 -> "cyan"; + case 7 -> "light_gray"; + case 8 -> "gray"; + case 9 -> "pink"; + case 10 -> "lime"; + case 11 -> "yellow"; + case 12 -> "light_blue"; + case 13 -> "magenta"; + case 14 -> "orange"; + case 15 -> "white"; + default -> null; + }; + if (color == null) { + return null; } return color + (isWall ? "_wall_banner" : "_banner"); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BedBlockCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BedBlockCompatibilityHandler.java index eea18f8df..c8c26cc91 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BedBlockCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/BedBlockCompatibilityHandler.java @@ -19,18 +19,15 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat; -import com.sk89q.jnbt.IntTag; -import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Direction; +import com.sk89q.worldedit.util.concurrency.LazyReference; +import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; +import org.enginehub.linbus.tree.LinTagType; -import java.util.Map; - -@SuppressWarnings("") public class BedBlockCompatibilityHandler implements NBTCompatibilityHandler { private static final Property FACING_PROPERTY; @@ -51,92 +48,63 @@ public class BedBlockCompatibilityHandler implements NBTCompatibilityHandler { } @Override - public > boolean isAffectedBlock(B block) { - return block.getBlockType() == BlockTypes.RED_BED; - } - - @Override - public > BlockStateHolder updateNBT(B block, Map values) { - Tag typeTag = values.get("color"); - if (typeTag instanceof IntTag) { - String bedType = convertBedType(((IntTag) typeTag).getValue()); - if (bedType != null) { - BlockType type = BlockTypes.get("minecraft:" + bedType); - if (type != null) { - BlockState state = type.getDefaultState(); - - Property facingProp = type.getProperty("facing"); - state = state.with(facingProp, block.getState(FACING_PROPERTY)); - - Property occupiedProp = type.getProperty("occupied"); - state = state.with(occupiedProp, false); - - Property partProp = type.getProperty("part"); - state = state.with(partProp, block.getState(PART_PROPERTY)); - - values.remove("color"); - return state; - } - } + public BaseBlock updateNbt(BaseBlock block) { + if (block.getBlockType() != BlockTypes.RED_BED) { + return block; } - return block; + var tag = block.getNbt(); + if (tag == null) { + return block; + } + var typeTag = tag.findTag("color", LinTagType.intTag()); + if (typeTag == null) { + return block; + } + String bedType = convertBedType(typeTag.valueAsInt()); + if (bedType == null) { + return block; + } + BlockType type = BlockTypes.get("minecraft:" + bedType); + if (type == null) { + return block; + } + BlockState state = type.getDefaultState(); + + Property facingProp = type.getProperty("facing"); + state = state.with(facingProp, block.getState(FACING_PROPERTY)); + + Property occupiedProp = type.getProperty("occupied"); + state = state.with(occupiedProp, false); + + Property partProp = type.getProperty("part"); + state = state.with(partProp, block.getState(PART_PROPERTY)); + + var newTag = tag.toBuilder(); + newTag.remove("color"); + return state.toBaseBlock(LazyReference.computed(newTag.build())); } private String convertBedType(int oldType) { - String color; - switch (oldType) { - case 0: - color = "white"; - break; - case 1: - color = "orange"; - break; - case 2: - color = "magenta"; - break; - case 3: - color = "light_blue"; - break; - case 4: - color = "yellow"; - break; - case 5: - color = "lime"; - break; - case 6: - color = "pink"; - break; - case 7: - color = "gray"; - break; - case 8: - color = "light_gray"; - break; - case 9: - color = "cyan"; - break; - case 10: - color = "purple"; - break; - case 11: - color = "blue"; - break; - case 12: - color = "brown"; - break; - case 13: - color = "green"; - break; - case 14: - color = "red"; - break; - case 15: - color = "black"; - break; - default: - return null; - } - return color + "_bed"; + String color = switch (oldType) { + case 0 -> "white"; + case 1 -> "orange"; + case 2 -> "magenta"; + case 3 -> "light_blue"; + case 4 -> "yellow"; + case 5 -> "lime"; + case 6 -> "pink"; + case 7 -> "gray"; + case 8 -> "light_gray"; + case 9 -> "cyan"; + case 10 -> "purple"; + case 11 -> "blue"; + case 12 -> "brown"; + case 13 -> "green"; + case 14 -> "red"; + case 15 -> "black"; + default -> null; + }; + return color == null ? null : color + "_bed"; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/EntityNBTCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/EntityNBTCompatibilityHandler.java index 6fcc6f422..cfd82833d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/EntityNBTCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/EntityNBTCompatibilityHandler.java @@ -20,12 +20,48 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.internal.util.DeprecationUtil; +import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility; import com.sk89q.worldedit.world.entity.EntityType; +import org.enginehub.linbus.tree.LinCompoundTag; public interface EntityNBTCompatibilityHandler { - boolean isAffectedEntity(EntityType type, CompoundTag entityTag); + /** + * Check if this is an entity affected by this handler. + * + * @deprecated this was never used, just return the same tag from + * {@link #updateNbt(EntityType, LinCompoundTag)} if it's not affected + */ + @Deprecated + default boolean isAffectedEntity(EntityType type, CompoundTag entityTag) { + var original = entityTag.toLinTag(); + var updated = updateNbt(type, original); + return !original.equals(updated); + } - CompoundTag updateNBT(EntityType type, CompoundTag entityTag); + @Deprecated + default CompoundTag updateNBT(EntityType type, CompoundTag entityTag) { + return new CompoundTag(updateNbt(type, entityTag.toLinTag())); + } + /** + * Given an entity type and data, update the data if needed. + * + * @param type the entity type + * @param entityTag the entity tag + * @return the updated tag, or the same tag if no update was needed + * @apiNote This must be overridden by new subclasses. See {@link NonAbstractForCompatibility} + * for details + */ + @SuppressWarnings("deprecation") + @NonAbstractForCompatibility( + delegateName = "updateNBT", + delegateParams = { EntityType.class, CompoundTag.class } + ) + default LinCompoundTag updateNbt(EntityType type, LinCompoundTag entityTag) { + DeprecationUtil.checkDelegatingOverride(getClass()); + + return updateNBT(type, new CompoundTag(entityTag)).toLinTag(); + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java index 95d2fb091..803b6c237 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java @@ -19,65 +19,50 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat; -import com.sk89q.jnbt.IntTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.registry.LegacyMapper; - -import java.util.Map; +import org.enginehub.linbus.tree.LinTagType; public class FlowerPotCompatibilityHandler implements NBTCompatibilityHandler { @Override - public > boolean isAffectedBlock(B block) { - return block.getBlockType() == BlockTypes.FLOWER_POT; - } - - @Override - public > BlockStateHolder updateNBT(B block, Map values) { - Tag item = values.get("Item"); - if (item instanceof StringTag) { - String id = ((StringTag) item).getValue(); - if (id.isEmpty()) { - return BlockTypes.FLOWER_POT.getDefaultState(); - } - int data = 0; - Tag dataTag = values.get("Data"); - if (dataTag instanceof IntTag) { - data = ((IntTag) dataTag).getValue(); - } - BlockState newState = convertLegacyBlockType(id, data); - if (newState != null) { - values.clear(); - return newState; - } + public BaseBlock updateNbt(BaseBlock block) { + if (block.getBlockType() != BlockTypes.FLOWER_POT) { + return block; } - return block; + var tag = block.getNbt(); + if (tag == null) { + return block; + } + var item = tag.findTag("Item", LinTagType.stringTag()); + if (item == null) { + return block; + } + String id = item.value(); + if (id.isEmpty()) { + return BlockTypes.FLOWER_POT.getDefaultState().toBaseBlock(); + } + int data = 0; + var dataTag = tag.findTag("Data", LinTagType.intTag()); + if (dataTag != null) { + data = dataTag.valueAsInt(); + } + BlockState newState = convertLegacyBlockType(id, data); + return newState != null ? newState.toBaseBlock() : block; } private BlockState convertLegacyBlockType(String id, int data) { - int newId = 0; - switch (id) { - case "minecraft:red_flower": - newId = 38; // now poppy - break; - case "minecraft:yellow_flower": - newId = 37; // now dandelion - break; - case "minecraft:sapling": - newId = 6; // oak_sapling - break; - case "minecraft:deadbush": - case "minecraft:tallgrass": - newId = 31; // dead_bush with fern and grass (not 32!) - break; - default: - break; - } + int newId = switch (id) { + case "minecraft:red_flower" -> 38; // now poppy + case "minecraft:yellow_flower" -> 37; // now dandelion + case "minecraft:sapling" -> 6; // oak_sapling + case "minecraft:deadbush", "minecraft:tallgrass" -> + 31; // dead_bush with fern and grass (not 32!) + default -> 0; + }; String plantedName = null; if (newId == 0 && id.startsWith("minecraft:")) { plantedName = id.substring(10); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NBTCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NBTCompatibilityHandler.java index b7093dd4d..a2d32ea93 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NBTCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NBTCompatibilityHandler.java @@ -19,15 +19,80 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.internal.util.DeprecationUtil; +import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility; +import com.sk89q.worldedit.util.concurrency.LazyReference; +import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; +import org.enginehub.linbus.tree.LinCompoundTag; +import java.util.HashMap; import java.util.Map; public interface NBTCompatibilityHandler { - > boolean isAffectedBlock(B block); + /** + * Check if this is a block affected by this handler. + * + * @deprecated this is handled by {@link #updateNbt(BaseBlock)} now + */ + @Deprecated + default > boolean isAffectedBlock(B block) { + BaseBlock state = block.toBaseBlock(); + BaseBlock updated = updateNbt(state); + return state != updated; + } - > BlockStateHolder updateNBT(B block, Map values); + @Deprecated + default > BlockStateHolder updateNBT(B block, Map> values) { + BaseBlock changed = updateNbt(block.toBaseBlock(LazyReference.from(() -> { + var builder = LinCompoundTag.builder(); + for (var entry : values.entrySet()) { + builder.put(entry.getKey(), entry.getValue().toLinTag()); + } + return builder.build(); + }))); + CompoundTag data = changed.getNbtData(); + values.clear(); + if (data != null) { + values.putAll(data.getValue()); + } + return changed; + } + + /** + * Given a block, update the block's NBT. The NBT may be {@code null}. + * + * @param block the block to update + * @return the updated block, or the same block if no change is necessary + * @apiNote This must be overridden by new subclasses. See {@link NonAbstractForCompatibility} + * for details + */ + @NonAbstractForCompatibility( + delegateName = "updateNBT", + delegateParams = { BlockStateHolder.class, Map.class } + ) + @SuppressWarnings("deprecated") + default BaseBlock updateNbt(BaseBlock block) { + DeprecationUtil.checkDelegatingOverride(getClass()); + if (!isAffectedBlock(block)) { + return block; + } + if (block.getNbt() == null) { + return block; + } + @SuppressWarnings("deprecation") + Map> values = new HashMap<>(new CompoundTag(block.getNbt()).getValue()); + BlockStateHolder changedBlock = updateNBT(block, values); + return changedBlock.toBaseBlock(LazyReference.from(() -> { + var builder = LinCompoundTag.builder(); + for (var entry : values.entrySet()) { + builder.put(entry.getKey(), entry.getValue().toLinTag()); + } + return builder.build(); + })); + } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NoteBlockCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NoteBlockCompatibilityHandler.java index 508e84280..04190197e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NoteBlockCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/NoteBlockCompatibilityHandler.java @@ -19,18 +19,15 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat; -import com.sk89q.jnbt.ByteTag; -import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.registry.state.IntegerProperty; import com.sk89q.worldedit.registry.state.Property; -import com.sk89q.worldedit.world.block.BlockStateHolder; +import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockTypes; - -import java.util.Map; +import org.enginehub.linbus.tree.LinTagType; public class NoteBlockCompatibilityHandler implements NBTCompatibilityHandler { - private static final IntegerProperty NoteProperty; + private static final IntegerProperty NOTE_PROPERTY; static { IntegerProperty temp; @@ -39,27 +36,25 @@ public class NoteBlockCompatibilityHandler implements NBTCompatibilityHandler { } catch (NullPointerException | IllegalArgumentException | ClassCastException e) { temp = null; } - NoteProperty = temp; + NOTE_PROPERTY = temp; } @Override - public > boolean isAffectedBlock(B block) { - return NoteProperty != null && block.getBlockType() == BlockTypes.NOTE_BLOCK; - } - - @Override - public > BlockStateHolder updateNBT(B block, Map values) { + public BaseBlock updateNbt(BaseBlock block) { + if (NOTE_PROPERTY == null || block.getBlockType() != BlockTypes.NOTE_BLOCK) { + return block; + } + var tag = block.getNbt(); + if (tag == null) { + return block; + } // note that instrument was not stored (in state or nbt) previously. // it will be updated to the block below when it gets set into the world for the first time - Tag noteTag = values.get("note"); - if (noteTag instanceof ByteTag) { - Byte note = ((ByteTag) noteTag).getValue(); - if (note != null) { - values.clear(); - return block.with(NoteProperty, (int) note).toImmutableState(); - } + var noteTag = tag.findTag("note", LinTagType.byteTag()); + if (noteTag == null) { + return block; } - return block; + return block.with(NOTE_PROPERTY, (int) noteTag.valueAsByte()).toBaseBlock(); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java index 346f5f29e..f0bea016f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java @@ -19,41 +19,31 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.CompoundTagBuilder; import com.sk89q.worldedit.internal.helper.MCDirections; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.world.entity.EntityType; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinNumberTag; public class Pre13HangingCompatibilityHandler implements EntityNBTCompatibilityHandler { @Override - public boolean isAffectedEntity(EntityType type, CompoundTag tag) { - if (!type.id().startsWith("minecraft:")) { - return false; + public LinCompoundTag updateNbt(EntityType type, LinCompoundTag tag) { + if (!type.getId().startsWith("minecraft:")) { + return tag; } - boolean hasLegacyDirection = tag.containsKey("Dir") || tag.containsKey("Direction"); - boolean hasFacing = tag.containsKey("Facing"); - return hasLegacyDirection || hasFacing; - } - - @Override - public CompoundTag updateNBT(EntityType type, CompoundTag tag) { - boolean hasLegacyDir = tag.containsKey("Dir"); - boolean hasLegacyDirection = tag.containsKey("Direction"); - boolean hasPre113Facing = tag.containsKey("Facing"); Direction newDirection; - if (hasLegacyDir) { - newDirection = MCDirections.fromPre13Hanging(MCDirections.fromLegacyHanging((byte) tag.asInt("Dir"))); - } else if (hasLegacyDirection) { - newDirection = MCDirections.fromPre13Hanging(tag.asInt("Direction")); - } else if (hasPre113Facing) { - newDirection = MCDirections.fromPre13Hanging(tag.asInt("Facing")); + if (tag.value().get("Dir") instanceof LinNumberTag legacyDir) { + newDirection = MCDirections.fromPre13Hanging(MCDirections.fromLegacyHanging(legacyDir.value().byteValue())); + } else if (tag.value().get("Direction") instanceof LinNumberTag legacyDirection) { + newDirection = MCDirections.fromPre13Hanging(legacyDirection.value().intValue()); + } else if (tag.value().get("Facing") instanceof LinNumberTag legacyFacing) { + newDirection = MCDirections.fromPre13Hanging(legacyFacing.value().intValue()); } else { return tag; } byte hangingByte = (byte) MCDirections.toHanging(newDirection); - CompoundTagBuilder builder = tag.createBuilder(); + var builder = tag.toBuilder(); builder.putByte("Facing", hangingByte); return builder.build(); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SignCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SignCompatibilityHandler.java index d2dd4f5a8..24c5de232 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SignCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SignCompatibilityHandler.java @@ -24,50 +24,52 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSyntaxException; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.internal.util.DeprecationUtil; -import com.sk89q.worldedit.world.block.BlockStateHolder; - -import java.util.Map; +import com.sk89q.worldedit.world.block.BaseBlock; +import org.enginehub.linbus.tree.LinStringTag; +import org.enginehub.linbus.tree.LinTagType; public class SignCompatibilityHandler implements NBTCompatibilityHandler { @Override - public > boolean isAffectedBlock(B block) { - return DeprecationUtil.isSign(block.getBlockType()); - } - - @Override - public > BlockStateHolder updateNBT(B block, Map values) { + public BaseBlock updateNbt(BaseBlock block) { + if (!DeprecationUtil.isSign(block.getBlockType())) { + return block; + } + var tag = block.getNbt(); + if (tag == null) { + return block; + } + var newTag = tag.toBuilder(); for (int i = 0; i < 4; ++i) { String key = "Text" + (i + 1); - Tag value = values.get(key); - if (value instanceof StringTag) { - String storedString = ((StringTag) value).getValue(); - JsonElement jsonElement = null; - if (storedString != null && storedString.startsWith("{")) { - try { - jsonElement = new JsonParser().parse(storedString); - } catch (JsonSyntaxException ex) { - // ignore: jsonElement will be null in the next check - } - } - if (jsonElement == null) { - jsonElement = new JsonPrimitive(storedString == null ? "" : storedString); - } - if (jsonElement.isJsonObject()) { - continue; - } - - if (jsonElement.isJsonNull()) { - jsonElement = new JsonPrimitive(""); - } - - JsonObject jsonTextObject = new JsonObject(); - jsonTextObject.add("text", jsonElement); - values.put("Text" + (i + 1), new StringTag(jsonTextObject.toString())); + var value = tag.findTag(key, LinTagType.stringTag()); + if (value == null) { + continue; } + String storedString = value.value(); + JsonElement jsonElement = null; + if (storedString.startsWith("{")) { + try { + jsonElement = JsonParser.parseString(storedString); + } catch (JsonSyntaxException ex) { + // ignore: jsonElement will be null in the next check + } + } + if (jsonElement == null) { + jsonElement = new JsonPrimitive(storedString); + } + if (jsonElement.isJsonObject()) { + continue; + } + + if (jsonElement.isJsonNull()) { + jsonElement = new JsonPrimitive(""); + } + + JsonObject jsonTextObject = new JsonObject(); + jsonTextObject.add("text", jsonElement); + newTag.put("Text" + (i + 1), LinStringTag.of(jsonTextObject.toString())); } return block; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SkullBlockCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SkullBlockCompatibilityHandler.java index f00622561..6d5158208 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SkullBlockCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/SkullBlockCompatibilityHandler.java @@ -19,20 +19,17 @@ package com.sk89q.worldedit.extent.clipboard.io.legacycompat; -import com.sk89q.jnbt.ByteTag; -import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Direction; +import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; - -import java.util.Map; +import org.enginehub.linbus.tree.LinTagType; public class SkullBlockCompatibilityHandler implements NBTCompatibilityHandler { - private static final Property FacingProperty; + private static final Property FACING_PROPERTY; static { Property tempFacing; @@ -41,61 +38,70 @@ public class SkullBlockCompatibilityHandler implements NBTCompatibilityHandler { } catch (NullPointerException | IllegalArgumentException | ClassCastException e) { tempFacing = null; } - FacingProperty = tempFacing; + FACING_PROPERTY = tempFacing; } @Override - public > boolean isAffectedBlock(B block) { - return block.getBlockType() == BlockTypes.SKELETON_SKULL - || block.getBlockType() == BlockTypes.SKELETON_WALL_SKULL; - } - - @Override - public > BlockStateHolder updateNBT(B block, Map values) { - boolean isWall = block.getBlockType() == BlockTypes.SKELETON_WALL_SKULL; - Tag typeTag = values.get("SkullType"); - if (typeTag instanceof ByteTag) { - String skullType = convertSkullType(((ByteTag) typeTag).getValue(), isWall); - if (skullType != null) { - BlockType type = BlockTypes.get("minecraft:" + skullType); - if (type != null) { - BlockState state = type.getDefaultState(); - if (isWall) { - Property newProp = type.getProperty("facing"); - state = state.with(newProp, block.getState(FacingProperty)); - } else { - Tag rotTag = values.get("Rot"); - if (rotTag instanceof ByteTag) { - Property newProp = type.getProperty("rotation"); - state = state.with(newProp, (int) ((ByteTag) rotTag).getValue()); - } - } - values.remove("SkullType"); - values.remove("Rot"); - return state; - } + public BaseBlock updateNbt(BaseBlock block) { + var blockType = block.getBlockType(); + boolean isWall = blockType == BlockTypes.SKELETON_WALL_SKULL; + if (blockType != BlockTypes.SKELETON_SKULL && !isWall) { + return block; + } + if (FACING_PROPERTY == null) { + return block; + } + var tag = block.getNbt(); + if (tag == null) { + return block; + } + var typeTag = tag.findTag("SkullType", LinTagType.byteTag()); + if (typeTag == null) { + return block; + } + String skullType = convertSkullType(typeTag.valueAsByte(), isWall); + if (skullType == null) { + return block; + } + BlockType type = BlockTypes.get("minecraft:" + skullType); + if (type == null) { + return block; + } + BlockState state = type.getDefaultState(); + if (isWall) { + Property newProp = type.getProperty("facing"); + state = state.with(newProp, block.getState(FACING_PROPERTY)); + } else { + var rotTag = tag.findTag("Rot", LinTagType.byteTag()); + if (rotTag != null) { + Property newProp = type.getProperty("rotation"); + state = state.with(newProp, (int) rotTag.valueAsByte()); } } - return block; + var newTag = tag.toBuilder() + .remove("SkullType") + .remove("Rot") + .build(); + return state.toBaseBlock(newTag); } - private String convertSkullType(Byte oldType, boolean isWall) { - switch (oldType) { - case 0: - return isWall ? "skeleton_wall_skull" : "skeleton_skull"; - case 1: - return isWall ? "wither_skeleton_wall_skull" : "wither_skeleton_skull"; - case 2: - return isWall ? "zombie_wall_head" : "zombie_head"; - case 3: - return isWall ? "player_wall_head" : "player_head"; - case 4: - return isWall ? "creeper_wall_head" : "creeper_head"; - case 5: - return isWall ? "dragon_wall_head" : "dragon_head"; - default: - return null; + private String convertSkullType(byte oldType, boolean isWall) { + record SkullData(String kind, String suffix) { } + + var skullData = switch (oldType) { + case 0 -> new SkullData("skeleton", "skull"); + case 1 -> new SkullData("wither_skeleton", "skull"); + case 2 -> new SkullData("zombie", "head"); + case 3 -> new SkullData("player", "head"); + case 4 -> new SkullData("creeper", "head"); + case 5 -> new SkullData("dragon", "head"); + default -> null; + }; + if (skullData == null) { + return null; + } + return skullData.kind + (isWall ? "_wall" : "") + "_" + skullData.suffix; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java index 5f434cf9b..519463760 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java @@ -401,7 +401,7 @@ public class BlockTransformExtent extends ResettableExtent { ); if (newDirection != null) { - Map values = new HashMap<>(tag.getValue()); + Map> values = new HashMap<>(tag.getValue()); values.put("Rot", new ByteTag((byte) MCDirections.toRotation(newDirection))); tag = new CompoundTag(values); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SurvivalModeExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SurvivalModeExtent.java index 88cf4fc6f..b2670113a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SurvivalModeExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/world/SurvivalModeExtent.java @@ -26,9 +26,9 @@ import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.extent.AbstractDelegateExtent; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BlockStateHolder; +import org.enginehub.linbus.tree.LinCompoundTag; import java.util.Collection; @@ -115,9 +115,7 @@ public class SurvivalModeExtent extends AbstractDelegateExtent { } else { // Can't be an inlined check due to inconsistent generic return type if (stripNbt) { - //FAWE start - Use CompoundBinaryTag - return super.setBlock(location, block.toBaseBlock((CompoundBinaryTag) null)); - //FAWE end + return super.setBlock(location, block.toBaseBlock((LinCompoundTag) null)); } else { return super.setBlock(location, block); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java index 093a7737f..e4b390797 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/ExtentBlockCopy.java @@ -28,10 +28,9 @@ import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Direction.Flag; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.NumberBinaryTag; import com.sk89q.worldedit.world.block.BaseBlock; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinTag; import static com.google.common.base.Preconditions.checkNotNull; @@ -88,14 +87,13 @@ public class ExtentBlockCopy implements RegionFunction { * @return a new state or the existing one */ private BaseBlock transformNbtData(BaseBlock state) { - //FAWE start - Replace CompoundTag with CompoundBinaryTag - CompoundBinaryTag tag = state.getNbt(); + LinCompoundTag tag = state.getNbt(); if (tag != null) { // Handle blocks which store their rotation in NBT - BinaryTag rotTag = tag.get("Rot"); - if (rotTag instanceof NumberBinaryTag) { - int rot = ((NumberBinaryTag) rotTag).intValue(); + LinTag rotTag = tag.value().get("Rot"); + if (rotTag.value() instanceof Number number) { + int rot = number.intValue(); Direction direction = MCDirections.fromRotation(rot); @@ -105,8 +103,9 @@ public class ExtentBlockCopy implements RegionFunction { if (newDirection != null) { return state.toBaseBlock( - tag.putByte("Rot", (byte) MCDirections.toRotation(newDirection)) - //FAWE end + tag.toBuilder() + .putByte("Rot", (byte) MCDirections.toRotation(newDirection)) + .build() ); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java index c30f6fa4d..49fac779a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java @@ -29,9 +29,9 @@ import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.RegionSelector; import com.sk89q.worldedit.regions.selector.CuboidRegionSelector; import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockTypes; +import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nullable; @@ -135,9 +135,6 @@ public class ServerCUIHandler { Math.min(Math.min(player.getWorld().getMaxY(), posY + MAX_DISTANCE), posY + 3) ); - //FAWE start - CBT > Map - CompoundBinaryTag.Builder structureTag = CompoundBinaryTag.builder(); - posX -= x; posY -= y; posZ -= z; @@ -147,7 +144,7 @@ public class ServerCUIHandler { return null; } - //FAWE start - see comment of CBT + LinCompoundTag.Builder structureTag = LinCompoundTag.builder(); structureTag.putString("name", "worldedit:" + player.getName()); structureTag.putString("author", player.getName()); structureTag.putString("metadata", ""); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java index aa90cb816..56cab805f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java @@ -19,17 +19,14 @@ package com.sk89q.worldedit.internal.wna; -import com.google.common.collect.ImmutableMap; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.IntBinaryTag; -import com.sk89q.worldedit.util.nbt.StringBinaryTag; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockStateHolder; +import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nullable; @@ -68,17 +65,15 @@ public interface WorldNativeAccess { // Create the TileEntity if (successful || old == newState) { - if (block instanceof BaseBlock) { - BaseBlock baseBlock = (BaseBlock) block; - //FAWE start - use CompoundBinaryTag over CompoundTag - CompoundBinaryTag tag = baseBlock.getNbt(); + if (block instanceof BaseBlock baseBlock) { + LinCompoundTag tag = baseBlock.getNbt(); if (tag != null) { - tag = tag.put(ImmutableMap.of( - "id", StringBinaryTag.of(baseBlock.getNbtId()), - "x", IntBinaryTag.of(position.x()), - "y", IntBinaryTag.of(position.y()), - "z", IntBinaryTag.of(position.z()) - )); + tag = tag.toBuilder() + .putString("id", baseBlock.getNbtId()) + .putInt("x", position.getX()) + .putInt("y", position.getY()) + .putInt("z", position.getZ()) + .build(); // update if TE changed as well successful = updateTileEntity(pos, tag); @@ -143,7 +138,7 @@ public interface WorldNativeAccess { void updateLightingForBlock(NP position); - boolean updateTileEntity(NP position, CompoundBinaryTag tag); + boolean updateTileEntity(NP position, LinCompoundTag tag); void notifyBlockUpdate(NC chunk, NP position, NBS oldState, NBS newState); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/DataFixer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/DataFixer.java index 5b69ddff0..414190a98 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/DataFixer.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/DataFixer.java @@ -20,8 +20,7 @@ package com.sk89q.worldedit.world; import com.google.common.annotations.Beta; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; +import org.enginehub.linbus.tree.LinCompoundTag; /** * This entire class is subject to heavy changes. Do not use this as API. @@ -41,15 +40,12 @@ public interface DataFixer { private FixTypes() { } - //FAWE start - BinaryTag - public static FixType CHUNK = new FixType<>(); - public static FixType BLOCK_ENTITY = new FixType<>(); - public static FixType ENTITY = new FixType<>(); - //FAWE end - public static FixType BLOCK_STATE = new FixType<>(); - public static FixType BIOME = new FixType<>(); - public static FixType ITEM_TYPE = new FixType<>(); - + public static final FixType CHUNK = new FixType<>(); + public static final FixType BLOCK_ENTITY = new FixType<>(); + public static final FixType ENTITY = new FixType<>(); + public static final FixType BLOCK_STATE = new FixType<>(); + public static final FixType BIOME = new FixType<>(); + public static final FixType ITEM_TYPE = new FixType<>(); } default T fixUp(FixType type, T original) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NbtValued.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NbtValued.java index a85868685..e1c5d6de0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NbtValued.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NbtValued.java @@ -23,7 +23,7 @@ import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.internal.util.DeprecationUtil; import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility; import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; +import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nullable; @@ -66,7 +66,7 @@ public interface NbtValued { @Deprecated @Nullable default CompoundTag getNbtData() { - CompoundBinaryTag tag = getNbt(); + LinCompoundTag tag = getNbt(); return tag == null ? null : new CompoundTag(tag); } @@ -78,7 +78,7 @@ public interface NbtValued { */ @Deprecated default void setNbtData(@Nullable CompoundTag nbtData) { - setNbtReference(nbtData == null ? null : LazyReference.from(nbtData::asBinaryTag)); + setNbtReference(nbtData == null ? null : LazyReference.from(nbtData::toLinTag)); } /** @@ -96,11 +96,12 @@ public interface NbtValued { delegateParams = {} ) @Nullable - default LazyReference getNbtReference() { + default LazyReference getNbtReference() { DeprecationUtil.checkDelegatingOverride(getClass()); + @SuppressWarnings("deprecation") CompoundTag nbtData = getNbtData(); - return nbtData == null ? null : LazyReference.from(nbtData::asBinaryTag); + return nbtData == null ? null : LazyReference.from(nbtData::toLinTag); } /** @@ -109,8 +110,8 @@ public interface NbtValued { * @return compound tag, or null */ @Nullable - default CompoundBinaryTag getNbt() { - LazyReference ref = getNbtReference(); + default LinCompoundTag getNbt() { + LazyReference ref = getNbtReference(); return ref == null ? null : ref.getValue(); } @@ -119,11 +120,12 @@ public interface NbtValued { * * @param nbtData NBT data, or null if no data */ + @SuppressWarnings("deprecation") @NonAbstractForCompatibility( delegateName = "setNbtData", delegateParams = {CompoundTag.class} ) - default void setNbtReference(@Nullable LazyReference nbtData) { + default void setNbtReference(@Nullable LazyReference nbtData) { DeprecationUtil.checkDelegatingOverride(getClass()); setNbtData(nbtData == null ? null : new CompoundTag(nbtData.getValue())); @@ -134,7 +136,7 @@ public interface NbtValued { * * @param nbtData NBT data, or null if no data */ - default void setNbt(@Nullable CompoundBinaryTag nbtData) { + default void setNbt(@Nullable LinCompoundTag nbtData) { setNbtReference(nbtData == null ? null : LazyReference.computed(nbtData)); } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java index 9828c9069..ab93a4016 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java @@ -21,7 +21,6 @@ package com.sk89q.worldedit.world.block; import com.fastasyncworldedit.core.registry.state.PropertyKey; import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.TileEntityBlock; import com.sk89q.worldedit.extent.Extent; @@ -29,13 +28,13 @@ import com.sk89q.worldedit.extent.OutputExtent; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.TagStringIO; import com.sk89q.worldedit.world.registry.BlockMaterial; import com.sk89q.worldedit.world.registry.LegacyMapper; +import org.enginehub.linbus.format.snbt.LinStringIO; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinTagType; import javax.annotation.Nullable; -import java.io.IOException; import java.util.Map; import java.util.Objects; @@ -54,7 +53,7 @@ public class BaseBlock implements BlockStateHolder, TileEntityBlock { private final BlockState blockState; @Nullable - private final LazyReference nbtData; + private final LazyReference nbtData; //FAWE start @@ -93,7 +92,7 @@ public class BaseBlock implements BlockStateHolder, TileEntityBlock { */ @Deprecated public BaseBlock(BlockState state, CompoundTag nbtData) { - this(state, LazyReference.from(checkNotNull(nbtData)::asBinaryTag)); + this(state, LazyReference.from(checkNotNull(nbtData)::toLinTag)); } //FAWE end @@ -104,7 +103,7 @@ public class BaseBlock implements BlockStateHolder, TileEntityBlock { * @param state The block state * @param nbtData NBT data, which must be provided */ - protected BaseBlock(BlockState state, LazyReference nbtData) { + protected BaseBlock(BlockState state, LazyReference nbtData) { checkNotNull(nbtData); this.blockState = state; this.nbtData = nbtData; @@ -165,21 +164,21 @@ public class BaseBlock implements BlockStateHolder, TileEntityBlock { @Override public String getNbtId() { - LazyReference nbtData = this.nbtData; + LazyReference nbtData = this.nbtData; if (nbtData == null) { return ""; } - return nbtData.getValue().getString("id"); + return nbtData.getValue().getTag("id", LinTagType.stringTag()).value(); } @Nullable @Override - public LazyReference getNbtReference() { + public LazyReference getNbtReference() { return this.nbtData; } @Override - public void setNbtReference(@Nullable LazyReference nbtData) { + public void setNbtReference(@Nullable LazyReference nbtData) { throw new UnsupportedOperationException("This class is immutable."); } @@ -244,7 +243,7 @@ public class BaseBlock implements BlockStateHolder, TileEntityBlock { } @Override - public BaseBlock toBaseBlock(LazyReference compoundTag) { + public BaseBlock toBaseBlock(LazyReference compoundTag) { if (compoundTag == null) { return this.blockState.toBaseBlock(); } else if (compoundTag == this.nbtData) { @@ -300,20 +299,20 @@ public class BaseBlock implements BlockStateHolder, TileEntityBlock { @Override public int hashCode() { - return getOrdinal(); + int ret = getOrdinal() << 3; + LinCompoundTag nbtData = getNbt(); + if (nbtData != null) { + ret += nbtData.hashCode(); + } + return ret; } //FAWE end @Override public String toString() { String nbtString = ""; - CompoundBinaryTag nbtData = getNbt(); if (nbtData != null) { - try { - nbtString = TagStringIO.get().asString(nbtData); - } catch (IOException e) { - WorldEdit.logger.error("Failed to serialize NBT of Block", e); - } + nbtString = LinStringIO.writeToString(nbtData.getValue()); } return blockState.getAsString() + nbtString; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java index 713204843..caa8ba919 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java @@ -45,8 +45,8 @@ import com.sk89q.worldedit.registry.state.AbstractProperty; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.concurrency.LazyReference; import com.sk89q.worldedit.util.formatting.text.TextComponent; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.registry.BlockMaterial; +import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -420,7 +420,7 @@ public class BlockState implements BlockStateHolder, Pattern { //FAWE end @Override - public BaseBlock toBaseBlock(LazyReference compoundTag) { + public BaseBlock toBaseBlock(LazyReference compoundTag) { if (compoundTag == null) { return toBaseBlock(); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java index e40482302..f2ea08b67 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java @@ -30,8 +30,8 @@ import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.registry.BlockMaterial; +import org.enginehub.linbus.tree.LinCompoundTag; import java.util.Locale; import java.util.Map; @@ -158,7 +158,7 @@ public interface BlockStateHolder> extends TileEnt */ @Deprecated default BaseBlock toBaseBlock(CompoundTag compoundTag) { - return toBaseBlock(compoundTag == null ? null : LazyReference.from(compoundTag::asBinaryTag)); + return toBaseBlock(compoundTag == null ? null : LazyReference.from(compoundTag::toLinTag)); } /** @@ -169,11 +169,12 @@ public interface BlockStateHolder> extends TileEnt * This must be overridden by new subclasses. See {@link NonAbstractForCompatibility} * for details */ + @SuppressWarnings("deprecation") @NonAbstractForCompatibility( delegateName = "toBaseBlock", delegateParams = {CompoundTag.class} ) - default BaseBlock toBaseBlock(LazyReference compoundTag) { + default BaseBlock toBaseBlock(LazyReference compoundTag) { DeprecationUtil.checkDelegatingOverride(getClass()); return toBaseBlock(compoundTag == null ? null : new CompoundTag(compoundTag.getValue())); @@ -185,7 +186,7 @@ public interface BlockStateHolder> extends TileEnt * @param compoundTag The NBT Data to apply * @return The BaseBlock */ - default BaseBlock toBaseBlock(CompoundBinaryTag compoundTag) { + default BaseBlock toBaseBlock(LinCompoundTag compoundTag) { return toBaseBlock(compoundTag == null ? null : LazyReference.computed(compoundTag)); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java index 5535f4305..8a3c3de89 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk.java @@ -19,21 +19,20 @@ package com.sk89q.worldedit.world.chunk; -import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.BinaryTagTypes; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.IntBinaryTag; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.registry.LegacyMapper; import com.sk89q.worldedit.world.storage.InvalidFormatException; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; import javax.annotation.Nullable; import java.util.HashMap; @@ -41,25 +40,25 @@ import java.util.Map; public class AnvilChunk implements Chunk { - private final CompoundBinaryTag rootTag; + private final LinCompoundTag rootTag; private final byte[][] blocks; private final byte[][] blocksAdd; private final byte[][] data; private final int rootX; private final int rootZ; - private Map tileEntities; + private Map tileEntities; /** * Construct the chunk with a compound tag. * * @param tag the tag to read * @throws DataException on a data error - * @deprecated Use {@link #AnvilChunk(CompoundBinaryTag)} + * @deprecated Use {@link #AnvilChunk(LinCompoundTag)} */ @Deprecated public AnvilChunk(CompoundTag tag) throws DataException { - this(tag.asBinaryTag()); + this(tag.toLinTag()); } /** @@ -68,45 +67,40 @@ public class AnvilChunk implements Chunk { * @param tag the tag to read * @throws DataException on a data error */ - public AnvilChunk(CompoundBinaryTag tag) throws DataException { + public AnvilChunk(LinCompoundTag tag) throws DataException { rootTag = tag; - rootX = NbtUtils.getChildTag(rootTag, "xPos", BinaryTagTypes.INT).value(); - rootZ = NbtUtils.getChildTag(rootTag, "zPos", BinaryTagTypes.INT).value(); + rootX = rootTag.getTag("xPos", LinTagType.intTag()).value(); + rootZ = rootTag.getTag("zPos", LinTagType.intTag()).value(); blocks = new byte[16][16 * 16 * 16]; blocksAdd = new byte[16][16 * 16 * 8]; data = new byte[16][16 * 16 * 8]; - ListBinaryTag sections = NbtUtils.getChildTag(rootTag, "Sections", BinaryTagTypes.LIST); + LinListTag> sections = rootTag.getTag("Sections", LinTagType.listTag()); - for (BinaryTag rawSectionTag : sections) { - if (!(rawSectionTag instanceof CompoundBinaryTag)) { + for (LinTag rawSectionTag : sections.value()) { + if (!(rawSectionTag instanceof LinCompoundTag sectionTag)) { continue; } - CompoundBinaryTag sectionTag = (CompoundBinaryTag) rawSectionTag; - if (sectionTag.get("Y") == null) { + var sectionYTag = sectionTag.findTag("Y", LinTagType.byteTag()); + if (sectionYTag == null) { continue; // Empty section. } - int y = NbtUtils.getChildTag(sectionTag, "Y", BinaryTagTypes.BYTE).value(); + int y = sectionYTag.value(); if (y < 0 || y >= 16) { continue; } - blocks[y] = NbtUtils.getChildTag(sectionTag, - "Blocks", BinaryTagTypes.BYTE_ARRAY - ).value(); - data[y] = NbtUtils.getChildTag(sectionTag, "Data", - BinaryTagTypes.BYTE_ARRAY - ).value(); + blocks[y] = sectionTag.getTag("Blocks", LinTagType.byteArrayTag()).value(); + data[y] = sectionTag.getTag("Data", LinTagType.byteArrayTag()).value(); // 4096 ID block support - if (sectionTag.get("Add") != null) { - blocksAdd[y] = NbtUtils.getChildTag(sectionTag, - "Add", BinaryTagTypes.BYTE_ARRAY - ).value(); + var addTag = sectionTag.findTag("Add", LinTagType.byteArrayTag()); + if (addTag != null) { + blocksAdd[y] = addTag.value(); } } @@ -144,17 +138,12 @@ public class AnvilChunk implements Chunk { int index = x + (z * 16 + (yindex * 16 * 16)); try { - int addId = 0; - // The block ID is the combination of the Blocks byte array with the // Add byte array. 'Blocks' stores the lowest 8 bits of a block's ID, and // 'Add' stores the highest 4 bits of the ID. The first block is stored // in the lowest nibble in the Add byte array. - if (index % 2 == 0) { - addId = (blocksAdd[section][index >> 1] & 0x0F) << 8; - } else { - addId = (blocksAdd[section][index >> 1] & 0xF0) << 4; - } + byte addByte = blocksAdd[section][index >> 1]; + int addId = (index & 1) == 0 ? (addByte & 0x0F) << 8 : (addByte & 0xF0) << 4; return (blocks[section][index] & 0xFF) + addId; } catch (IndexOutOfBoundsException e) { @@ -175,15 +164,12 @@ public class AnvilChunk implements Chunk { } int index = x + (z * 16 + (yIndex * 16 * 16)); - boolean shift = index % 2 == 0; - index /= 2; + boolean shift = (index & 1) != 0; + index >>= 2; try { - if (!shift) { - return (data[section][index] & 0xF0) >> 4; - } else { - return data[section][index] & 0xF; - } + byte dataByte = data[section][index]; + return shift ? (dataByte & 0xF0) >> 4 : dataByte & 0x0F; } catch (IndexOutOfBoundsException e) { throw new DataException("Chunk does not contain position " + position); } @@ -192,44 +178,40 @@ public class AnvilChunk implements Chunk { /** * Used to load the tile entities. */ - private void populateTileEntities() throws DataException { - ListBinaryTag tags = NbtUtils.getChildTag(rootTag, "TileEntities", BinaryTagTypes.LIST); + private void populateTileEntities() { + LinListTag tags = rootTag.getTag("TileEntities", LinTagType.listTag()) + .asTypeChecked(LinTagType.compoundTag()); - tileEntities = new HashMap<>(); - - for (BinaryTag tag : tags) { - if (!(tag instanceof CompoundBinaryTag)) { - throw new InvalidFormatException("CompoundTag expected in TileEntities"); - } - - CompoundBinaryTag t = (CompoundBinaryTag) tag; + tileEntities = new HashMap<>(tags.value().size()); + for (LinCompoundTag t : tags.value()) { int x = 0; int y = 0; int z = 0; - CompoundBinaryTag.Builder values = CompoundBinaryTag.builder(); + LinCompoundTag.Builder values = LinCompoundTag.builder(); - for (String key : t.keySet()) { - BinaryTag value = t.get(key); + for (String key : t.value().keySet()) { + LinTag value = t.value().get(key); switch (key) { - case "x": - if (value instanceof IntBinaryTag) { - x = ((IntBinaryTag) value).value(); + case "x" -> { + if (value instanceof LinIntTag v) { + x = v.valueAsInt(); } - break; - case "y": - if (value instanceof IntBinaryTag) { - y = ((IntBinaryTag) value).value(); + } + case "y" -> { + if (value instanceof LinIntTag v) { + y = v.valueAsInt(); } - break; - case "z": - if (value instanceof IntBinaryTag) { - z = ((IntBinaryTag) value).value(); + } + case "z" -> { + if (value instanceof LinIntTag v) { + z = v.valueAsInt(); } - break; - default: - break; + } + default -> { + // Do nothing. + } } values.put(key, value); @@ -250,14 +232,12 @@ public class AnvilChunk implements Chunk { * @throws DataException thrown if there is a data error */ @Nullable - private CompoundBinaryTag getBlockTileEntity(BlockVector3 position) throws DataException { + private LinCompoundTag getBlockTileEntity(BlockVector3 position) throws DataException { if (tileEntities == null) { populateTileEntities(); } - CompoundBinaryTag values = tileEntities.get(position); - - return values; + return tileEntities.get(position); } @Override @@ -270,7 +250,7 @@ public class AnvilChunk implements Chunk { WorldEdit.logger.warn("Unknown legacy block " + id + ":" + data + " found when loading legacy anvil chunk."); return BlockTypes.AIR.getDefaultState().toBaseBlock(); } - CompoundBinaryTag tileEntity = getBlockTileEntity(position); + LinCompoundTag tileEntity = getBlockTileEntity(position); if (tileEntity != null) { return state.toBaseBlock(tileEntity); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java index a8c2d63c2..9b3d54027 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java @@ -19,17 +19,12 @@ package com.sk89q.worldedit.world.chunk; -import com.fastasyncworldedit.core.util.NbtUtils; +import com.google.common.collect.ImmutableMap; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.BinaryTagTypes; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.IntBinaryTag; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; @@ -39,10 +34,14 @@ import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.entity.EntityTypes; import com.sk89q.worldedit.world.storage.InvalidFormatException; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinIntArrayTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; import javax.annotation.Nullable; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -51,26 +50,28 @@ import java.util.Map; */ public class AnvilChunk13 implements Chunk { - protected final CompoundBinaryTag rootTag; + protected final LinCompoundTag rootTag; + private final BlockState[][] blocks; //FAWE start - biome and entity restore protected BiomeType[] biomes; - //FAWE end - private Map tileEntities; - //FAWE start - biome and entity restore private List entities; //FAWE end + private Map tileEntities; + private final int rootX; + private final int rootZ; + /** * Construct the chunk with a compound tag. * * @param tag the tag to read * @throws DataException on a data error - * @deprecated Use {@link #AnvilChunk13(CompoundBinaryTag)} + * @deprecated Use {@link #AnvilChunk13(LinCompoundTag)} */ @Deprecated public AnvilChunk13(CompoundTag tag) throws DataException { - this(tag.asBinaryTag()); + this(tag.toLinTag()); } /** @@ -79,53 +80,58 @@ public class AnvilChunk13 implements Chunk { * @param tag the tag to read * @throws DataException on a data error */ - public AnvilChunk13(CompoundBinaryTag tag) throws DataException { + public AnvilChunk13(LinCompoundTag tag) throws DataException { rootTag = tag; + rootX = rootTag.getTag("xPos", LinTagType.intTag()).valueAsInt(); + rootZ = rootTag.getTag("zPos", LinTagType.intTag()).valueAsInt(); + blocks = new BlockState[16][]; - ListBinaryTag sections = NbtUtils.getChildTag(rootTag, "Sections", BinaryTagTypes.LIST); + LinListTag> sections = rootTag.getTag("Sections", LinTagType.listTag()); - for (BinaryTag rawSectionTag : sections) { - if (!(rawSectionTag instanceof CompoundBinaryTag)) { + for (LinTag rawSectionTag : sections.value()) { + if (!(rawSectionTag instanceof LinCompoundTag sectionTag)) { continue; } - CompoundBinaryTag sectionTag = (CompoundBinaryTag) rawSectionTag; - if (sectionTag.get("Y") == null) { + var sectionYTag = sectionTag.findTag("Y", LinTagType.byteTag()); + if (sectionYTag == null) { continue; // Empty section. } - int y = NbtUtils.getChildTag(sectionTag, "Y", BinaryTagTypes.BYTE).value(); + int y = sectionYTag.value(); if (y < 0 || y >= 16) { continue; } // parse palette - ListBinaryTag paletteEntries = sectionTag.getList("Palette", BinaryTagTypes.COMPOUND); - int paletteSize = paletteEntries.size(); + LinListTag paletteEntries = sectionTag.getTag( + "Palette", LinTagType.listTag() + ).asTypeChecked(LinTagType.compoundTag()); + int paletteSize = paletteEntries.value().size(); if (paletteSize == 0) { continue; } BlockState[] palette = new BlockState[paletteSize]; for (int paletteEntryId = 0; paletteEntryId < paletteSize; paletteEntryId++) { - CompoundBinaryTag paletteEntry = (CompoundBinaryTag) paletteEntries.get(paletteEntryId); - BlockType type = BlockTypes.get(paletteEntry.getString("Name")); + LinCompoundTag paletteEntry = paletteEntries.get(paletteEntryId); + String blockType = paletteEntry.getTag("Name", LinTagType.stringTag()).value(); + BlockType type = BlockTypes.get(blockType); if (type == null) { - throw new InvalidFormatException("Invalid block type: " + paletteEntry.getString("Name")); + throw new InvalidFormatException("Invalid block type: " + blockType); } BlockState blockState = type.getDefaultState(); - if (paletteEntry.get("Properties") != null) { - CompoundBinaryTag properties = NbtUtils.getChildTag(paletteEntry, "Properties", BinaryTagTypes.COMPOUND); + var propertiesTag = paletteEntry.findTag("Properties", LinTagType.compoundTag()); + if (propertiesTag != null) { for (Property property : blockState.getStates().keySet()) { - if (properties.get(property.getName()) != null) { - String value = properties.getString(property.getName()); + var propertyName = propertiesTag.findTag(property.getName(), LinTagType.stringTag()); + if (propertyName != null) { + String value = propertyName.value(); try { blockState = getBlockStateWith(blockState, property, value); } catch (IllegalArgumentException e) { - throw new InvalidFormatException("Invalid block state for " + blockState - .getBlockType() - .id() + ", " + property.getName() + ": " + value); + throw new InvalidFormatException("Invalid block state for " + blockState.getBlockType().id() + ", " + property.getName() + ": " + value); } } } @@ -134,7 +140,7 @@ public class AnvilChunk13 implements Chunk { } // parse block states - long[] blockStatesSerialized = NbtUtils.getChildTag(sectionTag, "BlockStates", BinaryTagTypes.LONG_ARRAY).value(); + long[] blockStatesSerialized = sectionTag.getTag("BlockStates", LinTagType.longArrayTag()).value(); BlockState[] chunkSectionBlocks = new BlockState[16 * 16 * 16]; blocks[y] = chunkSectionBlocks; @@ -143,8 +149,7 @@ public class AnvilChunk13 implements Chunk { } } - protected void readBlockStates(BlockState[] palette, long[] blockStatesSerialized, BlockState[] chunkSectionBlocks) throws - InvalidFormatException { + protected void readBlockStates(BlockState[] palette, long[] blockStatesSerialized, BlockState[] chunkSectionBlocks) throws InvalidFormatException { int paletteBits = 4; while ((1 << paletteBits) < palette.length) { ++paletteBits; @@ -163,7 +168,7 @@ public class AnvilChunk13 implements Chunk { throw new InvalidFormatException("Too short block state table"); } currentSerializedValue = blockStatesSerialized[nextSerializedItem++]; - localBlockId |= (int) ((currentSerializedValue & ((1 << bitsNextLong) - 1)) << remainingBits); + localBlockId |= (int) (currentSerializedValue & ((1L << bitsNextLong) - 1)) << remainingBits; currentSerializedValue >>>= bitsNextLong; remainingBits = 64 - bitsNextLong; } else { @@ -185,27 +190,23 @@ public class AnvilChunk13 implements Chunk { /** * Used to load the tile entities. */ - private void populateTileEntities() throws DataException { - tileEntities = new HashMap<>(); - if (rootTag.get("TileEntities") == null) { - return; + private Map populateTileEntities() { + LinListTag tags = rootTag.findListTag( + "TileEntities", LinTagType.compoundTag() + ); + if (tags == null) { + return ImmutableMap.of(); } - ListBinaryTag tags = NbtUtils.getChildTag(rootTag, "TileEntities", BinaryTagTypes.LIST); - - for (BinaryTag tag : tags) { - if (!(tag instanceof CompoundBinaryTag)) { - throw new InvalidFormatException("CompoundTag expected in TileEntities"); - } - - CompoundBinaryTag t = (CompoundBinaryTag) tag; - - int x = ((IntBinaryTag) t.get("x")).value(); - int y = ((IntBinaryTag) t.get("y")).value(); - int z = ((IntBinaryTag) t.get("z")).value(); + var tileEntities = ImmutableMap.builderWithExpectedSize(tags.value().size()); + for (LinCompoundTag tag : tags.value()) { + int x = tag.getTag("x", LinTagType.intTag()).valueAsInt(); + int y = tag.getTag("y", LinTagType.intTag()).valueAsInt(); + int z = tag.getTag("z", LinTagType.intTag()).valueAsInt(); BlockVector3 vec = BlockVector3.at(x, y, z); - tileEntities.put(vec, t); + tileEntities.put(vec, tag); } + return tileEntities.build(); } /** @@ -215,26 +216,21 @@ public class AnvilChunk13 implements Chunk { * * @param position the position * @return the compound tag for that position, which may be null - * @throws DataException thrown if there is a data error */ @Nullable - private CompoundBinaryTag getBlockTileEntity(BlockVector3 position) throws DataException { + private LinCompoundTag getBlockTileEntity(BlockVector3 position) { if (tileEntities == null) { - populateTileEntities(); + this.tileEntities = populateTileEntities(); } - CompoundBinaryTag values = tileEntities.get(position); - - return values; + return tileEntities.get(position); } @Override public BaseBlock getBlock(BlockVector3 position) throws DataException { - //FAWE start - simplified - int x = position.x() & 15; + int x = position.x() - rootX * 16; int y = position.y(); - int z = position.z() & 15; - //FAWE end + int z = position.z() - rootZ * 16; int section = y >> 4; int yIndex = y & 0x0F; @@ -246,15 +242,10 @@ public class AnvilChunk13 implements Chunk { BlockState[] sectionBlocks = blocks[section]; BlockState state = sectionBlocks != null ? sectionBlocks[(yIndex << 8) | (z << 4) | x] : BlockTypes.AIR.getDefaultState(); - CompoundBinaryTag tileEntity = getBlockTileEntity(position); + LinCompoundTag tileEntity = getBlockTileEntity(position); - if (tileEntity != null) { - return state.toBaseBlock(tileEntity); - } - - return state.toBaseBlock(); - } - //FAWE start - biome and entity restore + return state.toBaseBlock(tileEntity); + } //FAWE start - biome and entity restore @Override public BiomeType getBiome(final BlockVector3 position) throws DataException { @@ -277,21 +268,20 @@ public class AnvilChunk13 implements Chunk { /** * Used to load the biomes. */ - private void populateEntities() throws DataException { + private void populateEntities() { entities = new ArrayList<>(); - if (rootTag.get("Entities") == null) { + LinListTag tags = rootTag.findListTag( + "Entities", LinTagType.compoundTag() + ); + if (tags == null) { return; } - ListBinaryTag tags = NbtUtils.getChildTag(rootTag, "Entities", BinaryTagTypes.LIST); - for (BinaryTag tag : tags) { - if (!(tag instanceof CompoundBinaryTag)) { - throw new InvalidFormatException("CompoundTag expected in Entities"); - } - - CompoundBinaryTag t = (CompoundBinaryTag) tag; - - entities.add(new BaseEntity(EntityTypes.get(t.getString("id")), LazyReference.computed(t))); + for (LinCompoundTag tag : tags.value()) { + entities.add(new BaseEntity( + EntityTypes.get(tag.getTag("id", LinTagType.stringTag()).value()), + LazyReference.computed(tag) + )); } } @@ -299,12 +289,13 @@ public class AnvilChunk13 implements Chunk { /** * Used to load the biomes. */ - private void populateBiomes() throws DataException { + private void populateBiomes() { biomes = new BiomeType[256]; - if (rootTag.get("Biomes") == null) { + LinIntArrayTag biomeTag = rootTag.findTag("Biomes", LinTagType.intArrayTag()); + if (biomeTag == null) { return; } - int[] stored = NbtUtils.getChildTag(rootTag, "Biomes", BinaryTagTypes.INT_ARRAY).value(); + int[] stored = biomeTag.value(); for (int i = 0; i < 256; i++) { biomes[i] = BiomeTypes.getLegacy(stored[i]); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk15.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk15.java index 60b9d9617..955a6e70a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk15.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk15.java @@ -19,14 +19,14 @@ package com.sk89q.worldedit.world.chunk; -import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.util.nbt.BinaryTagTypes; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinIntArrayTag; +import org.enginehub.linbus.tree.LinTagType; /** * The chunk format for Minecraft 1.15 and newer @@ -38,7 +38,7 @@ public class AnvilChunk15 extends AnvilChunk13 { * * @param tag the tag to read * @throws DataException on a data error - * @deprecated Use {@link #AnvilChunk15(CompoundBinaryTag)} + * @deprecated Use {@link #AnvilChunk15(LinCompoundTag)} */ @Deprecated public AnvilChunk15(CompoundTag tag) throws DataException { @@ -51,7 +51,7 @@ public class AnvilChunk15 extends AnvilChunk13 { * @param tag the tag to read * @throws DataException on a data error */ - public AnvilChunk15(CompoundBinaryTag tag) throws DataException { + public AnvilChunk15(LinCompoundTag tag) throws DataException { super(tag); } @@ -68,10 +68,11 @@ public class AnvilChunk15 extends AnvilChunk13 { private void populateBiomes() throws DataException { biomes = new BiomeType[1024]; - if (rootTag.get("Biomes") == null) { + LinIntArrayTag biomeTag = rootTag.findTag("Biomes", LinTagType.intArrayTag()); + if (biomeTag == null) { return; } - int[] stored = NbtUtils.getChildTag(rootTag, "Biomes", BinaryTagTypes.INT_ARRAY).value(); + int[] stored = biomeTag.value(); for (int i = 0; i < 1024; i++) { biomes[i] = BiomeTypes.getLegacy(stored[i]); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk16.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk16.java index 92f7f6caf..ff4c89e65 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk16.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk16.java @@ -20,10 +20,10 @@ package com.sk89q.worldedit.world.chunk; import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.storage.InvalidFormatException; +import org.enginehub.linbus.tree.LinCompoundTag; /** * The chunk format for Minecraft 1.16 and 1.17 @@ -35,7 +35,7 @@ public class AnvilChunk16 extends AnvilChunk15 { * * @param tag the tag to read * @throws DataException on a data error - * @deprecated Use {@link #AnvilChunk16(CompoundBinaryTag)} + * @deprecated Use {@link #AnvilChunk16(LinCompoundTag)} */ @Deprecated public AnvilChunk16(CompoundTag tag) throws DataException { @@ -48,7 +48,7 @@ public class AnvilChunk16 extends AnvilChunk15 { * @param tag the tag to read * @throws DataException on a data error */ - public AnvilChunk16(CompoundBinaryTag tag) throws DataException { + public AnvilChunk16(LinCompoundTag tag) throws DataException { super(tag); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java index 3789f9a79..fbddb66f0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java @@ -20,16 +20,12 @@ package com.sk89q.worldedit.world.chunk; import com.fastasyncworldedit.core.util.NbtUtils; +import com.google.common.collect.ImmutableMap; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.BinaryTagTypes; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.IntBinaryTag; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; @@ -39,10 +35,15 @@ import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.entity.EntityTypes; import com.sk89q.worldedit.world.storage.InvalidFormatException; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinIntArrayTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinStringTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; import javax.annotation.Nullable; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Supplier; @@ -52,11 +53,11 @@ import java.util.function.Supplier; */ public class AnvilChunk17 implements Chunk { - private final CompoundBinaryTag rootTag; - private final Supplier entityTagSupplier; + private final LinCompoundTag rootTag; + private final Supplier entityTagSupplier; private BiomeType[] biomes; private BlockState[][] blocks; - private Map tileEntities; + private Map tileEntities; private List entities; // initialise with default values private int minSectionPosition = 0; @@ -68,16 +69,16 @@ public class AnvilChunk17 implements Chunk { * * @param tag the tag to read * @throws DataException on a data error - * @deprecated Use {@link #AnvilChunk17(CompoundBinaryTag, Supplier)} + * @deprecated Use {@link #AnvilChunk17(LinCompoundTag, Supplier)} */ @Deprecated public AnvilChunk17(CompoundTag tag, Supplier entitiesTag) throws DataException { - this(tag.asBinaryTag(), () -> { + this(tag.toLinTag(), () -> { CompoundTag compoundTag = entitiesTag.get(); if (compoundTag == null) { return null; } - return compoundTag.asBinaryTag(); + return compoundTag.toLinTag(); }); } @@ -89,20 +90,21 @@ public class AnvilChunk17 implements Chunk { * {@link #getEntities()} is called * @throws DataException on a data error */ - public AnvilChunk17(CompoundBinaryTag tag, Supplier entityTag) throws DataException { + public AnvilChunk17(LinCompoundTag tag, Supplier entityTag) throws DataException { rootTag = tag; entityTagSupplier = entityTag; blocks = new BlockState[16][]; // initialise with default length - ListBinaryTag sections = rootTag.getList("Sections"); + LinListTag> sections = rootTag.getTag("Sections", LinTagType.listTag()); - for (BinaryTag rawSectionTag : sections) { - if (!(rawSectionTag instanceof CompoundBinaryTag sectionTag)) { + for (LinTag rawSectionTag : sections.value()) { + if (!(rawSectionTag instanceof LinCompoundTag sectionTag)) { continue; } - if (sectionTag.get("Y") == null || sectionTag.get("BlockStates") == null) { + var sectionYTag = sectionTag.findTag("Y", LinTagType.byteTag()); + if (sectionYTag == null) { continue; // Empty section. } @@ -110,30 +112,32 @@ public class AnvilChunk17 implements Chunk { updateSectionIndexRange(y); // parse palette - ListBinaryTag paletteEntries = sectionTag.getList("Palette", BinaryTagTypes.COMPOUND); - int paletteSize = paletteEntries.size(); + LinListTag paletteEntries = sectionTag.getListTag("Palette", LinTagType.compoundTag()); + int paletteSize = paletteEntries.value().size(); if (paletteSize == 0) { continue; } BlockState[] palette = new BlockState[paletteSize]; for (int paletteEntryId = 0; paletteEntryId < paletteSize; paletteEntryId++) { - CompoundBinaryTag paletteEntry = (CompoundBinaryTag) paletteEntries.get(paletteEntryId); - BlockType type = BlockTypes.get(paletteEntry.getString("Name")); + LinCompoundTag paletteEntry = (LinCompoundTag) paletteEntries.get(paletteEntryId); + BlockType type = BlockTypes.get(paletteEntry.getTag("Name", LinTagType.stringTag()).value()); if (type == null) { - throw new InvalidFormatException("Invalid block type: " + paletteEntry.getString("Name")); + throw new InvalidFormatException("Invalid block type: " + paletteEntry + .getTag("Name", LinTagType.stringTag()) + .value()); } BlockState blockState = type.getDefaultState(); - if (paletteEntry.get("Properties") != null) { - CompoundBinaryTag properties = NbtUtils.getChildTag(paletteEntry, "Properties", BinaryTagTypes.COMPOUND); + LinCompoundTag properties = paletteEntry.findTag("Properties", LinTagType.compoundTag()); + if (properties != null) { for (Property property : blockState.getStates().keySet()) { - if (properties.get(property.getName()) != null) { - String value = properties.getString(property.getName()); + LinStringTag stringTag = properties.findTag(property.getName(), LinTagType.stringTag()); + if (stringTag != null) { try { - blockState = getBlockStateWith(blockState, property, value); + blockState = getBlockStateWith(blockState, property, stringTag.value()); } catch (IllegalArgumentException e) { throw new InvalidFormatException("Invalid block state for " + blockState .getBlockType() - .id() + ", " + property.getName() + ": " + value); + .id() + ", " + property.getName() + ": " + stringTag.value()); } } } @@ -142,7 +146,7 @@ public class AnvilChunk17 implements Chunk { } // parse block states - long[] blockStatesSerialized = sectionTag.getLongArray("BlockStates"); + long[] blockStatesSerialized = sectionTag.getTag("BlockStates", LinTagType.longArrayTag()).value(); BlockState[] chunkSectionBlocks = new BlockState[4096]; blocks[y - minSectionPosition] = chunkSectionBlocks; @@ -191,27 +195,24 @@ public class AnvilChunk17 implements Chunk { /** * Used to load the tile entities. */ - private void populateTileEntities() throws DataException { - tileEntities = new HashMap<>(); - if (rootTag.get("TileEntities") == null) { + private void populateTileEntities() { + LinListTag tags = rootTag.findListTag( + "TileEntities", LinTagType.compoundTag() + ); + if (tags == null) { + tileEntities = ImmutableMap.of(); return; } - ListBinaryTag tags = rootTag.getList("TileEntities"); - - for (BinaryTag tag : tags) { - if (!(tag instanceof CompoundBinaryTag)) { - throw new InvalidFormatException("CompoundTag expected in TileEntities"); - } - - CompoundBinaryTag t = (CompoundBinaryTag) tag; - - int x = ((IntBinaryTag) t.get("x")).value(); - int y = ((IntBinaryTag) t.get("y")).value(); - int z = ((IntBinaryTag) t.get("z")).value(); + var tileEntitiesBuilder = ImmutableMap.builderWithExpectedSize(tags.value().size()); + for (LinCompoundTag tag : tags.value()) { + int x = tag.getTag("x", LinTagType.intTag()).valueAsInt(); + int y = tag.getTag("y", LinTagType.intTag()).valueAsInt(); + int z = tag.getTag("z", LinTagType.intTag()).valueAsInt(); BlockVector3 vec = BlockVector3.at(x, y, z); - tileEntities.put(vec, t); + tileEntities.put(vec, tag); } + tileEntities = tileEntitiesBuilder.build(); } /** @@ -224,7 +225,7 @@ public class AnvilChunk17 implements Chunk { * @throws DataException thrown if there is a data error */ @Nullable - private CompoundBinaryTag getBlockTileEntity(BlockVector3 position) throws DataException { + private LinCompoundTag getBlockTileEntity(BlockVector3 position) throws DataException { if (tileEntities == null) { populateTileEntities(); } @@ -248,7 +249,7 @@ public class AnvilChunk17 implements Chunk { BlockState[] sectionBlocks = blocks[section - minSectionPosition]; BlockState state = sectionBlocks != null ? sectionBlocks[(yIndex << 8) | (z << 4) | x] : BlockTypes.AIR.getDefaultState(); - CompoundBinaryTag tileEntity = getBlockTileEntity(position); + LinCompoundTag tileEntity = getBlockTileEntity(position); if (tileEntity != null) { return state.toBaseBlock(tileEntity); @@ -270,10 +271,11 @@ public class AnvilChunk17 implements Chunk { private void populateBiomes() throws DataException { biomes = new BiomeType[64 * blocks.length]; - if (rootTag.get("Biomes") == null) { + LinIntArrayTag biomeTag = rootTag.findTag("Biomes", LinTagType.intArrayTag()); + if (biomeTag == null) { return; } - int[] stored = rootTag.getIntArray("Biomes"); + int[] stored = biomeTag.value(); for (int i = 0; i < 1024; i++) { biomes[i] = BiomeTypes.getLegacy(stored[i]); } @@ -290,22 +292,21 @@ public class AnvilChunk17 implements Chunk { /** * Used to load the biomes. */ - private void populateEntities() throws DataException { + private void populateEntities() { entities = new ArrayList<>(); - CompoundBinaryTag entityTag; - if (entityTagSupplier == null || (entityTag = entityTagSupplier.get()) == null) { + LinListTag tags = rootTag.findListTag( + "Entities", LinTagType.compoundTag() + ); + if (tags == null) { return; } - ListBinaryTag tags = entityTag.getList("Entities"); - for (BinaryTag tag : tags) { - if (!(tag instanceof CompoundBinaryTag)) { - throw new InvalidFormatException("CompoundTag expected in Entities"); - } + for (LinCompoundTag tag : tags.value()) { - CompoundBinaryTag t = (CompoundBinaryTag) tag; - - entities.add(new BaseEntity(EntityTypes.get(t.getString("id")), LazyReference.computed(t))); + entities.add(new BaseEntity( + EntityTypes.get(tag.getTag("id", LinTagType.stringTag()).value()), + LazyReference.computed(tag) + )); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java index 1e36938c4..c5736bfd5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java @@ -19,134 +19,93 @@ package com.sk89q.worldedit.world.chunk; -import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.jnbt.IntTag; +import com.sk89q.jnbt.ListTag; +import com.sk89q.jnbt.LongArrayTag; +import com.sk89q.jnbt.NBTUtils; +import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.registry.state.Property; -import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.BinaryTagTypes; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; import com.sk89q.worldedit.world.DataException; -import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; -import com.sk89q.worldedit.world.entity.EntityTypes; import com.sk89q.worldedit.world.storage.InvalidFormatException; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import javax.annotation.Nullable; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Supplier; /** * The chunk format for Minecraft 1.18 and newer */ public class AnvilChunk18 implements Chunk { - //FAWE start - CBT - private final CompoundBinaryTag rootTag; - //FAWE end + private final CompoundTag rootTag; private final Int2ObjectOpenHashMap blocks; - //FAWE start - entity and biome restore - private final int sectionCount; - private final Supplier entityTagSupplier; - private Int2ObjectOpenHashMap biomes = null; - private List entities; - private Map tileEntities; - //FAWE end + private final int rootX; + private final int rootZ; + private Map>> tileEntities; /** * Construct the chunk with a compound tag. * * @param tag the tag to read * @throws DataException on a data error - * @deprecated Use {@link AnvilChunk18#AnvilChunk18(CompoundBinaryTag, Supplier)} */ - @Deprecated public AnvilChunk18(CompoundTag tag) throws DataException { - //FAWE start - CBT - this(tag.asBinaryTag(), () -> null); - } - - /** - * Construct the chunk with a compound tag. - * - * @param tag the tag to read - * @throws DataException on a data error - * @deprecated Use {@link AnvilChunk18#AnvilChunk18(CompoundBinaryTag, Supplier)} - * @since 2.1.0 - */ - @Deprecated - public AnvilChunk18(CompoundTag tag, Supplier entitiesTag) throws DataException { - //FAWE start - CBT - this(tag.asBinaryTag(), () -> { - CompoundTag compoundTag = entitiesTag.get(); - return compoundTag == null ? null : compoundTag.asBinaryTag(); - }); - } - - /** - * Construct the chunk with a compound tag. - * - * @param tag the tag to read - * @throws DataException on a data error - * @since 2.1.0 - */ - public AnvilChunk18(CompoundBinaryTag tag, Supplier entityTag) throws DataException { - //FAWE end rootTag = tag; - entityTagSupplier = entityTag; - //FAWE start - CBT - ListBinaryTag sections = rootTag.getList("sections"); - this.sectionCount = sections.size(); + rootX = NBTUtils.getChildTag(rootTag.getValue(), "xPos", IntTag.class).getValue(); + rootZ = NBTUtils.getChildTag(rootTag.getValue(), "zPos", IntTag.class).getValue(); + List sections = NBTUtils.getChildTag(rootTag.getValue(), "sections", ListTag.class).getValue(); blocks = new Int2ObjectOpenHashMap<>(sections.size()); - for (BinaryTag rawSectionTag : sections) { - if (!(rawSectionTag instanceof CompoundBinaryTag sectionTag)) { + for (Tag rawSectionTag : sections) { + if (!(rawSectionTag instanceof CompoundTag)) { continue; } - int y = NbtUtils.getInt(sectionTag, "Y"); // sometimes a byte, sometimes an int + CompoundTag sectionTag = (CompoundTag) rawSectionTag; + Object yValue = sectionTag.getValue().get("Y").getValue(); // sometimes a byte, sometimes an int + if (!(yValue instanceof Number)) { + throw new InvalidFormatException("Y is not numeric: " + yValue); + } + int y = ((Number) yValue).intValue(); - BinaryTag rawBlockStatesTag = sectionTag.get("block_states"); // null for sections outside of the world limits - if (rawBlockStatesTag instanceof CompoundBinaryTag blockStatesTag) { + Tag rawBlockStatesTag = sectionTag.getValue().get("block_states"); // null for sections outside of the world limits + if (rawBlockStatesTag instanceof CompoundTag) { + CompoundTag blockStatesTag = (CompoundTag) rawBlockStatesTag; // parse palette - ListBinaryTag paletteEntries = blockStatesTag.getList("palette"); + List paletteEntries = blockStatesTag.getList("palette", CompoundTag.class); int paletteSize = paletteEntries.size(); if (paletteSize == 0) { continue; } BlockState[] palette = new BlockState[paletteSize]; for (int paletteEntryId = 0; paletteEntryId < paletteSize; paletteEntryId++) { - CompoundBinaryTag paletteEntry = (CompoundBinaryTag) paletteEntries.get(paletteEntryId); + CompoundTag paletteEntry = paletteEntries.get(paletteEntryId); BlockType type = BlockTypes.get(paletteEntry.getString("Name")); if (type == null) { throw new InvalidFormatException("Invalid block type: " + paletteEntry.getString("Name")); } BlockState blockState = type.getDefaultState(); - BinaryTag propertiesTag = paletteEntry.get("Properties"); - if (propertiesTag instanceof CompoundBinaryTag properties) { + if (paletteEntry.containsKey("Properties")) { + CompoundTag properties = NBTUtils.getChildTag(paletteEntry.getValue(), "Properties", CompoundTag.class); for (Property property : blockState.getStates().keySet()) { - String value; - if (!(value = properties.getString(property.getName())).isEmpty()) { + if (properties.containsKey(property.getName())) { + String value = properties.getString(property.getName()); try { blockState = getBlockStateWith(blockState, property, value); } catch (IllegalArgumentException e) { - throw new InvalidFormatException("Invalid block state for " + blockState - .getBlockType() - .id() + ", " + property.getName() + ": " + value); + throw new InvalidFormatException("Invalid block state for " + blockState.getBlockType().getId() + ", " + property.getName() + ": " + value); } } } @@ -160,7 +119,7 @@ public class AnvilChunk18 implements Chunk { } // parse block states - long[] blockStatesSerialized = blockStatesTag.getLongArray("data"); + long[] blockStatesSerialized = NBTUtils.getChildTag(blockStatesTag.getValue(), "data", LongArrayTag.class).getValue(); BlockState[] chunkSectionBlocks = new BlockState[16 * 16 * 16]; blocks.put(y, chunkSectionBlocks); @@ -168,7 +127,6 @@ public class AnvilChunk18 implements Chunk { readBlockStates(palette, blockStatesSerialized, chunkSectionBlocks); } } - //FAWE end } protected void readBlockStates(BlockState[] palette, long[] blockStatesSerialized, BlockState[] chunkSectionBlocks) throws InvalidFormatException { @@ -190,24 +148,28 @@ public class AnvilChunk18 implements Chunk { * Used to load the tile entities. */ private void populateTileEntities() throws DataException { - //FAWE start - CBT tileEntities = new HashMap<>(); - if (!(rootTag.get("block_entities") instanceof ListBinaryTag tags)) { + if (!rootTag.getValue().containsKey("block_entities")) { return; } - for (BinaryTag tag : tags) { - if (!(tag instanceof CompoundBinaryTag t)) { + List tags = NBTUtils.getChildTag(rootTag.getValue(), + "block_entities", ListTag.class).getValue(); + + for (Tag tag : tags) { + if (!(tag instanceof CompoundTag)) { throw new InvalidFormatException("CompoundTag expected in block_entities"); } - int x = t.getInt("x"); - int y = t.getInt("y"); - int z = t.getInt("z"); + CompoundTag t = (CompoundTag) tag; + + Map> values = new HashMap<>(t.getValue()); + int x = ((IntTag) values.get("x")).getValue(); + int y = ((IntTag) values.get("y")).getValue(); + int z = ((IntTag) values.get("z")).getValue(); BlockVector3 vec = BlockVector3.at(x, y, z); - tileEntities.put(vec, t); + tileEntities.put(vec, values); } - //FAWE end } /** @@ -220,21 +182,24 @@ public class AnvilChunk18 implements Chunk { * @throws DataException thrown if there is a data error */ @Nullable - private CompoundBinaryTag getBlockTileEntity(BlockVector3 position) throws DataException { - //FAWE start - CBT + private CompoundTag getBlockTileEntity(BlockVector3 position) throws DataException { if (tileEntities == null) { populateTileEntities(); } - return tileEntities.get(position); - //FAWE end + Map> values = tileEntities.get(position); + if (values == null) { + return null; + } + + return new CompoundTag(values); } @Override public BaseBlock getBlock(BlockVector3 position) throws DataException { - int x = position.x() & 15; - int y = position.y(); - int z = position.z() & 15; + int x = position.getX() - rootX * 16; + int y = position.getY(); + int z = position.getZ() - rootZ * 16; int section = y >> 4; int yIndex = y & 0x0F; @@ -245,7 +210,7 @@ public class AnvilChunk18 implements Chunk { } BlockState state = sectionBlocks[sectionBlocks.length == 1 ? 0 : ((yIndex << 8) | (z << 4) | x)]; - CompoundBinaryTag tileEntity = getBlockTileEntity(position); + CompoundTag tileEntity = getBlockTileEntity(position); if (tileEntity != null) { return state.toBaseBlock(tileEntity); @@ -254,110 +219,4 @@ public class AnvilChunk18 implements Chunk { return state.toBaseBlock(); } - @Override - public BiomeType getBiome(final BlockVector3 position) throws DataException { - if (biomes == null) { - populateBiomes(); - } - int x = (position.x() & 15) >> 2; - int y = (position.y() & 15) >> 2; - int z = (position.z() & 15) >> 2; - int section = position.y() >> 4; - BiomeType[] sectionBiomes = biomes.get(section); - if (sectionBiomes.length == 1) { - return sectionBiomes[0]; - } - return biomes.get(section)[y << 4 | z << 2 | x]; - } - - private void populateBiomes() throws DataException { - biomes = new Int2ObjectOpenHashMap<>(sectionCount); - ListBinaryTag sections = rootTag.getList("sections"); - for (BinaryTag rawSectionTag : sections) { - if (!(rawSectionTag instanceof CompoundBinaryTag sectionTag)) { - continue; - } - - int y = NbtUtils.getInt(sectionTag, "Y"); // sometimes a byte, sometimes an int - - BinaryTag rawBlockStatesTag = sectionTag.get("biomes"); // null for sections outside of the world limits - if (rawBlockStatesTag instanceof CompoundBinaryTag biomeTypesTag) { - - // parse palette - ListBinaryTag paletteEntries = biomeTypesTag.getList("palette"); - int paletteSize = paletteEntries.size(); - if (paletteSize == 0) { - continue; - } - BiomeType[] palette = new BiomeType[paletteSize]; - for (int paletteEntryId = 0; paletteEntryId < paletteSize; paletteEntryId++) { - String paletteEntry = paletteEntries.getString(paletteEntryId); - BiomeType type = BiomeType.REGISTRY.get(paletteEntry); - if (type == null) { - throw new InvalidFormatException("Invalid biome type: " + paletteEntry); - } - palette[paletteEntryId] = type; - } - if (paletteSize == 1) { - // the same block everywhere - biomes.put(y, palette); - continue; - } - - // parse block states - long[] biomesSerialized = biomeTypesTag.getLongArray("data"); - if (biomesSerialized.length == 0) { - throw new InvalidFormatException("Biome data not present."); - } - - BiomeType[] chunkSectionBiomes = new BiomeType[64]; - biomes.put(y, chunkSectionBiomes); - - readBiomes(palette, biomesSerialized, chunkSectionBiomes); - } - } - } - - protected void readBiomes(BiomeType[] palette, long[] biomesSerialized, BiomeType[] chunkSectionBiomes) throws - InvalidFormatException { - PackedIntArrayReader reader = new PackedIntArrayReader(biomesSerialized, 64); - for (int biomePos = 0; biomePos < chunkSectionBiomes.length; biomePos++) { - int index = reader.get(biomePos); - if (index >= palette.length) { - throw new InvalidFormatException("Invalid biome table entry: " + index); - } - chunkSectionBiomes[biomePos] = palette[index]; - } - } - - @Override - public List getEntities() throws DataException { - if (entities == null) { - populateEntities(); - } - return entities; - } - - /** - * Used to load the biomes. - */ - private void populateEntities() throws DataException { - entities = new ArrayList<>(); - CompoundBinaryTag entityTag; - if (entityTagSupplier == null || (entityTag = entityTagSupplier.get()) == null) { - return; - } - ListBinaryTag tags = NbtUtils.getChildTag(entityTag, "Entities", BinaryTagTypes.LIST); - - for (BinaryTag tag : tags) { - if (!(tag instanceof CompoundBinaryTag t)) { - throw new InvalidFormatException("CompoundTag expected in Entities"); - } - - entities.add(new BaseEntity(EntityTypes.get(t.getString("id")), LazyReference.computed(t))); - } - - } - - } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java index 7edb163e3..783045520 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/OldChunk.java @@ -19,21 +19,19 @@ package com.sk89q.worldedit.world.chunk; -import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.util.nbt.BinaryTag; -import com.sk89q.worldedit.util.nbt.BinaryTagTypes; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.IntBinaryTag; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.registry.LegacyMapper; import com.sk89q.worldedit.world.storage.InvalidFormatException; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinTagType; import java.util.HashMap; import java.util.Map; @@ -43,24 +41,24 @@ import java.util.Map; */ public class OldChunk implements Chunk { - private final CompoundBinaryTag rootTag; + private final LinCompoundTag rootTag; private final byte[] blocks; private final byte[] data; private final int rootX; private final int rootZ; - private Map tileEntities; + private Map tileEntities; /** * Construct the chunk with a compound tag. * * @param tag the tag * @throws DataException if there is an error getting the chunk data - * @deprecated Use {@link #OldChunk(CompoundBinaryTag)} + * @deprecated Use {@link #OldChunk(LinCompoundTag)} */ @Deprecated public OldChunk(CompoundTag tag) throws DataException { - this(tag.asBinaryTag()); + this(tag.toLinTag()); } /** @@ -69,13 +67,13 @@ public class OldChunk implements Chunk { * @param tag the tag * @throws DataException if there is an error getting the chunk data */ - public OldChunk(CompoundBinaryTag tag) throws DataException { + public OldChunk(LinCompoundTag tag) throws DataException { rootTag = tag; - blocks = NbtUtils.getChildTag(rootTag, "Blocks", BinaryTagTypes.BYTE_ARRAY).value(); - data = NbtUtils.getChildTag(rootTag, "Data", BinaryTagTypes.BYTE_ARRAY).value(); - rootX = NbtUtils.getChildTag(rootTag, "xPos", BinaryTagTypes.INT).value(); - rootZ = NbtUtils.getChildTag(rootTag, "zPos", BinaryTagTypes.INT).value(); + blocks = rootTag.getTag("Blocks", LinTagType.byteArrayTag()).value(); + data = rootTag.getTag("Data", LinTagType.byteArrayTag()).value(); + rootX = rootTag.getTag("xPos", LinTagType.intTag()).value(); + rootZ = rootTag.getTag("zPos", LinTagType.intTag()).value(); int size = 16 * 16 * 128; if (blocks.length != size) { @@ -95,43 +93,39 @@ public class OldChunk implements Chunk { * @throws DataException if there is an error getting the chunk data */ private void populateTileEntities() throws DataException { - ListBinaryTag tags = NbtUtils.getChildTag(rootTag, "TileEntities", BinaryTagTypes.LIST); + LinListTag tags = rootTag.getTag("TileEntities", LinTagType.listTag()) + .asTypeChecked(LinTagType.compoundTag()); tileEntities = new HashMap<>(); - for (BinaryTag tag : tags) { - if (!(tag instanceof CompoundBinaryTag)) { - throw new InvalidFormatException("CompoundTag expected in TileEntities"); - } - - CompoundBinaryTag t = (CompoundBinaryTag) tag; - + for (LinCompoundTag t : tags.value()) { int x = 0; int y = 0; int z = 0; - CompoundBinaryTag.Builder values = CompoundBinaryTag.builder(); + LinCompoundTag.Builder values = LinCompoundTag.builder(); - for (String key : t.keySet()) { - BinaryTag value = t.get(key); + for (String key : t.value().keySet()) { + var value = t.value().get(key); switch (key) { - case "x": - if (value instanceof IntBinaryTag) { - x = ((IntBinaryTag) value).value(); + case "x" -> { + if (value instanceof LinIntTag v) { + x = v.valueAsInt(); } - break; - case "y": - if (value instanceof IntBinaryTag) { - y = ((IntBinaryTag) value).value(); + } + case "y" -> { + if (value instanceof LinIntTag v) { + y = v.valueAsInt(); } - break; - case "z": - if (value instanceof IntBinaryTag) { - z = ((IntBinaryTag) value).value(); + } + case "z" -> { + if (value instanceof LinIntTag v) { + z = v.valueAsInt(); } - break; - default: - break; + } + default -> { + // Do nothing. + } } values.put(key, value); @@ -151,13 +145,12 @@ public class OldChunk implements Chunk { * @return a tag * @throws DataException if there is an error getting the chunk data */ - private CompoundBinaryTag getBlockTileEntity(BlockVector3 position) throws DataException { + private LinCompoundTag getBlockTileEntity(BlockVector3 position) throws DataException { if (tileEntities == null) { populateTileEntities(); } - CompoundBinaryTag values = tileEntities.get(position); - return values; + return tileEntities.get(position); } @Override @@ -197,13 +190,9 @@ public class OldChunk implements Chunk { return BlockTypes.AIR.getDefaultState().toBaseBlock(); } - CompoundBinaryTag tileEntity = getBlockTileEntity(position); + LinCompoundTag tileEntity = getBlockTileEntity(position); - if (tileEntity != null) { - return state.toBaseBlock(tileEntity); - } - - return state.toBaseBlock(); + return state.toBaseBlock(tileEntity); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java index 3e3201fb6..df506c67a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRestore.java @@ -28,12 +28,15 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.chunk.Chunk; import com.sk89q.worldedit.world.storage.ChunkStore; import com.sk89q.worldedit.world.storage.MissingChunkException; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinDoubleTag; +import org.enginehub.linbus.tree.LinFloatTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinTagType; import java.io.IOException; import java.util.ArrayList; @@ -197,14 +200,14 @@ public class SnapshotRestore { if (restoreEntities) { try { for (BaseEntity entity : chunk.getEntities()) { - CompoundBinaryTag tag = entity.getNbtReference().getValue(); - ListBinaryTag pos = tag.getList("Pos"); - ListBinaryTag rotation = tag.getList("Rotation"); - double x = pos.getDouble(0); - double y = pos.getDouble(1); - double z = pos.getDouble(2); - float yRot = rotation.getFloat(0); - float xRot = rotation.getFloat(1); + LinCompoundTag tag = entity.getNbtReference().getValue(); + LinListTag pos = tag.getListTag("Pos", LinTagType.doubleTag()); + LinListTag rotation = tag.getListTag("Rotation", LinTagType.floatTag()); + double x = pos.get(0).value(); + double y = pos.get(1).value(); + double z = pos.get(2).value(); + float yRot = rotation.get(0).value(); + float xRot = rotation.get(1).value(); Location location = new Location(editSession.getWorld(), x, y, z, yRot, xRot); BlockVector3 blockVector3 = BlockVector3.at(x, y, z); if (region.contains(blockVector3) && (editSession.getMask() == null diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/experimental/SnapshotRestore.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/experimental/SnapshotRestore.java index 5f9880fc0..39d4fb07b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/experimental/SnapshotRestore.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/experimental/SnapshotRestore.java @@ -27,13 +27,15 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.util.nbt.BinaryTagTypes; -import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; -import com.sk89q.worldedit.util.nbt.ListBinaryTag; import com.sk89q.worldedit.world.DataException; import com.sk89q.worldedit.world.chunk.Chunk; import com.sk89q.worldedit.world.storage.ChunkStore; import com.sk89q.worldedit.world.storage.MissingChunkException; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinDoubleTag; +import org.enginehub.linbus.tree.LinFloatTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinTagType; import java.io.IOException; import java.util.ArrayList; @@ -193,14 +195,14 @@ public class SnapshotRestore { if (restoreEntities) { try { for (BaseEntity entity : chunk.getEntities()) { - CompoundBinaryTag tag = entity.getNbtReference().getValue(); - ListBinaryTag pos = tag.getList("Pos", BinaryTagTypes.LIST); - ListBinaryTag rotation = tag.getList("Rotation", BinaryTagTypes.LIST); - double x = pos.getDouble(0); - double y = pos.getDouble(1); - double z = pos.getDouble(2); - float yRot = rotation.getFloat(0); - float xRot = rotation.getFloat(1); + LinCompoundTag tag = entity.getNbtReference().getValue(); + LinListTag pos = tag.getListTag("Pos", LinTagType.doubleTag()); + LinListTag rotation = tag.getListTag("Rotation", LinTagType.floatTag()); + double x = pos.get(0).value(); + double y = pos.get(1).value(); + double z = pos.get(2).value(); + float yRot = rotation.get(0).value(); + float xRot = rotation.get(1).value(); Location location = new Location(editSession.getWorld(), x, y, z, yRot, xRot); editSession.createEntity(location, entity); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ChunkStoreHelper.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ChunkStoreHelper.java index 58692732f..c8788a9ce 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ChunkStoreHelper.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ChunkStoreHelper.java @@ -19,7 +19,6 @@ package com.sk89q.worldedit.world.storage; -import com.sk89q.jnbt.AdventureNBTConverter; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.Tag; @@ -54,7 +53,7 @@ public class ChunkStoreHelper { public static CompoundTag readCompoundTag(ChunkDataInputSupplier input) throws DataException, IOException { try (InputStream stream = input.openInputStream(); - NBTInputStream nbt = new NBTInputStream(stream)) { + NBTInputStream nbt = new NBTInputStream(stream)) { Tag tag = nbt.readNamedTag().getTag(); if (!(tag instanceof CompoundTag)) { throw new ChunkStoreException("CompoundTag expected for chunk; got " @@ -99,23 +98,20 @@ public class ChunkStoreHelper { if ((dataVersion > 0 || hasLevelSections(rootTag)) && dataVersion < currentDataVersion) { // only fix up MCA format, DFU doesn't support MCR chunks final DataFixer dataFixer = platform.getDataFixer(); if (dataFixer != null) { - //FAWE start - CBT - rootTag = (CompoundTag) AdventureNBTConverter.fromAdventure(dataFixer.fixUp(DataFixer.FixTypes.CHUNK, - rootTag.asBinaryTag(), dataVersion)); - //FAWE end + rootTag = new CompoundTag(dataFixer.fixUp(DataFixer.FixTypes.CHUNK, rootTag.toLinTag(), dataVersion)); dataVersion = currentDataVersion; } } if (dataVersion >= Constants.DATA_VERSION_MC_1_18) { - return new AnvilChunk18(rootTag, entitiesTag); + return new AnvilChunk18(rootTag); } - Map children = rootTag.getValue(); + Map> children = rootTag.getValue(); CompoundTag tag = null; // Find Level tag - for (Map.Entry entry : children.entrySet()) { + for (Map.Entry> entry : children.entrySet()) { if (entry.getKey().equals("Level")) { if (entry.getValue() instanceof CompoundTag) { tag = (CompoundTag) entry.getValue(); @@ -150,7 +146,7 @@ public class ChunkStoreHelper { return new AnvilChunk13(tag); } - Map tags = tag.getValue(); + Map> tags = tag.getValue(); if (tags.containsKey("Sections")) { return new AnvilChunk(tag); } @@ -159,8 +155,8 @@ public class ChunkStoreHelper { } private static boolean hasLevelSections(CompoundTag rootTag) { - Map children = rootTag.getValue(); - Tag levelTag = children.get("Level"); + Map> children = rootTag.getValue(); + Tag levelTag = children.get("Level"); if (levelTag instanceof CompoundTag) { return ((CompoundTag) levelTag).getValue().containsKey("Sections"); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/NBTConversions.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/NBTConversions.java index 8d82026ff..90d552c10 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/NBTConversions.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/NBTConversions.java @@ -22,6 +22,9 @@ package com.sk89q.worldedit.world.storage; import com.sk89q.jnbt.ListTag; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.util.Location; +import org.enginehub.linbus.tree.LinDoubleTag; +import org.enginehub.linbus.tree.LinFloatTag; +import org.enginehub.linbus.tree.LinListTag; import static com.google.common.base.Preconditions.checkNotNull; @@ -44,15 +47,41 @@ public final class NBTConversions { * @param positionTag the position tag * @param directionTag the direction tag * @return a location + * @deprecated Use {@link #toLocation(Extent, LinListTag, LinListTag)} instead. */ + @Deprecated public static Location toLocation(Extent extent, ListTag positionTag, ListTag directionTag) { checkNotNull(extent); checkNotNull(positionTag); checkNotNull(directionTag); return new Location( - extent, - positionTag.asDouble(0), positionTag.asDouble(1), positionTag.asDouble(2), - directionTag.getFloat(0), directionTag.getFloat(1) + extent, + positionTag.asDouble(0), positionTag.asDouble(1), positionTag.asDouble(2), + directionTag.getFloat(0), directionTag.getFloat(1)); + } + + /** + * Read a {@code Location} from two list tags, the first of which contains + * three numbers for the X, Y, and Z components, and the second of + * which contains two numbers, the yaw and pitch in degrees. + * + *

    For values that are unavailable, their values will be 0.

    + * + * @param extent the extent + * @param positionTag the position tag + * @param rotationTag the rotation tag + * @return a location + */ + public static Location toLocation(Extent extent, LinListTag positionTag, LinListTag rotationTag) { + int posTagSize = positionTag.value().size(); + int rotTagSize = rotationTag.value().size(); + return new Location( + extent, + posTagSize > 0 ? positionTag.get(0).valueAsDouble() : 0, + posTagSize > 1 ? positionTag.get(1).valueAsDouble() : 0, + posTagSize > 2 ? positionTag.get(2).valueAsDouble() : 0, + rotTagSize > 0 ? rotationTag.get(0).valueAsFloat() : 0, + rotTagSize > 1 ? rotationTag.get(1).valueAsFloat() : 0 ); } diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/NBTConverter.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/NBTConverter.java index cd3c5c313..0d87917d9 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/NBTConverter.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/NBTConverter.java @@ -126,7 +126,7 @@ public final class NBTConverter { public static net.minecraft.nbt.CompoundTag toNative(CompoundTag tag) { net.minecraft.nbt.CompoundTag compound = new net.minecraft.nbt.CompoundTag(); - for (Entry child : tag.getValue().entrySet()) { + for (Entry> child : tag.getValue().entrySet()) { compound.put(child.getKey(), toNative(child.getValue())); } return compound; @@ -230,7 +230,7 @@ public final class NBTConverter { public static CompoundTag fromNative(net.minecraft.nbt.CompoundTag other) { Set tags = other.getKeys(); - Map map = new HashMap<>(); + Map> map = new HashMap<>(); for (String tagName : tags) { map.put(tagName, fromNative(other.getTag(tagName))); } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/NBTConverter.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/NBTConverter.java index 9c10a6d30..82ab9ae23 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/NBTConverter.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/internal/NBTConverter.java @@ -139,7 +139,7 @@ public final class NBTConverter { public static CompoundNBT toNative(CompoundTag tag) { CompoundNBT compound = new CompoundNBT(); - for (Entry child : tag.getValue().entrySet()) { + for (Entry> child : tag.getValue().entrySet()) { compound.put(child.getKey(), toNative(child.getValue())); } return compound; @@ -243,7 +243,7 @@ public final class NBTConverter { public static CompoundTag fromNative(CompoundNBT other) { Set tags = other.keySet(); - Map map = new HashMap<>(); + Map> map = new HashMap<>(); for (String tagName : tags) { map.put(tagName, fromNative(other.get(tagName))); } diff --git a/worldedit-libs/core/build.gradle.kts b/worldedit-libs/core/build.gradle.kts index c5eb10887..cace30cd0 100644 --- a/worldedit-libs/core/build.gradle.kts +++ b/worldedit-libs/core/build.gradle.kts @@ -12,5 +12,10 @@ dependencies { "shade"(libs.piston) "shade"(libs.pistonRuntime) "shade"(libs.pistonImpl) - "shade"(libs.adventureNbt) + // Linbus + "shade"(platform(libs.linBus.bom)) + "shade"(libs.linBus.common) + "shade"(libs.linBus.stream) + "shade"(libs.linBus.tree) + "shade"(libs.linBus.format.snbt) } From fee9029bf0e90094dc5453e91add495251d4c16c Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 27 Jun 2024 15:15:14 +0200 Subject: [PATCH 180/220] Add a BiomeCategories API (#2338) (#2777) * Add a BiomeCategories API (#2338) * Add a BiomeCategories API * licenses * Use a supplier to retain the lazy-load & dynamicness of the existing system, but still retaining the inversion of control that this PR was intended to provide * Minor fawe adapter cleanup * Actually add the new files? * Fixes --------- Co-authored-by: Maddy Miller --- .../ext/fawe/v1_19_R3/PaperweightAdapter.java | 40 ++ .../PaperweightWorldNativeAccess.java | 6 + .../PaperweightFaweWorldNativeAccess.java | 6 + .../ext/fawe/v1_20_R1/PaperweightAdapter.java | 57 ++- .../PaperweightWorldNativeAccess.java | 6 + .../PaperweightFaweWorldNativeAccess.java | 6 + .../ext/fawe/v1_20_R2/PaperweightAdapter.java | 258 ++++++++---- .../fawe/v1_20_R2/PaperweightFakePlayer.java | 2 +- .../PaperweightWorldNativeAccess.java | 23 +- .../PaperweightFaweWorldNativeAccess.java | 6 + .../ext.fawe/v1_20_R3/PaperweightAdapter.java | 253 ++++++++---- .../v1_20_R3/PaperweightFakePlayer.java | 2 +- .../PaperweightWorldNativeAccess.java | 15 +- .../PaperweightFaweWorldNativeAccess.java | 6 + .../ext.fawe/v1_20_R4/PaperweightAdapter.java | 368 ++++++++++-------- .../v1_20_R4/PaperweightFakePlayer.java | 2 +- .../PaperweightWorldNativeAccess.java | 27 +- .../PaperweightFaweWorldNativeAccess.java | 6 + .../adapter/IDelegateBukkitImplAdapter.java | 21 + .../bukkit/adapter/BukkitImplAdapter.java | 43 +- .../clipboard/io/FastSchematicReader.java | 4 - .../internal/wna/WorldNativeAccess.java | 4 +- .../sk89q/worldedit/registry/Category.java | 24 +- .../world/biome/BiomeCategories.java | 112 ++++++ .../worldedit/world/biome/BiomeCategory.java | 49 +++ 25 files changed, 975 insertions(+), 371 deletions(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeCategories.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeCategory.java diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java index a5c3da0e1..5b696c8f6 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java @@ -57,6 +57,7 @@ import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.util.io.file.SafeFiles; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.RegenOptions; +import com.sk89q.worldedit.world.biome.BiomeCategory; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; import com.sk89q.worldedit.world.block.BaseBlock; @@ -67,6 +68,9 @@ import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.item.ItemType; import net.minecraft.Util; import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; +import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; @@ -292,6 +296,14 @@ public final class PaperweightAdapter implements BukkitImplAdapter biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME); + biomeRegistry.getTagNames().forEach(tagKey -> { + String key = tagKey.location().toString(); + if (BiomeCategory.REGISTRY.get(key) == null) { + BiomeCategory.REGISTRY.register(key, new BiomeCategory( + key, + () -> biomeRegistry.getTag(tagKey) + .stream() + .flatMap(HolderSet.Named::stream) + .map(Holder::value) + .map(this::adapt) + .collect(Collectors.toSet())) + ); + } + }); + } + // ------------------------------------------------------------------------ // Code that is less likely to break // ------------------------------------------------------------------------ diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java index 7923c9e69..424422ce6 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java @@ -154,6 +154,12 @@ public class PaperweightWorldNativeAccess implements WorldNativeAccess (net.minecraft.nbt.CompoundTag) fromNative(nbtData) - )); - }*/ - @Override public void sendFakeOP(Player player) { ((CraftPlayer) player).getHandle().connection.send(new ClientboundEntityEventPacket( @@ -858,7 +873,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME); + biomeRegistry.getTagNames().forEach(tagKey -> { + String key = tagKey.location().toString(); + if (BiomeCategory.REGISTRY.get(key) == null) { + BiomeCategory.REGISTRY.register(key, new BiomeCategory( + key, + () -> biomeRegistry.getTag(tagKey) + .stream() + .flatMap(HolderSet.Named::stream) + .map(Holder::value) + .map(this::adapt) + .collect(Collectors.toSet())) + ); + } + }); + } // ------------------------------------------------------------------------ // Code that is less likely to break // ------------------------------------------------------------------------ diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java index c7f3d3f3c..ffca9e50d 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java @@ -154,6 +154,12 @@ public class PaperweightWorldNativeAccess implements WorldNativeAccess> 4, z >> 4); final BlockPos blockPos = new BlockPos(x, y, z); final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - int internalId = Block.getId(blockData); - BlockState state = BlockStateIdAccess.getBlockStateById(internalId); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - - return state; + return adapt(blockData); } @Override @@ -357,8 +381,40 @@ public final class PaperweightAdapter implements BukkitImplAdapter, BiomeType> biomeTypeFromNMSCache = new HashMap<>(); @Override - public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { - return new PaperweightWorldNativeAccess(this, new WeakReference<>(((CraftWorld) world).getHandle())); + public BiomeType getBiome(Location location) { + checkNotNull(location); + + CraftWorld craftWorld = ((CraftWorld) location.getWorld()); + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + + final ServerLevel handle = craftWorld.getHandle(); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); + + return biomeTypeFromNMSCache.computeIfAbsent(chunk.getNoiseBiome(x >> 2, y >> 2, z >> 2), b -> BiomeType.REGISTRY.get(b.unwrapKey().get().location().toString())); + } + + @Override + public void setBiome(Location location, BiomeType biome) { + checkNotNull(location); + checkNotNull(biome); + + CraftWorld craftWorld = ((CraftWorld) location.getWorld()); + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + + final ServerLevel handle = craftWorld.getHandle(); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); + chunk.setBiome(x >> 2, y >> 2, z >> 2, biomeTypeToNMSCache.computeIfAbsent(biome, b -> ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolderOrThrow(ResourceKey.create(Registries.BIOME, new ResourceLocation(b.id()))))); + chunk.setUnsaved(true); + } + + @Override + public WorldNativeAccess createWorldNativeAccess(World world) { + return new PaperweightWorldNativeAccess(this, + new WeakReference<>(((CraftWorld) world).getHandle())); } private static net.minecraft.core.Direction adapt(Direction face) { @@ -381,13 +437,13 @@ public final class PaperweightAdapter implements BukkitImplAdapter stateContainer, - net.minecraft.world.level.block.state.BlockState newState, - Map, Object> states + StateDefinition stateContainer, + net.minecraft.world.level.block.state.BlockState newState, + Map, Object> states ) { for (Map.Entry, Object> state : states.entrySet()) { net.minecraft.world.level.block.state.properties.Property property = - stateContainer.getProperty(state.getKey().getName()); + stateContainer.getProperty(state.getKey().getName()); Comparable value = (Comparable) state.getValue(); // we may need to adapt this value, depending on the source prop if (property instanceof DirectionProperty) { @@ -396,16 +452,16 @@ public final class PaperweightAdapter implements BukkitImplAdapter) property) - .getValue(enumName).orElseThrow(() -> - new IllegalStateException( - "Enum property " + property.getName() + " does not contain " + enumName - ) - ); + .getValue(enumName).orElseThrow(() -> + new IllegalStateException( + "Enum property " + property.getName() + " does not contain " + enumName + ) + ); } newState = newState.setValue( - (net.minecraft.world.level.block.state.properties.Property) property, - (Comparable) value + (net.minecraft.world.level.block.state.properties.Property) property, + (Comparable) value ); } return newState; @@ -502,10 +558,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).collect(Collectors.toList())); + (List) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).toList()); } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { return new EnumProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).collect(Collectors.toList())); + (List) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).toList()); } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); } else { @@ -520,7 +576,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter> properties = new TreeMap<>(); Block block = getBlockFromType(blockType); StateDefinition blockStateList = - block.getStateDefinition(); + block.getStateDefinition(); for (net.minecraft.world.level.block.state.properties.Property state : blockStateList.getProperties()) { Property property = PROPERTY_CACHE.getUnchecked(state); properties.put(property.getName(), property); @@ -542,15 +598,15 @@ public final class PaperweightAdapter implements BukkitImplAdapter fakePlayers - = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new)); + = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new)); @Override public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) { @@ -583,7 +639,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter map = (Map) serverWorldsField.get(Bukkit.getServer()); + Map map = (Map) serverWorldsField.get(Bukkit.getServer()); map.remove("faweregentempworld"); } catch (IllegalAccessException ignored) { } @@ -712,7 +769,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter { // bail out early if a future fails if (chunkLoadings.stream().anyMatch(ftr -> - ftr.isDone() && Futures.getUnchecked(ftr) == null + ftr.isDone() && Futures.getUnchecked(ftr) == null )) { return false; } @@ -758,9 +815,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter>) - getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) - .thenApply(either -> either.left().orElse(null)) + ((CompletableFuture>) + getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) + .thenApply(either -> either.left().orElse(null)) ); } catch (IllegalAccessException | InvocationTargetException e) { throw new IllegalStateException("Couldn't load chunk for regen.", e); @@ -782,12 +839,12 @@ public final class PaperweightAdapter implements BukkitImplAdapter SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( - SideEffect.NEIGHBORS, - SideEffect.LIGHTING, - SideEffect.VALIDATION, - SideEffect.ENTITY_AI, - SideEffect.EVENTS, - SideEffect.UPDATE + SideEffect.NEIGHBORS, + SideEffect.LIGHTING, + SideEffect.VALIDATION, + SideEffect.ENTITY_AI, + SideEffect.EVENTS, + SideEffect.UPDATE ); @Override @@ -796,7 +853,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME); + biomeRegistry.getTagNames().forEach(tagKey -> { + String key = tagKey.location().toString(); + if (BiomeCategory.REGISTRY.get(key) == null) { + BiomeCategory.REGISTRY.register(key, new BiomeCategory( + key, + () -> biomeRegistry.getTag(tagKey) + .stream() + .flatMap(HolderSet.Named::stream) + .map(Holder::value) + .map(this::adapt) + .collect(Collectors.toSet())) + ); + } + }); + } + + @Override + public void sendBiomeUpdates(World world, Iterable chunks) { + ServerLevel originalWorld = ((CraftWorld) world).getHandle(); + + List nativeChunks = chunks instanceof Collection chunkCollection ? Lists.newArrayListWithCapacity(chunkCollection.size()) : Lists.newArrayList(); + for (BlockVector2 chunk : chunks) { + nativeChunks.add(originalWorld.getChunk(chunk.x(), chunk.z(), ChunkStatus.BIOMES, false)); + } + originalWorld.getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks); + } + // ------------------------------------------------------------------------ // Code that is less likely to break // ------------------------------------------------------------------------ @@ -978,7 +1074,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter> 4, z >> 4); final BlockPos blockPos = new BlockPos(x, y, z); final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - int internalId = Block.getId(blockData); - BlockState state = BlockStateIdAccess.getBlockStateById(internalId); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - - return state; + return adapt(blockData); } @Override @@ -357,7 +381,38 @@ public final class PaperweightAdapter implements BukkitImplAdapter, BiomeType> biomeTypeFromNMSCache = new HashMap<>(); @Override - public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { + public BiomeType getBiome(Location location) { + checkNotNull(location); + + CraftWorld craftWorld = ((CraftWorld) location.getWorld()); + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + + final ServerLevel handle = craftWorld.getHandle(); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); + + return biomeTypeFromNMSCache.computeIfAbsent(chunk.getNoiseBiome(x >> 2, y >> 2, z >> 2), b -> BiomeType.REGISTRY.get(b.unwrapKey().get().location().toString())); + } + + @Override + public void setBiome(Location location, BiomeType biome) { + checkNotNull(location); + checkNotNull(biome); + + CraftWorld craftWorld = ((CraftWorld) location.getWorld()); + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + + final ServerLevel handle = craftWorld.getHandle(); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); + chunk.setBiome(x >> 2, y >> 2, z >> 2, biomeTypeToNMSCache.computeIfAbsent(biome, b -> ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolderOrThrow(ResourceKey.create(Registries.BIOME, new ResourceLocation(b.id()))))); + chunk.setUnsaved(true); + } + + @Override + public WorldNativeAccess createWorldNativeAccess(World world) { return new PaperweightWorldNativeAccess(this, new WeakReference<>(((CraftWorld) world).getHandle())); } @@ -381,13 +436,13 @@ public final class PaperweightAdapter implements BukkitImplAdapter stateContainer, - net.minecraft.world.level.block.state.BlockState newState, - Map, Object> states + StateDefinition stateContainer, + net.minecraft.world.level.block.state.BlockState newState, + Map, Object> states ) { for (Map.Entry, Object> state : states.entrySet()) { net.minecraft.world.level.block.state.properties.Property property = - stateContainer.getProperty(state.getKey().getName()); + stateContainer.getProperty(state.getKey().getName()); Comparable value = (Comparable) state.getValue(); // we may need to adapt this value, depending on the source prop if (property instanceof DirectionProperty) { @@ -396,16 +451,16 @@ public final class PaperweightAdapter implements BukkitImplAdapter) property) - .getValue(enumName).orElseThrow(() -> - new IllegalStateException( - "Enum property " + property.getName() + " does not contain " + enumName - ) - ); + .getValue(enumName).orElseThrow(() -> + new IllegalStateException( + "Enum property " + property.getName() + " does not contain " + enumName + ) + ); } newState = newState.setValue( - (net.minecraft.world.level.block.state.properties.Property) property, - (Comparable) value + (net.minecraft.world.level.block.state.properties.Property) property, + (Comparable) value ); } return newState; @@ -502,10 +557,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).collect(Collectors.toList())); + (List) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).toList()); } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { return new EnumProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).collect(Collectors.toList())); + (List) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).toList()); } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); } else { @@ -520,7 +575,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter> properties = new TreeMap<>(); Block block = getBlockFromType(blockType); StateDefinition blockStateList = - block.getStateDefinition(); + block.getStateDefinition(); for (net.minecraft.world.level.block.state.properties.Property state : blockStateList.getProperties()) { Property property = PROPERTY_CACHE.getUnchecked(state); properties.put(property.getName(), property); @@ -542,15 +597,15 @@ public final class PaperweightAdapter implements BukkitImplAdapter map = (Map) serverWorldsField.get(Bukkit.getServer()); + Map map = (Map) serverWorldsField.get(Bukkit.getServer()); map.remove("faweregentempworld"); } catch (IllegalAccessException ignored) { } @@ -712,7 +768,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter { // bail out early if a future fails if (chunkLoadings.stream().anyMatch(ftr -> - ftr.isDone() && Futures.getUnchecked(ftr) == null + ftr.isDone() && Futures.getUnchecked(ftr) == null )) { return false; } @@ -758,9 +814,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter>) - getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) - .thenApply(either -> either.left().orElse(null)) + ((CompletableFuture>) + getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) + .thenApply(either -> either.left().orElse(null)) ); } catch (IllegalAccessException | InvocationTargetException e) { throw new IllegalStateException("Couldn't load chunk for regen.", e); @@ -782,12 +838,12 @@ public final class PaperweightAdapter implements BukkitImplAdapter SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( - SideEffect.NEIGHBORS, - SideEffect.LIGHTING, - SideEffect.VALIDATION, - SideEffect.ENTITY_AI, - SideEffect.EVENTS, - SideEffect.UPDATE + SideEffect.NEIGHBORS, + SideEffect.LIGHTING, + SideEffect.VALIDATION, + SideEffect.ENTITY_AI, + SideEffect.EVENTS, + SideEffect.UPDATE ); @Override @@ -796,7 +852,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME); + biomeRegistry.getTagNames().forEach(tagKey -> { + String key = tagKey.location().toString(); + if (BiomeCategory.REGISTRY.get(key) == null) { + BiomeCategory.REGISTRY.register(key, new BiomeCategory( + key, + () -> biomeRegistry.getTag(tagKey) + .stream() + .flatMap(HolderSet.Named::stream) + .map(Holder::value) + .map(this::adapt) + .collect(Collectors.toSet())) + ); + } + }); + } + + @Override + public void sendBiomeUpdates(World world, Iterable chunks) { + ServerLevel originalWorld = ((CraftWorld) world).getHandle(); + + List nativeChunks = chunks instanceof Collection chunkCollection ? Lists.newArrayListWithCapacity(chunkCollection.size()) : Lists.newArrayList(); + for (BlockVector2 chunk : chunks) { + nativeChunks.add(originalWorld.getChunk(chunk.x(), chunk.z(), ChunkStatus.BIOMES, false)); + } + originalWorld.getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks); + } + // ------------------------------------------------------------------------ // Code that is less likely to break // ------------------------------------------------------------------------ @@ -978,7 +1073,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter> 4, z >> 4); final BlockPos blockPos = new BlockPos(x, y, z); final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - int internalId = Block.getId(blockData); - BlockState state = BlockStateIdAccess.getBlockStateById(internalId); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - - return state; + return adapt(blockData); } @Override @@ -387,7 +389,38 @@ public final class PaperweightAdapter implements BukkitImplAdapter, BiomeType> biomeTypeFromNMSCache = new HashMap<>(); @Override - public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { + public BiomeType getBiome(Location location) { + checkNotNull(location); + + CraftWorld craftWorld = ((CraftWorld) location.getWorld()); + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + + final ServerLevel handle = craftWorld.getHandle(); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); + + return biomeTypeFromNMSCache.computeIfAbsent(chunk.getNoiseBiome(x >> 2, y >> 2, z >> 2), b -> BiomeType.REGISTRY.get(b.unwrapKey().get().location().toString())); + } + + @Override + public void setBiome(Location location, BiomeType biome) { + checkNotNull(location); + checkNotNull(biome); + + CraftWorld craftWorld = ((CraftWorld) location.getWorld()); + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + + final ServerLevel handle = craftWorld.getHandle(); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); + chunk.setBiome(x >> 2, y >> 2, z >> 2, biomeTypeToNMSCache.computeIfAbsent(biome, b -> ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolderOrThrow(ResourceKey.create(Registries.BIOME, new ResourceLocation(b.id()))))); + chunk.setUnsaved(true); + } + + @Override + public WorldNativeAccess createWorldNativeAccess(World world) { return new PaperweightWorldNativeAccess(this, new WeakReference<>(((CraftWorld) world).getHandle())); } @@ -411,13 +444,13 @@ public final class PaperweightAdapter implements BukkitImplAdapter stateContainer, - net.minecraft.world.level.block.state.BlockState newState, - Map, Object> states + StateDefinition stateContainer, + net.minecraft.world.level.block.state.BlockState newState, + Map, Object> states ) { for (Map.Entry, Object> state : states.entrySet()) { net.minecraft.world.level.block.state.properties.Property property = - stateContainer.getProperty(state.getKey().getName()); + stateContainer.getProperty(state.getKey().getName()); Comparable value = (Comparable) state.getValue(); // we may need to adapt this value, depending on the source prop if (property instanceof DirectionProperty) { @@ -426,16 +459,16 @@ public final class PaperweightAdapter implements BukkitImplAdapter) property) - .getValue(enumName).orElseThrow(() -> - new IllegalStateException( - "Enum property " + property.getName() + " does not contain " + enumName - ) - ); + .getValue(enumName).orElseThrow(() -> + new IllegalStateException( + "Enum property " + property.getName() + " does not contain " + enumName + ) + ); } newState = newState.setValue( - (net.minecraft.world.level.block.state.properties.Property) property, - (Comparable) value + (net.minecraft.world.level.block.state.properties.Property) property, + (Comparable) value ); } return newState; @@ -486,7 +519,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter> PROPERTY_CACHE = CacheBuilder - .newBuilder() - .build(new CacheLoader>() { - @Override - public Property load(net.minecraft.world.level.block.state.properties.Property state) throws Exception { - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else if (state instanceof DirectionProperty) { - return new DirectionalProperty( - state.getName(), - (List) state - .getPossibleValues() - .stream() - .map(e -> Direction.valueOf(((StringRepresentable) e) - .getSerializedName() - .toUpperCase(Locale.ROOT))) - .collect(Collectors.toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - return new EnumProperty( - state.getName(), - (List) state - .getPossibleValues() - .stream() - .map(e -> ((StringRepresentable) e).getSerializedName()) - .collect(Collectors.toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else { - throw new IllegalArgumentException("WorldEdit needs an update to support " + state - .getClass() - .getSimpleName()); - } - } - }); + @SuppressWarnings({ "unchecked", "rawtypes" }) + private static final LoadingCache> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader>() { + @Override + public Property load(net.minecraft.world.level.block.state.properties.Property state) throws Exception { + if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { + return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else if (state instanceof DirectionProperty) { + return new DirectionalProperty(state.getName(), + (List) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).toList()); + } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { + return new EnumProperty(state.getName(), + (List) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).toList()); + } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { + return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else { + throw new IllegalArgumentException("WorldEdit needs an update to support " + state.getClass().getSimpleName()); + } + } + }); - @SuppressWarnings({"rawtypes"}) + @SuppressWarnings({ "rawtypes" }) @Override public Map> getProperties(BlockType blockType) { Map> properties = new TreeMap<>(); Block block = getBlockFromType(blockType); StateDefinition blockStateList = - block.getStateDefinition(); + block.getStateDefinition(); for (net.minecraft.world.level.block.state.properties.Property state : blockStateList.getProperties()) { Property property = PROPERTY_CACHE.getUnchecked(state); properties.put(property.getName(), property); @@ -579,8 +594,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter fakePlayers - = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new)); + = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new)); @Override - public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) { + public boolean simulateItemUse(World world, BlockVector3 position, BaseItem item, Direction face) { CraftWorld craftWorld = (CraftWorld) world; ServerLevel worldServer = craftWorld.getHandle(); ItemStack stack = CraftItemStack.asNMSCopy(adapt( - item instanceof BaseItemStack - ? ((BaseItemStack) item) - : new BaseItemStack(item.getType(), item.getNbtReference(), 1) + item instanceof BaseItemStack + ? ((BaseItemStack) item) + : new BaseItemStack(item.getType(), item.getNbtReference(), 1) )); PaperweightFakePlayer fakePlayer; @@ -647,8 +662,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter map = (Map) serverWorldsField.get(Bukkit.getServer()); + Map map = (Map) serverWorldsField.get(Bukkit.getServer()); map.remove("faweregentempworld"); } catch (IllegalAccessException ignored) { } @@ -777,8 +781,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter> chunkLoadings = submitChunkLoadTasks(region, serverWorld); BlockableEventLoop executor; try { @@ -789,7 +792,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter { // bail out early if a future fails if (chunkLoadings.stream().anyMatch(ftr -> - ftr.isDone() && Futures.getUnchecked(ftr) == null + ftr.isDone() && Futures.getUnchecked(ftr) == null )) { return false; } @@ -835,9 +838,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter>) - getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) - .thenApply(either -> either.orElse(null)) + ((CompletableFuture>) + getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) + .thenApply(either -> either.orElse(null)) ); } catch (IllegalAccessException | InvocationTargetException e) { throw new IllegalStateException("Couldn't load chunk for regen.", e); @@ -859,12 +862,12 @@ public final class PaperweightAdapter implements BukkitImplAdapter SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( - SideEffect.NEIGHBORS, - SideEffect.LIGHTING, - SideEffect.VALIDATION, - SideEffect.ENTITY_AI, - SideEffect.EVENTS, - SideEffect.UPDATE + SideEffect.NEIGHBORS, + SideEffect.LIGHTING, + SideEffect.VALIDATION, + SideEffect.ENTITY_AI, + SideEffect.EVENTS, + SideEffect.UPDATE ); @Override @@ -873,7 +876,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME); + biomeRegistry.getTagNames().forEach(tagKey -> { + String key = tagKey.location().toString(); + if (BiomeCategory.REGISTRY.get(key) == null) { + BiomeCategory.REGISTRY.register(key, new BiomeCategory( + key, + () -> biomeRegistry.getTag(tagKey) + .stream() + .flatMap(HolderSet.Named::stream) + .map(Holder::value) + .map(this::adapt) + .collect(Collectors.toSet())) + ); + } + }); + } + + @Override + public void sendBiomeUpdates(World world, Iterable chunks) { + ServerLevel originalWorld = ((CraftWorld) world).getHandle(); + + List nativeChunks = chunks instanceof Collection chunkCollection ? Lists.newArrayListWithCapacity(chunkCollection.size()) : Lists.newArrayList(); + for (BlockVector2 chunk : chunks) { + nativeChunks.add(originalWorld.getChunk(chunk.x(), chunk.z(), ChunkStatus.BIOMES, false)); + } + originalWorld.getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks); + } + // ------------------------------------------------------------------------ // Code that is less likely to break // ------------------------------------------------------------------------ @@ -1022,7 +1064,6 @@ public final class PaperweightAdapter implements BukkitImplAdapter extends BukkitImplAdapter { return getParent().getInternalBlockStateId(state); } + @Override + default boolean clearContainerBlockContents(World world, BlockVector3 pt) { + return getParent().clearContainerBlockContents(world, pt); + } + + @Override + default void setBiome(Location location, BiomeType biome) { + getParent().setBiome(location, biome); + } + + @Override + default BiomeType getBiome(Location location) { + return getParent().getBiome(location); + } + + @Override + default void sendBiomeUpdates(World world, Iterable chunks) { + getParent().sendBiomeUpdates(world, chunks); + } + @Override default BlockMaterial getMaterial(BlockType blockType) { return getParent().getMaterial(blockType); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java index d656e874a..8fee3b417 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java @@ -35,6 +35,7 @@ import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.internal.wna.WorldNativeAccess; +import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.registry.state.Property; @@ -110,7 +111,7 @@ public interface BukkitImplAdapter extends IBukkitAdapter { BlockState getBlock(Location location); /** - * Get the block at the given location. + * Get the block with NBT data at the given location. * * @param location the location * @return the block @@ -280,6 +281,46 @@ public interface BukkitImplAdapter extends IBukkitAdapter { throw new UnsupportedOperationException("This adapter does not support clearing block contents."); } + /** + * Set the biome at a location. + * + * @param location the location + * @param biome the new biome + */ + default void setBiome(Location location, BiomeType biome) { + throw new UnsupportedOperationException("This adapter does not support custom biomes."); + } + + /** + * Gets the current biome at a location. + * + * @param location the location + * @return the biome + */ + default BiomeType getBiome(Location location) { + throw new UnsupportedOperationException("This adapter does not support custom biomes."); + } + + /** + * Initialize registries that require NMS access. + */ + default void initializeRegistries() { + + } + + /** + * Sends biome updates for the given chunks. + * + *

    This doesn't modify biomes at all, it just sends the current state of the biomes + * in the world to all of the nearby players, updating the visual representation of the + * biomes on their clients.

    + * + * @param world the world + * @param chunks a list of chunk coordinates to send biome updates for + */ + default void sendBiomeUpdates(World world, Iterable chunks) { + } + //FAWE start default BlockMaterial getMaterial(BlockType blockType) { return getMaterial(blockType.getDefaultState()); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java index b32d42c04..71d139789 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java @@ -109,26 +109,22 @@ public class FastSchematicReader extends NBTSchematicReader { if (fixer == null || dataVersion == -1) { return tag; } - //FAWE start - LinTag return (CompoundTag) LinBusConverter.fromLinBus(fixer.fixUp( DataFixer.FixTypes.BLOCK_ENTITY, tag.toLinTag(), dataVersion )); - //FAWE end } private CompoundTag fixEntity(CompoundTag tag) { if (fixer == null || dataVersion == -1) { return tag; } - //FAWE start - LinTag return (CompoundTag) LinBusConverter.fromLinBus(fixer.fixUp( DataFixer.FixTypes.ENTITY, tag.toLinTag(), dataVersion )); - //FAWE end } private String fixBiome(String biomePalettePart) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java index 56cab805f..097db6964 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/wna/WorldNativeAccess.java @@ -146,7 +146,9 @@ public interface WorldNativeAccess { void markBlockChanged(NC chunk, NP position); - void notifyNeighbors(NP pos, NBS oldState, NBS newState); + void notifyNeighbors(NP pos, NBS oldState, NBS newState);; + + void updateBlock(NP pos, NBS oldState, NBS newState); void updateNeighbors(NP pos, NBS oldState, NBS newState, int recursionLimit); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java index 92a859652..e18499c04 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java @@ -23,17 +23,25 @@ import com.fastasyncworldedit.core.registry.RegistryItem; import java.util.HashSet; import java.util.Set; +import java.util.function.Supplier; //FAWE start - implements RegistryItem public abstract class Category implements RegistryItem, Keyed { //FAWE end private final Set set = new HashSet<>(); + private final Supplier> supplier; protected final String id; private boolean empty = true; - protected Category(final String id) { + public Category(final String id) { this.id = id; + this.supplier = null; + } + + public Category(String id, Supplier> contentSupplier) { + this.id = id; + this.supplier = contentSupplier; } @Override @@ -43,7 +51,11 @@ public abstract class Category implements RegistryItem, Keyed { public final Set getAll() { if (this.empty) { - this.set.addAll(this.load()); + if (supplier != null) { + this.set.addAll(this.supplier.get()); + } else { + this.set.addAll(this.load()); + } this.empty = false; } return this.set; @@ -62,6 +74,14 @@ public abstract class Category implements RegistryItem, Keyed { return internalId; } + /** + * Loads the contents of this category from the platform. + * + * @return The loaded contents of the category + * @deprecated The load system will be removed in a future WorldEdit release. The registries should be populated by + * the platforms via the supplier constructor. + */ + @Deprecated protected abstract Set load(); //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeCategories.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeCategories.java new file mode 100644 index 000000000..ee1cca1c0 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeCategories.java @@ -0,0 +1,112 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.world.biome; + +/** + * Stores a list of common {@link BiomeCategory BiomeCategories}. + * + * @see BiomeCategory + */ +@SuppressWarnings("unused") +public final class BiomeCategories { + public static final BiomeCategory ALLOWS_SURFACE_SLIME_SPAWNS = get("minecraft:allows_surface_slime_spawns"); + public static final BiomeCategory ALLOWS_TROPICAL_FISH_SPAWNS_AT_ANY_HEIGHT = get("minecraft:allows_tropical_fish_spawns_at_any_height"); + public static final BiomeCategory HAS_CLOSER_WATER_FOG = get("minecraft:has_closer_water_fog"); + public static final BiomeCategory HAS_STRUCTURE_ANCIENT_CITY = get("minecraft:has_structure/ancient_city"); + public static final BiomeCategory HAS_STRUCTURE_BASTION_REMNANT = get("minecraft:has_structure/bastion_remnant"); + public static final BiomeCategory HAS_STRUCTURE_BURIED_TREASURE = get("minecraft:has_structure/buried_treasure"); + public static final BiomeCategory HAS_STRUCTURE_DESERT_PYRAMID = get("minecraft:has_structure/desert_pyramid"); + public static final BiomeCategory HAS_STRUCTURE_END_CITY = get("minecraft:has_structure/end_city"); + public static final BiomeCategory HAS_STRUCTURE_IGLOO = get("minecraft:has_structure/igloo"); + public static final BiomeCategory HAS_STRUCTURE_JUNGLE_TEMPLE = get("minecraft:has_structure/jungle_temple"); + public static final BiomeCategory HAS_STRUCTURE_MINESHAFT = get("minecraft:has_structure/mineshaft"); + public static final BiomeCategory HAS_STRUCTURE_MINESHAFT_MESA = get("minecraft:has_structure/mineshaft_mesa"); + public static final BiomeCategory HAS_STRUCTURE_NETHER_FORTRESS = get("minecraft:has_structure/nether_fortress"); + public static final BiomeCategory HAS_STRUCTURE_NETHER_FOSSIL = get("minecraft:has_structure/nether_fossil"); + public static final BiomeCategory HAS_STRUCTURE_OCEAN_MONUMENT = get("minecraft:has_structure/ocean_monument"); + public static final BiomeCategory HAS_STRUCTURE_OCEAN_RUIN_COLD = get("minecraft:has_structure/ocean_ruin_cold"); + public static final BiomeCategory HAS_STRUCTURE_OCEAN_RUIN_WARM = get("minecraft:has_structure/ocean_ruin_warm"); + public static final BiomeCategory HAS_STRUCTURE_PILLAGER_OUTPOST = get("minecraft:has_structure/pillager_outpost"); + public static final BiomeCategory HAS_STRUCTURE_RUINED_PORTAL_DESERT = get("minecraft:has_structure/ruined_portal_desert"); + public static final BiomeCategory HAS_STRUCTURE_RUINED_PORTAL_JUNGLE = get("minecraft:has_structure/ruined_portal_jungle"); + public static final BiomeCategory HAS_STRUCTURE_RUINED_PORTAL_MOUNTAIN = get("minecraft:has_structure/ruined_portal_mountain"); + public static final BiomeCategory HAS_STRUCTURE_RUINED_PORTAL_NETHER = get("minecraft:has_structure/ruined_portal_nether"); + public static final BiomeCategory HAS_STRUCTURE_RUINED_PORTAL_OCEAN = get("minecraft:has_structure/ruined_portal_ocean"); + public static final BiomeCategory HAS_STRUCTURE_RUINED_PORTAL_STANDARD = get("minecraft:has_structure/ruined_portal_standard"); + public static final BiomeCategory HAS_STRUCTURE_RUINED_PORTAL_SWAMP = get("minecraft:has_structure/ruined_portal_swamp"); + public static final BiomeCategory HAS_STRUCTURE_SHIPWRECK = get("minecraft:has_structure/shipwreck"); + public static final BiomeCategory HAS_STRUCTURE_SHIPWRECK_BEACHED = get("minecraft:has_structure/shipwreck_beached"); + public static final BiomeCategory HAS_STRUCTURE_STRONGHOLD = get("minecraft:has_structure/stronghold"); + public static final BiomeCategory HAS_STRUCTURE_SWAMP_HUT = get("minecraft:has_structure/swamp_hut"); + public static final BiomeCategory HAS_STRUCTURE_TRAIL_RUINS = get("minecraft:has_structure/trail_ruins"); + public static final BiomeCategory HAS_STRUCTURE_VILLAGE_DESERT = get("minecraft:has_structure/village_desert"); + public static final BiomeCategory HAS_STRUCTURE_VILLAGE_PLAINS = get("minecraft:has_structure/village_plains"); + public static final BiomeCategory HAS_STRUCTURE_VILLAGE_SAVANNA = get("minecraft:has_structure/village_savanna"); + public static final BiomeCategory HAS_STRUCTURE_VILLAGE_SNOWY = get("minecraft:has_structure/village_snowy"); + public static final BiomeCategory HAS_STRUCTURE_VILLAGE_TAIGA = get("minecraft:has_structure/village_taiga"); + public static final BiomeCategory HAS_STRUCTURE_WOODLAND_MANSION = get("minecraft:has_structure/woodland_mansion"); + public static final BiomeCategory INCREASED_FIRE_BURNOUT = get("minecraft:increased_fire_burnout"); + public static final BiomeCategory IS_BADLANDS = get("minecraft:is_badlands"); + public static final BiomeCategory IS_BEACH = get("minecraft:is_beach"); + public static final BiomeCategory IS_DEEP_OCEAN = get("minecraft:is_deep_ocean"); + public static final BiomeCategory IS_END = get("minecraft:is_end"); + public static final BiomeCategory IS_FOREST = get("minecraft:is_forest"); + public static final BiomeCategory IS_HILL = get("minecraft:is_hill"); + public static final BiomeCategory IS_JUNGLE = get("minecraft:is_jungle"); + public static final BiomeCategory IS_MOUNTAIN = get("minecraft:is_mountain"); + public static final BiomeCategory IS_NETHER = get("minecraft:is_nether"); + public static final BiomeCategory IS_OCEAN = get("minecraft:is_ocean"); + public static final BiomeCategory IS_OVERWORLD = get("minecraft:is_overworld"); + public static final BiomeCategory IS_RIVER = get("minecraft:is_river"); + public static final BiomeCategory IS_SAVANNA = get("minecraft:is_savanna"); + public static final BiomeCategory IS_TAIGA = get("minecraft:is_taiga"); + public static final BiomeCategory MINESHAFT_BLOCKING = get("minecraft:mineshaft_blocking"); + public static final BiomeCategory MORE_FREQUENT_DROWNED_SPAWNS = get("minecraft:more_frequent_drowned_spawns"); + public static final BiomeCategory PLAYS_UNDERWATER_MUSIC = get("minecraft:plays_underwater_music"); + public static final BiomeCategory POLAR_BEARS_SPAWN_ON_ALTERNATE_BLOCKS = get("minecraft:polar_bears_spawn_on_alternate_blocks"); + public static final BiomeCategory PRODUCES_CORALS_FROM_BONEMEAL = get("minecraft:produces_corals_from_bonemeal"); + public static final BiomeCategory REDUCE_WATER_AMBIENT_SPAWNS = get("minecraft:reduce_water_ambient_spawns"); + public static final BiomeCategory REQUIRED_OCEAN_MONUMENT_SURROUNDING = get("minecraft:required_ocean_monument_surrounding"); + public static final BiomeCategory SNOW_GOLEM_MELTS = get("minecraft:snow_golem_melts"); + public static final BiomeCategory SPAWNS_COLD_VARIANT_FROGS = get("minecraft:spawns_cold_variant_frogs"); + public static final BiomeCategory SPAWNS_GOLD_RABBITS = get("minecraft:spawns_gold_rabbits"); + public static final BiomeCategory SPAWNS_SNOW_FOXES = get("minecraft:spawns_snow_foxes"); + public static final BiomeCategory SPAWNS_WARM_VARIANT_FROGS = get("minecraft:spawns_warm_variant_frogs"); + public static final BiomeCategory SPAWNS_WHITE_RABBITS = get("minecraft:spawns_white_rabbits"); + public static final BiomeCategory STRONGHOLD_BIASED_TO = get("minecraft:stronghold_biased_to"); + public static final BiomeCategory WATER_ON_MAP_OUTLINES = get("minecraft:water_on_map_outlines"); + public static final BiomeCategory WITHOUT_PATROL_SPAWNS = get("minecraft:without_patrol_spawns"); + public static final BiomeCategory WITHOUT_WANDERING_TRADER_SPAWNS = get("minecraft:without_wandering_trader_spawns"); + public static final BiomeCategory WITHOUT_ZOMBIE_SIEGES = get("minecraft:without_zombie_sieges"); + + private BiomeCategories() { + } + + /** + * Gets the {@link BiomeCategory} associated with the given id. + */ + public static BiomeCategory get(String id) { + BiomeCategory entry = BiomeCategory.REGISTRY.get(id); + if (entry == null) { + return new BiomeCategory(id); + } + return entry; + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeCategory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeCategory.java new file mode 100644 index 000000000..a51a86823 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeCategory.java @@ -0,0 +1,49 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.world.biome; + +import com.sk89q.worldedit.registry.Category; +import com.sk89q.worldedit.registry.Keyed; +import com.sk89q.worldedit.registry.NamespacedRegistry; + +import java.util.Set; +import java.util.function.Supplier; + +/** + * A category of biomes. + */ +public class BiomeCategory extends Category implements Keyed { + + public static final NamespacedRegistry REGISTRY = new NamespacedRegistry<>("biome tag", true); + + public BiomeCategory(final String id) { + super(id); + } + + public BiomeCategory(final String id, final Supplier> contentSupplier) { + super(id, contentSupplier); + } + + @Override + protected Set load() { + return Set.of(); + } + +} From 99a58f66cd95a1f4edffed60731f7f37b1b54d7d Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Thu, 27 Jun 2024 14:59:32 +0100 Subject: [PATCH 181/220] Fix property loading --- .../ext/fawe/v1_19_R3/PaperweightAdapter.java | 54 ++++++++++++------ .../ext/fawe/v1_20_R1/PaperweightAdapter.java | 54 ++++++++++++------ .../ext/fawe/v1_20_R2/PaperweightAdapter.java | 54 ++++++++++++------ .../ext.fawe/v1_20_R3/PaperweightAdapter.java | 54 ++++++++++++------ .../ext.fawe/v1_20_R4/PaperweightAdapter.java | 56 ++++++++++++------- 5 files changed, 181 insertions(+), 91 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java index 5b696c8f6..87135fa86 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java @@ -507,24 +507,42 @@ public final class PaperweightAdapter implements BukkitImplAdapter> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader>() { - @Override - public Property load(net.minecraft.world.level.block.state.properties.Property state) throws Exception { - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else if (state instanceof DirectionProperty) { - return new DirectionalProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).collect(Collectors.toList())); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - return new EnumProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).collect(Collectors.toList())); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else { - throw new IllegalArgumentException("WorldEdit needs an update to support " + state.getClass().getSimpleName()); - } - } - }); + private static final LoadingCache> PROPERTY_CACHE = CacheBuilder + .newBuilder() + .build(new CacheLoader<>() { + @Override + public Property load(net.minecraft.world.level.block.state.properties.Property state) { + if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { + return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else if (state instanceof DirectionProperty) { + return new DirectionalProperty( + state.getName(), + new ArrayList<>((List) state + .getPossibleValues() + .stream() + .map(e -> Direction.valueOf(((StringRepresentable) e) + .getSerializedName() + .toUpperCase(Locale.ROOT))) + .toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { + return new EnumProperty( + state.getName(), + new ArrayList<>((List) state + .getPossibleValues() + .stream() + .map(e -> ((StringRepresentable) e).getSerializedName()) + .toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { + return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else { + throw new IllegalArgumentException("WorldEdit needs an update to support " + state + .getClass() + .getSimpleName()); + } + } + }); @SuppressWarnings({ "rawtypes" }) @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java index 233212aef..0cecbb45b 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java @@ -561,24 +561,42 @@ public final class PaperweightAdapter implements BukkitImplAdapter> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader>() { - @Override - public Property load(net.minecraft.world.level.block.state.properties.Property state) throws Exception { - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else if (state instanceof DirectionProperty) { - return new DirectionalProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).collect(Collectors.toList())); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - return new EnumProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).collect(Collectors.toList())); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else { - throw new IllegalArgumentException("WorldEdit needs an update to support " + state.getClass().getSimpleName()); - } - } - }); + private static final LoadingCache> PROPERTY_CACHE = CacheBuilder + .newBuilder() + .build(new CacheLoader<>() { + @Override + public Property load(net.minecraft.world.level.block.state.properties.Property state) { + if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { + return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else if (state instanceof DirectionProperty) { + return new DirectionalProperty( + state.getName(), + new ArrayList<>((List) state + .getPossibleValues() + .stream() + .map(e -> Direction.valueOf(((StringRepresentable) e) + .getSerializedName() + .toUpperCase(Locale.ROOT))) + .toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { + return new EnumProperty( + state.getName(), + new ArrayList<>((List) state + .getPossibleValues() + .stream() + .map(e -> ((StringRepresentable) e).getSerializedName()) + .toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { + return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else { + throw new IllegalArgumentException("WorldEdit needs an update to support " + state + .getClass() + .getSimpleName()); + } + } + }); @SuppressWarnings({ "rawtypes" }) @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java index 19f9aa596..9aaeb7bc2 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java @@ -551,24 +551,42 @@ public final class PaperweightAdapter implements BukkitImplAdapter> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader>() { - @Override - public Property load(net.minecraft.world.level.block.state.properties.Property state) throws Exception { - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else if (state instanceof DirectionProperty) { - return new DirectionalProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).toList()); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - return new EnumProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).toList()); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else { - throw new IllegalArgumentException("WorldEdit needs an update to support " + state.getClass().getSimpleName()); - } - } - }); + private static final LoadingCache> PROPERTY_CACHE = CacheBuilder + .newBuilder() + .build(new CacheLoader<>() { + @Override + public Property load(net.minecraft.world.level.block.state.properties.Property state) { + if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { + return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else if (state instanceof DirectionProperty) { + return new DirectionalProperty( + state.getName(), + new ArrayList<>((List) state + .getPossibleValues() + .stream() + .map(e -> Direction.valueOf(((StringRepresentable) e) + .getSerializedName() + .toUpperCase(Locale.ROOT))) + .toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { + return new EnumProperty( + state.getName(), + new ArrayList<>((List) state + .getPossibleValues() + .stream() + .map(e -> ((StringRepresentable) e).getSerializedName()) + .toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { + return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else { + throw new IllegalArgumentException("WorldEdit needs an update to support " + state + .getClass() + .getSimpleName()); + } + } + }); @SuppressWarnings({ "rawtypes" }) @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java index 571fc61cc..ded4bcfdd 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java @@ -550,24 +550,42 @@ public final class PaperweightAdapter implements BukkitImplAdapter> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader>() { - @Override - public Property load(net.minecraft.world.level.block.state.properties.Property state) throws Exception { - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else if (state instanceof DirectionProperty) { - return new DirectionalProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).toList()); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - return new EnumProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).toList()); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else { - throw new IllegalArgumentException("WorldEdit needs an update to support " + state.getClass().getSimpleName()); - } - } - }); + private static final LoadingCache> PROPERTY_CACHE = CacheBuilder + .newBuilder() + .build(new CacheLoader<>() { + @Override + public Property load(net.minecraft.world.level.block.state.properties.Property state) { + if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { + return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else if (state instanceof DirectionProperty) { + return new DirectionalProperty( + state.getName(), + new ArrayList<>((List) state + .getPossibleValues() + .stream() + .map(e -> Direction.valueOf(((StringRepresentable) e) + .getSerializedName() + .toUpperCase(Locale.ROOT))) + .toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { + return new EnumProperty( + state.getName(), + new ArrayList<>((List) state + .getPossibleValues() + .stream() + .map(e -> ((StringRepresentable) e).getSerializedName()) + .toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { + return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else { + throw new IllegalArgumentException("WorldEdit needs an update to support " + state + .getClass() + .getSimpleName()); + } + } + }); @SuppressWarnings({ "rawtypes" }) @Override diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java index 89acd6847..206ade66a 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java @@ -557,25 +557,43 @@ public final class PaperweightAdapter implements BukkitImplAdapter> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader>() { - @Override - public Property load(net.minecraft.world.level.block.state.properties.Property state) throws Exception { - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else if (state instanceof DirectionProperty) { - return new DirectionalProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).toList()); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - return new EnumProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).toList()); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else { - throw new IllegalArgumentException("WorldEdit needs an update to support " + state.getClass().getSimpleName()); - } - } - }); + @SuppressWarnings({"unchecked", "rawtypes"}) + private static final LoadingCache> PROPERTY_CACHE = CacheBuilder + .newBuilder() + .build(new CacheLoader<>() { + @Override + public Property load(net.minecraft.world.level.block.state.properties.Property state) { + if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { + return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else if (state instanceof DirectionProperty) { + return new DirectionalProperty( + state.getName(), + new ArrayList<>((List) state + .getPossibleValues() + .stream() + .map(e -> Direction.valueOf(((StringRepresentable) e) + .getSerializedName() + .toUpperCase(Locale.ROOT))) + .toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { + return new EnumProperty( + state.getName(), + new ArrayList<>((List) state + .getPossibleValues() + .stream() + .map(e -> ((StringRepresentable) e).getSerializedName()) + .toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { + return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else { + throw new IllegalArgumentException("WorldEdit needs an update to support " + state + .getClass() + .getSimpleName()); + } + } + }); @SuppressWarnings({ "rawtypes" }) @Override From 4853a65e7c5159eeade483f8b5403e951e10ce19 Mon Sep 17 00:00:00 2001 From: Jordan Date: Fri, 28 Jun 2024 21:46:30 +0200 Subject: [PATCH 182/220] feat: implement graceful world bounds check where appropriate (#2804) - closes #2494 --- .../exception/OutsideWorldBoundsException.java | 17 +++++++++++++++++ .../java/com/sk89q/worldedit/WorldEdit.java | 16 ++++++++++++++++ .../worldedit/command/UtilityCommands.java | 14 +++++++++++--- .../exception/WorldEditExceptionConverter.java | 6 ++++++ .../src/main/resources/lang/strings.json | 1 + 5 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/OutsideWorldBoundsException.java diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/OutsideWorldBoundsException.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/OutsideWorldBoundsException.java new file mode 100644 index 000000000..73d871135 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/exception/OutsideWorldBoundsException.java @@ -0,0 +1,17 @@ +package com.fastasyncworldedit.core.exception; + +import com.sk89q.worldedit.WorldEditException; + +public class OutsideWorldBoundsException extends WorldEditException { + + private final int y; + + public OutsideWorldBoundsException(int y) { + this.y = y; + } + + public int y() { + return y; + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java index be4c9af8c..402310def 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit; import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.exception.BrushRadiusLimitException; +import com.fastasyncworldedit.core.exception.OutsideWorldBoundsException; import com.fastasyncworldedit.core.exception.RadiusLimitException; import com.fastasyncworldedit.core.extension.factory.TransformFactory; import com.fastasyncworldedit.core.extent.ResettableExtent; @@ -46,6 +47,7 @@ import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.Locatable; import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.PlatformManager; +import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.pattern.Pattern; @@ -523,6 +525,20 @@ public final class WorldEdit { throw new BrushRadiusLimitException(max); } } + + /** + * Check if the given position is contained by the extent's min/max height + * + * @param position Position to check + * @param extent Extent to check in + * @throws OutsideWorldBoundsException If the position is outside the world height limits + * @since TODO + */ + public void checkExtentHeightBounds(BlockVector3 position, Extent extent) { + if (position.y() < extent.getMinY() || position.y() > extent.getMaxY()) { + throw new OutsideWorldBoundsException(position.y()); + } + } //FAWE end /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index a289f7cff..c81db21d8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -242,6 +242,7 @@ public class UtilityCommands { we.checkMaxRadius(depth, actor); BlockVector3 pos = session.getPlacementPosition(actor); + we.checkExtentHeightBounds(pos, editSession); int affected = editSession.fillDirection(pos, pattern, radius, depth, direction); actor.print(Caption.of("worldedit.fill.created", TextComponent.of(affected))); return affected; @@ -330,6 +331,7 @@ public class UtilityCommands { we.checkMaxRadius(radius, actor); BlockVector3 pos = session.getPlacementPosition(actor); + we.checkExtentHeightBounds(pos, editSession); int affected = editSession.fillXZ(pos, pattern, radius, depth, true); actor.print(Caption.of("worldedit.fillr.created", TextComponent.of(affected))); return affected; @@ -357,7 +359,9 @@ public class UtilityCommands { double radius = radiusExp.evaluate(); radius = Math.max(0, radius); we.checkMaxRadius(radius, actor); - int affected = editSession.drainArea(session.getPlacementPosition(actor), radius, waterlogged, plants); + BlockVector3 pos = session.getPlacementPosition(actor); + we.checkExtentHeightBounds(pos, editSession); + int affected = editSession.drainArea(pos, radius, waterlogged, plants); actor.print(Caption.of("worldedit.drain.drained", TextComponent.of(affected))); return affected; } @@ -376,7 +380,9 @@ public class UtilityCommands { ) throws WorldEditException { radius = Math.max(0, radius); we.checkMaxRadius(radius, actor); - int affected = editSession.fixLiquid(session.getPlacementPosition(actor), radius, BlockTypes.LAVA); + BlockVector3 pos = session.getPlacementPosition(actor); + we.checkExtentHeightBounds(pos, editSession); + int affected = editSession.fixLiquid(pos, radius, BlockTypes.LAVA); actor.print(Caption.of("worldedit.fixlava.fixed", TextComponent.of(affected))); return affected; } @@ -395,7 +401,9 @@ public class UtilityCommands { ) throws WorldEditException { radius = Math.max(0, radius); we.checkMaxRadius(radius, actor); - int affected = editSession.fixLiquid(session.getPlacementPosition(actor), radius, BlockTypes.WATER); + BlockVector3 pos = session.getPlacementPosition(actor); + we.checkExtentHeightBounds(pos, editSession); + int affected = editSession.fixLiquid(pos, radius, BlockTypes.WATER); actor.print(Caption.of("worldedit.fixwater.fixed", TextComponent.of(affected))); return affected; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java index b07f3f61d..b3b3b5df8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/command/exception/WorldEditExceptionConverter.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit.internal.command.exception; import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.exception.BrushRadiusLimitException; +import com.fastasyncworldedit.core.exception.OutsideWorldBoundsException; import com.fastasyncworldedit.core.exception.RadiusLimitException; import com.fastasyncworldedit.core.internal.exception.FaweException; import com.google.common.collect.ImmutableList; @@ -146,6 +147,11 @@ public class WorldEditExceptionConverter extends ExceptionConverterHelper { public void convert(RadiusLimitException e) throws CommandException { throw newCommandException(Caption.of("fawe.error.limit.max-radius", TextComponent.of(e.getMaxRadius())), e); } + + @ExceptionMatch + public void convert(OutsideWorldBoundsException e) throws CommandException { + throw newCommandException(Caption.of("fawe.cancel.reason.world.limit", TextComponent.of(e.y())), e); + } //FAWE end @ExceptionMatch diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index a8dddbdcf..16e10a00d 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -164,6 +164,7 @@ "fawe.cancel.reason.no.region.not.added": "Not added to region", "fawe.cancel.reason.player-only": "This operation requires a player, and cannot be executed from console, or without an actor.", "fawe.cancel.reason.actor-required": "This operation requires an actor.", + "fawe.cancel.reason.world.limit": "This operation cannot be performed at y={0} as it is outside world limits.", "fawe.cancel.worldedit.failed.load.chunk": "Skipped loading chunk: {0};{1}. Try increasing chunk-wait.", "fawe.navigation.no.block": "No block in sight! (or too far)", "fawe.selection.sel.max": "{0} points maximum.", From ff04c93b48c5ab4130b44f47fade13c954bf6668 Mon Sep 17 00:00:00 2001 From: Jordan Date: Fri, 28 Jun 2024 21:46:51 +0200 Subject: [PATCH 183/220] feat: add option to prevent parsing legacy blocks to the FaweLimit (#2783) - Closes #951 --- .../core/command/tool/scroll/Scroll.java | 1 + .../core/configuration/Settings.java | 5 ++++ .../factory/parser/mask/RichMaskParser.java | 2 +- .../platform/binding/ConsumeBindings.java | 1 + .../core/function/mask/BlockMaskBuilder.java | 26 +++++++++++++++++-- .../core/limit/FaweLimit.java | 6 ++++- .../worldedit/command/GeneralCommands.java | 1 + .../command/argument/FactoryConverter.java | 1 + .../factory/parser/mask/BlocksMaskParser.java | 1 + .../scripting/CraftScriptContext.java | 3 +++ 10 files changed, 43 insertions(+), 4 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/scroll/Scroll.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/scroll/Scroll.java index dd7c23984..8e34d3996 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/scroll/Scroll.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/scroll/Scroll.java @@ -51,6 +51,7 @@ public abstract class Scroll implements ScrollTool { parserContext.setActor(player); parserContext.setWorld(player.getWorld()); parserContext.setSession(session); + parserContext.setTryLegacy(player.getLimit().ALLOW_LEGACY); switch (mode) { case CLIPBOARD: if (arguments.size() != 2) { 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 5a10ad344..3b80dcdfa 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 @@ -191,6 +191,7 @@ public class Settings extends Config { } } limit.UNIVERSAL_DISALLOWED_BLOCKS &= newLimit.UNIVERSAL_DISALLOWED_BLOCKS; + limit.ALLOW_LEGACY &= newLimit.ALLOW_LEGACY; if (limit.DISALLOWED_BLOCKS == null) { limit.DISALLOWED_BLOCKS = newLimit.DISALLOWED_BLOCKS.isEmpty() ? Collections.emptySet() : new HashSet<>( @@ -439,6 +440,10 @@ public class Settings extends Config { " - If fast-placement is disabled, this may cause edits to be slower." }) public boolean UNIVERSAL_DISALLOWED_BLOCKS = true; + @Comment({ + "If legacy, mumerical, blocks IDs should be able to be used (i.e. 12:2)," + }) + public boolean ALLOW_LEGACY = true; @Comment({ "List of blocks to deny use of. Can be either an entire block type or a block with a specific property value.", "Where block properties are specified, any blockstate with the property will be disallowed (e.g. all directions", diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/RichMaskParser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/RichMaskParser.java index 84437c19a..1b6640ecd 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/RichMaskParser.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/RichMaskParser.java @@ -143,7 +143,7 @@ public class RichMaskParser extends FaweParser { int end = command.lastIndexOf(']'); mask = parseFromInput(command.substring(1, end == -1 ? command.length() : end), context); } else { - BlockMaskBuilder builder = new BlockMaskBuilder(); + BlockMaskBuilder builder = new BlockMaskBuilder(context); try { builder.addRegex(full); } catch (InputParseException ignored) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/platform/binding/ConsumeBindings.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/platform/binding/ConsumeBindings.java index c1997bb0d..615f1a586 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/platform/binding/ConsumeBindings.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/platform/binding/ConsumeBindings.java @@ -200,6 +200,7 @@ public class ConsumeBindings extends Bindings { public BaseBlock baseBlock(Actor actor, String argument) { ParserContext parserContext = new ParserContext(); parserContext.setActor(actor); + parserContext.setTryLegacy(actor.getLimit().ALLOW_LEGACY); if (actor instanceof Entity) { Extent extent = ((Entity) actor).getExtent(); if (extent instanceof World) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java index baef7f767..33ea8e3f7 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java @@ -9,6 +9,7 @@ import com.fastasyncworldedit.core.util.MutableCharSequence; import com.fastasyncworldedit.core.util.StringMan; import com.fastasyncworldedit.core.world.block.BlanketBaseBlock; import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.mask.BlockMask; import com.sk89q.worldedit.registry.state.AbstractProperty; @@ -53,6 +54,7 @@ public class BlockMaskBuilder { private static final long[] ALL = new long[0]; private final long[][] bitSets; + private final ParserContext context; private boolean[] ordinals; private boolean optimizedStates = true; @@ -60,8 +62,28 @@ public class BlockMaskBuilder { this(new long[BlockTypes.size()][]); } + /** + * Create a new instance with a given {@link ParserContext} to use if parsing regex + * + * @since TODO + */ + public BlockMaskBuilder(ParserContext context) { + this(new long[BlockTypes.size()][], context); + } + protected BlockMaskBuilder(long[][] bitSets) { this.bitSets = bitSets; + this.context = new ParserContext(); + } + + /** + * Create a new instance with a given {@link ParserContext} to use if parsing regex + * + * @since TODO + */ + protected BlockMaskBuilder(long[][] bitSets, ParserContext context) { + this.bitSets = bitSets; + this.context = context; } private boolean handleRegex(BlockType blockType, PropertyKey key, String regex, FuzzyStateAllowingBuilder builder) { @@ -173,7 +195,7 @@ public class BlockMaskBuilder { List blockTypeList; List builders; if (StringMan.isAlphanumericUnd(charSequence)) { - BlockType type = BlockTypes.parse(charSequence.toString()); + BlockType type = BlockTypes.parse(charSequence.toString(), context); blockTypeList = Collections.singletonList(type); builders = Collections.singletonList(new FuzzyStateAllowingBuilder(type)); add(type); @@ -280,7 +302,7 @@ public class BlockMaskBuilder { } } else { if (StringMan.isAlphanumericUnd(input)) { - add(BlockTypes.parse(input)); + add(BlockTypes.parse(input, context)); } else { boolean success = false; for (BlockType myType : BlockTypesCache.values) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java index e30ee4db6..d17787f03 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java @@ -28,6 +28,7 @@ public class FaweLimit { public boolean FAST_PLACEMENT = false; public boolean CONFIRM_LARGE = true; public boolean RESTRICT_HISTORY_TO_REGIONS = true; + public boolean ALLOW_LEGACY = true; public Set STRIP_NBT = null; public boolean UNIVERSAL_DISALLOWED_BLOCKS = true; public Set DISALLOWED_BLOCKS = null; @@ -127,6 +128,7 @@ public class FaweLimit { MAX.RESTRICT_HISTORY_TO_REGIONS = false; MAX.STRIP_NBT = Collections.emptySet(); MAX.UNIVERSAL_DISALLOWED_BLOCKS = false; + MAX.ALLOW_LEGACY = true; MAX.DISALLOWED_BLOCKS = Collections.emptySet(); MAX.REMAP_PROPERTIES = Collections.emptySet(); MAX.MAX_RADIUS = Integer.MAX_VALUE; @@ -259,13 +261,13 @@ public class FaweLimit { && !RESTRICT_HISTORY_TO_REGIONS && (STRIP_NBT == null || STRIP_NBT.isEmpty()) // && !UNIVERSAL_DISALLOWED_BLOCKS --> do not include this, it effectively has no relevance + && ALLOW_LEGACY && (DISALLOWED_BLOCKS == null || DISALLOWED_BLOCKS.isEmpty()) && (REMAP_PROPERTIES == null || REMAP_PROPERTIES.isEmpty()) && MAX_RADIUS == Integer.MAX_VALUE && MAX_SUPER_PICKAXE_SIZE == Integer.MAX_VALUE && MAX_BRUSH_RADIUS == Integer.MAX_VALUE && MAX_BUTCHER_RADIUS == Integer.MAX_VALUE; - } public void set(FaweLimit limit) { @@ -286,6 +288,7 @@ public class FaweLimit { RESTRICT_HISTORY_TO_REGIONS = limit.RESTRICT_HISTORY_TO_REGIONS; STRIP_NBT = limit.STRIP_NBT; UNIVERSAL_DISALLOWED_BLOCKS = limit.UNIVERSAL_DISALLOWED_BLOCKS; + ALLOW_LEGACY = limit.ALLOW_LEGACY; DISALLOWED_BLOCKS = limit.DISALLOWED_BLOCKS; REMAP_PROPERTIES = limit.REMAP_PROPERTIES; MAX_RADIUS = limit.MAX_RADIUS; @@ -313,6 +316,7 @@ public class FaweLimit { limit.RESTRICT_HISTORY_TO_REGIONS = RESTRICT_HISTORY_TO_REGIONS; limit.STRIP_NBT = STRIP_NBT; limit.UNIVERSAL_DISALLOWED_BLOCKS = UNIVERSAL_DISALLOWED_BLOCKS; + limit.ALLOW_LEGACY = ALLOW_LEGACY; limit.DISALLOWED_BLOCKS = DISALLOWED_BLOCKS; limit.REMAP_PROPERTIES = REMAP_PROPERTIES; limit.MAX_RADIUS = MAX_RADIUS; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java index 3b271a1ec..865e6f937 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java @@ -510,6 +510,7 @@ public class GeneralCommands { parserContext.setWorld(worldArg); parserContext.setSession(session); parserContext.setExtent(editSession); + parserContext.setTryLegacy(actor.getLimit().ALLOW_LEGACY); Mask mask = worldEdit.getMaskFactory().parseFromInput(arg, parserContext); util = TextureUtil.fromMask(mask); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/FactoryConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/FactoryConverter.java index d82d25394..d3189f1f1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/FactoryConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/FactoryConverter.java @@ -133,6 +133,7 @@ public class FactoryConverter implements ArgumentConverter { parserContext.setSession(session); parserContext.setRestricted(true); parserContext.setInjected(context); + parserContext.setTryLegacy(actor.getLimit().ALLOW_LEGACY); if (contextTweaker != null) { contextTweaker.accept(parserContext); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlocksMaskParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlocksMaskParser.java index de6eea718..ac94b12d4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlocksMaskParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/mask/BlocksMaskParser.java @@ -49,6 +49,7 @@ public class BlocksMaskParser extends InputParser { ParserContext tempContext = new ParserContext(context); tempContext.setRestricted(false); tempContext.setPreferringWildcard(true); + tempContext.setTryLegacy(context.isTryingLegacy()); try { Set holders = worldEdit.getBlockFactory().parseFromListInput(component, tempContext); if (holders.isEmpty()) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java index 8eb6df755..4358a6932 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/scripting/CraftScriptContext.java @@ -183,6 +183,7 @@ public class CraftScriptContext extends CraftScriptEnvironment { context.setSession(session); context.setRestricted(!allAllowed); context.setPreferringWildcard(false); + context.setTryLegacy(player.getLimit().ALLOW_LEGACY); return controller.getBlockFactory().parseFromListInput(input, context).stream().findFirst().orElse(null); } @@ -212,6 +213,7 @@ public class CraftScriptContext extends CraftScriptEnvironment { context.setActor(player); context.setWorld(player.getWorld()); context.setSession(session); + context.setTryLegacy(player.getLimit().ALLOW_LEGACY); return controller.getPatternFactory().parseFromInput(list, context); } @@ -230,6 +232,7 @@ public class CraftScriptContext extends CraftScriptEnvironment { context.setWorld(player.getWorld()); context.setSession(session); context.setRestricted(!allBlocksAllowed); + context.setTryLegacy(player.getLimit().ALLOW_LEGACY); return controller.getBlockFactory().parseFromListInput(list, context); } From 2ccfd50546dc71c86b7417338a0c135e66bcd34d Mon Sep 17 00:00:00 2001 From: Jordan Date: Sun, 30 Jun 2024 10:40:13 +0200 Subject: [PATCH 184/220] feat: implement 1.21 (#2808) * feat: implement 1.21 * fix: adjust mojang mapped field name in ChunkMap * Fix property cache --------- Co-authored-by: Pierre Maurice Schwang --- build.gradle.kts | 2 +- buildSrc/src/main/kotlin/CommonJavaConfig.kt | 2 +- gradle/libs.versions.toml | 2 +- settings.gradle.kts | 2 +- .../adapters/adapter-1_21/build.gradle.kts | 17 + .../ext/fawe/v1_21_R1/PaperweightAdapter.java | 1158 +++++++ .../v1_21_R1/PaperweightDataConverters.java | 2795 +++++++++++++++++ .../fawe/v1_21_R1/PaperweightFakePlayer.java | 91 + .../PaperweightWorldNativeAccess.java | 191 ++ .../ext/fawe/v1_21_R1/StaticRefraction.java | 90 + .../v1_21_R1/PaperweightBlockMaterial.java | 176 ++ .../fawe/v1_21_R1/PaperweightFaweAdapter.java | 639 ++++ .../PaperweightFaweWorldNativeAccess.java | 293 ++ .../fawe/v1_21_R1/PaperweightGetBlocks.java | 1186 +++++++ .../v1_21_R1/PaperweightGetBlocks_Copy.java | 260 ++ .../v1_21_R1/PaperweightMapChunkUtil.java | 34 + .../v1_21_R1/PaperweightPlatformAdapter.java | 727 +++++ .../v1_21_R1/PaperweightPostProcessor.java | 175 ++ .../PaperweightStarlightRelighter.java | 79 + .../PaperweightStarlightRelighterFactory.java | 25 + .../nbt/PaperweightLazyCompoundTag.java | 161 + .../fawe/v1_21_R1/regen/PaperweightRegen.java | 623 ++++ worldedit-bukkit/build.gradle.kts | 2 +- 23 files changed, 8725 insertions(+), 5 deletions(-) create mode 100644 worldedit-bukkit/adapters/adapter-1_21/build.gradle.kts create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightAdapter.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightDataConverters.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightFakePlayer.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightWorldNativeAccess.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/StaticRefraction.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightBlockMaterial.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweWorldNativeAccess.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks_Copy.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightMapChunkUtil.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPostProcessor.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightStarlightRelighter.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightStarlightRelighterFactory.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/nbt/PaperweightLazyCompoundTag.java create mode 100644 worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/regen/PaperweightRegen.java diff --git a/build.gradle.kts b/build.gradle.kts index 8fdea3200..0f188deeb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -83,7 +83,7 @@ allprojects { } applyCommonConfiguration() -val supportedVersions = listOf("1.19.4", "1.20", "1.20.4", "1.20.5", "1.20.6") +val supportedVersions = listOf("1.19.4", "1.20", "1.20.4", "1.20.5", "1.20.6", "1.21") tasks { supportedVersions.forEach { diff --git a/buildSrc/src/main/kotlin/CommonJavaConfig.kt b/buildSrc/src/main/kotlin/CommonJavaConfig.kt index fec02d1a0..60860f7f7 100644 --- a/buildSrc/src/main/kotlin/CommonJavaConfig.kt +++ b/buildSrc/src/main/kotlin/CommonJavaConfig.kt @@ -61,7 +61,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean "https://jd.advntr.dev/api/latest/", "https://logging.apache.org/log4j/2.x/javadoc/log4j-api/", "https://www.antlr.org/api/Java/", - "https://jd.papermc.io/paper/1.20.6/", + "https://jd.papermc.io/paper/1.21/", "https://intellectualsites.github.io/fastasyncworldedit-javadocs/worldedit-core/" ) docTitle = "${rootProject.name}-${project.description}" + " " + "${rootProject.version}" diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4f64aa273..b02ec474b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] # Minecraft expectations -paper = "1.20.6-R0.1-SNAPSHOT" +paper = "1.21-R0.1-SNAPSHOT" fastutil = "8.5.9" guava = "31.1-jre" log4j = "2.19.0" diff --git a/settings.gradle.kts b/settings.gradle.kts index 48318b908..de52de2f9 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,7 +2,7 @@ rootProject.name = "FastAsyncWorldEdit" include("worldedit-libs") -listOf("1_19_4", "1_20", "1_20_2", "1_20_4", "1_20_5").forEach { +listOf("1_19_4", "1_20", "1_20_2", "1_20_4", "1_20_5", "1_21").forEach { include("worldedit-bukkit:adapters:adapter-$it") } diff --git a/worldedit-bukkit/adapters/adapter-1_21/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_21/build.gradle.kts new file mode 100644 index 000000000..39ff980f6 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/build.gradle.kts @@ -0,0 +1,17 @@ +import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension + +plugins { + java +} + +applyPaperweightAdapterConfiguration() + +repositories { + gradlePluginPortal() +} + +dependencies { + // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.21-R0.1-SNAPSHOT/ + the().paperDevBundle("1.21-R0.1-20240629.091304-42") + compileOnly(libs.paperlib) +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightAdapter.java new file mode 100644 index 000000000..f66bb1460 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightAdapter.java @@ -0,0 +1,1158 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_21_R1; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.common.util.concurrent.Futures; +import com.mojang.serialization.Codec; +import com.mojang.serialization.Lifecycle; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.blocks.BaseItem; +import com.sk89q.worldedit.blocks.BaseItemStack; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.extension.platform.Watchdog; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.internal.Constants; +import com.sk89q.worldedit.internal.block.BlockStateIdAccess; +import com.sk89q.worldedit.internal.wna.WorldNativeAccess; +import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.registry.state.BooleanProperty; +import com.sk89q.worldedit.registry.state.DirectionalProperty; +import com.sk89q.worldedit.registry.state.EnumProperty; +import com.sk89q.worldedit.registry.state.IntegerProperty; +import com.sk89q.worldedit.registry.state.Property; +import com.sk89q.worldedit.util.Direction; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.concurrency.LazyReference; +import com.sk89q.worldedit.util.formatting.text.Component; +import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; +import com.sk89q.worldedit.util.io.file.SafeFiles; +import com.sk89q.worldedit.world.DataFixer; +import com.sk89q.worldedit.world.RegenOptions; +import com.sk89q.worldedit.world.biome.BiomeCategory; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.biome.BiomeTypes; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; +import com.sk89q.worldedit.world.block.BlockType; +import com.sk89q.worldedit.world.block.BlockTypes; +import com.sk89q.worldedit.world.entity.EntityTypes; +import com.sk89q.worldedit.world.item.ItemType; +import net.minecraft.Util; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; +import net.minecraft.core.Registry; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; +import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.server.level.ChunkResult; +import net.minecraft.server.level.ServerChunkCache; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.progress.ChunkProgressListener; +import net.minecraft.util.RandomSource; +import net.minecraft.util.StringRepresentable; +import net.minecraft.util.thread.BlockableEventLoop; +import net.minecraft.world.Clearable; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.LevelSettings; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.StructureBlockEntity; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.status.ChunkStatus; +import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.WorldOptions; +import net.minecraft.world.level.storage.LevelStorageSource; +import net.minecraft.world.level.storage.PrimaryLevelData; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.World.Environment; +import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.block.data.CraftBlockData; +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.util.CraftMagicNumbers; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.generator.ChunkGenerator; +import org.enginehub.linbus.common.LinTagId; +import org.enginehub.linbus.tree.LinByteArrayTag; +import org.enginehub.linbus.tree.LinByteTag; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinDoubleTag; +import org.enginehub.linbus.tree.LinEndTag; +import org.enginehub.linbus.tree.LinFloatTag; +import org.enginehub.linbus.tree.LinIntArrayTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinLongArrayTag; +import org.enginehub.linbus.tree.LinLongTag; +import org.enginehub.linbus.tree.LinShortTag; +import org.enginehub.linbus.tree.LinStringTag; +import org.enginehub.linbus.tree.LinTag; +import org.enginehub.linbus.tree.LinTagType; +import org.spigotmc.SpigotConfig; +import org.spigotmc.WatchdogThread; + +import javax.annotation.Nullable; +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.OptionalInt; +import java.util.OptionalLong; +import java.util.Set; +import java.util.TreeMap; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +public final class PaperweightAdapter implements BukkitImplAdapter { + + private final Logger logger = Logger.getLogger(getClass().getCanonicalName()); + + private final Field serverWorldsField; + private final Method getChunkFutureMethod; + private final Field chunkProviderExecutorField; + private final PaperweightDataConverters dataFixer; + private final Watchdog watchdog; + + private static final RandomSource random = RandomSource.create(); + + // ------------------------------------------------------------------------ + // Code that may break between versions of Minecraft + // ------------------------------------------------------------------------ + + public PaperweightAdapter() throws NoSuchFieldException, NoSuchMethodException { + // A simple test + CraftServer.class.cast(Bukkit.getServer()); + + int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion(); + if (dataVersion != 3953) { + throw new UnsupportedClassVersionError("Not 1.21!"); + } + + serverWorldsField = CraftServer.class.getDeclaredField("worlds"); + serverWorldsField.setAccessible(true); + + getChunkFutureMethod = ServerChunkCache.class.getDeclaredMethod( + StaticRefraction.GET_CHUNK_FUTURE_MAIN_THREAD, + int.class, int.class, ChunkStatus.class, boolean.class + ); + getChunkFutureMethod.setAccessible(true); + + chunkProviderExecutorField = ServerChunkCache.class.getDeclaredField( + StaticRefraction.MAIN_THREAD_PROCESSOR + ); + chunkProviderExecutorField.setAccessible(true); + + this.dataFixer = new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this); + + Watchdog watchdog; + try { + Class.forName("org.spigotmc.WatchdogThread"); + watchdog = new SpigotWatchdog(); + } catch (ClassNotFoundException | NoSuchFieldException e) { + try { + watchdog = new MojangWatchdog(((CraftServer) Bukkit.getServer()).getServer()); + } catch (NoSuchFieldException ex) { + watchdog = null; + } + } + this.watchdog = watchdog; + + try { + Class.forName("org.spigotmc.SpigotConfig"); + SpigotConfig.config.set("world-settings.worldeditregentempworld.verbose", false); + } catch (ClassNotFoundException ignored) { + } + } + + @Override + public DataFixer getDataFixer() { + return this.dataFixer; + } + + /** + * Read the given NBT data into the given tile entity. + * + * @param tileEntity the tile entity + * @param tag the tag + */ + static void readTagIntoTileEntity(net.minecraft.nbt.CompoundTag tag, BlockEntity tileEntity) { + tileEntity.loadWithComponents(tag, MinecraftServer.getServer().registryAccess()); + tileEntity.setChanged(); + } + + /** + * Get the ID string of the given entity. + * + * @param entity the entity + * @return the entity ID + */ + private static String getEntityId(Entity entity) { + return EntityType.getKey(entity.getType()).toString(); + } + + /** + * Create an entity using the given entity ID. + * + * @param id the entity ID + * @param world the world + * @return an entity or null + */ + @Nullable + private static Entity createEntityFromId(String id, net.minecraft.world.level.Level world) { + return EntityType.byString(id).map(t -> t.create(world)).orElse(null); + } + + /** + * Write the given NBT data into the given entity. + * + * @param entity the entity + * @param tag the tag + */ + private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) { + entity.load(tag); + } + + /** + * Write the entity's NBT data to the given tag. + * + * @param entity the entity + * @param tag the tag + */ + private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag tag) { + entity.save(tag); + } + + private static Block getBlockFromType(BlockType blockType) { + return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK).get(ResourceLocation.tryParse(blockType.id())); + } + + private static Item getItemFromType(ItemType itemType) { + return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(itemType.id())); + } + + @Override + public OptionalInt getInternalBlockStateId(BlockData data) { + net.minecraft.world.level.block.state.BlockState state = ((CraftBlockData) data).getState(); + int combinedId = Block.getId(state); + return combinedId == 0 && state.getBlock() != Blocks.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId); + } + + @Override + public OptionalInt getInternalBlockStateId(BlockState state) { + Block mcBlock = getBlockFromType(state.getBlockType()); + net.minecraft.world.level.block.state.BlockState newState = mcBlock.defaultBlockState(); + Map, Object> states = state.getStates(); + newState = applyProperties(mcBlock.getStateDefinition(), newState, states); + final int combinedId = Block.getId(newState); + return combinedId == 0 && state.getBlockType() != BlockTypes.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId); + } + + public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { + int internalId = Block.getId(blockState); + BlockState state = BlockStateIdAccess.getBlockStateById(internalId); + if (state == null) { + state = BukkitAdapter.adapt(CraftBlockData.createData(blockState)); + } + + return state; + } + + public BiomeType adapt(Biome biome) { + var mcBiome = ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getKey(biome); + if (mcBiome == null) { + return null; + } + return BiomeType.REGISTRY.get(mcBiome.toString()); + } + + public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) { + int internalId = BlockStateIdAccess.getBlockStateId(blockState); + return Block.stateById(internalId); + } + + @Override + public BlockState getBlock(Location location) { + checkNotNull(location); + + CraftWorld craftWorld = ((CraftWorld) location.getWorld()); + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + + final ServerLevel handle = craftWorld.getHandle(); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); + final BlockPos blockPos = new BlockPos(x, y, z); + final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); + return adapt(blockData); + } + + @Override + public BaseBlock getFullBlock(Location location) { + BlockState state = getBlock(location); + + CraftWorld craftWorld = ((CraftWorld) location.getWorld()); + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + + final ServerLevel handle = craftWorld.getHandle(); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); + final BlockPos blockPos = new BlockPos(x, y, z); + + // Read the NBT data + BlockEntity te = chunk.getBlockEntity(blockPos); + if (te != null) { + net.minecraft.nbt.CompoundTag tag = te.saveWithId(MinecraftServer.getServer().registryAccess()); + return state.toBaseBlock(LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag))); + } + + return state.toBaseBlock(); + } + + private static final HashMap> biomeTypeToNMSCache = new HashMap<>(); + private static final HashMap, BiomeType> biomeTypeFromNMSCache = new HashMap<>(); + + @Override + public BiomeType getBiome(Location location) { + checkNotNull(location); + + CraftWorld craftWorld = ((CraftWorld) location.getWorld()); + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + + final ServerLevel handle = craftWorld.getHandle(); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); + + return biomeTypeFromNMSCache.computeIfAbsent(chunk.getNoiseBiome(x >> 2, y >> 2, z >> 2), b -> BiomeType.REGISTRY.get(b.unwrapKey().get().location().toString())); + } + + @Override + public void setBiome(Location location, BiomeType biome) { + checkNotNull(location); + checkNotNull(biome); + + CraftWorld craftWorld = ((CraftWorld) location.getWorld()); + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + + final ServerLevel handle = craftWorld.getHandle(); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); + chunk.setBiome(x >> 2, y >> 2, z >> 2, biomeTypeToNMSCache.computeIfAbsent(biome, b -> ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolderOrThrow(ResourceKey.create(Registries.BIOME, ResourceLocation.parse(b.id()))))); + chunk.setUnsaved(true); + } + + @Override + public WorldNativeAccess createWorldNativeAccess(World world) { + return new PaperweightWorldNativeAccess(this, new WeakReference<>(((CraftWorld) world).getHandle())); + } + + private static net.minecraft.core.Direction adapt(Direction face) { + switch (face) { + case NORTH: + return net.minecraft.core.Direction.NORTH; + case SOUTH: + return net.minecraft.core.Direction.SOUTH; + case WEST: + return net.minecraft.core.Direction.WEST; + case EAST: + return net.minecraft.core.Direction.EAST; + case DOWN: + return net.minecraft.core.Direction.DOWN; + case UP: + default: + return net.minecraft.core.Direction.UP; + } + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private net.minecraft.world.level.block.state.BlockState applyProperties( + StateDefinition stateContainer, + net.minecraft.world.level.block.state.BlockState newState, + Map, Object> states + ) { + for (Map.Entry, Object> state : states.entrySet()) { + net.minecraft.world.level.block.state.properties.Property property = + stateContainer.getProperty(state.getKey().getName()); + Comparable value = (Comparable) state.getValue(); + // we may need to adapt this value, depending on the source prop + if (property instanceof DirectionProperty) { + Direction dir = (Direction) value; + value = adapt(dir); + } else if (property instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { + String enumName = (String) value; + value = ((net.minecraft.world.level.block.state.properties.EnumProperty) property) + .getValue(enumName).orElseThrow(() -> + new IllegalStateException( + "Enum property " + property.getName() + " does not contain " + enumName + ) + ); + } + + newState = newState.setValue( + (net.minecraft.world.level.block.state.properties.Property) property, + (Comparable) value + ); + } + return newState; + } + + @Override + public BaseEntity getEntity(org.bukkit.entity.Entity entity) { + checkNotNull(entity); + + CraftEntity craftEntity = ((CraftEntity) entity); + Entity mcEntity = craftEntity.getHandle(); + + // Do not allow creating of passenger entity snapshots, passengers are included in the vehicle entity + if (mcEntity.isPassenger()) { + return null; + } + + String id = getEntityId(mcEntity); + + net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); + readEntityIntoTag(mcEntity, tag); + return new BaseEntity( + EntityTypes.get(id), + LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)) + ); + } + + @Nullable + @Override + public org.bukkit.entity.Entity createEntity(Location location, BaseEntity state) { + checkNotNull(location); + checkNotNull(state); + + CraftWorld craftWorld = ((CraftWorld) location.getWorld()); + ServerLevel worldServer = craftWorld.getHandle(); + + String entityId = state.getType().id(); + + LinCompoundTag nativeTag = state.getNbt(); + net.minecraft.nbt.CompoundTag tag; + if (nativeTag != null) { + tag = (net.minecraft.nbt.CompoundTag) fromNativeLin(nativeTag); + removeUnwantedEntityTagsRecursively(tag); + } else { + tag = new net.minecraft.nbt.CompoundTag(); + } + + tag.putString("id", entityId); + + Entity createdEntity = EntityType.loadEntityRecursive(tag, craftWorld.getHandle(), (loadedEntity) -> { + loadedEntity.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + return loadedEntity; + }); + + if (createdEntity != null) { + worldServer.addFreshEntityWithPassengers(createdEntity, SpawnReason.CUSTOM); + return createdEntity.getBukkitEntity(); + } else { + return null; + } + } + + // This removes all unwanted tags from the main entity and all its passengers + private void removeUnwantedEntityTagsRecursively(net.minecraft.nbt.CompoundTag tag) { + for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { + tag.remove(name); + } + + // Adapted from net.minecraft.world.entity.EntityType#loadEntityRecursive + if (tag.contains("Passengers", LinTagId.LIST.id())) { + net.minecraft.nbt.ListTag nbttaglist = tag.getList("Passengers", LinTagId.COMPOUND.id()); + + for (int i = 0; i < nbttaglist.size(); ++i) { + removeUnwantedEntityTagsRecursively(nbttaglist.getCompound(i)); + } + } + } + + @Override + public Component getRichBlockName(BlockType blockType) { + return TranslatableComponent.of(getBlockFromType(blockType).getDescriptionId()); + } + + @Override + public Component getRichItemName(ItemType itemType) { + return TranslatableComponent.of(getItemFromType(itemType).getDescriptionId()); + } + + @Override + public Component getRichItemName(BaseItemStack itemStack) { + return TranslatableComponent.of(CraftItemStack.asNMSCopy(BukkitAdapter.adapt(itemStack)).getDescriptionId()); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + private static final LoadingCache> PROPERTY_CACHE = CacheBuilder + .newBuilder() + .build(new CacheLoader<>() { + @Override + public Property load(net.minecraft.world.level.block.state.properties.Property state) { + if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { + return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else if (state instanceof DirectionProperty) { + return new DirectionalProperty( + state.getName(), + new ArrayList<>((List) state + .getPossibleValues() + .stream() + .map(e -> Direction.valueOf(((StringRepresentable) e) + .getSerializedName() + .toUpperCase(Locale.ROOT))) + .toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { + return new EnumProperty( + state.getName(), + new ArrayList<>((List) state + .getPossibleValues() + .stream() + .map(e -> ((StringRepresentable) e).getSerializedName()) + .toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { + return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); + } else { + throw new IllegalArgumentException("WorldEdit needs an update to support " + state + .getClass() + .getSimpleName()); + } + } + }); + + @SuppressWarnings({ "rawtypes" }) + @Override + public Map> getProperties(BlockType blockType) { + Map> properties = new TreeMap<>(); + Block block = getBlockFromType(blockType); + StateDefinition blockStateList = + block.getStateDefinition(); + for (net.minecraft.world.level.block.state.properties.Property state : blockStateList.getProperties()) { + Property property = PROPERTY_CACHE.getUnchecked(state); + properties.put(property.getName(), property); + } + return properties; + } + + @Override + public void sendFakeNBT(Player player, BlockVector3 pos, LinCompoundTag nbtData) { + var structureBlock = new StructureBlockEntity( + new BlockPos(pos.x(), pos.y(), pos.z()), + Blocks.STRUCTURE_BLOCK.defaultBlockState() + ); + structureBlock.setLevel(((CraftPlayer) player).getHandle().level()); + ((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create( + structureBlock, + (blockEntity, registryAccess) -> (net.minecraft.nbt.CompoundTag) fromNativeLin(nbtData) + )); + } + + @Override + public void sendFakeOP(Player player) { + ((CraftPlayer) player).getHandle().connection.send(new ClientboundEntityEventPacket( + ((CraftPlayer) player).getHandle(), (byte) 28 + )); + } + + /** + * For serializing and deserializing components. + */ + private static final Codec COMPONENTS_CODEC = DataComponentPatch.CODEC.optionalFieldOf( + "components", DataComponentPatch.EMPTY + ).codec(); + + @Override + public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) { + var registryAccess = DedicatedServer.getServer().registryAccess(); + ItemStack stack = new ItemStack( + registryAccess.registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(baseItemStack.getType().id())), + baseItemStack.getAmount() + ); + LinCompoundTag nbt = baseItemStack.getNbt(); + if (nbt != null) { + DataComponentPatch componentPatch = COMPONENTS_CODEC.parse( + registryAccess.createSerializationContext(NbtOps.INSTANCE), + fromNativeLin(nbt) + ).getOrThrow(); + stack.applyComponents(componentPatch); + } + return CraftItemStack.asCraftMirror(stack); + } + + @Override + public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { + var registryAccess = DedicatedServer.getServer().registryAccess(); + final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); + CompoundTag tag = (CompoundTag) COMPONENTS_CODEC.encodeStart( + registryAccess.createSerializationContext(NbtOps.INSTANCE), + nmsStack.getComponentsPatch() + ).getOrThrow(); + return new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)), itemStack.getAmount()); + } + + private final LoadingCache fakePlayers + = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new)); + + @Override + public boolean simulateItemUse(World world, BlockVector3 position, BaseItem item, Direction face) { + CraftWorld craftWorld = (CraftWorld) world; + ServerLevel worldServer = craftWorld.getHandle(); + ItemStack stack = CraftItemStack.asNMSCopy(adapt( + item instanceof BaseItemStack + ? ((BaseItemStack) item) + : new BaseItemStack(item.getType(), item.getNbtReference(), 1) + )); + + PaperweightFakePlayer fakePlayer; + try { + fakePlayer = fakePlayers.get(worldServer); + } catch (ExecutionException ignored) { + return false; + } + fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack); + fakePlayer.absMoveTo(position.x(), position.y(), position.z(), + (float) face.toVector().toYaw(), (float) face.toVector().toPitch()); + + final BlockPos blockPos = new BlockPos(position.x(), position.y(), position.z()); + final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos); + final net.minecraft.core.Direction enumFacing = adapt(face); + BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false); + UseOnContext context = new UseOnContext(fakePlayer, InteractionHand.MAIN_HAND, rayTrace); + InteractionResult result = stack.useOn(context); + if (result != InteractionResult.SUCCESS) { + if (worldServer.getBlockState(blockPos).useItemOn(stack, worldServer, fakePlayer, InteractionHand.MAIN_HAND, rayTrace).consumesAction()) { + result = InteractionResult.SUCCESS; + } else { + result = stack.getItem().use(worldServer, fakePlayer, InteractionHand.MAIN_HAND).getResult(); + } + } + + return result == InteractionResult.SUCCESS; + } + + @Override + public boolean canPlaceAt(World world, BlockVector3 position, BlockState blockState) { + int internalId = BlockStateIdAccess.getBlockStateId(blockState); + net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId); + return blockData.canSurvive(((CraftWorld) world).getHandle(), new BlockPos(position.x(), position.y(), position.z())); + } + + @Override + public boolean regenerate(World bukkitWorld, Region region, Extent extent, RegenOptions options) { + try { + doRegen(bukkitWorld, region, extent, options); + } catch (Exception e) { + throw new IllegalStateException("Regen failed.", e); + } + + return true; + } + + private void doRegen(World bukkitWorld, Region region, Extent extent, RegenOptions options) throws Exception { + Environment env = bukkitWorld.getEnvironment(); + ChunkGenerator gen = bukkitWorld.getGenerator(); + + Path tempDir = Files.createTempDirectory("WorldEditWorldGen"); + LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir); + ResourceKey worldDimKey = getWorldDimKey(env); + try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("worldeditregentempworld", worldDimKey)) { + ServerLevel originalWorld = ((CraftWorld) bukkitWorld).getHandle(); + PrimaryLevelData levelProperties = (PrimaryLevelData) originalWorld.getServer() + .getWorldData().overworldData(); + WorldOptions originalOpts = levelProperties.worldGenOptions(); + + long seed = options.getSeed().orElse(originalWorld.getSeed()); + WorldOptions newOpts = options.getSeed().isPresent() + ? originalOpts.withSeed(OptionalLong.of(seed)) + : originalOpts; + + LevelSettings newWorldSettings = new LevelSettings( + "worldeditregentempworld", + levelProperties.settings.gameType(), + levelProperties.settings.hardcore(), + levelProperties.settings.difficulty(), + levelProperties.settings.allowCommands(), + levelProperties.settings.gameRules(), + levelProperties.settings.getDataConfiguration() + ); + + @SuppressWarnings("deprecation") + PrimaryLevelData.SpecialWorldProperty specialWorldProperty = + levelProperties.isFlatWorld() + ? PrimaryLevelData.SpecialWorldProperty.FLAT + : levelProperties.isDebugWorld() + ? PrimaryLevelData.SpecialWorldProperty.DEBUG + : PrimaryLevelData.SpecialWorldProperty.NONE; + + PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, specialWorldProperty, Lifecycle.stable()); + + ServerLevel freshWorld = new ServerLevel( + originalWorld.getServer(), + originalWorld.getServer().executor, + session, newWorldData, + originalWorld.dimension(), + new LevelStem( + originalWorld.dimensionTypeRegistration(), + originalWorld.getChunkSource().getGenerator() + ), + new NoOpWorldLoadListener(), + originalWorld.isDebug(), + seed, + ImmutableList.of(), + false, + originalWorld.getRandomSequences(), + env, + gen, + bukkitWorld.getBiomeProvider() + ); + try { + regenForWorld(region, extent, freshWorld, options); + } finally { + freshWorld.getChunkSource().close(false); + } + } finally { + try { + @SuppressWarnings("unchecked") + Map map = (Map) serverWorldsField.get(Bukkit.getServer()); + map.remove("worldeditregentempworld"); + } catch (IllegalAccessException ignored) { + } + SafeFiles.tryHardToDeleteDir(tempDir); + } + } + + private BiomeType adapt(ServerLevel serverWorld, Biome origBiome) { + ResourceLocation key = serverWorld.registryAccess().registryOrThrow(Registries.BIOME).getKey(origBiome); + if (key == null) { + return null; + } + return BiomeTypes.get(key.toString()); + } + + @SuppressWarnings("unchecked") + private void regenForWorld(Region region, Extent extent, ServerLevel serverWorld, RegenOptions options) throws WorldEditException { + List> chunkLoadings = submitChunkLoadTasks(region, serverWorld); + BlockableEventLoop executor; + try { + executor = (BlockableEventLoop) chunkProviderExecutorField.get(serverWorld.getChunkSource()); + } catch (IllegalAccessException e) { + throw new IllegalStateException("Couldn't get executor for chunk loading.", e); + } + executor.managedBlock(() -> { + // bail out early if a future fails + if (chunkLoadings.stream().anyMatch(ftr -> + ftr.isDone() && Futures.getUnchecked(ftr) == null + )) { + return false; + } + return chunkLoadings.stream().allMatch(CompletableFuture::isDone); + }); + Map chunks = new HashMap<>(); + for (CompletableFuture future : chunkLoadings) { + @Nullable + ChunkAccess chunk = future.getNow(null); + checkState(chunk != null, "Failed to generate a chunk, regen failed."); + chunks.put(chunk.getPos(), chunk); + } + + for (BlockVector3 vec : region) { + BlockPos pos = new BlockPos(vec.x(), vec.y(), vec.z()); + ChunkAccess chunk = chunks.get(new ChunkPos(pos)); + final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos); + int internalId = Block.getId(blockData); + BlockStateHolder state = BlockStateIdAccess.getBlockStateById(internalId); + Objects.requireNonNull(state); + BlockEntity blockEntity = chunk.getBlockEntity(pos); + if (blockEntity != null) { + net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(serverWorld.registryAccess()); + state = state.toBaseBlock(LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag))); + } + extent.setBlock(vec, state.toBaseBlock()); + if (options.shouldRegenBiomes()) { + Biome origBiome = chunk.getNoiseBiome(vec.x(), vec.y(), vec.z()).value(); + BiomeType adaptedBiome = adapt(serverWorld, origBiome); + if (adaptedBiome != null) { + extent.setBiome(vec, adaptedBiome); + } + } + } + } + + @SuppressWarnings("unchecked") + private List> submitChunkLoadTasks(Region region, ServerLevel serverWorld) { + ServerChunkCache chunkManager = serverWorld.getChunkSource(); + List> chunkLoadings = new ArrayList<>(); + // Pre-gen all the chunks + for (BlockVector2 chunk : region.getChunks()) { + try { + //noinspection unchecked + chunkLoadings.add( + ((CompletableFuture>) + getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) + .thenApply(either -> either.orElse(null)) + ); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new IllegalStateException("Couldn't load chunk for regen.", e); + } + } + return chunkLoadings; + } + + private ResourceKey getWorldDimKey(Environment env) { + switch (env) { + case NETHER: + return LevelStem.NETHER; + case THE_END: + return LevelStem.END; + case NORMAL: + default: + return LevelStem.OVERWORLD; + } + } + + private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( + SideEffect.NEIGHBORS, + SideEffect.LIGHTING, + SideEffect.VALIDATION, + SideEffect.ENTITY_AI, + SideEffect.EVENTS, + SideEffect.UPDATE + ); + + @Override + public Set getSupportedSideEffects() { + return SUPPORTED_SIDE_EFFECTS; + } + + @Override + public boolean clearContainerBlockContents(World world, BlockVector3 pt) { + ServerLevel originalWorld = ((CraftWorld) world).getHandle(); + + BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.x(), pt.y(), pt.z())); + if (entity instanceof Clearable) { + ((Clearable) entity).clearContent(); + return true; + } + return false; + } + + @Override + public void initializeRegistries() { + DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer(); + // Biomes + for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.BIOME).keySet()) { + if (BiomeType.REGISTRY.get(name.toString()) == null) { + BiomeType.REGISTRY.register(name.toString(), new BiomeType(name.toString())); + } + } + + // BiomeCategories + Registry biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME); + biomeRegistry.getTagNames().forEach(tagKey -> { + String key = tagKey.location().toString(); + if (BiomeCategory.REGISTRY.get(key) == null) { + BiomeCategory.REGISTRY.register(key, new BiomeCategory( + key, + () -> biomeRegistry.getTag(tagKey) + .stream() + .flatMap(HolderSet.Named::stream) + .map(Holder::value) + .map(this::adapt) + .collect(Collectors.toSet())) + ); + } + }); + } + + @Override + public void sendBiomeUpdates(World world, Iterable chunks) { + ServerLevel originalWorld = ((CraftWorld) world).getHandle(); + + List nativeChunks = chunks instanceof Collection chunkCollection ? Lists.newArrayListWithCapacity(chunkCollection.size()) : Lists.newArrayList(); + for (BlockVector2 chunk : chunks) { + nativeChunks.add(originalWorld.getChunk(chunk.x(), chunk.z(), ChunkStatus.BIOMES, false)); + } + originalWorld.getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks); + } + + // ------------------------------------------------------------------------ + // Code that is less likely to break + // ------------------------------------------------------------------------ + + /** + * Converts from a non-native NMS NBT structure to a native WorldEdit NBT + * structure. + * + * @param foreign non-native NMS NBT structure + * @return native WorldEdit NBT structure + */ + @Override + public LinTag toNativeLin(net.minecraft.nbt.Tag foreign) { + if (foreign == null) { + return null; + } + if (foreign instanceof net.minecraft.nbt.CompoundTag) { + Map> values = new HashMap<>(); + Set foreignKeys = ((net.minecraft.nbt.CompoundTag) foreign).getAllKeys(); + + for (String str : foreignKeys) { + net.minecraft.nbt.Tag base = ((net.minecraft.nbt.CompoundTag) foreign).get(str); + values.put(str, toNativeLin(base)); + } + return LinCompoundTag.of(values); + } else if (foreign instanceof net.minecraft.nbt.ByteTag) { + return LinByteTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); + } else if (foreign instanceof net.minecraft.nbt.ByteArrayTag) { + return LinByteArrayTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); + } else if (foreign instanceof net.minecraft.nbt.DoubleTag) { + return LinDoubleTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); + } else if (foreign instanceof net.minecraft.nbt.FloatTag) { + return LinFloatTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); + } else if (foreign instanceof net.minecraft.nbt.IntTag) { + return LinIntTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); + } else if (foreign instanceof net.minecraft.nbt.IntArrayTag) { + return LinIntArrayTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); + } else if (foreign instanceof net.minecraft.nbt.LongArrayTag) { + return LinLongArrayTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); + } else if (foreign instanceof net.minecraft.nbt.ListTag) { + try { + return toNativeLinList((net.minecraft.nbt.ListTag) foreign); + } catch (Throwable e) { + logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); + } + } else if (foreign instanceof net.minecraft.nbt.LongTag) { + return LinLongTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); + } else if (foreign instanceof net.minecraft.nbt.ShortTag) { + return LinShortTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); + } else if (foreign instanceof net.minecraft.nbt.StringTag) { + return LinStringTag.of(foreign.getAsString()); + } else if (foreign instanceof net.minecraft.nbt.EndTag) { + return LinEndTag.instance(); + } + throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); + } + + /** + * Convert a foreign NBT list tag into a native WorldEdit one. + * + * @param foreign the foreign tag + * @return the converted tag + * @throws SecurityException on error + * @throws IllegalArgumentException on error + */ + private LinListTag toNativeLinList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException { + LinListTag.Builder> builder = LinListTag.builder( + LinTagType.fromId(LinTagId.fromId(foreign.getElementType())) + ); + + for (net.minecraft.nbt.Tag tag : foreign) { + builder.add(toNativeLin(tag)); + } + + return builder.build(); + } + + /** + * Converts a WorldEdit-native NBT structure to a NMS structure. + * + * @param foreign structure to convert + * @return non-native structure + */ + @Override + public net.minecraft.nbt.Tag fromNativeLin(LinTag foreign) { + if (foreign == null) { + return null; + } + if (foreign instanceof LinCompoundTag compoundTag) { + net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); + for (var entry : compoundTag.value().entrySet()) { + tag.put(entry.getKey(), fromNativeLin(entry.getValue())); + } + return tag; + } else if (foreign instanceof LinByteTag byteTag) { + return net.minecraft.nbt.ByteTag.valueOf(byteTag.valueAsByte()); + } else if (foreign instanceof LinByteArrayTag byteArrayTag) { + return new net.minecraft.nbt.ByteArrayTag(byteArrayTag.value()); + } else if (foreign instanceof LinDoubleTag doubleTag) { + return net.minecraft.nbt.DoubleTag.valueOf(doubleTag.valueAsDouble()); + } else if (foreign instanceof LinFloatTag floatTag) { + return net.minecraft.nbt.FloatTag.valueOf(floatTag.valueAsFloat()); + } else if (foreign instanceof LinIntTag intTag) { + return net.minecraft.nbt.IntTag.valueOf(intTag.valueAsInt()); + } else if (foreign instanceof LinIntArrayTag intArrayTag) { + return new net.minecraft.nbt.IntArrayTag(intArrayTag.value()); + } else if (foreign instanceof LinLongArrayTag longArrayTag) { + return new net.minecraft.nbt.LongArrayTag(longArrayTag.value()); + } else if (foreign instanceof LinListTag listTag) { + net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); + for (var t : listTag.value()) { + tag.add(fromNativeLin(t)); + } + return tag; + } else if (foreign instanceof LinLongTag longTag) { + return net.minecraft.nbt.LongTag.valueOf(longTag.valueAsLong()); + } else if (foreign instanceof LinShortTag shortTag) { + return net.minecraft.nbt.ShortTag.valueOf(shortTag.valueAsShort()); + } else if (foreign instanceof LinStringTag stringTag) { + return net.minecraft.nbt.StringTag.valueOf(stringTag.value()); + } else if (foreign instanceof LinEndTag) { + return net.minecraft.nbt.EndTag.INSTANCE; + } else { + throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName()); + } + } + + @Override + public boolean supportsWatchdog() { + return watchdog != null; + } + + @Override + public void tickWatchdog() { + watchdog.tick(); + } + + private class SpigotWatchdog implements Watchdog { + private final Field instanceField; + private final Field lastTickField; + + SpigotWatchdog() throws NoSuchFieldException { + Field instanceField = WatchdogThread.class.getDeclaredField("instance"); + instanceField.setAccessible(true); + this.instanceField = instanceField; + + Field lastTickField = WatchdogThread.class.getDeclaredField("lastTick"); + lastTickField.setAccessible(true); + this.lastTickField = lastTickField; + } + + @Override + public void tick() { + try { + WatchdogThread instance = (WatchdogThread) this.instanceField.get(null); + if ((long) lastTickField.get(instance) != 0) { + WatchdogThread.tick(); + } + } catch (IllegalAccessException e) { + logger.log(Level.WARNING, "Failed to tick watchdog", e); + } + } + } + + private static class MojangWatchdog implements Watchdog { + private final DedicatedServer server; + private final Field tickField; + + MojangWatchdog(DedicatedServer server) throws NoSuchFieldException { + this.server = server; + Field tickField = MinecraftServer.class.getDeclaredField(StaticRefraction.NEXT_TICK_TIME); + if (tickField.getType() != long.class) { + throw new IllegalStateException("nextTickTime is not a long field, mapping is likely incorrect"); + } + tickField.setAccessible(true); + this.tickField = tickField; + } + + @Override + public void tick() { + try { + tickField.set(server, Util.getMillis()); + } catch (IllegalAccessException ignored) { + } + } + } + + private static class NoOpWorldLoadListener implements ChunkProgressListener { + @Override + public void updateSpawnPos(ChunkPos spawnPos) { + } + + @Override + public void onStatusChange(ChunkPos pos, @org.jetbrains.annotations.Nullable ChunkStatus status) { + } + + @Override + public void start() { + } + + @Override + public void stop() { + } + + } +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightDataConverters.java new file mode 100644 index 000000000..e84ba0d4e --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightDataConverters.java @@ -0,0 +1,2795 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_21_R1; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.mojang.datafixers.DSL.TypeReference; +import com.mojang.datafixers.DataFixer; +import com.mojang.datafixers.schemas.Schema; +import com.mojang.serialization.Dynamic; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.FloatTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.nbt.StringTag; +import net.minecraft.nbt.Tag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.GsonHelper; +import net.minecraft.util.StringUtil; +import net.minecraft.util.datafix.DataFixers; +import net.minecraft.util.datafix.fixes.References; +import net.minecraft.world.item.DyeColor; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.enginehub.linbus.tree.LinCompoundTag; + +import javax.annotation.Nullable; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Random; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +/** + * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2) + * + *

    + * We register a DFU Fixer per Legacy Data Version and apply the fixes using legacy strategy + * which is safer, faster and cleaner code. + *

    + * + *

    + * The pre DFU code did not fail when the Source version was unknown. + *

    + * + *

    + * This class also provides util methods for converting compounds to wrap the update call to + * receive the source version in the compound + *

    + */ +@SuppressWarnings({ "rawtypes", "unchecked" }) +class PaperweightDataConverters implements com.sk89q.worldedit.world.DataFixer { + + @SuppressWarnings("unchecked") + @Override + public T fixUp(FixType type, T original, int srcVer) { + if (type == FixTypes.CHUNK) { + return (T) fixChunk((LinCompoundTag) original, srcVer); + } else if (type == FixTypes.BLOCK_ENTITY) { + return (T) fixBlockEntity((LinCompoundTag) original, srcVer); + } else if (type == FixTypes.ENTITY) { + return (T) fixEntity((LinCompoundTag) original, srcVer); + } else if (type == FixTypes.BLOCK_STATE) { + return (T) fixBlockState((String) original, srcVer); + } else if (type == FixTypes.ITEM_TYPE) { + return (T) fixItemType((String) original, srcVer); + } else if (type == FixTypes.BIOME) { + return (T) fixBiome((String) original, srcVer); + } + return original; + } + + private LinCompoundTag fixChunk(LinCompoundTag originalChunk, int srcVer) { + CompoundTag tag = (CompoundTag) adapter.fromNativeLin(originalChunk); + CompoundTag fixed = convert(LegacyType.CHUNK, tag, srcVer); + return (LinCompoundTag) adapter.toNativeLin(fixed); + } + + private LinCompoundTag fixBlockEntity(LinCompoundTag origTileEnt, int srcVer) { + CompoundTag tag = (CompoundTag) adapter.fromNativeLin(origTileEnt); + CompoundTag fixed = convert(LegacyType.BLOCK_ENTITY, tag, srcVer); + return (LinCompoundTag) adapter.toNativeLin(fixed); + } + + private LinCompoundTag fixEntity(LinCompoundTag origEnt, int srcVer) { + CompoundTag tag = (CompoundTag) adapter.fromNativeLin(origEnt); + CompoundTag fixed = convert(LegacyType.ENTITY, tag, srcVer); + return (LinCompoundTag) adapter.toNativeLin(fixed); + } + + private String fixBlockState(String blockState, int srcVer) { + CompoundTag stateNBT = stateToNBT(blockState); + Dynamic dynamic = new Dynamic<>(OPS_NBT, stateNBT); + CompoundTag fixed = (CompoundTag) INSTANCE.fixer.update(References.BLOCK_STATE, dynamic, srcVer, DATA_VERSION).getValue(); + return nbtToState(fixed); + } + + private String nbtToState(CompoundTag tagCompound) { + StringBuilder sb = new StringBuilder(); + sb.append(tagCompound.getString("Name")); + if (tagCompound.contains("Properties", 10)) { + sb.append('['); + CompoundTag props = tagCompound.getCompound("Properties"); + sb.append(props.getAllKeys().stream().map(k -> k + "=" + props.getString(k).replace("\"", "")).collect(Collectors.joining(","))); + sb.append(']'); + } + return sb.toString(); + } + + private static CompoundTag stateToNBT(String blockState) { + int propIdx = blockState.indexOf('['); + CompoundTag tag = new CompoundTag(); + if (propIdx < 0) { + tag.putString("Name", blockState); + } else { + tag.putString("Name", blockState.substring(0, propIdx)); + CompoundTag propTag = new CompoundTag(); + String props = blockState.substring(propIdx + 1, blockState.length() - 1); + String[] propArr = props.split(","); + for (String pair : propArr) { + final String[] split = pair.split("="); + propTag.putString(split[0], split[1]); + } + tag.put("Properties", propTag); + } + return tag; + } + + private String fixBiome(String key, int srcVer) { + return fixName(key, srcVer, References.BIOME); + } + + private String fixItemType(String key, int srcVer) { + return fixName(key, srcVer, References.ITEM_NAME); + } + + private static String fixName(String key, int srcVer, TypeReference type) { + return INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, StringTag.valueOf(key)), srcVer, DATA_VERSION) + .getValue().getAsString(); + } + + private final PaperweightAdapter adapter; + + private static final NbtOps OPS_NBT = NbtOps.INSTANCE; + private static final int LEGACY_VERSION = 1343; + private static int DATA_VERSION; + static PaperweightDataConverters INSTANCE; + + private final Map> converters = new EnumMap<>(LegacyType.class); + private final Map> inspectors = new EnumMap<>(LegacyType.class); + + // Set on build + private DataFixer fixer; + private static final Map DFU_TO_LEGACY = new HashMap<>(); + + public enum LegacyType { + LEVEL(References.LEVEL), + PLAYER(References.PLAYER), + CHUNK(References.CHUNK), + BLOCK_ENTITY(References.BLOCK_ENTITY), + ENTITY(References.ENTITY), + ITEM_INSTANCE(References.ITEM_STACK), + OPTIONS(References.OPTIONS), + STRUCTURE(References.STRUCTURE); + + private final TypeReference type; + + LegacyType(TypeReference type) { + this.type = type; + DFU_TO_LEGACY.put(type.typeName(), this); + } + + public TypeReference getDFUType() { + return type; + } + } + + PaperweightDataConverters(int dataVersion, PaperweightAdapter adapter) { + DATA_VERSION = dataVersion; + INSTANCE = this; + this.adapter = adapter; + registerConverters(); + registerInspectors(); + this.fixer = new WrappedDataFixer(DataFixers.getDataFixer()); + } + + @SuppressWarnings("unchecked") + private class WrappedDataFixer implements DataFixer { + private final DataFixer realFixer; + + WrappedDataFixer(DataFixer realFixer) { + this.realFixer = realFixer; + } + + @Override + public Dynamic update(TypeReference type, Dynamic dynamic, int sourceVer, int targetVer) { + LegacyType legacyType = DFU_TO_LEGACY.get(type.typeName()); + if (sourceVer < LEGACY_VERSION && legacyType != null) { + CompoundTag cmp = (CompoundTag) dynamic.getValue(); + int desiredVersion = Math.min(targetVer, LEGACY_VERSION); + + cmp = convert(legacyType, cmp, sourceVer, desiredVersion); + sourceVer = desiredVersion; + dynamic = new Dynamic(OPS_NBT, cmp); + } + return realFixer.update(type, dynamic, sourceVer, targetVer); + } + + private CompoundTag convert(LegacyType type, CompoundTag cmp, int sourceVer, int desiredVersion) { + List converters = PaperweightDataConverters.this.converters.get(type); + if (converters != null && !converters.isEmpty()) { + for (DataConverter converter : converters) { + int dataVersion = converter.getDataVersion(); + if (dataVersion > sourceVer && dataVersion <= desiredVersion) { + cmp = converter.convert(cmp); + } + } + } + + List inspectors = PaperweightDataConverters.this.inspectors.get(type); + if (inspectors != null && !inspectors.isEmpty()) { + for (DataInspector inspector : inspectors) { + cmp = inspector.inspect(cmp, sourceVer, desiredVersion); + } + } + + return cmp; + } + + @Override + public Schema getSchema(int i) { + return realFixer.getSchema(i); + } + } + + public static CompoundTag convert(LegacyType type, CompoundTag cmp) { + return convert(type.getDFUType(), cmp); + } + + public static CompoundTag convert(LegacyType type, CompoundTag cmp, int sourceVer) { + return convert(type.getDFUType(), cmp, sourceVer); + } + + public static CompoundTag convert(LegacyType type, CompoundTag cmp, int sourceVer, int targetVer) { + return convert(type.getDFUType(), cmp, sourceVer, targetVer); + } + + public static CompoundTag convert(TypeReference type, CompoundTag cmp) { + int i = cmp.contains("DataVersion", 99) ? cmp.getInt("DataVersion") : -1; + return convert(type, cmp, i); + } + + public static CompoundTag convert(TypeReference type, CompoundTag cmp, int sourceVer) { + return convert(type, cmp, sourceVer, DATA_VERSION); + } + + public static CompoundTag convert(TypeReference type, CompoundTag cmp, int sourceVer, int targetVer) { + if (sourceVer >= targetVer) { + return cmp; + } + return (CompoundTag) INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, cmp), sourceVer, targetVer).getValue(); + } + + + public interface DataInspector { + CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer); + } + + public interface DataConverter { + + int getDataVersion(); + + CompoundTag convert(CompoundTag cmp); + } + + + private void registerInspector(LegacyType type, DataInspector inspector) { + this.inspectors.computeIfAbsent(type, k -> new ArrayList<>()).add(inspector); + } + + private void registerConverter(LegacyType type, DataConverter converter) { + int version = converter.getDataVersion(); + + List list = this.converters.computeIfAbsent(type, k -> new ArrayList<>()); + if (!list.isEmpty() && list.get(list.size() - 1).getDataVersion() > version) { + for (int j = 0; j < list.size(); ++j) { + if (list.get(j).getDataVersion() > version) { + list.add(j, converter); + break; + } + } + } else { + list.add(converter); + } + } + + private void registerInspectors() { + registerEntityItemList("EntityHorseDonkey", "SaddleItem", "Items"); + registerEntityItemList("EntityHorseMule", "Items"); + registerEntityItemList("EntityMinecartChest", "Items"); + registerEntityItemList("EntityMinecartHopper", "Items"); + registerEntityItemList("EntityVillager", "Inventory"); + registerEntityItemListEquipment("EntityArmorStand"); + registerEntityItemListEquipment("EntityBat"); + registerEntityItemListEquipment("EntityBlaze"); + registerEntityItemListEquipment("EntityCaveSpider"); + registerEntityItemListEquipment("EntityChicken"); + registerEntityItemListEquipment("EntityCow"); + registerEntityItemListEquipment("EntityCreeper"); + registerEntityItemListEquipment("EntityEnderDragon"); + registerEntityItemListEquipment("EntityEnderman"); + registerEntityItemListEquipment("EntityEndermite"); + registerEntityItemListEquipment("EntityEvoker"); + registerEntityItemListEquipment("EntityGhast"); + registerEntityItemListEquipment("EntityGiantZombie"); + registerEntityItemListEquipment("EntityGuardian"); + registerEntityItemListEquipment("EntityGuardianElder"); + registerEntityItemListEquipment("EntityHorse"); + registerEntityItemListEquipment("EntityHorseDonkey"); + registerEntityItemListEquipment("EntityHorseMule"); + registerEntityItemListEquipment("EntityHorseSkeleton"); + registerEntityItemListEquipment("EntityHorseZombie"); + registerEntityItemListEquipment("EntityIronGolem"); + registerEntityItemListEquipment("EntityMagmaCube"); + registerEntityItemListEquipment("EntityMushroomCow"); + registerEntityItemListEquipment("EntityOcelot"); + registerEntityItemListEquipment("EntityPig"); + registerEntityItemListEquipment("EntityPigZombie"); + registerEntityItemListEquipment("EntityRabbit"); + registerEntityItemListEquipment("EntitySheep"); + registerEntityItemListEquipment("EntityShulker"); + registerEntityItemListEquipment("EntitySilverfish"); + registerEntityItemListEquipment("EntitySkeleton"); + registerEntityItemListEquipment("EntitySkeletonStray"); + registerEntityItemListEquipment("EntitySkeletonWither"); + registerEntityItemListEquipment("EntitySlime"); + registerEntityItemListEquipment("EntitySnowman"); + registerEntityItemListEquipment("EntitySpider"); + registerEntityItemListEquipment("EntitySquid"); + registerEntityItemListEquipment("EntityVex"); + registerEntityItemListEquipment("EntityVillager"); + registerEntityItemListEquipment("EntityVindicator"); + registerEntityItemListEquipment("EntityWitch"); + registerEntityItemListEquipment("EntityWither"); + registerEntityItemListEquipment("EntityWolf"); + registerEntityItemListEquipment("EntityZombie"); + registerEntityItemListEquipment("EntityZombieHusk"); + registerEntityItemListEquipment("EntityZombieVillager"); + registerEntityItemSingle("EntityFireworks", "FireworksItem"); + registerEntityItemSingle("EntityHorse", "ArmorItem"); + registerEntityItemSingle("EntityHorse", "SaddleItem"); + registerEntityItemSingle("EntityHorseMule", "SaddleItem"); + registerEntityItemSingle("EntityHorseSkeleton", "SaddleItem"); + registerEntityItemSingle("EntityHorseZombie", "SaddleItem"); + registerEntityItemSingle("EntityItem", "Item"); + registerEntityItemSingle("EntityItemFrame", "Item"); + registerEntityItemSingle("EntityPotion", "Potion"); + + registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItem("TileEntityRecordPlayer", "RecordItem")); + registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityBrewingStand", "Items")); + registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityChest", "Items")); + registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDispenser", "Items")); + registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDropper", "Items")); + registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityFurnace", "Items")); + registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityHopper", "Items")); + registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityShulkerBox", "Items")); + registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorMobSpawnerMobs()); + registerInspector(LegacyType.CHUNK, new DataInspectorChunks()); + registerInspector(LegacyType.ENTITY, new DataInspectorCommandBlock()); + registerInspector(LegacyType.ENTITY, new DataInspectorEntityPassengers()); + registerInspector(LegacyType.ENTITY, new DataInspectorMobSpawnerMinecart()); + registerInspector(LegacyType.ENTITY, new DataInspectorVillagers()); + registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorBlockEntity()); + registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorEntity()); + registerInspector(LegacyType.LEVEL, new DataInspectorLevelPlayer()); + registerInspector(LegacyType.PLAYER, new DataInspectorPlayer()); + registerInspector(LegacyType.PLAYER, new DataInspectorPlayerVehicle()); + registerInspector(LegacyType.STRUCTURE, new DataInspectorStructure()); + } + + private void registerConverters() { + registerConverter(LegacyType.ENTITY, new DataConverterEquipment()); + registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterSignText()); + registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterMaterialId()); + registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionId()); + registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterSpawnEgg()); + registerConverter(LegacyType.ENTITY, new DataConverterMinecart()); + registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterMobSpawner()); + registerConverter(LegacyType.ENTITY, new DataConverterUUID()); + registerConverter(LegacyType.ENTITY, new DataConverterHealth()); + registerConverter(LegacyType.ENTITY, new DataConverterSaddle()); + registerConverter(LegacyType.ENTITY, new DataConverterHanging()); + registerConverter(LegacyType.ENTITY, new DataConverterDropChances()); + registerConverter(LegacyType.ENTITY, new DataConverterRiding()); + registerConverter(LegacyType.ENTITY, new DataConverterArmorStand()); + registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBook()); + registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterCookedFish()); + registerConverter(LegacyType.ENTITY, new DataConverterZombie()); + registerConverter(LegacyType.OPTIONS, new DataConverterVBO()); + registerConverter(LegacyType.ENTITY, new DataConverterGuardian()); + registerConverter(LegacyType.ENTITY, new DataConverterSkeleton()); + registerConverter(LegacyType.ENTITY, new DataConverterZombieType()); + registerConverter(LegacyType.ENTITY, new DataConverterHorse()); + registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterTileEntity()); + registerConverter(LegacyType.ENTITY, new DataConverterEntity()); + registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBanner()); + registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionWater()); + registerConverter(LegacyType.ENTITY, new DataConverterShulker()); + registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterShulkerBoxItem()); + registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterShulkerBoxBlock()); + registerConverter(LegacyType.OPTIONS, new DataConverterLang()); + registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterTotem()); + registerConverter(LegacyType.CHUNK, new DataConverterBedBlock()); + registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBedItem()); + } + + private void registerEntityItemList(String type, String... keys) { + registerInspector(LegacyType.ENTITY, new DataInspectorItemList(type, keys)); + } + + private void registerEntityItemSingle(String type, String key) { + registerInspector(LegacyType.ENTITY, new DataInspectorItem(type, key)); + } + + private void registerEntityItemListEquipment(String type) { + registerEntityItemList(type, "ArmorItems", "HandItems"); + } + + private static final Map OLD_ID_TO_KEY_MAP = new HashMap<>(); + + static { + final Map map = OLD_ID_TO_KEY_MAP; + map.put("EntityItem", ResourceLocation.parse("item")); + map.put("EntityExperienceOrb", ResourceLocation.parse("xp_orb")); + map.put("EntityAreaEffectCloud", ResourceLocation.parse("area_effect_cloud")); + map.put("EntityGuardianElder", ResourceLocation.parse("elder_guardian")); + map.put("EntitySkeletonWither", ResourceLocation.parse("wither_skeleton")); + map.put("EntitySkeletonStray", ResourceLocation.parse("stray")); + map.put("EntityEgg", ResourceLocation.parse("egg")); + map.put("EntityLeash", ResourceLocation.parse("leash_knot")); + map.put("EntityPainting", ResourceLocation.parse("painting")); + map.put("EntityTippedArrow", ResourceLocation.parse("arrow")); + map.put("EntitySnowball", ResourceLocation.parse("snowball")); + map.put("EntityLargeFireball", ResourceLocation.parse("fireball")); + map.put("EntitySmallFireball", ResourceLocation.parse("small_fireball")); + map.put("EntityEnderPearl", ResourceLocation.parse("ender_pearl")); + map.put("EntityEnderSignal", ResourceLocation.parse("eye_of_ender_signal")); + map.put("EntityPotion", ResourceLocation.parse("potion")); + map.put("EntityThrownExpBottle", ResourceLocation.parse("xp_bottle")); + map.put("EntityItemFrame", ResourceLocation.parse("item_frame")); + map.put("EntityWitherSkull", ResourceLocation.parse("wither_skull")); + map.put("EntityTNTPrimed", ResourceLocation.parse("tnt")); + map.put("EntityFallingBlock", ResourceLocation.parse("falling_block")); + map.put("EntityFireworks", ResourceLocation.parse("fireworks_rocket")); + map.put("EntityZombieHusk", ResourceLocation.parse("husk")); + map.put("EntitySpectralArrow", ResourceLocation.parse("spectral_arrow")); + map.put("EntityShulkerBullet", ResourceLocation.parse("shulker_bullet")); + map.put("EntityDragonFireball", ResourceLocation.parse("dragon_fireball")); + map.put("EntityZombieVillager", ResourceLocation.parse("zombie_villager")); + map.put("EntityHorseSkeleton", ResourceLocation.parse("skeleton_horse")); + map.put("EntityHorseZombie", ResourceLocation.parse("zombie_horse")); + map.put("EntityArmorStand", ResourceLocation.parse("armor_stand")); + map.put("EntityHorseDonkey", ResourceLocation.parse("donkey")); + map.put("EntityHorseMule", ResourceLocation.parse("mule")); + map.put("EntityEvokerFangs", ResourceLocation.parse("evocation_fangs")); + map.put("EntityEvoker", ResourceLocation.parse("evocation_illager")); + map.put("EntityVex", ResourceLocation.parse("vex")); + map.put("EntityVindicator", ResourceLocation.parse("vindication_illager")); + map.put("EntityIllagerIllusioner", ResourceLocation.parse("illusion_illager")); + map.put("EntityMinecartCommandBlock", ResourceLocation.parse("commandblock_minecart")); + map.put("EntityBoat", ResourceLocation.parse("boat")); + map.put("EntityMinecartRideable", ResourceLocation.parse("minecart")); + map.put("EntityMinecartChest", ResourceLocation.parse("chest_minecart")); + map.put("EntityMinecartFurnace", ResourceLocation.parse("furnace_minecart")); + map.put("EntityMinecartTNT", ResourceLocation.parse("tnt_minecart")); + map.put("EntityMinecartHopper", ResourceLocation.parse("hopper_minecart")); + map.put("EntityMinecartMobSpawner", ResourceLocation.parse("spawner_minecart")); + map.put("EntityCreeper", ResourceLocation.parse("creeper")); + map.put("EntitySkeleton", ResourceLocation.parse("skeleton")); + map.put("EntitySpider", ResourceLocation.parse("spider")); + map.put("EntityGiantZombie", ResourceLocation.parse("giant")); + map.put("EntityZombie", ResourceLocation.parse("zombie")); + map.put("EntitySlime", ResourceLocation.parse("slime")); + map.put("EntityGhast", ResourceLocation.parse("ghast")); + map.put("EntityPigZombie", ResourceLocation.parse("zombie_pigman")); + map.put("EntityEnderman", ResourceLocation.parse("enderman")); + map.put("EntityCaveSpider", ResourceLocation.parse("cave_spider")); + map.put("EntitySilverfish", ResourceLocation.parse("silverfish")); + map.put("EntityBlaze", ResourceLocation.parse("blaze")); + map.put("EntityMagmaCube", ResourceLocation.parse("magma_cube")); + map.put("EntityEnderDragon", ResourceLocation.parse("ender_dragon")); + map.put("EntityWither", ResourceLocation.parse("wither")); + map.put("EntityBat", ResourceLocation.parse("bat")); + map.put("EntityWitch", ResourceLocation.parse("witch")); + map.put("EntityEndermite", ResourceLocation.parse("endermite")); + map.put("EntityGuardian", ResourceLocation.parse("guardian")); + map.put("EntityShulker", ResourceLocation.parse("shulker")); + map.put("EntityPig", ResourceLocation.parse("pig")); + map.put("EntitySheep", ResourceLocation.parse("sheep")); + map.put("EntityCow", ResourceLocation.parse("cow")); + map.put("EntityChicken", ResourceLocation.parse("chicken")); + map.put("EntitySquid", ResourceLocation.parse("squid")); + map.put("EntityWolf", ResourceLocation.parse("wolf")); + map.put("EntityMushroomCow", ResourceLocation.parse("mooshroom")); + map.put("EntitySnowman", ResourceLocation.parse("snowman")); + map.put("EntityOcelot", ResourceLocation.parse("ocelot")); + map.put("EntityIronGolem", ResourceLocation.parse("villager_golem")); + map.put("EntityHorse", ResourceLocation.parse("horse")); + map.put("EntityRabbit", ResourceLocation.parse("rabbit")); + map.put("EntityPolarBear", ResourceLocation.parse("polar_bear")); + map.put("EntityLlama", ResourceLocation.parse("llama")); + map.put("EntityLlamaSpit", ResourceLocation.parse("llama_spit")); + map.put("EntityParrot", ResourceLocation.parse("parrot")); + map.put("EntityVillager", ResourceLocation.parse("villager")); + map.put("EntityEnderCrystal", ResourceLocation.parse("ender_crystal")); + map.put("TileEntityFurnace", ResourceLocation.parse("furnace")); + map.put("TileEntityChest", ResourceLocation.parse("chest")); + map.put("TileEntityEnderChest", ResourceLocation.parse("ender_chest")); + map.put("TileEntityRecordPlayer", ResourceLocation.parse("jukebox")); + map.put("TileEntityDispenser", ResourceLocation.parse("dispenser")); + map.put("TileEntityDropper", ResourceLocation.parse("dropper")); + map.put("TileEntitySign", ResourceLocation.parse("sign")); + map.put("TileEntityMobSpawner", ResourceLocation.parse("mob_spawner")); + map.put("TileEntityNote", ResourceLocation.parse("noteblock")); + map.put("TileEntityPiston", ResourceLocation.parse("piston")); + map.put("TileEntityBrewingStand", ResourceLocation.parse("brewing_stand")); + map.put("TileEntityEnchantTable", ResourceLocation.parse("enchanting_table")); + map.put("TileEntityEnderPortal", ResourceLocation.parse("end_portal")); + map.put("TileEntityBeacon", ResourceLocation.parse("beacon")); + map.put("TileEntitySkull", ResourceLocation.parse("skull")); + map.put("TileEntityLightDetector", ResourceLocation.parse("daylight_detector")); + map.put("TileEntityHopper", ResourceLocation.parse("hopper")); + map.put("TileEntityComparator", ResourceLocation.parse("comparator")); + map.put("TileEntityFlowerPot", ResourceLocation.parse("flower_pot")); + map.put("TileEntityBanner", ResourceLocation.parse("banner")); + map.put("TileEntityStructure", ResourceLocation.parse("structure_block")); + map.put("TileEntityEndGateway", ResourceLocation.parse("end_gateway")); + map.put("TileEntityCommand", ResourceLocation.parse("command_block")); + map.put("TileEntityShulkerBox", ResourceLocation.parse("shulker_box")); + map.put("TileEntityBed", ResourceLocation.parse("bed")); + } + + private static ResourceLocation getKey(String type) { + final ResourceLocation key = OLD_ID_TO_KEY_MAP.get(type); + if (key == null) { + throw new IllegalArgumentException("Unknown mapping for " + type); + } + return key; + } + + private static void convertCompound(LegacyType type, CompoundTag cmp, String key, int sourceVer, int targetVer) { + cmp.put(key, convert(type, cmp.getCompound(key), sourceVer, targetVer)); + } + + private static void convertItem(CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { + if (nbttagcompound.contains(key, 10)) { + convertCompound(LegacyType.ITEM_INSTANCE, nbttagcompound, key, sourceVer, targetVer); + } + } + + private static void convertItems(CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { + if (nbttagcompound.contains(key, 9)) { + ListTag nbttaglist = nbttagcompound.getList(key, 10); + + for (int j = 0; j < nbttaglist.size(); ++j) { + nbttaglist.set(j, convert(LegacyType.ITEM_INSTANCE, nbttaglist.getCompound(j), sourceVer, targetVer)); + } + } + + } + + private static class DataConverterEquipment implements DataConverter { + + DataConverterEquipment() { + } + + public int getDataVersion() { + return 100; + } + + public CompoundTag convert(CompoundTag cmp) { + ListTag nbttaglist = cmp.getList("Equipment", 10); + ListTag nbttaglist1; + + if (!nbttaglist.isEmpty() && !cmp.contains("HandItems", 10)) { + nbttaglist1 = new ListTag(); + nbttaglist1.add(nbttaglist.get(0)); + nbttaglist1.add(new CompoundTag()); + cmp.put("HandItems", nbttaglist1); + } + + if (nbttaglist.size() > 1 && !cmp.contains("ArmorItem", 10)) { + nbttaglist1 = new ListTag(); + nbttaglist1.add(nbttaglist.get(1)); + nbttaglist1.add(nbttaglist.get(2)); + nbttaglist1.add(nbttaglist.get(3)); + nbttaglist1.add(nbttaglist.get(4)); + cmp.put("ArmorItems", nbttaglist1); + } + + cmp.remove("Equipment"); + if (cmp.contains("DropChances", 9)) { + nbttaglist1 = cmp.getList("DropChances", 5); + ListTag nbttaglist2; + + if (!cmp.contains("HandDropChances", 10)) { + nbttaglist2 = new ListTag(); + nbttaglist2.add(FloatTag.valueOf(nbttaglist1.getFloat(0))); + nbttaglist2.add(FloatTag.valueOf(0.0F)); + cmp.put("HandDropChances", nbttaglist2); + } + + if (!cmp.contains("ArmorDropChances", 10)) { + nbttaglist2 = new ListTag(); + nbttaglist2.add(FloatTag.valueOf(nbttaglist1.getFloat(1))); + nbttaglist2.add(FloatTag.valueOf(nbttaglist1.getFloat(2))); + nbttaglist2.add(FloatTag.valueOf(nbttaglist1.getFloat(3))); + nbttaglist2.add(FloatTag.valueOf(nbttaglist1.getFloat(4))); + cmp.put("ArmorDropChances", nbttaglist2); + } + + cmp.remove("DropChances"); + } + + return cmp; + } + } + + private static class DataInspectorBlockEntity implements DataInspector { + + private static final Map b = Maps.newHashMap(); + private static final Map c = Maps.newHashMap(); + + DataInspectorBlockEntity() { + } + + @Nullable + private static String convertEntityId(int i, String s) { + String key = ResourceLocation.parse(s).toString(); + if (i < 515 && DataInspectorBlockEntity.b.containsKey(key)) { + return DataInspectorBlockEntity.b.get(key); + } else { + return DataInspectorBlockEntity.c.get(key); + } + } + + public CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer) { + if (!cmp.contains("tag", 10)) { + return cmp; + } else { + CompoundTag nbttagcompound1 = cmp.getCompound("tag"); + + if (nbttagcompound1.contains("BlockEntityTag", 10)) { + CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); + String s = cmp.getString("id"); + String s1 = convertEntityId(sourceVer, s); + boolean flag; + + if (s1 == null) { + // CraftBukkit - Remove unnecessary warning (occurs when deserializing a Shulker Box item) + // DataInspectorBlockEntity.a.warn("Unable to resolve BlockEntity for ItemInstance: {}", s); + flag = false; + } else { + flag = !nbttagcompound2.contains("id"); + nbttagcompound2.putString("id", s1); + } + + convert(LegacyType.BLOCK_ENTITY, nbttagcompound2, sourceVer, targetVer); + if (flag) { + nbttagcompound2.remove("id"); + } + } + + return cmp; + } + } + + static { + Map map = DataInspectorBlockEntity.b; + + map.put("minecraft:furnace", "Furnace"); + map.put("minecraft:lit_furnace", "Furnace"); + map.put("minecraft:chest", "Chest"); + map.put("minecraft:trapped_chest", "Chest"); + map.put("minecraft:ender_chest", "EnderChest"); + map.put("minecraft:jukebox", "RecordPlayer"); + map.put("minecraft:dispenser", "Trap"); + map.put("minecraft:dropper", "Dropper"); + map.put("minecraft:sign", "Sign"); + map.put("minecraft:mob_spawner", "MobSpawner"); + map.put("minecraft:noteblock", "Music"); + map.put("minecraft:brewing_stand", "Cauldron"); + map.put("minecraft:enhanting_table", "EnchantTable"); + map.put("minecraft:command_block", "CommandBlock"); + map.put("minecraft:beacon", "Beacon"); + map.put("minecraft:skull", "Skull"); + map.put("minecraft:daylight_detector", "DLDetector"); + map.put("minecraft:hopper", "Hopper"); + map.put("minecraft:banner", "Banner"); + map.put("minecraft:flower_pot", "FlowerPot"); + map.put("minecraft:repeating_command_block", "CommandBlock"); + map.put("minecraft:chain_command_block", "CommandBlock"); + map.put("minecraft:standing_sign", "Sign"); + map.put("minecraft:wall_sign", "Sign"); + map.put("minecraft:piston_head", "Piston"); + map.put("minecraft:daylight_detector_inverted", "DLDetector"); + map.put("minecraft:unpowered_comparator", "Comparator"); + map.put("minecraft:powered_comparator", "Comparator"); + map.put("minecraft:wall_banner", "Banner"); + map.put("minecraft:standing_banner", "Banner"); + map.put("minecraft:structure_block", "Structure"); + map.put("minecraft:end_portal", "Airportal"); + map.put("minecraft:end_gateway", "EndGateway"); + map.put("minecraft:shield", "Shield"); + map = DataInspectorBlockEntity.c; + map.put("minecraft:furnace", "minecraft:furnace"); + map.put("minecraft:lit_furnace", "minecraft:furnace"); + map.put("minecraft:chest", "minecraft:chest"); + map.put("minecraft:trapped_chest", "minecraft:chest"); + map.put("minecraft:ender_chest", "minecraft:enderchest"); + map.put("minecraft:jukebox", "minecraft:jukebox"); + map.put("minecraft:dispenser", "minecraft:dispenser"); + map.put("minecraft:dropper", "minecraft:dropper"); + map.put("minecraft:sign", "minecraft:sign"); + map.put("minecraft:mob_spawner", "minecraft:mob_spawner"); + map.put("minecraft:noteblock", "minecraft:noteblock"); + map.put("minecraft:brewing_stand", "minecraft:brewing_stand"); + map.put("minecraft:enhanting_table", "minecraft:enchanting_table"); + map.put("minecraft:command_block", "minecraft:command_block"); + map.put("minecraft:beacon", "minecraft:beacon"); + map.put("minecraft:skull", "minecraft:skull"); + map.put("minecraft:daylight_detector", "minecraft:daylight_detector"); + map.put("minecraft:hopper", "minecraft:hopper"); + map.put("minecraft:banner", "minecraft:banner"); + map.put("minecraft:flower_pot", "minecraft:flower_pot"); + map.put("minecraft:repeating_command_block", "minecraft:command_block"); + map.put("minecraft:chain_command_block", "minecraft:command_block"); + map.put("minecraft:shulker_box", "minecraft:shulker_box"); + map.put("minecraft:white_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:orange_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:magenta_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:light_blue_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:yellow_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:lime_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:pink_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:gray_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:silver_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:cyan_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:purple_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:blue_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:brown_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:green_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:red_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:black_shulker_box", "minecraft:shulker_box"); + map.put("minecraft:bed", "minecraft:bed"); + map.put("minecraft:standing_sign", "minecraft:sign"); + map.put("minecraft:wall_sign", "minecraft:sign"); + map.put("minecraft:piston_head", "minecraft:piston"); + map.put("minecraft:daylight_detector_inverted", "minecraft:daylight_detector"); + map.put("minecraft:unpowered_comparator", "minecraft:comparator"); + map.put("minecraft:powered_comparator", "minecraft:comparator"); + map.put("minecraft:wall_banner", "minecraft:banner"); + map.put("minecraft:standing_banner", "minecraft:banner"); + map.put("minecraft:structure_block", "minecraft:structure_block"); + map.put("minecraft:end_portal", "minecraft:end_portal"); + map.put("minecraft:end_gateway", "minecraft:end_gateway"); + map.put("minecraft:shield", "minecraft:shield"); + } + } + + private static class DataInspectorEntity implements DataInspector { + + DataInspectorEntity() { + } + + public CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer) { + CompoundTag nbttagcompound1 = cmp.getCompound("tag"); + + if (nbttagcompound1.contains("EntityTag", 10)) { + CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); + String s = cmp.getString("id"); + String s1; + + if ("minecraft:armor_stand".equals(s)) { + s1 = sourceVer < 515 ? "ArmorStand" : "minecraft:armor_stand"; + } else { + if (!"minecraft:spawn_egg".equals(s)) { + return cmp; + } + + s1 = nbttagcompound2.getString("id"); + } + + boolean flag; + + flag = !nbttagcompound2.contains("id", 8); + nbttagcompound2.putString("id", s1); + + convert(LegacyType.ENTITY, nbttagcompound2, sourceVer, targetVer); + if (flag) { + nbttagcompound2.remove("id"); + } + } + + return cmp; + } + } + + + private abstract static class DataInspectorTagged implements DataInspector { + + private final ResourceLocation key; + + DataInspectorTagged(String type) { + this.key = getKey(type); + } + + public CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer) { + if (this.key.equals(ResourceLocation.parse(cmp.getString("id")))) { + cmp = this.inspectChecked(cmp, sourceVer, targetVer); + } + + return cmp; + } + + abstract CompoundTag inspectChecked(CompoundTag nbttagcompound, int sourceVer, int targetVer); + } + + private static class DataInspectorItemList extends DataInspectorTagged { + + private final String[] keys; + + DataInspectorItemList(String oclass, String... astring) { + super(oclass); + this.keys = astring; + } + + CompoundTag inspectChecked(CompoundTag nbttagcompound, int sourceVer, int targetVer) { + for (String s : this.keys) { + PaperweightDataConverters.convertItems(nbttagcompound, s, sourceVer, targetVer); + } + + return nbttagcompound; + } + } + + private static class DataInspectorItem extends DataInspectorTagged { + + private final String[] keys; + + DataInspectorItem(String oclass, String... astring) { + super(oclass); + this.keys = astring; + } + + CompoundTag inspectChecked(CompoundTag nbttagcompound, int sourceVer, int targetVer) { + for (String key : this.keys) { + PaperweightDataConverters.convertItem(nbttagcompound, key, sourceVer, targetVer); + } + + return nbttagcompound; + } + } + + private static class DataConverterMaterialId implements DataConverter { + + private static final String[] materials = new String[2268]; + + DataConverterMaterialId() { + } + + public int getDataVersion() { + return 102; + } + + public CompoundTag convert(CompoundTag cmp) { + if (cmp.contains("id", 99)) { + short short0 = cmp.getShort("id"); + + if (short0 > 0 && short0 < materials.length && materials[short0] != null) { + cmp.putString("id", materials[short0]); + } + } + + return cmp; + } + + static { + materials[1] = "minecraft:stone"; + materials[2] = "minecraft:grass"; + materials[3] = "minecraft:dirt"; + materials[4] = "minecraft:cobblestone"; + materials[5] = "minecraft:planks"; + materials[6] = "minecraft:sapling"; + materials[7] = "minecraft:bedrock"; + materials[8] = "minecraft:flowing_water"; + materials[9] = "minecraft:water"; + materials[10] = "minecraft:flowing_lava"; + materials[11] = "minecraft:lava"; + materials[12] = "minecraft:sand"; + materials[13] = "minecraft:gravel"; + materials[14] = "minecraft:gold_ore"; + materials[15] = "minecraft:iron_ore"; + materials[16] = "minecraft:coal_ore"; + materials[17] = "minecraft:log"; + materials[18] = "minecraft:leaves"; + materials[19] = "minecraft:sponge"; + materials[20] = "minecraft:glass"; + materials[21] = "minecraft:lapis_ore"; + materials[22] = "minecraft:lapis_block"; + materials[23] = "minecraft:dispenser"; + materials[24] = "minecraft:sandstone"; + materials[25] = "minecraft:noteblock"; + materials[27] = "minecraft:golden_rail"; + materials[28] = "minecraft:detector_rail"; + materials[29] = "minecraft:sticky_piston"; + materials[30] = "minecraft:web"; + materials[31] = "minecraft:tallgrass"; + materials[32] = "minecraft:deadbush"; + materials[33] = "minecraft:piston"; + materials[35] = "minecraft:wool"; + materials[37] = "minecraft:yellow_flower"; + materials[38] = "minecraft:red_flower"; + materials[39] = "minecraft:brown_mushroom"; + materials[40] = "minecraft:red_mushroom"; + materials[41] = "minecraft:gold_block"; + materials[42] = "minecraft:iron_block"; + materials[43] = "minecraft:double_stone_slab"; + materials[44] = "minecraft:stone_slab"; + materials[45] = "minecraft:brick_block"; + materials[46] = "minecraft:tnt"; + materials[47] = "minecraft:bookshelf"; + materials[48] = "minecraft:mossy_cobblestone"; + materials[49] = "minecraft:obsidian"; + materials[50] = "minecraft:torch"; + materials[51] = "minecraft:fire"; + materials[52] = "minecraft:mob_spawner"; + materials[53] = "minecraft:oak_stairs"; + materials[54] = "minecraft:chest"; + materials[56] = "minecraft:diamond_ore"; + materials[57] = "minecraft:diamond_block"; + materials[58] = "minecraft:crafting_table"; + materials[60] = "minecraft:farmland"; + materials[61] = "minecraft:furnace"; + materials[62] = "minecraft:lit_furnace"; + materials[65] = "minecraft:ladder"; + materials[66] = "minecraft:rail"; + materials[67] = "minecraft:stone_stairs"; + materials[69] = "minecraft:lever"; + materials[70] = "minecraft:stone_pressure_plate"; + materials[72] = "minecraft:wooden_pressure_plate"; + materials[73] = "minecraft:redstone_ore"; + materials[76] = "minecraft:redstone_torch"; + materials[77] = "minecraft:stone_button"; + materials[78] = "minecraft:snow_layer"; + materials[79] = "minecraft:ice"; + materials[80] = "minecraft:snow"; + materials[81] = "minecraft:cactus"; + materials[82] = "minecraft:clay"; + materials[84] = "minecraft:jukebox"; + materials[85] = "minecraft:fence"; + materials[86] = "minecraft:pumpkin"; + materials[87] = "minecraft:netherrack"; + materials[88] = "minecraft:soul_sand"; + materials[89] = "minecraft:glowstone"; + materials[90] = "minecraft:portal"; + materials[91] = "minecraft:lit_pumpkin"; + materials[95] = "minecraft:stained_glass"; + materials[96] = "minecraft:trapdoor"; + materials[97] = "minecraft:monster_egg"; + materials[98] = "minecraft:stonebrick"; + materials[99] = "minecraft:brown_mushroom_block"; + materials[100] = "minecraft:red_mushroom_block"; + materials[101] = "minecraft:iron_bars"; + materials[102] = "minecraft:glass_pane"; + materials[103] = "minecraft:melon_block"; + materials[106] = "minecraft:vine"; + materials[107] = "minecraft:fence_gate"; + materials[108] = "minecraft:brick_stairs"; + materials[109] = "minecraft:stone_brick_stairs"; + materials[110] = "minecraft:mycelium"; + materials[111] = "minecraft:waterlily"; + materials[112] = "minecraft:nether_brick"; + materials[113] = "minecraft:nether_brick_fence"; + materials[114] = "minecraft:nether_brick_stairs"; + materials[116] = "minecraft:enchanting_table"; + materials[119] = "minecraft:end_portal"; + materials[120] = "minecraft:end_portal_frame"; + materials[121] = "minecraft:end_stone"; + materials[122] = "minecraft:dragon_egg"; + materials[123] = "minecraft:redstone_lamp"; + materials[125] = "minecraft:double_wooden_slab"; + materials[126] = "minecraft:wooden_slab"; + materials[127] = "minecraft:cocoa"; + materials[128] = "minecraft:sandstone_stairs"; + materials[129] = "minecraft:emerald_ore"; + materials[130] = "minecraft:ender_chest"; + materials[131] = "minecraft:tripwire_hook"; + materials[133] = "minecraft:emerald_block"; + materials[134] = "minecraft:spruce_stairs"; + materials[135] = "minecraft:birch_stairs"; + materials[136] = "minecraft:jungle_stairs"; + materials[137] = "minecraft:command_block"; + materials[138] = "minecraft:beacon"; + materials[139] = "minecraft:cobblestone_wall"; + materials[141] = "minecraft:carrots"; + materials[142] = "minecraft:potatoes"; + materials[143] = "minecraft:wooden_button"; + materials[145] = "minecraft:anvil"; + materials[146] = "minecraft:trapped_chest"; + materials[147] = "minecraft:light_weighted_pressure_plate"; + materials[148] = "minecraft:heavy_weighted_pressure_plate"; + materials[151] = "minecraft:daylight_detector"; + materials[152] = "minecraft:redstone_block"; + materials[153] = "minecraft:quartz_ore"; + materials[154] = "minecraft:hopper"; + materials[155] = "minecraft:quartz_block"; + materials[156] = "minecraft:quartz_stairs"; + materials[157] = "minecraft:activator_rail"; + materials[158] = "minecraft:dropper"; + materials[159] = "minecraft:stained_hardened_clay"; + materials[160] = "minecraft:stained_glass_pane"; + materials[161] = "minecraft:leaves2"; + materials[162] = "minecraft:log2"; + materials[163] = "minecraft:acacia_stairs"; + materials[164] = "minecraft:dark_oak_stairs"; + materials[170] = "minecraft:hay_block"; + materials[171] = "minecraft:carpet"; + materials[172] = "minecraft:hardened_clay"; + materials[173] = "minecraft:coal_block"; + materials[174] = "minecraft:packed_ice"; + materials[175] = "minecraft:double_plant"; + materials[256] = "minecraft:iron_shovel"; + materials[257] = "minecraft:iron_pickaxe"; + materials[258] = "minecraft:iron_axe"; + materials[259] = "minecraft:flint_and_steel"; + materials[260] = "minecraft:apple"; + materials[261] = "minecraft:bow"; + materials[262] = "minecraft:arrow"; + materials[263] = "minecraft:coal"; + materials[264] = "minecraft:diamond"; + materials[265] = "minecraft:iron_ingot"; + materials[266] = "minecraft:gold_ingot"; + materials[267] = "minecraft:iron_sword"; + materials[268] = "minecraft:wooden_sword"; + materials[269] = "minecraft:wooden_shovel"; + materials[270] = "minecraft:wooden_pickaxe"; + materials[271] = "minecraft:wooden_axe"; + materials[272] = "minecraft:stone_sword"; + materials[273] = "minecraft:stone_shovel"; + materials[274] = "minecraft:stone_pickaxe"; + materials[275] = "minecraft:stone_axe"; + materials[276] = "minecraft:diamond_sword"; + materials[277] = "minecraft:diamond_shovel"; + materials[278] = "minecraft:diamond_pickaxe"; + materials[279] = "minecraft:diamond_axe"; + materials[280] = "minecraft:stick"; + materials[281] = "minecraft:bowl"; + materials[282] = "minecraft:mushroom_stew"; + materials[283] = "minecraft:golden_sword"; + materials[284] = "minecraft:golden_shovel"; + materials[285] = "minecraft:golden_pickaxe"; + materials[286] = "minecraft:golden_axe"; + materials[287] = "minecraft:string"; + materials[288] = "minecraft:feather"; + materials[289] = "minecraft:gunpowder"; + materials[290] = "minecraft:wooden_hoe"; + materials[291] = "minecraft:stone_hoe"; + materials[292] = "minecraft:iron_hoe"; + materials[293] = "minecraft:diamond_hoe"; + materials[294] = "minecraft:golden_hoe"; + materials[295] = "minecraft:wheat_seeds"; + materials[296] = "minecraft:wheat"; + materials[297] = "minecraft:bread"; + materials[298] = "minecraft:leather_helmet"; + materials[299] = "minecraft:leather_chestplate"; + materials[300] = "minecraft:leather_leggings"; + materials[301] = "minecraft:leather_boots"; + materials[302] = "minecraft:chainmail_helmet"; + materials[303] = "minecraft:chainmail_chestplate"; + materials[304] = "minecraft:chainmail_leggings"; + materials[305] = "minecraft:chainmail_boots"; + materials[306] = "minecraft:iron_helmet"; + materials[307] = "minecraft:iron_chestplate"; + materials[308] = "minecraft:iron_leggings"; + materials[309] = "minecraft:iron_boots"; + materials[310] = "minecraft:diamond_helmet"; + materials[311] = "minecraft:diamond_chestplate"; + materials[312] = "minecraft:diamond_leggings"; + materials[313] = "minecraft:diamond_boots"; + materials[314] = "minecraft:golden_helmet"; + materials[315] = "minecraft:golden_chestplate"; + materials[316] = "minecraft:golden_leggings"; + materials[317] = "minecraft:golden_boots"; + materials[318] = "minecraft:flint"; + materials[319] = "minecraft:porkchop"; + materials[320] = "minecraft:cooked_porkchop"; + materials[321] = "minecraft:painting"; + materials[322] = "minecraft:golden_apple"; + materials[323] = "minecraft:sign"; + materials[324] = "minecraft:wooden_door"; + materials[325] = "minecraft:bucket"; + materials[326] = "minecraft:water_bucket"; + materials[327] = "minecraft:lava_bucket"; + materials[328] = "minecraft:minecart"; + materials[329] = "minecraft:saddle"; + materials[330] = "minecraft:iron_door"; + materials[331] = "minecraft:redstone"; + materials[332] = "minecraft:snowball"; + materials[333] = "minecraft:boat"; + materials[334] = "minecraft:leather"; + materials[335] = "minecraft:milk_bucket"; + materials[336] = "minecraft:brick"; + materials[337] = "minecraft:clay_ball"; + materials[338] = "minecraft:reeds"; + materials[339] = "minecraft:paper"; + materials[340] = "minecraft:book"; + materials[341] = "minecraft:slime_ball"; + materials[342] = "minecraft:chest_minecart"; + materials[343] = "minecraft:furnace_minecart"; + materials[344] = "minecraft:egg"; + materials[345] = "minecraft:compass"; + materials[346] = "minecraft:fishing_rod"; + materials[347] = "minecraft:clock"; + materials[348] = "minecraft:glowstone_dust"; + materials[349] = "minecraft:fish"; + materials[350] = "minecraft:cooked_fish"; // Paper - cooked_fished -> cooked_fish + materials[351] = "minecraft:dye"; + materials[352] = "minecraft:bone"; + materials[353] = "minecraft:sugar"; + materials[354] = "minecraft:cake"; + materials[355] = "minecraft:bed"; + materials[356] = "minecraft:repeater"; + materials[357] = "minecraft:cookie"; + materials[358] = "minecraft:filled_map"; + materials[359] = "minecraft:shears"; + materials[360] = "minecraft:melon"; + materials[361] = "minecraft:pumpkin_seeds"; + materials[362] = "minecraft:melon_seeds"; + materials[363] = "minecraft:beef"; + materials[364] = "minecraft:cooked_beef"; + materials[365] = "minecraft:chicken"; + materials[366] = "minecraft:cooked_chicken"; + materials[367] = "minecraft:rotten_flesh"; + materials[368] = "minecraft:ender_pearl"; + materials[369] = "minecraft:blaze_rod"; + materials[370] = "minecraft:ghast_tear"; + materials[371] = "minecraft:gold_nugget"; + materials[372] = "minecraft:nether_wart"; + materials[373] = "minecraft:potion"; + materials[374] = "minecraft:glass_bottle"; + materials[375] = "minecraft:spider_eye"; + materials[376] = "minecraft:fermented_spider_eye"; + materials[377] = "minecraft:blaze_powder"; + materials[378] = "minecraft:magma_cream"; + materials[379] = "minecraft:brewing_stand"; + materials[380] = "minecraft:cauldron"; + materials[381] = "minecraft:ender_eye"; + materials[382] = "minecraft:speckled_melon"; + materials[383] = "minecraft:spawn_egg"; + materials[384] = "minecraft:experience_bottle"; + materials[385] = "minecraft:fire_charge"; + materials[386] = "minecraft:writable_book"; + materials[387] = "minecraft:written_book"; + materials[388] = "minecraft:emerald"; + materials[389] = "minecraft:item_frame"; + materials[390] = "minecraft:flower_pot"; + materials[391] = "minecraft:carrot"; + materials[392] = "minecraft:potato"; + materials[393] = "minecraft:baked_potato"; + materials[394] = "minecraft:poisonous_potato"; + materials[395] = "minecraft:map"; + materials[396] = "minecraft:golden_carrot"; + materials[397] = "minecraft:skull"; + materials[398] = "minecraft:carrot_on_a_stick"; + materials[399] = "minecraft:nether_star"; + materials[400] = "minecraft:pumpkin_pie"; + materials[401] = "minecraft:fireworks"; + materials[402] = "minecraft:firework_charge"; + materials[403] = "minecraft:enchanted_book"; + materials[404] = "minecraft:comparator"; + materials[405] = "minecraft:netherbrick"; + materials[406] = "minecraft:quartz"; + materials[407] = "minecraft:tnt_minecart"; + materials[408] = "minecraft:hopper_minecart"; + materials[417] = "minecraft:iron_horse_armor"; + materials[418] = "minecraft:golden_horse_armor"; + materials[419] = "minecraft:diamond_horse_armor"; + materials[420] = "minecraft:lead"; + materials[421] = "minecraft:name_tag"; + materials[422] = "minecraft:command_block_minecart"; + materials[2256] = "minecraft:record_13"; + materials[2257] = "minecraft:record_cat"; + materials[2258] = "minecraft:record_blocks"; + materials[2259] = "minecraft:record_chirp"; + materials[2260] = "minecraft:record_far"; + materials[2261] = "minecraft:record_mall"; + materials[2262] = "minecraft:record_mellohi"; + materials[2263] = "minecraft:record_stal"; + materials[2264] = "minecraft:record_strad"; + materials[2265] = "minecraft:record_ward"; + materials[2266] = "minecraft:record_11"; + materials[2267] = "minecraft:record_wait"; + // Paper start + materials[409] = "minecraft:prismarine_shard"; + materials[410] = "minecraft:prismarine_crystals"; + materials[411] = "minecraft:rabbit"; + materials[412] = "minecraft:cooked_rabbit"; + materials[413] = "minecraft:rabbit_stew"; + materials[414] = "minecraft:rabbit_foot"; + materials[415] = "minecraft:rabbit_hide"; + materials[416] = "minecraft:armor_stand"; + materials[423] = "minecraft:mutton"; + materials[424] = "minecraft:cooked_mutton"; + materials[425] = "minecraft:banner"; + materials[426] = "minecraft:end_crystal"; + materials[427] = "minecraft:spruce_door"; + materials[428] = "minecraft:birch_door"; + materials[429] = "minecraft:jungle_door"; + materials[430] = "minecraft:acacia_door"; + materials[431] = "minecraft:dark_oak_door"; + materials[432] = "minecraft:chorus_fruit"; + materials[433] = "minecraft:chorus_fruit_popped"; + materials[434] = "minecraft:beetroot"; + materials[435] = "minecraft:beetroot_seeds"; + materials[436] = "minecraft:beetroot_soup"; + materials[437] = "minecraft:dragon_breath"; + materials[438] = "minecraft:splash_potion"; + materials[439] = "minecraft:spectral_arrow"; + materials[440] = "minecraft:tipped_arrow"; + materials[441] = "minecraft:lingering_potion"; + materials[442] = "minecraft:shield"; + materials[443] = "minecraft:elytra"; + materials[444] = "minecraft:spruce_boat"; + materials[445] = "minecraft:birch_boat"; + materials[446] = "minecraft:jungle_boat"; + materials[447] = "minecraft:acacia_boat"; + materials[448] = "minecraft:dark_oak_boat"; + materials[449] = "minecraft:totem_of_undying"; + materials[450] = "minecraft:shulker_shell"; + materials[452] = "minecraft:iron_nugget"; + materials[453] = "minecraft:knowledge_book"; + // Paper end + } + } + + private static class DataConverterArmorStand implements DataConverter { + + DataConverterArmorStand() { + } + + public int getDataVersion() { + return 147; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("ArmorStand".equals(cmp.getString("id")) && cmp.getBoolean("Silent") && !cmp.getBoolean("Marker")) { + cmp.remove("Silent"); + } + + return cmp; + } + } + + private static class DataConverterBanner implements DataConverter { + + DataConverterBanner() { + } + + public int getDataVersion() { + return 804; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("minecraft:banner".equals(cmp.getString("id")) && cmp.contains("tag", 10)) { + CompoundTag nbttagcompound1 = cmp.getCompound("tag"); + + if (nbttagcompound1.contains("BlockEntityTag", 10)) { + CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); + + if (nbttagcompound2.contains("Base", 99)) { + cmp.putShort("Damage", (short) (nbttagcompound2.getShort("Base") & 15)); + if (nbttagcompound1.contains("display", 10)) { + CompoundTag nbttagcompound3 = nbttagcompound1.getCompound("display"); + + if (nbttagcompound3.contains("Lore", 9)) { + ListTag nbttaglist = nbttagcompound3.getList("Lore", 8); + + if (nbttaglist.size() == 1 && "(+NBT)".equals(nbttaglist.getString(0))) { + return cmp; + } + } + } + + nbttagcompound2.remove("Base"); + if (nbttagcompound2.isEmpty()) { + nbttagcompound1.remove("BlockEntityTag"); + } + + if (nbttagcompound1.isEmpty()) { + cmp.remove("tag"); + } + } + } + } + + return cmp; + } + } + + private static class DataConverterPotionId implements DataConverter { + + private static final String[] potions = new String[128]; + + DataConverterPotionId() { + } + + public int getDataVersion() { + return 102; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("minecraft:potion".equals(cmp.getString("id"))) { + CompoundTag nbttagcompound1 = cmp.getCompound("tag"); + short short0 = cmp.getShort("Damage"); + + if (!nbttagcompound1.contains("Potion", 8)) { + String s = DataConverterPotionId.potions[short0 & 127]; + + nbttagcompound1.putString("Potion", s == null ? "minecraft:water" : s); + cmp.put("tag", nbttagcompound1); + if ((short0 & 16384) == 16384) { + cmp.putString("id", "minecraft:splash_potion"); + } + } + + if (short0 != 0) { + cmp.putShort("Damage", (short) 0); + } + } + + return cmp; + } + + static { + DataConverterPotionId.potions[0] = "minecraft:water"; + DataConverterPotionId.potions[1] = "minecraft:regeneration"; + DataConverterPotionId.potions[2] = "minecraft:swiftness"; + DataConverterPotionId.potions[3] = "minecraft:fire_resistance"; + DataConverterPotionId.potions[4] = "minecraft:poison"; + DataConverterPotionId.potions[5] = "minecraft:healing"; + DataConverterPotionId.potions[6] = "minecraft:night_vision"; + DataConverterPotionId.potions[7] = null; + DataConverterPotionId.potions[8] = "minecraft:weakness"; + DataConverterPotionId.potions[9] = "minecraft:strength"; + DataConverterPotionId.potions[10] = "minecraft:slowness"; + DataConverterPotionId.potions[11] = "minecraft:leaping"; + DataConverterPotionId.potions[12] = "minecraft:harming"; + DataConverterPotionId.potions[13] = "minecraft:water_breathing"; + DataConverterPotionId.potions[14] = "minecraft:invisibility"; + DataConverterPotionId.potions[15] = null; + DataConverterPotionId.potions[16] = "minecraft:awkward"; + DataConverterPotionId.potions[17] = "minecraft:regeneration"; + DataConverterPotionId.potions[18] = "minecraft:swiftness"; + DataConverterPotionId.potions[19] = "minecraft:fire_resistance"; + DataConverterPotionId.potions[20] = "minecraft:poison"; + DataConverterPotionId.potions[21] = "minecraft:healing"; + DataConverterPotionId.potions[22] = "minecraft:night_vision"; + DataConverterPotionId.potions[23] = null; + DataConverterPotionId.potions[24] = "minecraft:weakness"; + DataConverterPotionId.potions[25] = "minecraft:strength"; + DataConverterPotionId.potions[26] = "minecraft:slowness"; + DataConverterPotionId.potions[27] = "minecraft:leaping"; + DataConverterPotionId.potions[28] = "minecraft:harming"; + DataConverterPotionId.potions[29] = "minecraft:water_breathing"; + DataConverterPotionId.potions[30] = "minecraft:invisibility"; + DataConverterPotionId.potions[31] = null; + DataConverterPotionId.potions[32] = "minecraft:thick"; + DataConverterPotionId.potions[33] = "minecraft:strong_regeneration"; + DataConverterPotionId.potions[34] = "minecraft:strong_swiftness"; + DataConverterPotionId.potions[35] = "minecraft:fire_resistance"; + DataConverterPotionId.potions[36] = "minecraft:strong_poison"; + DataConverterPotionId.potions[37] = "minecraft:strong_healing"; + DataConverterPotionId.potions[38] = "minecraft:night_vision"; + DataConverterPotionId.potions[39] = null; + DataConverterPotionId.potions[40] = "minecraft:weakness"; + DataConverterPotionId.potions[41] = "minecraft:strong_strength"; + DataConverterPotionId.potions[42] = "minecraft:slowness"; + DataConverterPotionId.potions[43] = "minecraft:strong_leaping"; + DataConverterPotionId.potions[44] = "minecraft:strong_harming"; + DataConverterPotionId.potions[45] = "minecraft:water_breathing"; + DataConverterPotionId.potions[46] = "minecraft:invisibility"; + DataConverterPotionId.potions[47] = null; + DataConverterPotionId.potions[48] = null; + DataConverterPotionId.potions[49] = "minecraft:strong_regeneration"; + DataConverterPotionId.potions[50] = "minecraft:strong_swiftness"; + DataConverterPotionId.potions[51] = "minecraft:fire_resistance"; + DataConverterPotionId.potions[52] = "minecraft:strong_poison"; + DataConverterPotionId.potions[53] = "minecraft:strong_healing"; + DataConverterPotionId.potions[54] = "minecraft:night_vision"; + DataConverterPotionId.potions[55] = null; + DataConverterPotionId.potions[56] = "minecraft:weakness"; + DataConverterPotionId.potions[57] = "minecraft:strong_strength"; + DataConverterPotionId.potions[58] = "minecraft:slowness"; + DataConverterPotionId.potions[59] = "minecraft:strong_leaping"; + DataConverterPotionId.potions[60] = "minecraft:strong_harming"; + DataConverterPotionId.potions[61] = "minecraft:water_breathing"; + DataConverterPotionId.potions[62] = "minecraft:invisibility"; + DataConverterPotionId.potions[63] = null; + DataConverterPotionId.potions[64] = "minecraft:mundane"; + DataConverterPotionId.potions[65] = "minecraft:long_regeneration"; + DataConverterPotionId.potions[66] = "minecraft:long_swiftness"; + DataConverterPotionId.potions[67] = "minecraft:long_fire_resistance"; + DataConverterPotionId.potions[68] = "minecraft:long_poison"; + DataConverterPotionId.potions[69] = "minecraft:healing"; + DataConverterPotionId.potions[70] = "minecraft:long_night_vision"; + DataConverterPotionId.potions[71] = null; + DataConverterPotionId.potions[72] = "minecraft:long_weakness"; + DataConverterPotionId.potions[73] = "minecraft:long_strength"; + DataConverterPotionId.potions[74] = "minecraft:long_slowness"; + DataConverterPotionId.potions[75] = "minecraft:long_leaping"; + DataConverterPotionId.potions[76] = "minecraft:harming"; + DataConverterPotionId.potions[77] = "minecraft:long_water_breathing"; + DataConverterPotionId.potions[78] = "minecraft:long_invisibility"; + DataConverterPotionId.potions[79] = null; + DataConverterPotionId.potions[80] = "minecraft:awkward"; + DataConverterPotionId.potions[81] = "minecraft:long_regeneration"; + DataConverterPotionId.potions[82] = "minecraft:long_swiftness"; + DataConverterPotionId.potions[83] = "minecraft:long_fire_resistance"; + DataConverterPotionId.potions[84] = "minecraft:long_poison"; + DataConverterPotionId.potions[85] = "minecraft:healing"; + DataConverterPotionId.potions[86] = "minecraft:long_night_vision"; + DataConverterPotionId.potions[87] = null; + DataConverterPotionId.potions[88] = "minecraft:long_weakness"; + DataConverterPotionId.potions[89] = "minecraft:long_strength"; + DataConverterPotionId.potions[90] = "minecraft:long_slowness"; + DataConverterPotionId.potions[91] = "minecraft:long_leaping"; + DataConverterPotionId.potions[92] = "minecraft:harming"; + DataConverterPotionId.potions[93] = "minecraft:long_water_breathing"; + DataConverterPotionId.potions[94] = "minecraft:long_invisibility"; + DataConverterPotionId.potions[95] = null; + DataConverterPotionId.potions[96] = "minecraft:thick"; + DataConverterPotionId.potions[97] = "minecraft:regeneration"; + DataConverterPotionId.potions[98] = "minecraft:swiftness"; + DataConverterPotionId.potions[99] = "minecraft:long_fire_resistance"; + DataConverterPotionId.potions[100] = "minecraft:poison"; + DataConverterPotionId.potions[101] = "minecraft:strong_healing"; + DataConverterPotionId.potions[102] = "minecraft:long_night_vision"; + DataConverterPotionId.potions[103] = null; + DataConverterPotionId.potions[104] = "minecraft:long_weakness"; + DataConverterPotionId.potions[105] = "minecraft:strength"; + DataConverterPotionId.potions[106] = "minecraft:long_slowness"; + DataConverterPotionId.potions[107] = "minecraft:leaping"; + DataConverterPotionId.potions[108] = "minecraft:strong_harming"; + DataConverterPotionId.potions[109] = "minecraft:long_water_breathing"; + DataConverterPotionId.potions[110] = "minecraft:long_invisibility"; + DataConverterPotionId.potions[111] = null; + DataConverterPotionId.potions[112] = null; + DataConverterPotionId.potions[113] = "minecraft:regeneration"; + DataConverterPotionId.potions[114] = "minecraft:swiftness"; + DataConverterPotionId.potions[115] = "minecraft:long_fire_resistance"; + DataConverterPotionId.potions[116] = "minecraft:poison"; + DataConverterPotionId.potions[117] = "minecraft:strong_healing"; + DataConverterPotionId.potions[118] = "minecraft:long_night_vision"; + DataConverterPotionId.potions[119] = null; + DataConverterPotionId.potions[120] = "minecraft:long_weakness"; + DataConverterPotionId.potions[121] = "minecraft:strength"; + DataConverterPotionId.potions[122] = "minecraft:long_slowness"; + DataConverterPotionId.potions[123] = "minecraft:leaping"; + DataConverterPotionId.potions[124] = "minecraft:strong_harming"; + DataConverterPotionId.potions[125] = "minecraft:long_water_breathing"; + DataConverterPotionId.potions[126] = "minecraft:long_invisibility"; + DataConverterPotionId.potions[127] = null; + } + } + + private static class DataConverterSpawnEgg implements DataConverter { + + private static final String[] eggs = new String[256]; + + DataConverterSpawnEgg() { + } + + public int getDataVersion() { + return 105; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("minecraft:spawn_egg".equals(cmp.getString("id"))) { + CompoundTag nbttagcompound1 = cmp.getCompound("tag"); + CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); + short short0 = cmp.getShort("Damage"); + + if (!nbttagcompound2.contains("id", 8)) { + String s = DataConverterSpawnEgg.eggs[short0 & 255]; + + if (s != null) { + nbttagcompound2.putString("id", s); + nbttagcompound1.put("EntityTag", nbttagcompound2); + cmp.put("tag", nbttagcompound1); + } + } + + if (short0 != 0) { + cmp.putShort("Damage", (short) 0); + } + } + + return cmp; + } + + static { + + DataConverterSpawnEgg.eggs[1] = "Item"; + DataConverterSpawnEgg.eggs[2] = "XPOrb"; + DataConverterSpawnEgg.eggs[7] = "ThrownEgg"; + DataConverterSpawnEgg.eggs[8] = "LeashKnot"; + DataConverterSpawnEgg.eggs[9] = "Painting"; + DataConverterSpawnEgg.eggs[10] = "Arrow"; + DataConverterSpawnEgg.eggs[11] = "Snowball"; + DataConverterSpawnEgg.eggs[12] = "Fireball"; + DataConverterSpawnEgg.eggs[13] = "SmallFireball"; + DataConverterSpawnEgg.eggs[14] = "ThrownEnderpearl"; + DataConverterSpawnEgg.eggs[15] = "EyeOfEnderSignal"; + DataConverterSpawnEgg.eggs[16] = "ThrownPotion"; + DataConverterSpawnEgg.eggs[17] = "ThrownExpBottle"; + DataConverterSpawnEgg.eggs[18] = "ItemFrame"; + DataConverterSpawnEgg.eggs[19] = "WitherSkull"; + DataConverterSpawnEgg.eggs[20] = "PrimedTnt"; + DataConverterSpawnEgg.eggs[21] = "FallingSand"; + DataConverterSpawnEgg.eggs[22] = "FireworksRocketEntity"; + DataConverterSpawnEgg.eggs[23] = "TippedArrow"; + DataConverterSpawnEgg.eggs[24] = "SpectralArrow"; + DataConverterSpawnEgg.eggs[25] = "ShulkerBullet"; + DataConverterSpawnEgg.eggs[26] = "DragonFireball"; + DataConverterSpawnEgg.eggs[30] = "ArmorStand"; + DataConverterSpawnEgg.eggs[41] = "Boat"; + DataConverterSpawnEgg.eggs[42] = "MinecartRideable"; + DataConverterSpawnEgg.eggs[43] = "MinecartChest"; + DataConverterSpawnEgg.eggs[44] = "MinecartFurnace"; + DataConverterSpawnEgg.eggs[45] = "MinecartTNT"; + DataConverterSpawnEgg.eggs[46] = "MinecartHopper"; + DataConverterSpawnEgg.eggs[47] = "MinecartSpawner"; + DataConverterSpawnEgg.eggs[40] = "MinecartCommandBlock"; + DataConverterSpawnEgg.eggs[48] = "Mob"; + DataConverterSpawnEgg.eggs[49] = "Monster"; + DataConverterSpawnEgg.eggs[50] = "Creeper"; + DataConverterSpawnEgg.eggs[51] = "Skeleton"; + DataConverterSpawnEgg.eggs[52] = "Spider"; + DataConverterSpawnEgg.eggs[53] = "Giant"; + DataConverterSpawnEgg.eggs[54] = "Zombie"; + DataConverterSpawnEgg.eggs[55] = "Slime"; + DataConverterSpawnEgg.eggs[56] = "Ghast"; + DataConverterSpawnEgg.eggs[57] = "PigZombie"; + DataConverterSpawnEgg.eggs[58] = "Enderman"; + DataConverterSpawnEgg.eggs[59] = "CaveSpider"; + DataConverterSpawnEgg.eggs[60] = "Silverfish"; + DataConverterSpawnEgg.eggs[61] = "Blaze"; + DataConverterSpawnEgg.eggs[62] = "LavaSlime"; + DataConverterSpawnEgg.eggs[63] = "EnderDragon"; + DataConverterSpawnEgg.eggs[64] = "WitherBoss"; + DataConverterSpawnEgg.eggs[65] = "Bat"; + DataConverterSpawnEgg.eggs[66] = "Witch"; + DataConverterSpawnEgg.eggs[67] = "Endermite"; + DataConverterSpawnEgg.eggs[68] = "Guardian"; + DataConverterSpawnEgg.eggs[69] = "Shulker"; + DataConverterSpawnEgg.eggs[90] = "Pig"; + DataConverterSpawnEgg.eggs[91] = "Sheep"; + DataConverterSpawnEgg.eggs[92] = "Cow"; + DataConverterSpawnEgg.eggs[93] = "Chicken"; + DataConverterSpawnEgg.eggs[94] = "Squid"; + DataConverterSpawnEgg.eggs[95] = "Wolf"; + DataConverterSpawnEgg.eggs[96] = "MushroomCow"; + DataConverterSpawnEgg.eggs[97] = "SnowMan"; + DataConverterSpawnEgg.eggs[98] = "Ozelot"; + DataConverterSpawnEgg.eggs[99] = "VillagerGolem"; + DataConverterSpawnEgg.eggs[100] = "EntityHorse"; + DataConverterSpawnEgg.eggs[101] = "Rabbit"; + DataConverterSpawnEgg.eggs[120] = "Villager"; + DataConverterSpawnEgg.eggs[200] = "EnderCrystal"; + } + } + + private static class DataConverterMinecart implements DataConverter { + + private static final List a = Lists.newArrayList("MinecartRideable", "MinecartChest", "MinecartFurnace", "MinecartTNT", "MinecartSpawner", "MinecartHopper", "MinecartCommandBlock"); + + DataConverterMinecart() { + } + + public int getDataVersion() { + return 106; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("Minecart".equals(cmp.getString("id"))) { + String s = "MinecartRideable"; + int i = cmp.getInt("Type"); + + if (i > 0 && i < DataConverterMinecart.a.size()) { + s = DataConverterMinecart.a.get(i); + } + + cmp.putString("id", s); + cmp.remove("Type"); + } + + return cmp; + } + } + + private static class DataConverterMobSpawner implements DataConverter { + + DataConverterMobSpawner() { + } + + public int getDataVersion() { + return 107; + } + + public CompoundTag convert(CompoundTag cmp) { + if (!"MobSpawner".equals(cmp.getString("id"))) { + return cmp; + } else { + if (cmp.contains("EntityId", 8)) { + String s = cmp.getString("EntityId"); + CompoundTag nbttagcompound1 = cmp.getCompound("SpawnData"); + + nbttagcompound1.putString("id", s.isEmpty() ? "Pig" : s); + cmp.put("SpawnData", nbttagcompound1); + cmp.remove("EntityId"); + } + + if (cmp.contains("SpawnPotentials", 9)) { + ListTag nbttaglist = cmp.getList("SpawnPotentials", 10); + + for (int i = 0; i < nbttaglist.size(); ++i) { + CompoundTag nbttagcompound2 = nbttaglist.getCompound(i); + + if (nbttagcompound2.contains("Type", 8)) { + CompoundTag nbttagcompound3 = nbttagcompound2.getCompound("Properties"); + + nbttagcompound3.putString("id", nbttagcompound2.getString("Type")); + nbttagcompound2.put("Entity", nbttagcompound3); + nbttagcompound2.remove("Type"); + nbttagcompound2.remove("Properties"); + } + } + } + + return cmp; + } + } + } + + private static class DataConverterUUID implements DataConverter { + + DataConverterUUID() { + } + + public int getDataVersion() { + return 108; + } + + public CompoundTag convert(CompoundTag cmp) { + if (cmp.contains("UUID", 8)) { + cmp.putUUID("UUID", UUID.fromString(cmp.getString("UUID"))); + } + + return cmp; + } + } + + private static class DataConverterHealth implements DataConverter { + + private static final Set a = Sets.newHashSet("ArmorStand", "Bat", "Blaze", "CaveSpider", "Chicken", "Cow", "Creeper", "EnderDragon", "Enderman", "Endermite", "EntityHorse", "Ghast", "Giant", "Guardian", "LavaSlime", "MushroomCow", "Ozelot", "Pig", "PigZombie", "Rabbit", "Sheep", "Shulker", "Silverfish", "Skeleton", "Slime", "SnowMan", "Spider", "Squid", "Villager", "VillagerGolem", "Witch", "WitherBoss", "Wolf", "Zombie"); + + DataConverterHealth() { + } + + public int getDataVersion() { + return 109; + } + + public CompoundTag convert(CompoundTag cmp) { + if (DataConverterHealth.a.contains(cmp.getString("id"))) { + float f; + + if (cmp.contains("HealF", 99)) { + f = cmp.getFloat("HealF"); + cmp.remove("HealF"); + } else { + if (!cmp.contains("Health", 99)) { + return cmp; + } + + f = cmp.getFloat("Health"); + } + + cmp.putFloat("Health", f); + } + + return cmp; + } + } + + private static class DataConverterSaddle implements DataConverter { + + DataConverterSaddle() { + } + + public int getDataVersion() { + return 110; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("EntityHorse".equals(cmp.getString("id")) && !cmp.contains("SaddleItem", 10) && cmp.getBoolean("Saddle")) { + CompoundTag nbttagcompound1 = new CompoundTag(); + + nbttagcompound1.putString("id", "minecraft:saddle"); + nbttagcompound1.putByte("Count", (byte) 1); + nbttagcompound1.putShort("Damage", (short) 0); + cmp.put("SaddleItem", nbttagcompound1); + cmp.remove("Saddle"); + } + + return cmp; + } + } + + private static class DataConverterHanging implements DataConverter { + + DataConverterHanging() { + } + + public int getDataVersion() { + return 111; + } + + public CompoundTag convert(CompoundTag cmp) { + String s = cmp.getString("id"); + boolean flag = "Painting".equals(s); + boolean flag1 = "ItemFrame".equals(s); + + if ((flag || flag1) && !cmp.contains("Facing", 99)) { + Direction enumdirection; + + if (cmp.contains("Direction", 99)) { + enumdirection = Direction.from2DDataValue(cmp.getByte("Direction")); + cmp.putInt("TileX", cmp.getInt("TileX") + enumdirection.getStepX()); + cmp.putInt("TileY", cmp.getInt("TileY") + enumdirection.getStepY()); + cmp.putInt("TileZ", cmp.getInt("TileZ") + enumdirection.getStepZ()); + cmp.remove("Direction"); + if (flag1 && cmp.contains("ItemRotation", 99)) { + cmp.putByte("ItemRotation", (byte) (cmp.getByte("ItemRotation") * 2)); + } + } else { + enumdirection = Direction.from2DDataValue(cmp.getByte("Dir")); + cmp.remove("Dir"); + } + + cmp.putByte("Facing", (byte) enumdirection.get2DDataValue()); + } + + return cmp; + } + } + + private static class DataConverterDropChances implements DataConverter { + + DataConverterDropChances() { + } + + public int getDataVersion() { + return 113; + } + + public CompoundTag convert(CompoundTag cmp) { + ListTag nbttaglist; + + if (cmp.contains("HandDropChances", 9)) { + nbttaglist = cmp.getList("HandDropChances", 5); + if (nbttaglist.size() == 2 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F) { + cmp.remove("HandDropChances"); + } + } + + if (cmp.contains("ArmorDropChances", 9)) { + nbttaglist = cmp.getList("ArmorDropChances", 5); + if (nbttaglist.size() == 4 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F && nbttaglist.getFloat(2) == 0.0F && nbttaglist.getFloat(3) == 0.0F) { + cmp.remove("ArmorDropChances"); + } + } + + return cmp; + } + } + + private static class DataConverterRiding implements DataConverter { + + DataConverterRiding() { + } + + public int getDataVersion() { + return 135; + } + + public CompoundTag convert(CompoundTag cmp) { + while (cmp.contains("Riding", 10)) { + CompoundTag nbttagcompound1 = this.b(cmp); + + this.convert(cmp, nbttagcompound1); + cmp = nbttagcompound1; + } + + return cmp; + } + + protected void convert(CompoundTag nbttagcompound, CompoundTag nbttagcompound1) { + ListTag nbttaglist = new ListTag(); + + nbttaglist.add(nbttagcompound); + nbttagcompound1.put("Passengers", nbttaglist); + } + + protected CompoundTag b(CompoundTag nbttagcompound) { + CompoundTag nbttagcompound1 = nbttagcompound.getCompound("Riding"); + + nbttagcompound.remove("Riding"); + return nbttagcompound1; + } + } + + private static class DataConverterBook implements DataConverter { + + DataConverterBook() { + } + + public int getDataVersion() { + return 165; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("minecraft:written_book".equals(cmp.getString("id"))) { + CompoundTag nbttagcompound1 = cmp.getCompound("tag"); + + if (nbttagcompound1.contains("pages", 9)) { + ListTag nbttaglist = nbttagcompound1.getList("pages", 8); + + for (int i = 0; i < nbttaglist.size(); ++i) { + String s = nbttaglist.getString(i); + Component object = null; + + if (!"null".equals(s) && !StringUtil.isNullOrEmpty(s)) { + if ((s.charAt(0) != 34 || s.charAt(s.length() - 1) != 34) && (s.charAt(0) != 123 || s.charAt(s.length() - 1) != 125)) { + object = Component.literal(s); + } else { + try { + object = GsonHelper.fromJson(DataConverterSignText.a, s, Component.class, true); + if (object == null) { + object = Component.literal(""); + } + } catch (JsonParseException jsonparseexception) { + ; + } + + if (object == null) { + try { + object = Component.Serializer.fromJson(s, MinecraftServer.getServer().registryAccess()); + } catch (JsonParseException jsonparseexception1) { + ; + } + } + + if (object == null) { + try { + object = Component.Serializer.fromJsonLenient(s, MinecraftServer.getServer().registryAccess()); + } catch (JsonParseException jsonparseexception2) { + ; + } + } + + if (object == null) { + object = Component.literal(s); + } + } + } else { + object = Component.literal(""); + } + + nbttaglist.set(i, StringTag.valueOf(Component.Serializer.toJson(object, MinecraftServer.getServer().registryAccess()))); + } + + nbttagcompound1.put("pages", nbttaglist); + } + } + + return cmp; + } + } + + private static class DataConverterCookedFish implements DataConverter { + + private static final ResourceLocation a = ResourceLocation.parse("cooked_fished"); + + DataConverterCookedFish() { + } + + public int getDataVersion() { + return 502; + } + + public CompoundTag convert(CompoundTag cmp) { + if (cmp.contains("id", 8) && DataConverterCookedFish.a.equals(ResourceLocation.parse(cmp.getString("id")))) { + cmp.putString("id", "minecraft:cooked_fish"); + } + + return cmp; + } + } + + private static class DataConverterZombie implements DataConverter { + + private static final Random a = new Random(); + + DataConverterZombie() { + } + + public int getDataVersion() { + return 502; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("Zombie".equals(cmp.getString("id")) && cmp.getBoolean("IsVillager")) { + if (!cmp.contains("ZombieType", 99)) { + int i = -1; + + if (cmp.contains("VillagerProfession", 99)) { + try { + i = this.convert(cmp.getInt("VillagerProfession")); + } catch (RuntimeException runtimeexception) { + ; + } + } + + if (i == -1) { + i = this.convert(DataConverterZombie.a.nextInt(6)); + } + + cmp.putInt("ZombieType", i); + } + + cmp.remove("IsVillager"); + } + + return cmp; + } + + private int convert(int i) { + return i >= 0 && i < 6 ? i : -1; + } + } + + private static class DataConverterVBO implements DataConverter { + + DataConverterVBO() { + } + + public int getDataVersion() { + return 505; + } + + public CompoundTag convert(CompoundTag cmp) { + cmp.putString("useVbo", "true"); + return cmp; + } + } + + private static class DataConverterGuardian implements DataConverter { + + DataConverterGuardian() { + } + + public int getDataVersion() { + return 700; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("Guardian".equals(cmp.getString("id"))) { + if (cmp.getBoolean("Elder")) { + cmp.putString("id", "ElderGuardian"); + } + + cmp.remove("Elder"); + } + + return cmp; + } + } + + private static class DataConverterSkeleton implements DataConverter { + + DataConverterSkeleton() { + } + + public int getDataVersion() { + return 701; + } + + public CompoundTag convert(CompoundTag cmp) { + String s = cmp.getString("id"); + + if ("Skeleton".equals(s)) { + int i = cmp.getInt("SkeletonType"); + + if (i == 1) { + cmp.putString("id", "WitherSkeleton"); + } else if (i == 2) { + cmp.putString("id", "Stray"); + } + + cmp.remove("SkeletonType"); + } + + return cmp; + } + } + + private static class DataConverterZombieType implements DataConverter { + + DataConverterZombieType() { + } + + public int getDataVersion() { + return 702; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("Zombie".equals(cmp.getString("id"))) { + int i = cmp.getInt("ZombieType"); + + switch (i) { + case 0: + default: + break; + + case 1: + case 2: + case 3: + case 4: + case 5: + cmp.putString("id", "ZombieVillager"); + cmp.putInt("Profession", i - 1); + break; + + case 6: + cmp.putString("id", "Husk"); + } + + cmp.remove("ZombieType"); + } + + return cmp; + } + } + + private static class DataConverterHorse implements DataConverter { + + DataConverterHorse() { + } + + public int getDataVersion() { + return 703; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("EntityHorse".equals(cmp.getString("id"))) { + int i = cmp.getInt("Type"); + + switch (i) { + case 0: + default: + cmp.putString("id", "Horse"); + break; + + case 1: + cmp.putString("id", "Donkey"); + break; + + case 2: + cmp.putString("id", "Mule"); + break; + + case 3: + cmp.putString("id", "ZombieHorse"); + break; + + case 4: + cmp.putString("id", "SkeletonHorse"); + } + + cmp.remove("Type"); + } + + return cmp; + } + } + + private static class DataConverterTileEntity implements DataConverter { + + private static final Map a = Maps.newHashMap(); + + DataConverterTileEntity() { + } + + public int getDataVersion() { + return 704; + } + + public CompoundTag convert(CompoundTag cmp) { + String s = DataConverterTileEntity.a.get(cmp.getString("id")); + + if (s != null) { + cmp.putString("id", s); + } + + return cmp; + } + + static { + DataConverterTileEntity.a.put("Airportal", "minecraft:end_portal"); + DataConverterTileEntity.a.put("Banner", "minecraft:banner"); + DataConverterTileEntity.a.put("Beacon", "minecraft:beacon"); + DataConverterTileEntity.a.put("Cauldron", "minecraft:brewing_stand"); + DataConverterTileEntity.a.put("Chest", "minecraft:chest"); + DataConverterTileEntity.a.put("Comparator", "minecraft:comparator"); + DataConverterTileEntity.a.put("Control", "minecraft:command_block"); + DataConverterTileEntity.a.put("DLDetector", "minecraft:daylight_detector"); + DataConverterTileEntity.a.put("Dropper", "minecraft:dropper"); + DataConverterTileEntity.a.put("EnchantTable", "minecraft:enchanting_table"); + DataConverterTileEntity.a.put("EndGateway", "minecraft:end_gateway"); + DataConverterTileEntity.a.put("EnderChest", "minecraft:ender_chest"); + DataConverterTileEntity.a.put("FlowerPot", "minecraft:flower_pot"); + DataConverterTileEntity.a.put("Furnace", "minecraft:furnace"); + DataConverterTileEntity.a.put("Hopper", "minecraft:hopper"); + DataConverterTileEntity.a.put("MobSpawner", "minecraft:mob_spawner"); + DataConverterTileEntity.a.put("Music", "minecraft:noteblock"); + DataConverterTileEntity.a.put("Piston", "minecraft:piston"); + DataConverterTileEntity.a.put("RecordPlayer", "minecraft:jukebox"); + DataConverterTileEntity.a.put("Sign", "minecraft:sign"); + DataConverterTileEntity.a.put("Skull", "minecraft:skull"); + DataConverterTileEntity.a.put("Structure", "minecraft:structure_block"); + DataConverterTileEntity.a.put("Trap", "minecraft:dispenser"); + } + } + + private static class DataConverterEntity implements DataConverter { + + private static final Map a = Maps.newHashMap(); + + DataConverterEntity() { + } + + public int getDataVersion() { + return 704; + } + + public CompoundTag convert(CompoundTag cmp) { + String s = DataConverterEntity.a.get(cmp.getString("id")); + + if (s != null) { + cmp.putString("id", s); + } + + return cmp; + } + + static { + DataConverterEntity.a.put("AreaEffectCloud", "minecraft:area_effect_cloud"); + DataConverterEntity.a.put("ArmorStand", "minecraft:armor_stand"); + DataConverterEntity.a.put("Arrow", "minecraft:arrow"); + DataConverterEntity.a.put("Bat", "minecraft:bat"); + DataConverterEntity.a.put("Blaze", "minecraft:blaze"); + DataConverterEntity.a.put("Boat", "minecraft:boat"); + DataConverterEntity.a.put("CaveSpider", "minecraft:cave_spider"); + DataConverterEntity.a.put("Chicken", "minecraft:chicken"); + DataConverterEntity.a.put("Cow", "minecraft:cow"); + DataConverterEntity.a.put("Creeper", "minecraft:creeper"); + DataConverterEntity.a.put("Donkey", "minecraft:donkey"); + DataConverterEntity.a.put("DragonFireball", "minecraft:dragon_fireball"); + DataConverterEntity.a.put("ElderGuardian", "minecraft:elder_guardian"); + DataConverterEntity.a.put("EnderCrystal", "minecraft:ender_crystal"); + DataConverterEntity.a.put("EnderDragon", "minecraft:ender_dragon"); + DataConverterEntity.a.put("Enderman", "minecraft:enderman"); + DataConverterEntity.a.put("Endermite", "minecraft:endermite"); + DataConverterEntity.a.put("EyeOfEnderSignal", "minecraft:eye_of_ender_signal"); + DataConverterEntity.a.put("FallingSand", "minecraft:falling_block"); + DataConverterEntity.a.put("Fireball", "minecraft:fireball"); + DataConverterEntity.a.put("FireworksRocketEntity", "minecraft:fireworks_rocket"); + DataConverterEntity.a.put("Ghast", "minecraft:ghast"); + DataConverterEntity.a.put("Giant", "minecraft:giant"); + DataConverterEntity.a.put("Guardian", "minecraft:guardian"); + DataConverterEntity.a.put("Horse", "minecraft:horse"); + DataConverterEntity.a.put("Husk", "minecraft:husk"); + DataConverterEntity.a.put("Item", "minecraft:item"); + DataConverterEntity.a.put("ItemFrame", "minecraft:item_frame"); + DataConverterEntity.a.put("LavaSlime", "minecraft:magma_cube"); + DataConverterEntity.a.put("LeashKnot", "minecraft:leash_knot"); + DataConverterEntity.a.put("MinecartChest", "minecraft:chest_minecart"); + DataConverterEntity.a.put("MinecartCommandBlock", "minecraft:commandblock_minecart"); + DataConverterEntity.a.put("MinecartFurnace", "minecraft:furnace_minecart"); + DataConverterEntity.a.put("MinecartHopper", "minecraft:hopper_minecart"); + DataConverterEntity.a.put("MinecartRideable", "minecraft:minecart"); + DataConverterEntity.a.put("MinecartSpawner", "minecraft:spawner_minecart"); + DataConverterEntity.a.put("MinecartTNT", "minecraft:tnt_minecart"); + DataConverterEntity.a.put("Mule", "minecraft:mule"); + DataConverterEntity.a.put("MushroomCow", "minecraft:mooshroom"); + DataConverterEntity.a.put("Ozelot", "minecraft:ocelot"); + DataConverterEntity.a.put("Painting", "minecraft:painting"); + DataConverterEntity.a.put("Pig", "minecraft:pig"); + DataConverterEntity.a.put("PigZombie", "minecraft:zombie_pigman"); + DataConverterEntity.a.put("PolarBear", "minecraft:polar_bear"); + DataConverterEntity.a.put("PrimedTnt", "minecraft:tnt"); + DataConverterEntity.a.put("Rabbit", "minecraft:rabbit"); + DataConverterEntity.a.put("Sheep", "minecraft:sheep"); + DataConverterEntity.a.put("Shulker", "minecraft:shulker"); + DataConverterEntity.a.put("ShulkerBullet", "minecraft:shulker_bullet"); + DataConverterEntity.a.put("Silverfish", "minecraft:silverfish"); + DataConverterEntity.a.put("Skeleton", "minecraft:skeleton"); + DataConverterEntity.a.put("SkeletonHorse", "minecraft:skeleton_horse"); + DataConverterEntity.a.put("Slime", "minecraft:slime"); + DataConverterEntity.a.put("SmallFireball", "minecraft:small_fireball"); + DataConverterEntity.a.put("SnowMan", "minecraft:snowman"); + DataConverterEntity.a.put("Snowball", "minecraft:snowball"); + DataConverterEntity.a.put("SpectralArrow", "minecraft:spectral_arrow"); + DataConverterEntity.a.put("Spider", "minecraft:spider"); + DataConverterEntity.a.put("Squid", "minecraft:squid"); + DataConverterEntity.a.put("Stray", "minecraft:stray"); + DataConverterEntity.a.put("ThrownEgg", "minecraft:egg"); + DataConverterEntity.a.put("ThrownEnderpearl", "minecraft:ender_pearl"); + DataConverterEntity.a.put("ThrownExpBottle", "minecraft:xp_bottle"); + DataConverterEntity.a.put("ThrownPotion", "minecraft:potion"); + DataConverterEntity.a.put("Villager", "minecraft:villager"); + DataConverterEntity.a.put("VillagerGolem", "minecraft:villager_golem"); + DataConverterEntity.a.put("Witch", "minecraft:witch"); + DataConverterEntity.a.put("WitherBoss", "minecraft:wither"); + DataConverterEntity.a.put("WitherSkeleton", "minecraft:wither_skeleton"); + DataConverterEntity.a.put("WitherSkull", "minecraft:wither_skull"); + DataConverterEntity.a.put("Wolf", "minecraft:wolf"); + DataConverterEntity.a.put("XPOrb", "minecraft:xp_orb"); + DataConverterEntity.a.put("Zombie", "minecraft:zombie"); + DataConverterEntity.a.put("ZombieHorse", "minecraft:zombie_horse"); + DataConverterEntity.a.put("ZombieVillager", "minecraft:zombie_villager"); + } + } + + private static class DataConverterPotionWater implements DataConverter { + + DataConverterPotionWater() { + } + + public int getDataVersion() { + return 806; + } + + public CompoundTag convert(CompoundTag cmp) { + String s = cmp.getString("id"); + + if ("minecraft:potion".equals(s) || "minecraft:splash_potion".equals(s) || "minecraft:lingering_potion".equals(s) || "minecraft:tipped_arrow".equals(s)) { + CompoundTag nbttagcompound1 = cmp.getCompound("tag"); + + if (!nbttagcompound1.contains("Potion", 8)) { + nbttagcompound1.putString("Potion", "minecraft:water"); + } + + if (!cmp.contains("tag", 10)) { + cmp.put("tag", nbttagcompound1); + } + } + + return cmp; + } + } + + private static class DataConverterShulker implements DataConverter { + + DataConverterShulker() { + } + + public int getDataVersion() { + return 808; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("minecraft:shulker".equals(cmp.getString("id")) && !cmp.contains("Color", 99)) { + cmp.putByte("Color", (byte) 10); + } + + return cmp; + } + } + + private static class DataConverterShulkerBoxItem implements DataConverter { + + public static final String[] a = new String[] { "minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box" }; + + DataConverterShulkerBoxItem() { + } + + public int getDataVersion() { + return 813; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("minecraft:shulker_box".equals(cmp.getString("id")) && cmp.contains("tag", 10)) { + CompoundTag nbttagcompound1 = cmp.getCompound("tag"); + + if (nbttagcompound1.contains("BlockEntityTag", 10)) { + CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); + + if (nbttagcompound2.getList("Items", 10).isEmpty()) { + nbttagcompound2.remove("Items"); + } + + int i = nbttagcompound2.getInt("Color"); + + nbttagcompound2.remove("Color"); + if (nbttagcompound2.isEmpty()) { + nbttagcompound1.remove("BlockEntityTag"); + } + + if (nbttagcompound1.isEmpty()) { + cmp.remove("tag"); + } + + cmp.putString("id", DataConverterShulkerBoxItem.a[i % 16]); + } + } + + return cmp; + } + } + + private static class DataConverterShulkerBoxBlock implements DataConverter { + + DataConverterShulkerBoxBlock() { + } + + public int getDataVersion() { + return 813; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("minecraft:shulker".equals(cmp.getString("id"))) { + cmp.remove("Color"); + } + + return cmp; + } + } + + private static class DataConverterLang implements DataConverter { + + DataConverterLang() { + } + + public int getDataVersion() { + return 816; + } + + public CompoundTag convert(CompoundTag cmp) { + if (cmp.contains("lang", 8)) { + cmp.putString("lang", cmp.getString("lang").toLowerCase(Locale.ROOT)); + } + + return cmp; + } + } + + private static class DataConverterTotem implements DataConverter { + + DataConverterTotem() { + } + + public int getDataVersion() { + return 820; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("minecraft:totem".equals(cmp.getString("id"))) { + cmp.putString("id", "minecraft:totem_of_undying"); + } + + return cmp; + } + } + + private static class DataConverterBedBlock implements DataConverter { + + private static final Logger a = LogManager.getLogger(PaperweightDataConverters.class); + + DataConverterBedBlock() { + } + + public int getDataVersion() { + return 1125; + } + + public CompoundTag convert(CompoundTag cmp) { + try { + CompoundTag nbttagcompound1 = cmp.getCompound("Level"); + int i = nbttagcompound1.getInt("xPos"); + int j = nbttagcompound1.getInt("zPos"); + ListTag nbttaglist = nbttagcompound1.getList("TileEntities", 10); + ListTag nbttaglist1 = nbttagcompound1.getList("Sections", 10); + + for (int k = 0; k < nbttaglist1.size(); ++k) { + CompoundTag nbttagcompound2 = nbttaglist1.getCompound(k); + byte b0 = nbttagcompound2.getByte("Y"); + byte[] abyte = nbttagcompound2.getByteArray("Blocks"); + + for (int l = 0; l < abyte.length; ++l) { + if (416 == (abyte[l] & 255) << 4) { + int i1 = l & 15; + int j1 = l >> 8 & 15; + int k1 = l >> 4 & 15; + CompoundTag nbttagcompound3 = new CompoundTag(); + + nbttagcompound3.putString("id", "bed"); + nbttagcompound3.putInt("x", i1 + (i << 4)); + nbttagcompound3.putInt("y", j1 + (b0 << 4)); + nbttagcompound3.putInt("z", k1 + (j << 4)); + nbttaglist.add(nbttagcompound3); + } + } + } + } catch (Exception exception) { + DataConverterBedBlock.a.warn("Unable to datafix Bed blocks, level format may be missing tags."); + } + + return cmp; + } + } + + private static class DataConverterBedItem implements DataConverter { + + DataConverterBedItem() { + } + + public int getDataVersion() { + return 1125; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("minecraft:bed".equals(cmp.getString("id")) && cmp.getShort("Damage") == 0) { + cmp.putShort("Damage", (short) DyeColor.RED.getId()); + } + + return cmp; + } + } + + private static class DataConverterSignText implements DataConverter { + + public static final Gson a = new GsonBuilder().registerTypeAdapter(Component.class, new JsonDeserializer() { + MutableComponent a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { + if (jsonelement.isJsonPrimitive()) { + return Component.literal(jsonelement.getAsString()); + } else if (jsonelement.isJsonArray()) { + JsonArray jsonarray = jsonelement.getAsJsonArray(); + MutableComponent ichatbasecomponent = null; + Iterator iterator = jsonarray.iterator(); + + while (iterator.hasNext()) { + JsonElement jsonelement1 = (JsonElement) iterator.next(); + MutableComponent ichatbasecomponent1 = this.a(jsonelement1, jsonelement1.getClass(), jsondeserializationcontext); + + if (ichatbasecomponent == null) { + ichatbasecomponent = ichatbasecomponent1; + } else { + ichatbasecomponent.append(ichatbasecomponent1); + } + } + + return ichatbasecomponent; + } else { + throw new JsonParseException("Don't know how to turn " + jsonelement + " into a Component"); + } + } + + public Object deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { + return this.a(jsonelement, type, jsondeserializationcontext); + } + }).create(); + + DataConverterSignText() { + } + + public int getDataVersion() { + return 101; + } + + public CompoundTag convert(CompoundTag cmp) { + if ("Sign".equals(cmp.getString("id"))) { + this.convert(cmp, "Text1"); + this.convert(cmp, "Text2"); + this.convert(cmp, "Text3"); + this.convert(cmp, "Text4"); + } + + return cmp; + } + + private void convert(CompoundTag nbttagcompound, String s) { + String s1 = nbttagcompound.getString(s); + Component object = null; + + if (!"null".equals(s1) && !StringUtil.isNullOrEmpty(s1)) { + if ((s1.charAt(0) != 34 || s1.charAt(s1.length() - 1) != 34) && (s1.charAt(0) != 123 || s1.charAt(s1.length() - 1) != 125)) { + object = Component.literal(s1); + } else { + try { + object = GsonHelper.fromJson(DataConverterSignText.a, s1, Component.class, true); + if (object == null) { + object = Component.literal(""); + } + } catch (JsonParseException jsonparseexception) { + ; + } + + if (object == null) { + try { + object = Component.Serializer.fromJson(s1, MinecraftServer.getServer().registryAccess()); + } catch (JsonParseException jsonparseexception1) { + ; + } + } + + if (object == null) { + try { + object = Component.Serializer.fromJsonLenient(s1, MinecraftServer.getServer().registryAccess()); + } catch (JsonParseException jsonparseexception2) { + ; + } + } + + if (object == null) { + object = Component.literal(s1); + } + } + } else { + object = Component.literal(""); + } + + nbttagcompound.putString(s, Component.Serializer.toJson(object, MinecraftServer.getServer().registryAccess())); + } + } + + private static class DataInspectorPlayerVehicle implements DataInspector { + @Override + public CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer) { + if (cmp.contains("RootVehicle", 10)) { + CompoundTag nbttagcompound1 = cmp.getCompound("RootVehicle"); + + if (nbttagcompound1.contains("Entity", 10)) { + convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer); + } + } + + return cmp; + } + } + + private static class DataInspectorLevelPlayer implements DataInspector { + @Override + public CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer) { + if (cmp.contains("Player", 10)) { + convertCompound(LegacyType.PLAYER, cmp, "Player", sourceVer, targetVer); + } + + return cmp; + } + } + + private static class DataInspectorStructure implements DataInspector { + @Override + public CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer) { + ListTag nbttaglist; + int j; + CompoundTag nbttagcompound1; + + if (cmp.contains("entities", 9)) { + nbttaglist = cmp.getList("entities", 10); + + for (j = 0; j < nbttaglist.size(); ++j) { + nbttagcompound1 = (CompoundTag) nbttaglist.get(j); + if (nbttagcompound1.contains("nbt", 10)) { + convertCompound(LegacyType.ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer); + } + } + } + + if (cmp.contains("blocks", 9)) { + nbttaglist = cmp.getList("blocks", 10); + + for (j = 0; j < nbttaglist.size(); ++j) { + nbttagcompound1 = (CompoundTag) nbttaglist.get(j); + if (nbttagcompound1.contains("nbt", 10)) { + convertCompound(LegacyType.BLOCK_ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer); + } + } + } + + return cmp; + } + } + + private static class DataInspectorChunks implements DataInspector { + @Override + public CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer) { + if (cmp.contains("Level", 10)) { + CompoundTag nbttagcompound1 = cmp.getCompound("Level"); + ListTag nbttaglist; + int j; + + if (nbttagcompound1.contains("Entities", 9)) { + nbttaglist = nbttagcompound1.getList("Entities", 10); + + for (j = 0; j < nbttaglist.size(); ++j) { + nbttaglist.set(j, convert(LegacyType.ENTITY, (CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); + } + } + + if (nbttagcompound1.contains("TileEntities", 9)) { + nbttaglist = nbttagcompound1.getList("TileEntities", 10); + + for (j = 0; j < nbttaglist.size(); ++j) { + nbttaglist.set(j, convert(LegacyType.BLOCK_ENTITY, (CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); + } + } + } + + return cmp; + } + } + + private static class DataInspectorEntityPassengers implements DataInspector { + @Override + public CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer) { + if (cmp.contains("Passengers", 9)) { + ListTag nbttaglist = cmp.getList("Passengers", 10); + + for (int j = 0; j < nbttaglist.size(); ++j) { + nbttaglist.set(j, convert(LegacyType.ENTITY, nbttaglist.getCompound(j), sourceVer, targetVer)); + } + } + + return cmp; + } + } + + private static class DataInspectorPlayer implements DataInspector { + @Override + public CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer) { + convertItems(cmp, "Inventory", sourceVer, targetVer); + convertItems(cmp, "EnderItems", sourceVer, targetVer); + if (cmp.contains("ShoulderEntityLeft", 10)) { + convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityLeft", sourceVer, targetVer); + } + + if (cmp.contains("ShoulderEntityRight", 10)) { + convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityRight", sourceVer, targetVer); + } + + return cmp; + } + } + + private static class DataInspectorVillagers implements DataInspector { + ResourceLocation entityVillager = getKey("EntityVillager"); + + @Override + public CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer) { + if (entityVillager.equals(ResourceLocation.parse(cmp.getString("id"))) && cmp.contains("Offers", 10)) { + CompoundTag nbttagcompound1 = cmp.getCompound("Offers"); + + if (nbttagcompound1.contains("Recipes", 9)) { + ListTag nbttaglist = nbttagcompound1.getList("Recipes", 10); + + for (int j = 0; j < nbttaglist.size(); ++j) { + CompoundTag nbttagcompound2 = nbttaglist.getCompound(j); + + convertItem(nbttagcompound2, "buy", sourceVer, targetVer); + convertItem(nbttagcompound2, "buyB", sourceVer, targetVer); + convertItem(nbttagcompound2, "sell", sourceVer, targetVer); + nbttaglist.set(j, nbttagcompound2); + } + } + } + + return cmp; + } + } + + private static class DataInspectorMobSpawnerMinecart implements DataInspector { + ResourceLocation entityMinecartMobSpawner = getKey("EntityMinecartMobSpawner"); + ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); + + @Override + public CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer) { + String s = cmp.getString("id"); + if (entityMinecartMobSpawner.equals(ResourceLocation.parse(s))) { + cmp.putString("id", tileEntityMobSpawner.toString()); + convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer); + cmp.putString("id", s); + } + + return cmp; + } + } + + private static class DataInspectorMobSpawnerMobs implements DataInspector { + ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); + + @Override + public CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer) { + if (tileEntityMobSpawner.equals(ResourceLocation.parse(cmp.getString("id")))) { + if (cmp.contains("SpawnPotentials", 9)) { + ListTag nbttaglist = cmp.getList("SpawnPotentials", 10); + + for (int j = 0; j < nbttaglist.size(); ++j) { + CompoundTag nbttagcompound1 = nbttaglist.getCompound(j); + + convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer); + } + } + + convertCompound(LegacyType.ENTITY, cmp, "SpawnData", sourceVer, targetVer); + } + + return cmp; + } + } + + private static class DataInspectorCommandBlock implements DataInspector { + ResourceLocation tileEntityCommand = getKey("TileEntityCommand"); + + @Override + public CompoundTag inspect(CompoundTag cmp, int sourceVer, int targetVer) { + if (tileEntityCommand.equals(ResourceLocation.parse(cmp.getString("id")))) { + cmp.putString("id", "Control"); + convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer); + cmp.putString("id", "MinecartCommandBlock"); + } + + return cmp; + } + } +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightFakePlayer.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightFakePlayer.java new file mode 100644 index 000000000..d9c89b0e3 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightFakePlayer.java @@ -0,0 +1,91 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_21_R1; + +import com.mojang.authlib.GameProfile; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ClientInformation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.stats.Stat; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.HumanoidArm; +import net.minecraft.world.entity.player.ChatVisiblity; +import net.minecraft.world.level.block.entity.SignBlockEntity; +import net.minecraft.world.phys.Vec3; + +import java.util.OptionalInt; +import java.util.UUID; + +class PaperweightFakePlayer extends ServerPlayer { + private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]"); + private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D); + private static final ClientInformation FAKE_CLIENT_INFO = new ClientInformation( + "en_US", 16, ChatVisiblity.FULL, true, 0, HumanoidArm.LEFT, false, false + ); + + PaperweightFakePlayer(ServerLevel world) { + super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE, FAKE_CLIENT_INFO); + } + + @Override + public Vec3 position() { + return ORIGIN; + } + + @Override + public void tick() { + } + + @Override + public void die(DamageSource damagesource) { + } + + @Override + public OptionalInt openMenu(MenuProvider factory) { + return OptionalInt.empty(); + } + + @Override + public void updateOptions(ClientInformation clientOptions) { + } + + @Override + public void displayClientMessage(Component message, boolean actionBar) { + } + + @Override + public void awardStat(Stat stat, int amount) { + } + + @Override + public void awardStat(Stat stat) { + } + + @Override + public boolean isInvulnerableTo(DamageSource damageSource) { + return true; + } + + @Override + public void openTextEdit(SignBlockEntity sign, boolean front) { + } +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightWorldNativeAccess.java new file mode 100644 index 000000000..d51295053 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightWorldNativeAccess.java @@ -0,0 +1,191 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_21_R1; + +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.internal.block.BlockStateIdAccess; +import com.sk89q.worldedit.internal.wna.WorldNativeAccess; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; +import com.sk89q.worldedit.world.block.BlockState; +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.Tag; +import net.minecraft.server.level.FullChunkStatus; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.chunk.LevelChunk; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.block.data.CraftBlockData; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.enginehub.linbus.tree.LinCompoundTag; + +import javax.annotation.Nullable; +import java.lang.ref.WeakReference; +import java.util.Objects; + +public class PaperweightWorldNativeAccess implements WorldNativeAccess { + private static final int UPDATE = 1; + private static final int NOTIFY = 2; + + private final PaperweightAdapter adapter; + private final WeakReference world; + private SideEffectSet sideEffectSet; + + public PaperweightWorldNativeAccess(PaperweightAdapter adapter, WeakReference world) { + this.adapter = adapter; + this.world = world; + } + + private ServerLevel getWorld() { + return Objects.requireNonNull(world.get(), "The reference to the world was lost"); + } + + @Override + public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) { + this.sideEffectSet = sideEffectSet; + } + + @Override + public LevelChunk getChunk(int x, int z) { + return getWorld().getChunk(x, z); + } + + @Override + public net.minecraft.world.level.block.state.BlockState toNative(BlockState state) { + int stateId = BlockStateIdAccess.getBlockStateId(state); + return BlockStateIdAccess.isValidInternalId(stateId) + ? Block.stateById(stateId) + : ((CraftBlockData) BukkitAdapter.adapt(state)).getState(); + } + + @Override + public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk chunk, BlockPos position) { + return chunk.getBlockState(position); + } + + @Nullable + @Override + public net.minecraft.world.level.block.state.BlockState setBlockState(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState state) { + return chunk.setBlockState(position, state, false, this.sideEffectSet.shouldApply(SideEffect.UPDATE)); + } + + @Override + public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition(net.minecraft.world.level.block.state.BlockState block, BlockPos position) { + return Block.updateFromNeighbourShapes(block, getWorld(), position); + } + + @Override + public BlockPos getPosition(int x, int y, int z) { + return new BlockPos(x, y, z); + } + + @Override + public void updateLightingForBlock(BlockPos position) { + getWorld().getChunkSource().getLightEngine().checkBlock(position); + } + + @Override + public boolean updateTileEntity(BlockPos position, LinCompoundTag tag) { + // We will assume that the tile entity was created for us + BlockEntity tileEntity = getWorld().getBlockEntity(position); + if (tileEntity == null) { + return false; + } + Tag nativeTag = adapter.fromNativeLin(tag); + PaperweightAdapter.readTagIntoTileEntity((net.minecraft.nbt.CompoundTag) nativeTag, tileEntity); + return true; + } + + @Override + public void notifyBlockUpdate(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { + if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { + getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY); + } + } + + @Override + public boolean isChunkTicking(LevelChunk chunk) { + return chunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING); + } + + @Override + public void markBlockChanged(LevelChunk chunk, BlockPos position) { + if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { + getWorld().getChunkSource().blockChanged(position); + } + } + + @Override + public void notifyNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { + ServerLevel world = getWorld(); + if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { + world.updateNeighborsAt(pos, oldState.getBlock()); + } else { + // When we don't want events, manually run the physics without them. + Block block = oldState.getBlock(); + fireNeighborChanged(pos, world, block, pos.west()); + fireNeighborChanged(pos, world, block, pos.east()); + fireNeighborChanged(pos, world, block, pos.below()); + fireNeighborChanged(pos, world, block, pos.above()); + fireNeighborChanged(pos, world, block, pos.north()); + fireNeighborChanged(pos, world, block, pos.south()); + } + if (newState.hasAnalogOutputSignal()) { + world.updateNeighbourForOutputSignal(pos, newState.getBlock()); + } + } + + @Override + public void updateBlock(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { + ServerLevel world = getWorld(); + newState.onPlace(world, pos, oldState, false); + } + + private void fireNeighborChanged(BlockPos pos, ServerLevel world, Block block, BlockPos neighborPos) { + world.getBlockState(neighborPos).handleNeighborChanged(world, neighborPos, block, pos, false); + } + + @Override + public void updateNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState, int recursionLimit) { + ServerLevel world = getWorld(); + oldState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); + if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { + CraftWorld craftWorld = world.getWorld(); + BlockPhysicsEvent event = new BlockPhysicsEvent(craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), CraftBlockData.fromData(newState)); + world.getCraftServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + } + newState.updateNeighbourShapes(world, pos, NOTIFY, recursionLimit); + newState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); + } + + @Override + public void onBlockStateChange(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { + getWorld().onBlockStateChange(pos, oldState, newState); + } + + @Override + public void flush() { + + } +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/StaticRefraction.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/StaticRefraction.java new file mode 100644 index 000000000..5056a7981 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/StaticRefraction.java @@ -0,0 +1,90 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_21_R1; + +import com.sk89q.worldedit.bukkit.adapter.Refraction; + +/** + * Dedicated class to map all names that we use. + * + *

    + * Overloads are split into multiple fields, as they CAN have different obfuscated names. + *

    + */ +public final class StaticRefraction { + public static final String GET_CHUNK_FUTURE_MAIN_THREAD = Refraction.pickName( + "getChunkFutureMainThread", "c" + ); + public static final String MAIN_THREAD_PROCESSOR = Refraction.pickName( + "mainThreadProcessor", "g" + ); + public static final String NEXT_TICK_TIME = Refraction.pickName("nextTickTime", "e"); + public static final String GET_BLOCK_STATE = Refraction.pickName("getBlockState", "a_"); + /** + * {@code addFreshEntityWithPassengers(Entity entity)}. + */ + public static final String ADD_FRESH_ENTITY_WITH_PASSENGERS_ENTITY = Refraction.pickName( + "addFreshEntityWithPassengers", "a_" + ); + /** + * {@code addFreshEntityWithPassengers(Entity entity, CreatureSpawnEvent.SpawnReason reason)}. + */ + public static final String ADD_FRESH_ENTITY_WITH_PASSENGERS_ENTITY_SPAWN_REASON = + Refraction.pickName("addFreshEntityWithPassengers", "a_"); + /** + * {@code addFreshEntity(Entity entity)}. + */ + public static final String ADD_FRESH_ENTITY = Refraction.pickName("addFreshEntity", "b"); + /** + * {@code addFreshEntity(Entity entity, CreatureSpawnEvent.SpawnReason reason)}. + */ + public static final String ADD_FRESH_ENTITY_SPAWN_REASON = Refraction.pickName( + "addFreshEntity", "b" + ); + /** + * {@code getBlockEntity(BlockPos blockPos)}. + */ + public static final String GET_BLOCK_ENTITY = Refraction.pickName("getBlockEntity", "c_"); + /** + * {@code setBlock(BlockPos blockPos, BlockState blockState, int flags)}. + */ + public static final String SET_BLOCK = Refraction.pickName("setBlock", "a"); + /** + * {@code setBlock(BlockPos blockPos, BlockState blockState, int flags, int maxUpdateDepth)}. + */ + public static final String SET_BLOCK_MAX_UPDATE = Refraction.pickName("setBlock", "a"); + public static final String REMOVE_BLOCK = Refraction.pickName("removeBlock", "a"); + /** + * {@code destroyBlock(BlockPos blockPos, boolean drop)}. + */ + public static final String DESTROY_BLOCK = Refraction.pickName("destroyBlock", "b"); + /** + * {@code destroyBlock(BlockPos blockPos, boolean drop, Entity breakingEntity)}. + */ + public static final String DESTROY_BLOCK_BREAKING_ENTITY = Refraction.pickName( + "destroyBlock", "a" + ); + /** + * {@code destroyBlock(BlockPos blockPos, boolean drop, Entity breakingEntity, int maxUpdateDepth)}. + */ + public static final String DESTROY_BLOCK_BREAKING_ENTITY_MAX_UPDATE = Refraction.pickName( + "destroyBlock", "a" + ); +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightBlockMaterial.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightBlockMaterial.java new file mode 100644 index 000000000..359527396 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightBlockMaterial.java @@ -0,0 +1,176 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1; + +import com.google.common.base.Suppliers; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1.nbt.PaperweightLazyCompoundTag; +import com.sk89q.worldedit.world.registry.BlockMaterial; +import net.minecraft.core.BlockPos; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.world.level.EmptyBlockGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.level.material.PushReaction; +import org.bukkit.craftbukkit.block.data.CraftBlockData; + +public class PaperweightBlockMaterial implements BlockMaterial { + + private final Block block; + private final BlockState blockState; + private final CraftBlockData craftBlockData; + private final org.bukkit.Material craftMaterial; + private final int opacity; + private final CompoundTag tile; + + public PaperweightBlockMaterial(Block block) { + this(block, block.defaultBlockState()); + } + + public PaperweightBlockMaterial(Block block, BlockState blockState) { + this.block = block; + this.blockState = blockState; + this.craftBlockData = CraftBlockData.fromData(blockState); + this.craftMaterial = craftBlockData.getMaterial(); + opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); + BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity( + BlockPos.ZERO, + blockState + ); + tile = tileEntity == null ? null : new PaperweightLazyCompoundTag( + Suppliers.memoize(() -> tileEntity.saveWithId(DedicatedServer.getServer().registryAccess())) + ); + } + + public Block getBlock() { + return block; + } + + public BlockState getState() { + return blockState; + } + + public CraftBlockData getCraftBlockData() { + return craftBlockData; + } + + @Override + public boolean isAir() { + return blockState.isAir(); + } + + @Override + public boolean isFullCube() { + return craftMaterial.isOccluding(); + } + + @Override + public boolean isOpaque() { + return blockState.canOcclude(); + } + + @Override + public boolean isPowerSource() { + return blockState.isSignalSource(); + } + + @Override + public boolean isLiquid() { + return !blockState.getFluidState().is(Fluids.EMPTY); + } + + @Override + public boolean isSolid() { + // No access to world -> EmptyBlockGetter + return blockState.isSolidRender(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); + } + + @Override + public float getHardness() { + return craftBlockData.getState().destroySpeed; + } + + @Override + public float getResistance() { + return block.getExplosionResistance(); + } + + @Override + public float getSlipperiness() { + return block.getFriction(); + } + + @Override + public int getLightValue() { + return blockState.getLightEmission(); + } + + @Override + public int getLightOpacity() { + return opacity; + } + + @Override + public boolean isFragileWhenPushed() { + return blockState.getPistonPushReaction() == PushReaction.DESTROY; + } + + @Override + public boolean isUnpushable() { + return blockState.getPistonPushReaction() == PushReaction.BLOCK; + } + + @Override + public boolean isTicksRandomly() { + return blockState.isRandomlyTicking(); + } + + @Override + public boolean isMovementBlocker() { + return craftMaterial.isSolid(); + } + + @Override + public boolean isBurnable() { + return craftMaterial.isBurnable(); + } + + @Override + public boolean isToolRequired() { + // Removed in 1.16.1, this is not present in higher versions + return false; + } + + @Override + public boolean isReplacedDuringPlacement() { + return blockState.canBeReplaced(); + } + + @Override + public boolean isTranslucent() { + return !blockState.canOcclude(); + } + + @Override + public boolean hasContainer() { + return block instanceof EntityBlock; + } + + @Override + public boolean isTile() { + return block instanceof EntityBlock; + } + + @Override + public CompoundTag getDefaultTile() { + return tile; + } + + @Override + public int getMapColor() { + // rgb field + return block.defaultMapColor().col; + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java new file mode 100644 index 000000000..e0dae1b2f --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java @@ -0,0 +1,639 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1; + +import com.fastasyncworldedit.bukkit.adapter.FaweAdapter; +import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory; +import com.fastasyncworldedit.core.FaweCache; +import com.fastasyncworldedit.core.entity.LazyBaseEntity; +import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; +import com.fastasyncworldedit.core.queue.IBatchProcessor; +import com.fastasyncworldedit.core.queue.IChunkGet; +import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket; +import com.fastasyncworldedit.core.util.NbtUtils; +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.mojang.serialization.Codec; +import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.blocks.BaseItemStack; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; +import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1.nbt.PaperweightLazyCompoundTag; +import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1.regen.PaperweightRegen; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.internal.block.BlockStateIdAccess; +import com.sk89q.worldedit.internal.util.LogManagerCompat; +import com.sk89q.worldedit.internal.wna.WorldNativeAccess; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.registry.state.BooleanProperty; +import com.sk89q.worldedit.registry.state.DirectionalProperty; +import com.sk89q.worldedit.registry.state.EnumProperty; +import com.sk89q.worldedit.registry.state.IntegerProperty; +import com.sk89q.worldedit.registry.state.Property; +import com.sk89q.worldedit.util.Direction; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; +import com.sk89q.worldedit.util.concurrency.LazyReference; +import com.sk89q.worldedit.util.formatting.text.Component; +import com.sk89q.worldedit.world.RegenOptions; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; +import com.sk89q.worldedit.world.block.BlockType; +import com.sk89q.worldedit.world.block.BlockTypesCache; +import com.sk89q.worldedit.world.entity.EntityType; +import com.sk89q.worldedit.world.item.ItemType; +import com.sk89q.worldedit.world.registry.BlockMaterial; +import io.papermc.lib.PaperLib; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.WritableRegistry; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtOps; +import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.StringRepresentable; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.chunk.LevelChunk; +import org.apache.logging.log4j.Logger; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.NamespacedKey; +import org.bukkit.World; +import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.block.data.CraftBlockData; +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.util.CraftNamespacedKey; +import org.bukkit.entity.Player; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinStringTag; +import org.enginehub.linbus.tree.LinTag; + +import javax.annotation.Nullable; +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.OptionalInt; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static net.minecraft.core.registries.Registries.BIOME; + +public final class PaperweightFaweAdapter extends FaweAdapter { + + private static final Logger LOGGER = LogManagerCompat.getLogger(); + private static Method CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE; + private static final Codec COMPONENTS_CODEC = DataComponentPatch.CODEC.optionalFieldOf( + "components", DataComponentPatch.EMPTY + ).codec(); + + static { + try { + CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE = ChunkHolder.class.getDeclaredMethod("wasAccessibleSinceLastSave"); + } catch (NoSuchMethodException ignored) { // may not be present in newer paper versions + } + } + + private final com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_21_R1.PaperweightAdapter parent; + // ------------------------------------------------------------------------ + // Code that may break between versions of Minecraft + // ------------------------------------------------------------------------ + private final PaperweightMapChunkUtil mapUtil = new PaperweightMapChunkUtil(); + private char[] ibdToStateOrdinal = null; + private int[] ordinalToIbdID = null; + private boolean initialised = false; + private Map>> allBlockProperties = null; + + public PaperweightFaweAdapter() throws NoSuchFieldException, NoSuchMethodException { + this.parent = new com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_21_R1.PaperweightAdapter(); + } + + @Nullable + private static String getEntityId(Entity entity) { + ResourceLocation resourceLocation = net.minecraft.world.entity.EntityType.getKey(entity.getType()); + return resourceLocation == null ? null : resourceLocation.toString(); + } + + private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) { + entity.save(compoundTag); + } + + @Override + public BukkitImplAdapter getParent() { + return parent; + } + + private synchronized boolean init() { + if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) { + return false; + } + ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size + ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size + for (int i = 0; i < ibdToStateOrdinal.length; i++) { + BlockState blockState = BlockTypesCache.states[i]; + PaperweightBlockMaterial material = (PaperweightBlockMaterial) blockState.getMaterial(); + int id = Block.BLOCK_STATE_REGISTRY.getId(material.getState()); + char ordinal = blockState.getOrdinalChar(); + ibdToStateOrdinal[id] = ordinal; + ordinalToIbdID[ordinal] = id; + } + Map>> properties = new HashMap<>(); + try { + for (Field field : BlockStateProperties.class.getDeclaredFields()) { + Object obj = field.get(null); + if (!(obj instanceof net.minecraft.world.level.block.state.properties.Property state)) { + continue; + } + Property property; + if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { + property = new BooleanProperty( + state.getName(), + (List) ImmutableList.copyOf(state.getPossibleValues()) + ); + } else if (state instanceof DirectionProperty) { + property = new DirectionalProperty( + state.getName(), + state + .getPossibleValues() + .stream() + .map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase())) + .collect(Collectors.toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { + property = new EnumProperty( + state.getName(), + state + .getPossibleValues() + .stream() + .map(e -> ((StringRepresentable) e).getSerializedName()) + .collect(Collectors.toList()) + ); + } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { + property = new IntegerProperty( + state.getName(), + (List) ImmutableList.copyOf(state.getPossibleValues()) + ); + } else { + throw new IllegalArgumentException("FastAsyncWorldEdit needs an update to support " + state + .getClass() + .getSimpleName()); + } + properties.compute(property.getName().toLowerCase(Locale.ROOT), (k, v) -> { + if (v == null) { + v = new ArrayList<>(Collections.singletonList(property)); + } else { + v.add(property); + } + return v; + }); + } + } catch (IllegalAccessException e) { + e.printStackTrace(); + } finally { + allBlockProperties = ImmutableMap.copyOf(properties); + } + initialised = true; + return true; + } + + @Override + public BlockMaterial getMaterial(BlockType blockType) { + Block block = getBlock(blockType); + return new PaperweightBlockMaterial(block); + } + + @Override + public synchronized BlockMaterial getMaterial(BlockState state) { + net.minecraft.world.level.block.state.BlockState blockState = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState(); + return new PaperweightBlockMaterial(blockState.getBlock(), blockState); + } + + public Block getBlock(BlockType blockType) { + return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK) + .get(ResourceLocation.fromNamespaceAndPath(blockType.getNamespace(), blockType.getResource())); + } + + @Deprecated + @Override + public BlockState getBlock(Location location) { + Preconditions.checkNotNull(location); + + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + final ServerLevel handle = getServerLevel(location.getWorld()); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); + final BlockPos blockPos = new BlockPos(x, y, z); + final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); + BlockState state = adapt(blockData); + if (state == null) { + org.bukkit.block.Block bukkitBlock = location.getBlock(); + state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); + } + return state; + } + + @Override + public BaseBlock getFullBlock(final Location location) { + Preconditions.checkNotNull(location); + + int x = location.getBlockX(); + int y = location.getBlockY(); + int z = location.getBlockZ(); + + final ServerLevel handle = getServerLevel(location.getWorld()); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); + final BlockPos blockPos = new BlockPos(x, y, z); + final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); + BlockState state = adapt(blockData); + if (state == null) { + org.bukkit.block.Block bukkitBlock = location.getBlock(); + state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); + } + if (state.getBlockType().getMaterial().hasContainer()) { + + // Read the NBT data + BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK); + if (blockEntity != null) { + net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(DedicatedServer.getServer().registryAccess()); + return state.toBaseBlock((LinCompoundTag) toNativeLin(tag)); + } + } + + return state.toBaseBlock(); + } + + @Override + public Set getSupportedSideEffects() { + return SideEffectSet.defaults().getSideEffectsToApply(); + } + + @Override + public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { + return new PaperweightFaweWorldNativeAccess(this, new WeakReference<>(getServerLevel(world))); + } + + @Override + public BaseEntity getEntity(org.bukkit.entity.Entity entity) { + Preconditions.checkNotNull(entity); + + CraftEntity craftEntity = ((CraftEntity) entity); + Entity mcEntity = craftEntity.getHandle(); + + String id = getEntityId(mcEntity); + + if (id != null) { + EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id); + Supplier saveTag = () -> { + final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag(); + readEntityIntoTag(mcEntity, minecraftTag); + //add Id for AbstractChangeSet to work + final LinCompoundTag tag = (LinCompoundTag) toNativeLin(minecraftTag); + final Map> tags = NbtUtils.getLinCompoundTagValues(tag); + tags.put("Id", LinStringTag.of(id)); + return LinCompoundTag.of(tags); + }; + return new LazyBaseEntity(type, saveTag); + } else { + return null; + } + } + + @Override + public Component getRichBlockName(BlockType blockType) { + return parent.getRichBlockName(blockType); + } + + @Override + public Component getRichItemName(ItemType itemType) { + return parent.getRichItemName(itemType); + } + + @Override + public Component getRichItemName(BaseItemStack itemStack) { + return parent.getRichItemName(itemStack); + } + + @Override + public OptionalInt getInternalBlockStateId(BlockState state) { + PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial(); + net.minecraft.world.level.block.state.BlockState mcState = material.getCraftBlockData().getState(); + return OptionalInt.of(Block.BLOCK_STATE_REGISTRY.getId(mcState)); + } + + @Override + public BlockState adapt(BlockData blockData) { + CraftBlockData cbd = ((CraftBlockData) blockData); + net.minecraft.world.level.block.state.BlockState ibd = cbd.getState(); + return adapt(ibd); + } + + public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { + return BlockTypesCache.states[adaptToChar(blockState)]; + } + + public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { + int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); + if (initialised) { + return ibdToStateOrdinal[id]; + } + synchronized (this) { + if (initialised) { + return ibdToStateOrdinal[id]; + } + try { + init(); + return ibdToStateOrdinal[id]; + } catch (ArrayIndexOutOfBoundsException e1) { + LOGGER.error("Attempted to convert {} with ID {} to char. ibdToStateOrdinal length: {}. Defaulting to air!", + blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToStateOrdinal.length, e1 + ); + return BlockTypesCache.ReservedIDs.AIR; + } + } + } + + public char ibdIDToOrdinal(int id) { + if (initialised) { + return ibdToStateOrdinal[id]; + } + synchronized (this) { + if (initialised) { + return ibdToStateOrdinal[id]; + } + init(); + return ibdToStateOrdinal[id]; + } + } + + @Override + public char[] getIbdToStateOrdinal() { + if (initialised) { + return ibdToStateOrdinal; + } + synchronized (this) { + if (initialised) { + return ibdToStateOrdinal; + } + init(); + return ibdToStateOrdinal; + } + } + + public int ordinalToIbdID(char ordinal) { + if (initialised) { + return ordinalToIbdID[ordinal]; + } + synchronized (this) { + if (initialised) { + return ordinalToIbdID[ordinal]; + } + init(); + return ordinalToIbdID[ordinal]; + } + } + + @Override + public int[] getOrdinalToIbdID() { + if (initialised) { + return ordinalToIbdID; + } + synchronized (this) { + if (initialised) { + return ordinalToIbdID; + } + init(); + return ordinalToIbdID; + } + } + + @Override + public > BlockData adapt(B state) { + PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial(); + return material.getCraftBlockData(); + } + + @Override + public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) { + ServerLevel nmsWorld = getServerLevel(world); + ChunkHolder map = PaperweightPlatformAdapter.getPlayerChunk(nmsWorld, chunkPacket.getChunkX(), chunkPacket.getChunkZ()); + if (map != null && wasAccessibleSinceLastSave(map)) { + boolean flag = false; + // PlayerChunk.d players = map.players; + Stream stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag) + */ Stream.empty(); + + ServerPlayer checkPlayer = player == null ? null : ((CraftPlayer) player).getHandle(); + stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer) + .forEach(entityPlayer -> { + synchronized (chunkPacket) { + ClientboundLevelChunkWithLightPacket nmsPacket = (ClientboundLevelChunkWithLightPacket) chunkPacket.getNativePacket(); + if (nmsPacket == null) { + nmsPacket = mapUtil.create(this, chunkPacket); + chunkPacket.setNativePacket(nmsPacket); + } + try { + FaweCache.INSTANCE.CHUNK_FLAG.get().set(true); + entityPlayer.connection.send(nmsPacket); + } finally { + FaweCache.INSTANCE.CHUNK_FLAG.get().set(false); + } + } + }); + } + } + + @Override + public Map> getProperties(BlockType blockType) { + return getParent().getProperties(blockType); + } + + @Override + public boolean canPlaceAt(org.bukkit.World world, BlockVector3 blockVector3, BlockState blockState) { + int internalId = BlockStateIdAccess.getBlockStateId(blockState); + net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId); + return blockState1.hasPostProcess( + getServerLevel(world), + new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z()) + ); + } + + @Override + public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) { + final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess(); + ItemStack stack = new ItemStack( + registryAccess.registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(baseItemStack.getType().id())), + baseItemStack.getAmount() + ); + final CompoundTag nbt = (net.minecraft.nbt.CompoundTag) fromNative(baseItemStack.getNbtData()); + if (nbt != null) { + final DataComponentPatch patch = COMPONENTS_CODEC + .parse(registryAccess.createSerializationContext(NbtOps.INSTANCE), nbt) + .getOrThrow(); + stack.applyComponents(patch); + } + return CraftItemStack.asCraftMirror(stack); + } + + @Override + protected void preCaptureStates(final ServerLevel serverLevel) { + serverLevel.captureTreeGeneration = true; + serverLevel.captureBlockStates = true; + } + + @Override + protected List getCapturedBlockStatesCopy(final ServerLevel serverLevel) { + return new ArrayList<>(serverLevel.capturedBlockStates.values()); + } + + @Override + protected void postCaptureBlockStates(final ServerLevel serverLevel) { + serverLevel.captureBlockStates = false; + serverLevel.captureTreeGeneration = false; + serverLevel.capturedBlockStates.clear(); + } + + @Override + protected ServerLevel getServerLevel(final World world) { + return ((CraftWorld) world).getHandle(); + } + + @Override + public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { + final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess(); + final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); + final net.minecraft.nbt.Tag tag = COMPONENTS_CODEC.encodeStart( + registryAccess.createSerializationContext(NbtOps.INSTANCE), + nmsStack.getComponentsPatch() + ).getOrThrow(); + return new BaseItemStack( + BukkitAdapter.asItemType(itemStack.getType()), + LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)), + itemStack.getAmount() + ); + } + + @Override + public Tag toNative(net.minecraft.nbt.Tag foreign) { + return parent.toNative(foreign); + } + + @Override + public net.minecraft.nbt.Tag fromNative(Tag foreign) { + if (foreign instanceof PaperweightLazyCompoundTag) { + return ((PaperweightLazyCompoundTag) foreign).get(); + } + return parent.fromNative(foreign); + } + + @Override + public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent target, RegenOptions options) throws Exception { + return new PaperweightRegen(bukkitWorld, region, target, options).regenerate(); + } + + @Override + public IChunkGet get(org.bukkit.World world, int chunkX, int chunkZ) { + return new PaperweightGetBlocks(world, chunkX, chunkZ); + } + + @Override + public int getInternalBiomeId(BiomeType biomeType) { + final Registry registry = MinecraftServer + .getServer() + .registryAccess() + .registryOrThrow(BIOME); + ResourceLocation resourceLocation = ResourceLocation.tryParse(biomeType.id()); + Biome biome = registry.get(resourceLocation); + return registry.getId(biome); + } + + @Override + public Iterable getRegisteredBiomes() { + WritableRegistry biomeRegistry = (WritableRegistry) ((CraftServer) Bukkit.getServer()) + .getServer() + .registryAccess() + .registryOrThrow(BIOME); + List keys = biomeRegistry.stream() + .map(biomeRegistry::getKey).filter(Objects::nonNull).toList(); + List namespacedKeys = new ArrayList<>(); + for (ResourceLocation key : keys) { + try { + namespacedKeys.add(CraftNamespacedKey.fromMinecraft(key)); + } catch (IllegalArgumentException e) { + LOGGER.error("Error converting biome key {}", key.toString(), e); + } + } + return namespacedKeys; + } + + @Override + public RelighterFactory getRelighterFactory() { + if (PaperLib.isPaper()) { + return new PaperweightStarlightRelighterFactory(); + } else { + return new NMSRelighterFactory(); + } + } + + @Override + public Map>> getAllProperties() { + if (initialised) { + return allBlockProperties; + } + synchronized (this) { + if (initialised) { + return allBlockProperties; + } + init(); + return allBlockProperties; + } + } + + @Override + public IBatchProcessor getTickingPostProcessor() { + return new PaperweightPostProcessor(); + } + + private boolean wasAccessibleSinceLastSave(ChunkHolder holder) { + if (!PaperLib.isPaper() || !PaperweightPlatformAdapter.POST_CHUNK_REWRITE) { + try { + return (boolean) CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE.invoke(holder); + } catch (IllegalAccessException | InvocationTargetException ignored) { + // fall-through + } + } + // Papers new chunk system has no related replacement - therefor we assume true. + return true; + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweWorldNativeAccess.java new file mode 100644 index 000000000..f7c2dc8e8 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweWorldNativeAccess.java @@ -0,0 +1,293 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1; + +import com.fastasyncworldedit.core.Fawe; +import com.fastasyncworldedit.core.math.IntPair; +import com.fastasyncworldedit.core.util.TaskManager; +import com.fastasyncworldedit.core.util.task.RunnableVal; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.internal.block.BlockStateIdAccess; +import com.sk89q.worldedit.internal.wna.WorldNativeAccess; +import com.sk89q.worldedit.util.SideEffect; +import com.sk89q.worldedit.util.SideEffectSet; +import com.sk89q.worldedit.world.block.BlockState; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.server.level.FullChunkStatus; +import net.minecraft.server.level.ServerChunkCache; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.chunk.LevelChunk; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.block.data.CraftBlockData; +import org.bukkit.event.block.BlockPhysicsEvent; +import org.enginehub.linbus.tree.LinCompoundTag; + +import javax.annotation.Nullable; +import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; + +public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess { + + private static final int UPDATE = 1; + private static final int NOTIFY = 2; + private static final Direction[] NEIGHBOUR_ORDER = { + Direction.EAST, + Direction.WEST, + Direction.DOWN, + Direction.UP, + Direction.NORTH, + Direction.SOUTH + }; + private final PaperweightFaweAdapter paperweightFaweAdapter; + private final WeakReference level; + private final AtomicInteger lastTick; + private final Set cachedChanges = new HashSet<>(); + private final Set cachedChunksToSend = new HashSet<>(); + private SideEffectSet sideEffectSet; + + public PaperweightFaweWorldNativeAccess(PaperweightFaweAdapter paperweightFaweAdapter, WeakReference level) { + this.paperweightFaweAdapter = paperweightFaweAdapter; + this.level = level; + // Use the actual tick as minecraft-defined so we don't try to force blocks into the world when the server's already lagging. + // - With the caveat that we don't want to have too many cached changed (1024) so we'd flush those at 1024 anyway. + this.lastTick = new AtomicInteger(MinecraftServer.currentTick); + } + + private Level getLevel() { + return Objects.requireNonNull(level.get(), "The reference to the world was lost"); + } + + @Override + public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) { + this.sideEffectSet = sideEffectSet; + } + + @Override + public LevelChunk getChunk(int x, int z) { + return getLevel().getChunk(x, z); + } + + @Override + public net.minecraft.world.level.block.state.BlockState toNative(BlockState blockState) { + int stateId = paperweightFaweAdapter.ordinalToIbdID(blockState.getOrdinalChar()); + return BlockStateIdAccess.isValidInternalId(stateId) + ? Block.stateById(stateId) + : ((CraftBlockData) BukkitAdapter.adapt(blockState)).getState(); + } + + @Override + public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk levelChunk, BlockPos blockPos) { + return levelChunk.getBlockState(blockPos); + } + + @Nullable + @Override + public synchronized net.minecraft.world.level.block.state.BlockState setBlockState( + LevelChunk levelChunk, BlockPos blockPos, + net.minecraft.world.level.block.state.BlockState blockState + ) { + int currentTick = MinecraftServer.currentTick; + if (Fawe.isMainThread()) { + return levelChunk.setBlockState(blockPos, blockState, + this.sideEffectSet != null && this.sideEffectSet.shouldApply(SideEffect.UPDATE) + ); + } + // Since FAWE is.. Async we need to do it on the main thread (wooooo.. :( ) + cachedChanges.add(new CachedChange(levelChunk, blockPos, blockState)); + cachedChunksToSend.add(new IntPair(levelChunk.locX, levelChunk.locZ)); + boolean nextTick = lastTick.get() > currentTick; + if (nextTick || cachedChanges.size() >= 1024) { + if (nextTick) { + lastTick.set(currentTick); + } + flushAsync(nextTick); + } + return blockState; + } + + @Override + public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition( + net.minecraft.world.level.block.state.BlockState blockState, + BlockPos blockPos + ) { + return Block.updateFromNeighbourShapes(blockState, getLevel(), blockPos); + } + + @Override + public BlockPos getPosition(int x, int y, int z) { + return new BlockPos(x, y, z); + } + + @Override + public void updateLightingForBlock(BlockPos blockPos) { + getLevel().getChunkSource().getLightEngine().checkBlock(blockPos); + } + + @Override + public boolean updateTileEntity(BlockPos blockPos, LinCompoundTag tag) { + // We will assume that the tile entity was created for us, + // though we do not do this on the other versions + BlockEntity blockEntity = getLevel().getBlockEntity(blockPos); + if (blockEntity == null) { + return false; + } + net.minecraft.nbt.Tag nativeTag = paperweightFaweAdapter.fromNativeLin(tag); + blockEntity.loadWithComponents((CompoundTag) nativeTag, DedicatedServer.getServer().registryAccess()); + return true; + } + + @Override + public void notifyBlockUpdate( + LevelChunk levelChunk, BlockPos blockPos, + net.minecraft.world.level.block.state.BlockState oldState, + net.minecraft.world.level.block.state.BlockState newState + ) { + if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) { + getLevel().sendBlockUpdated(blockPos, oldState, newState, UPDATE | NOTIFY); + } + } + + @Override + public boolean isChunkTicking(LevelChunk levelChunk) { + return levelChunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING); + } + + @Override + public void markBlockChanged(LevelChunk levelChunk, BlockPos blockPos) { + if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) { + ((ServerChunkCache) getLevel().getChunkSource()).blockChanged(blockPos); + } + } + + @Override + public void notifyNeighbors( + BlockPos blockPos, + net.minecraft.world.level.block.state.BlockState oldState, + net.minecraft.world.level.block.state.BlockState newState + ) { + Level level = getLevel(); + if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { + level.blockUpdated(blockPos, oldState.getBlock()); + } else { + // When we don't want events, manually run the physics without them. + // Un-nest neighbour updating + for (Direction direction : NEIGHBOUR_ORDER) { + BlockPos shifted = blockPos.relative(direction); + level.getBlockState(shifted).handleNeighborChanged(level, shifted, oldState.getBlock(), blockPos, false); + } + } + if (newState.hasAnalogOutputSignal()) { + level.updateNeighbourForOutputSignal(blockPos, newState.getBlock()); + } + } + + @Override + public void updateNeighbors( + BlockPos blockPos, + net.minecraft.world.level.block.state.BlockState oldState, + net.minecraft.world.level.block.state.BlockState newState, + int recursionLimit + ) { + Level level = getLevel(); + // a == updateNeighbors + // b == updateDiagonalNeighbors + oldState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit); + if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { + CraftWorld craftWorld = level.getWorld(); + if (craftWorld != null) { + BlockPhysicsEvent event = new BlockPhysicsEvent( + craftWorld.getBlockAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()), + CraftBlockData.fromData(newState) + ); + level.getCraftServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return; + } + } + } + newState.triggerEvent(level, blockPos, NOTIFY, recursionLimit); + newState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit); + } + + @Override + public void updateBlock(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { + Level world = getLevel(); + newState.onPlace(world, pos, oldState, false); + } + + @Override + public void onBlockStateChange( + BlockPos blockPos, + net.minecraft.world.level.block.state.BlockState oldState, + net.minecraft.world.level.block.state.BlockState newState + ) { + getLevel().onBlockStateChange(blockPos, oldState, newState); + } + + private synchronized void flushAsync(final boolean sendChunks) { + final Set changes = Set.copyOf(cachedChanges); + cachedChanges.clear(); + final Set toSend; + if (sendChunks) { + toSend = Set.copyOf(cachedChunksToSend); + cachedChunksToSend.clear(); + } else { + toSend = Collections.emptySet(); + } + RunnableVal runnableVal = new RunnableVal<>() { + @Override + public void run(Object value) { + changes.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState, + sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE) + )); + if (!sendChunks) { + return; + } + for (IntPair chunk : toSend) { + PaperweightPlatformAdapter.sendChunk(chunk, getLevel().getWorld().getHandle(), chunk.x(), chunk.z()); + } + } + }; + TaskManager.taskManager().async(() -> TaskManager.taskManager().sync(runnableVal)); + } + + @Override + public synchronized void flush() { + RunnableVal runnableVal = new RunnableVal<>() { + @Override + public void run(Object value) { + cachedChanges.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState, + sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE) + )); + for (IntPair chunk : cachedChunksToSend) { + PaperweightPlatformAdapter.sendChunk(chunk, getLevel().getWorld().getHandle(), chunk.x(), chunk.z()); + } + } + }; + if (Fawe.isMainThread()) { + runnableVal.run(); + } else { + TaskManager.taskManager().sync(runnableVal); + } + cachedChanges.clear(); + cachedChunksToSend.clear(); + } + + private record CachedChange( + LevelChunk levelChunk, + BlockPos blockPos, + net.minecraft.world.level.block.state.BlockState blockState + ) { + + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks.java new file mode 100644 index 000000000..bdd9d0648 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks.java @@ -0,0 +1,1186 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1; + +import com.fastasyncworldedit.bukkit.adapter.BukkitGetBlocks; +import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; +import com.fastasyncworldedit.core.Fawe; +import com.fastasyncworldedit.core.FaweCache; +import com.fastasyncworldedit.core.configuration.Settings; +import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; +import com.fastasyncworldedit.core.math.BitArrayUnstretched; +import com.fastasyncworldedit.core.queue.IChunkGet; +import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.QueueHandler; +import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks; +import com.fastasyncworldedit.core.util.MathMan; +import com.fastasyncworldedit.core.util.collection.AdaptedMap; +import com.google.common.base.Suppliers; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.ListTag; +import com.sk89q.jnbt.StringTag; +import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1.nbt.PaperweightLazyCompoundTag; +import com.sk89q.worldedit.internal.Constants; +import com.sk89q.worldedit.internal.util.LogManagerCompat; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.biome.BiomeTypes; +import com.sk89q.worldedit.world.block.BlockTypesCache; +import io.papermc.lib.PaperLib; +import io.papermc.paper.event.block.BeaconDeactivatedEvent; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.IdMap; +import net.minecraft.core.Registry; +import net.minecraft.core.SectionPos; +import net.minecraft.nbt.IntTag; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.BitStorage; +import net.minecraft.util.ZeroBitStorage; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.LightLayer; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.entity.BeaconBlockEntity; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.DataLayer; +import net.minecraft.world.level.chunk.HashMapPalette; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.LinearPalette; +import net.minecraft.world.level.chunk.Palette; +import net.minecraft.world.level.chunk.PalettedContainer; +import net.minecraft.world.level.chunk.PalettedContainerRO; +import net.minecraft.world.level.levelgen.Heightmap; +import net.minecraft.world.level.lighting.LevelLightEngine; +import org.apache.logging.log4j.Logger; +import org.bukkit.World; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.event.entity.CreatureSpawnEvent; + +import javax.annotation.Nonnull; +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Future; +import java.util.concurrent.Semaphore; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static net.minecraft.core.registries.Registries.BIOME; + +public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks { + + private static final Logger LOGGER = LogManagerCompat.getLogger(); + + private static final Function posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ()); + private static final Function nmsTile2We = tileEntity -> new PaperweightLazyCompoundTag( + Suppliers.memoize(() -> tileEntity.saveWithId(DedicatedServer.getServer().registryAccess())) + ); + private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin + .getInstance() + .getBukkitImplAdapter()); + private final ReadWriteLock sectionLock = new ReentrantReadWriteLock(); + private final ReentrantLock callLock = new ReentrantLock(); + private final ServerLevel serverLevel; + private final int chunkX; + private final int chunkZ; + private final int minHeight; + private final int maxHeight; + private final int minSectionPosition; + private final int maxSectionPosition; + private final Registry biomeRegistry; + private final IdMap> biomeHolderIdMap; + private final ConcurrentHashMap copies = new ConcurrentHashMap<>(); + private final Object sendLock = new Object(); + private LevelChunkSection[] sections; + private LevelChunk levelChunk; + private DataLayer[] blockLight; + private DataLayer[] skyLight; + private boolean createCopy = false; + private boolean forceLoadSections = true; + private boolean lightUpdate = false; + private int copyKey = 0; + + public PaperweightGetBlocks(World world, int chunkX, int chunkZ) { + this(((CraftWorld) world).getHandle(), chunkX, chunkZ); + } + + public PaperweightGetBlocks(ServerLevel serverLevel, int chunkX, int chunkZ) { + super(serverLevel.getMinBuildHeight() >> 4, (serverLevel.getMaxBuildHeight() - 1) >> 4); + this.serverLevel = serverLevel; + this.chunkX = chunkX; + this.chunkZ = chunkZ; + this.minHeight = serverLevel.getMinBuildHeight(); + this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. + this.minSectionPosition = minHeight >> 4; + this.maxSectionPosition = maxHeight >> 4; + this.skyLight = new DataLayer[getSectionCount()]; + this.blockLight = new DataLayer[getSectionCount()]; + this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(BIOME); + this.biomeHolderIdMap = biomeRegistry.asHolderIdMap(); + } + + public int getChunkX() { + return chunkX; + } + + public int getChunkZ() { + return chunkZ; + } + + @Override + public boolean isCreateCopy() { + return createCopy; + } + + @Override + public int setCreateCopy(boolean createCopy) { + if (!callLock.isHeldByCurrentThread()) { + throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); + } + this.createCopy = createCopy; + // Increment regardless of whether copy will be created or not to return null from getCopy() + return ++this.copyKey; + } + + @Override + public IChunkGet getCopy(final int key) { + return copies.remove(key); + } + + @Override + public void lockCall() { + this.callLock.lock(); + } + + @Override + public void unlockCall() { + this.callLock.unlock(); + } + + @Override + public void setLightingToGet(char[][] light, int minSectionPosition, int maxSectionPosition) { + if (light != null) { + lightUpdate = true; + try { + fillLightNibble(light, LightLayer.BLOCK, minSectionPosition, maxSectionPosition); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + @Override + public void setSkyLightingToGet(char[][] light, int minSectionPosition, int maxSectionPosition) { + if (light != null) { + lightUpdate = true; + try { + fillLightNibble(light, LightLayer.SKY, minSectionPosition, maxSectionPosition); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + @Override + public void setHeightmapToGet(HeightMapType type, int[] data) { + // height + 1 to match server internal + BitArrayUnstretched bitArray = new BitArrayUnstretched(MathMan.log2nlz(getChunk().getHeight() + 1), 256); + bitArray.fromRaw(data); + Heightmap.Types nativeType = Heightmap.Types.valueOf(type.name()); + Heightmap heightMap = getChunk().heightmaps.get(nativeType); + heightMap.setRawData(getChunk(), nativeType, bitArray.getData()); + } + + @Override + public int getMaxY() { + return maxHeight; + } + + @Override + public int getMinY() { + return minHeight; + } + + @Override + public BiomeType getBiomeType(int x, int y, int z) { + LevelChunkSection section = getSections(false)[(y >> 4) - getMinSectionPosition()]; + Holder biomes = section.getNoiseBiome(x >> 2, (y & 15) >> 2, z >> 2); + return PaperweightPlatformAdapter.adapt(biomes, serverLevel); + } + + @Override + public void removeSectionLighting(int layer, boolean sky) { + SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); + DataLayer dataLayer = serverLevel.getChunkSource().getLightEngine().getLayerListener(LightLayer.BLOCK).getDataLayerData( + sectionPos); + if (dataLayer != null) { + lightUpdate = true; + synchronized (dataLayer) { + byte[] bytes = dataLayer.getData(); + Arrays.fill(bytes, (byte) 0); + } + } + if (sky) { + SectionPos sectionPos1 = SectionPos.of(getChunk().getPos(), layer); + DataLayer dataLayer1 = serverLevel + .getChunkSource() + .getLightEngine() + .getLayerListener(LightLayer.SKY) + .getDataLayerData(sectionPos1); + if (dataLayer1 != null) { + lightUpdate = true; + synchronized (dataLayer1) { + byte[] bytes = dataLayer1.getData(); + Arrays.fill(bytes, (byte) 0); + } + } + } + } + + @Override + public CompoundTag getTile(int x, int y, int z) { + BlockEntity blockEntity = getChunk().getBlockEntity(new BlockPos((x & 15) + ( + chunkX << 4), y, (z & 15) + ( + chunkZ << 4))); + if (blockEntity == null) { + return null; + } + return new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.saveWithId(DedicatedServer.getServer().registryAccess()))); + } + + @Override + public Map getTiles() { + Map nmsTiles = getChunk().getBlockEntities(); + if (nmsTiles.isEmpty()) { + return Collections.emptyMap(); + } + return AdaptedMap.immutable(nmsTiles, posNms2We, nmsTile2We); + } + + @Override + public int getSkyLight(int x, int y, int z) { + int layer = y >> 4; + int alayer = layer - getMinSectionPosition(); + if (skyLight[alayer] == null) { + SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); + DataLayer dataLayer = + serverLevel.getChunkSource().getLightEngine().getLayerListener(LightLayer.SKY).getDataLayerData(sectionPos); + // If the server hasn't generated the section's NibbleArray yet, it will be null + if (dataLayer == null) { + byte[] LAYER_COUNT = new byte[2048]; + // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. + Arrays.fill(LAYER_COUNT, (byte) 15); + dataLayer = new DataLayer(LAYER_COUNT); + ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( + LightLayer.BLOCK, + sectionPos, + dataLayer + ); + } + skyLight[alayer] = dataLayer; + } + return skyLight[alayer].get(x & 15, y & 15, z & 15); + } + + @Override + public int getEmittedLight(int x, int y, int z) { + int layer = y >> 4; + int alayer = layer - getMinSectionPosition(); + if (blockLight[alayer] == null) { + serverLevel.getRawBrightness(new BlockPos(1, 1, 1), 5); + SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); + DataLayer dataLayer = serverLevel + .getChunkSource() + .getLightEngine() + .getLayerListener(LightLayer.BLOCK) + .getDataLayerData(sectionPos); + // If the server hasn't generated the section's DataLayer yet, it will be null + if (dataLayer == null) { + byte[] LAYER_COUNT = new byte[2048]; + // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. + Arrays.fill(LAYER_COUNT, (byte) 15); + dataLayer = new DataLayer(LAYER_COUNT); + ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(LightLayer.BLOCK, sectionPos, + dataLayer + ); + } + blockLight[alayer] = dataLayer; + } + return blockLight[alayer].get(x & 15, y & 15, z & 15); + } + + @Override + public int[] getHeightMap(HeightMapType type) { + long[] longArray = getChunk().heightmaps.get(Heightmap.Types.valueOf(type.name())).getRawData(); + BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256, longArray); + return bitArray.toRaw(new int[256]); + } + + @Override + public CompoundTag getEntity(UUID uuid) { + ensureLoaded(serverLevel, chunkX, chunkZ); + List entities = PaperweightPlatformAdapter.getEntities(getChunk()); + Entity entity = null; + for (Entity e : entities) { + if (e.getUUID().equals(uuid)) { + entity = e; + break; + } + } + if (entity != null) { + org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity(); + return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); + } + for (CompoundTag tag : getEntities()) { + if (uuid.equals(tag.getUUID())) { + return tag; + } + } + return null; + } + + @Override + public Set getEntities() { + ensureLoaded(serverLevel, chunkX, chunkZ); + List entities = PaperweightPlatformAdapter.getEntities(getChunk()); + if (entities.isEmpty()) { + return Collections.emptySet(); + } + int size = entities.size(); + return new AbstractSet<>() { + @Override + public int size() { + return size; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean contains(Object get) { + if (!(get instanceof CompoundTag getTag)) { + return false; + } + UUID getUUID = getTag.getUUID(); + for (Entity entity : entities) { + UUID uuid = entity.getUUID(); + if (uuid.equals(getUUID)) { + return true; + } + } + return false; + } + + @Nonnull + @Override + public Iterator iterator() { + Iterable result = entities.stream().map(input -> { + net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); + input.save(tag); + return (CompoundTag) adapter.toNative(tag); + }).collect(Collectors.toList()); + return result.iterator(); + } + }; + } + + private void removeEntity(Entity entity) { + entity.discard(); + } + + public LevelChunk ensureLoaded(ServerLevel nmsWorld, int chunkX, int chunkZ) { + return PaperweightPlatformAdapter.ensureLoaded(nmsWorld, chunkX, chunkZ); + } + + @Override + @SuppressWarnings("rawtypes") + public synchronized > T call(IChunkSet set, Runnable finalizer) { + if (!callLock.isHeldByCurrentThread()) { + throw new IllegalStateException("Attempted to call chunk GET but chunk was not call-locked."); + } + forceLoadSections = false; + PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null; + if (createCopy) { + if (copies.containsKey(copyKey)) { + throw new IllegalStateException("Copy key already used."); + } + copies.put(copyKey, copy); + } + try { + ServerLevel nmsWorld = serverLevel; + LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ); + + // Remove existing tiles. Create a copy so that we can remove blocks + Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); + List beacons = null; + if (!chunkTiles.isEmpty()) { + for (Map.Entry entry : chunkTiles.entrySet()) { + final BlockPos pos = entry.getKey(); + final int lx = pos.getX() & 15; + final int ly = pos.getY(); + final int lz = pos.getZ() & 15; + final int layer = ly >> 4; + if (!set.hasSection(layer)) { + continue; + } + + int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); + if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { + BlockEntity tile = entry.getValue(); + if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { + if (beacons == null) { + beacons = new ArrayList<>(); + } + beacons.add(tile); + PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); + continue; + } + nmsChunk.removeBlockEntity(tile.getBlockPos()); + if (createCopy) { + copy.storeTile(tile); + } + } + } + } + final BiomeType[][] biomes = set.getBiomes(); + + int bitMask = 0; + synchronized (nmsChunk) { + LevelChunkSection[] levelChunkSections = nmsChunk.getSections(); + + for (int layerNo = getMinSectionPosition(); layerNo <= getMaxSectionPosition(); layerNo++) { + + int getSectionIndex = layerNo - getMinSectionPosition(); + int setSectionIndex = layerNo - set.getMinSectionPosition(); + + if (!set.hasSection(layerNo)) { + // No blocks, but might be biomes present. Handle this lazily. + if (biomes == null) { + continue; + } + if (layerNo < set.getMinSectionPosition() || layerNo > set.getMaxSectionPosition()) { + continue; + } + if (biomes[setSectionIndex] != null) { + synchronized (super.sectionLocks[getSectionIndex]) { + LevelChunkSection existingSection = levelChunkSections[getSectionIndex]; + if (createCopy && existingSection != null) { + copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); + } + + if (existingSection == null) { + PalettedContainer> biomeData = PaperweightPlatformAdapter.getBiomePalettedContainer( + biomes[setSectionIndex], + biomeHolderIdMap + ); + LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + new char[4096], + adapter, + biomeRegistry, + biomeData + ); + if (PaperweightPlatformAdapter.setSectionAtomic( + levelChunkSections, + null, + newSection, + getSectionIndex + )) { + updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); + continue; + } else { + existingSection = levelChunkSections[getSectionIndex]; + if (existingSection == null) { + LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, + getSectionIndex + ); + continue; + } + } + } else { + PalettedContainer> paletteBiomes = setBiomesToPalettedContainer( + biomes, + setSectionIndex, + existingSection.getBiomes() + ); + if (paletteBiomes != null) { + PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); + } + } + } + } + continue; + } + + bitMask |= 1 << getSectionIndex; + + // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to + // this chunk GET when #updateGet is called. Future dords, please listen this time. + char[] tmp = set.load(layerNo); + char[] setArr = new char[tmp.length]; + System.arraycopy(tmp, 0, setArr, 0, tmp.length); + + // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was + // submitted to keep loaded internal chunks to queue target size. + synchronized (super.sectionLocks[getSectionIndex]) { + + LevelChunkSection newSection; + LevelChunkSection existingSection = levelChunkSections[getSectionIndex]; + // Don't attempt to tick section whilst we're editing + if (existingSection != null) { + PaperweightPlatformAdapter.clearCounts(existingSection); + } + + if (createCopy) { + char[] tmpLoad = loadPrivately(layerNo); + char[] copyArr = new char[4096]; + System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); + copy.storeSection(getSectionIndex, copyArr); + if (biomes != null && existingSection != null) { + copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); + } + } + + if (existingSection == null) { + PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( + biomeHolderIdMap, + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), + PalettedContainer.Strategy.SECTION_BIOMES + ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); + newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + setArr, + adapter, + biomeRegistry, + biomeData + ); + if (PaperweightPlatformAdapter.setSectionAtomic( + levelChunkSections, + null, + newSection, + getSectionIndex + )) { + updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex); + continue; + } else { + existingSection = levelChunkSections[getSectionIndex]; + if (existingSection == null) { + LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, + getSectionIndex + ); + continue; + } + } + } + + //ensure that the server doesn't try to tick the chunksection while we're editing it. (Again) + PaperweightPlatformAdapter.clearCounts(existingSection); + DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(existingSection); + + // Synchronize to prevent further acquisitions + synchronized (lock) { + lock.acquire(); // Wait until we have the lock + lock.release(); + try { + sectionLock.writeLock().lock(); + if (this.getChunk() != nmsChunk) { + this.levelChunk = nmsChunk; + this.sections = null; + this.reset(); + } else if (existingSection != getSections(false)[getSectionIndex]) { + this.sections[getSectionIndex] = existingSection; + this.reset(); + } else if (!Arrays.equals( + update(getSectionIndex, new char[4096], true), + loadPrivately(layerNo) + )) { + this.reset(layerNo); + /*} else if (lock.isModified()) { + this.reset(layerNo);*/ + } + } finally { + sectionLock.writeLock().unlock(); + } + + PalettedContainer> biomeData = setBiomesToPalettedContainer( + biomes, + setSectionIndex, + existingSection.getBiomes() + ); + + newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + this::loadPrivately, + setArr, + adapter, + biomeRegistry, + biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() + ); + if (!PaperweightPlatformAdapter.setSectionAtomic(levelChunkSections, existingSection, + newSection, + getSectionIndex + )) { + LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, + getSectionIndex + ); + } else { + updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex); + } + } + } + } + + Map heightMaps = set.getHeightMaps(); + for (Map.Entry entry : heightMaps.entrySet()) { + PaperweightGetBlocks.this.setHeightmapToGet(entry.getKey(), entry.getValue()); + } + PaperweightGetBlocks.this.setLightingToGet( + set.getLight(), + set.getMinSectionPosition(), + set.getMaxSectionPosition() + ); + PaperweightGetBlocks.this.setSkyLightingToGet( + set.getSkyLight(), + set.getMinSectionPosition(), + set.getMaxSectionPosition() + ); + + Runnable[] syncTasks = null; + + int bx = chunkX << 4; + int bz = chunkZ << 4; + + // Call beacon deactivate events here synchronously + // list will be null on spigot, so this is an implicit isPaper check + if (beacons != null && !beacons.isEmpty()) { + final List finalBeacons = beacons; + + syncTasks = new Runnable[4]; + + syncTasks[3] = () -> { + for (BlockEntity beacon : finalBeacons) { + BeaconBlockEntity.playSound(beacon.getLevel(), beacon.getBlockPos(), SoundEvents.BEACON_DEACTIVATE); + new BeaconDeactivatedEvent(CraftBlock.at(beacon.getLevel(), beacon.getBlockPos())).callEvent(); + } + }; + } + + Set entityRemoves = set.getEntityRemoves(); + if (entityRemoves != null && !entityRemoves.isEmpty()) { + if (syncTasks == null) { + syncTasks = new Runnable[3]; + } + + syncTasks[2] = () -> { + Set entitiesRemoved = new HashSet<>(); + final List entities = PaperweightPlatformAdapter.getEntities(nmsChunk); + + for (Entity entity : entities) { + UUID uuid = entity.getUUID(); + if (entityRemoves.contains(uuid)) { + if (createCopy) { + copy.storeEntity(entity); + } + removeEntity(entity); + entitiesRemoved.add(uuid); + entityRemoves.remove(uuid); + } + } + if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) { + for (UUID uuid : entityRemoves) { + Entity entity = nmsWorld.getEntities().get(uuid); + if (entity != null) { + removeEntity(entity); + } + } + } + // Only save entities that were actually removed to history + set.getEntityRemoves().clear(); + set.getEntityRemoves().addAll(entitiesRemoved); + }; + } + + Set entities = set.getEntities(); + if (entities != null && !entities.isEmpty()) { + if (syncTasks == null) { + syncTasks = new Runnable[2]; + } + + syncTasks[1] = () -> { + Iterator iterator = entities.iterator(); + while (iterator.hasNext()) { + final CompoundTag nativeTag = iterator.next(); + final Map> entityTagMap = nativeTag.getValue(); + final StringTag idTag = (StringTag) entityTagMap.get("Id"); + final ListTag posTag = (ListTag) entityTagMap.get("Pos"); + final ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); + if (idTag == null || posTag == null || rotTag == null) { + LOGGER.error("Unknown entity tag: {}", nativeTag); + continue; + } + final double x = posTag.getDouble(0); + final double y = posTag.getDouble(1); + final double z = posTag.getDouble(2); + final float yaw = rotTag.getFloat(0); + final float pitch = rotTag.getFloat(1); + final String id = idTag.getValue(); + + EntityType type = EntityType.byString(id).orElse(null); + if (type != null) { + Entity entity = type.create(nmsWorld); + if (entity != null) { + final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative( + nativeTag); + for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { + tag.remove(name); + } + entity.load(tag); + entity.absMoveTo(x, y, z, yaw, pitch); + entity.setUUID(nativeTag.getUUID()); + if (!nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) { + LOGGER.warn( + "Error creating entity of type `{}` in world `{}` at location `{},{},{}`", + id, + nmsWorld.getWorld().getName(), + x, + y, + z + ); + // Unsuccessful create should not be saved to history + iterator.remove(); + } + } + } + } + }; + } + + // set tiles + Map tiles = set.getTiles(); + if (tiles != null && !tiles.isEmpty()) { + if (syncTasks == null) { + syncTasks = new Runnable[1]; + } + + syncTasks[0] = () -> { + for (final Map.Entry entry : tiles.entrySet()) { + final CompoundTag nativeTag = entry.getValue(); + final BlockVector3 blockHash = entry.getKey(); + final int x = blockHash.x() + bx; + final int y = blockHash.y(); + final int z = blockHash.z() + bz; + final BlockPos pos = new BlockPos(x, y, z); + + synchronized (nmsWorld) { + BlockEntity tileEntity = nmsWorld.getBlockEntity(pos); + if (tileEntity == null || tileEntity.isRemoved()) { + nmsWorld.removeBlockEntity(pos); + tileEntity = nmsWorld.getBlockEntity(pos); + } + if (tileEntity != null) { + final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative( + nativeTag); + tag.put("x", IntTag.valueOf(x)); + tag.put("y", IntTag.valueOf(y)); + tag.put("z", IntTag.valueOf(z)); + tileEntity.loadWithComponents(tag, DedicatedServer.getServer().registryAccess()); + } + } + } + }; + } + + Runnable callback; + if (bitMask == 0 && biomes == null && !lightUpdate) { + callback = null; + } else { + int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0; + boolean finalLightUpdate = lightUpdate; + callback = () -> { + // Set Modified + nmsChunk.setLightCorrect(true); // Set Modified + nmsChunk.mustNotSave = false; + nmsChunk.setUnsaved(true); + // send to player + if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) { + this.send(); + } + if (finalizer != null) { + finalizer.run(); + } + }; + } + if (syncTasks != null) { + QueueHandler queueHandler = Fawe.instance().getQueueHandler(); + Runnable[] finalSyncTasks = syncTasks; + + // Chain the sync tasks and the callback + Callable chain = () -> { + try { + // Run the sync tasks + for (Runnable task : finalSyncTasks) { + if (task != null) { + task.run(); + } + } + if (callback == null) { + if (finalizer != null) { + queueHandler.async(finalizer, null); + } + return null; + } else { + return queueHandler.async(callback, null); + } + } catch (Throwable e) { + e.printStackTrace(); + throw e; + } + }; + //noinspection unchecked - required at compile time + return (T) (Future) queueHandler.sync(chain); + } else { + if (callback == null) { + if (finalizer != null) { + finalizer.run(); + } + } else { + callback.run(); + } + } + } + return null; + } catch (Throwable e) { + e.printStackTrace(); + return null; + } finally { + forceLoadSections = true; + } + } + + private void updateGet( + LevelChunk nmsChunk, + LevelChunkSection[] chunkSections, + LevelChunkSection section, + char[] arr, + int layer + ) { + try { + sectionLock.writeLock().lock(); + if (this.getChunk() != nmsChunk) { + this.levelChunk = nmsChunk; + this.sections = new LevelChunkSection[chunkSections.length]; + System.arraycopy(chunkSections, 0, this.sections, 0, chunkSections.length); + this.reset(); + } + if (this.sections == null) { + this.sections = new LevelChunkSection[chunkSections.length]; + System.arraycopy(chunkSections, 0, this.sections, 0, chunkSections.length); + } + if (this.sections[layer] != section) { + // Not sure why it's funky, but it's what I did in commit fda7d00747abe97d7891b80ed8bb88d97e1c70d1 and I don't want to touch it >dords + this.sections[layer] = new LevelChunkSection[]{section}.clone()[0]; + } + } finally { + sectionLock.writeLock().unlock(); + } + this.blocks[layer] = arr; + } + + private char[] loadPrivately(int layer) { + layer -= getMinSectionPosition(); + if (super.sections[layer] != null) { + synchronized (super.sectionLocks[layer]) { + if (super.sections[layer].isFull() && super.blocks[layer] != null) { + return super.blocks[layer]; + } + } + } + return PaperweightGetBlocks.this.update(layer, null, true); + } + + @Override + public void send() { + synchronized (sendLock) { + PaperweightPlatformAdapter.sendChunk(this, serverLevel, chunkX, chunkZ); + } + } + + /** + * Update a given (nullable) data array to the current data stored in the server's chunk, associated with this + * {@link PaperweightPlatformAdapter} instance. Not synchronised to the {@link PaperweightPlatformAdapter} instance as synchronisation + * is handled where necessary in the method, and should otherwise be handled correctly by this method's caller. + * + * @param layer layer index (0 may denote a negative layer in the world, e.g. at y=-32) + * @param data array to be updated/filled with data or null + * @param aggressive if the cached section array should be re-acquired. + * @return the given array to be filled with data, or a new array if null is given. + */ + @Override + @SuppressWarnings("unchecked") + public char[] update(int layer, char[] data, boolean aggressive) { + LevelChunkSection section = getSections(aggressive)[layer]; + // Section is null, return empty array + if (section == null) { + data = new char[4096]; + Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); + return data; + } + if (data != null && data.length != 4096) { + data = new char[4096]; + Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); + } + if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096) { + data = new char[4096]; + Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); + } + Semaphore lock = PaperweightPlatformAdapter.applyLock(section); + synchronized (lock) { + // Efficiently convert ChunkSection to raw data + try { + lock.acquire(); + + final PalettedContainer blocks = section.getStates(); + final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocks); + final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); + + if (bits instanceof ZeroBitStorage) { + Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper + return data; + } + + final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get(dataObject); + + final int bitsPerEntry = bits.getBits(); + final long[] blockStates = bits.getRaw(); + + new BitArrayUnstretched(bitsPerEntry, 4096, blockStates).toRaw(data); + + int num_palette; + if (palette instanceof LinearPalette || palette instanceof HashMapPalette) { + num_palette = palette.getSize(); + } else { + // The section's palette is the global block palette. + for (int i = 0; i < 4096; i++) { + char paletteVal = data[i]; + char ordinal = adapter.ibdIDToOrdinal(paletteVal); + data[i] = ordinal; + } + return data; + } + + char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); + try { + if (num_palette != 1) { + for (int i = 0; i < num_palette; i++) { + char ordinal = ordinal(palette.valueFor(i), adapter); + paletteToOrdinal[i] = ordinal; + } + for (int i = 0; i < 4096; i++) { + char paletteVal = data[i]; + char val = paletteToOrdinal[paletteVal]; + if (val == Character.MAX_VALUE) { + val = ordinal(palette.valueFor(i), adapter); + paletteToOrdinal[i] = val; + } + data[i] = val; + } + } else { + char ordinal = ordinal(palette.valueFor(0), adapter); + Arrays.fill(data, ordinal); + } + } finally { + for (int i = 0; i < num_palette; i++) { + paletteToOrdinal[i] = Character.MAX_VALUE; + } + } + return data; + } catch (IllegalAccessException | InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } finally { + lock.release(); + } + } + } + + private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { + if (ibd == null) { + return BlockTypesCache.ReservedIDs.AIR; + } else { + return adapter.adaptToChar(ibd); + } + } + + public LevelChunkSection[] getSections(boolean force) { + force &= forceLoadSections; + LevelChunkSection[] tmp = sections; + if (tmp == null || force) { + try { + sectionLock.writeLock().lock(); + tmp = sections; + if (tmp == null || force) { + LevelChunkSection[] chunkSections = getChunk().getSections(); + tmp = new LevelChunkSection[chunkSections.length]; + System.arraycopy(chunkSections, 0, tmp, 0, chunkSections.length); + sections = tmp; + } + } finally { + sectionLock.writeLock().unlock(); + } + } + return tmp; + } + + public LevelChunk getChunk() { + LevelChunk levelChunk = this.levelChunk; + if (levelChunk == null) { + synchronized (this) { + levelChunk = this.levelChunk; + if (levelChunk == null) { + this.levelChunk = levelChunk = ensureLoaded(this.serverLevel, chunkX, chunkZ); + } + } + } + return levelChunk; + } + + private void fillLightNibble(char[][] light, LightLayer lightLayer, int minSectionPosition, int maxSectionPosition) { + for (int Y = 0; Y <= maxSectionPosition - minSectionPosition; Y++) { + if (light[Y] == null) { + continue; + } + SectionPos sectionPos = SectionPos.of(levelChunk.getPos(), Y + minSectionPosition); + DataLayer dataLayer = serverLevel.getChunkSource().getLightEngine().getLayerListener(lightLayer).getDataLayerData( + sectionPos); + if (dataLayer == null) { + byte[] LAYER_COUNT = new byte[2048]; + Arrays.fill(LAYER_COUNT, lightLayer == LightLayer.SKY ? (byte) 15 : (byte) 0); + dataLayer = new DataLayer(LAYER_COUNT); + ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( + lightLayer, + sectionPos, + dataLayer + ); + } + synchronized (dataLayer) { + for (int x = 0; x < 16; x++) { + for (int y = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + int i = y << 8 | z << 4 | x; + if (light[Y][i] < 16) { + dataLayer.set(x, y, z, light[Y][i]); + } + } + } + } + } + } + } + + private PalettedContainer> setBiomesToPalettedContainer( + final BiomeType[][] biomes, + final int sectionIndex, + final PalettedContainerRO> data + ) { + BiomeType[] sectionBiomes; + if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { + return null; + } + PalettedContainer> biomeData = data.recreate(); + for (int y = 0, index = 0; y < 4; y++) { + for (int z = 0; z < 4; z++) { + for (int x = 0; x < 4; x++, index++) { + BiomeType biomeType = sectionBiomes[index]; + if (biomeType == null) { + biomeData.set(x, y, z, data.get(x, y, z)); + } else { + biomeData.set( + x, + y, + z, + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) + ); + } + } + } + } + return biomeData; + } + + @Override + public boolean hasSection(int layer) { + layer -= getMinSectionPosition(); + return getSections(false)[layer] != null; + } + + @Override + @SuppressWarnings("unchecked") + public synchronized boolean trim(boolean aggressive) { + skyLight = new DataLayer[getSectionCount()]; + blockLight = new DataLayer[getSectionCount()]; + if (aggressive) { + sectionLock.writeLock().lock(); + sections = null; + levelChunk = null; + sectionLock.writeLock().unlock(); + return super.trim(true); + } else if (sections == null) { + // don't bother trimming if there are no sections stored. + return true; + } else { + for (int i = getMinSectionPosition(); i <= getMaxSectionPosition(); i++) { + int layer = i - getMinSectionPosition(); + if (!hasSection(i) || !super.sections[layer].isFull()) { + continue; + } + LevelChunkSection existing = getSections(true)[layer]; + try { + final PalettedContainer blocksExisting = existing.getStates(); + + final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocksExisting); + final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get( + dataObject); + int paletteSize; + + if (palette instanceof LinearPalette || palette instanceof HashMapPalette) { + paletteSize = palette.getSize(); + } else { + super.trim(false, i); + continue; + } + if (paletteSize == 1) { + //If the cached palette size is 1 then no blocks can have been changed i.e. do not need to update these chunks. + continue; + } + super.trim(false, i); + } catch (IllegalAccessException ignored) { + super.trim(false, i); + } + } + return true; + } + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks_Copy.java new file mode 100644 index 000000000..a0a4d02d9 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks_Copy.java @@ -0,0 +1,260 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1; + +import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; +import com.fastasyncworldedit.core.queue.IBlocks; +import com.fastasyncworldedit.core.queue.IChunkGet; +import com.fastasyncworldedit.core.queue.IChunkSet; +import com.google.common.base.Suppliers; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; +import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1.nbt.PaperweightLazyCompoundTag; +import com.sk89q.worldedit.internal.util.LogManagerCompat; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockTypesCache; +import net.minecraft.core.Holder; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.PalettedContainer; +import net.minecraft.world.level.chunk.PalettedContainerRO; +import org.apache.logging.log4j.Logger; + +import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.Future; + +public class PaperweightGetBlocks_Copy implements IChunkGet { + + private static final Logger LOGGER = LogManagerCompat.getLogger(); + + private final Map tiles = new HashMap<>(); + private final Set entities = new HashSet<>(); + private final char[][] blocks; + private final int minHeight; + private final int maxHeight; + final ServerLevel serverLevel; + final LevelChunk levelChunk; + private Holder[][] biomes = null; + + protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { + this.levelChunk = levelChunk; + this.serverLevel = levelChunk.level; + this.minHeight = serverLevel.getMinBuildHeight(); + this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. + this.blocks = new char[getSectionCount()][]; + } + + protected void storeTile(BlockEntity blockEntity) { + tiles.put( + BlockVector3.at( + blockEntity.getBlockPos().getX(), + blockEntity.getBlockPos().getY(), + blockEntity.getBlockPos().getZ() + ), + new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.saveWithId(DedicatedServer.getServer().registryAccess()))) + ); + } + + @Override + public Map getTiles() { + return tiles; + } + + @Override + @Nullable + public CompoundTag getTile(int x, int y, int z) { + return tiles.get(BlockVector3.at(x, y, z)); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + protected void storeEntity(Entity entity) { + BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); + net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag(); + entity.save(compoundTag); + entities.add((CompoundTag) adapter.toNative(compoundTag)); + } + + @Override + public Set getEntities() { + return this.entities; + } + + @Override + public CompoundTag getEntity(UUID uuid) { + for (CompoundTag tag : entities) { + if (uuid.equals(tag.getUUID())) { + return tag; + } + } + return null; + } + + @Override + public boolean isCreateCopy() { + return false; + } + + @Override + public int setCreateCopy(boolean createCopy) { + return -1; + } + + @Override + public void setLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) { + } + + @Override + public void setSkyLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) { + } + + @Override + public void setHeightmapToGet(HeightMapType type, int[] data) { + } + + @Override + public int getMaxY() { + return maxHeight; + } + + @Override + public int getMinY() { + return minHeight; + } + + @Override + public int getMaxSectionPosition() { + return maxHeight >> 4; + } + + @Override + public int getMinSectionPosition() { + return minHeight >> 4; + } + + @Override + public BiomeType getBiomeType(int x, int y, int z) { + Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; + return PaperweightPlatformAdapter.adapt(biome, serverLevel); + } + + @Override + public void removeSectionLighting(int layer, boolean sky) { + } + + @Override + public boolean trim(boolean aggressive, int layer) { + return false; + } + + @Override + public IBlocks reset() { + return null; + } + + @Override + public int getSectionCount() { + return serverLevel.getSectionsCount(); + } + + protected void storeSection(int layer, char[] data) { + blocks[layer] = data; + } + + protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { + if (biomes == null) { + biomes = new Holder[getSectionCount()][]; + } + if (biomes[layer] == null) { + biomes[layer] = new Holder[64]; + } + if (biomeData instanceof PalettedContainer> palettedContainer) { + for (int i = 0; i < 64; i++) { + biomes[layer][i] = palettedContainer.get(i); + } + } else { + LOGGER.error( + "Cannot correctly save biomes to history. Expected class type {} but got {}", + PalettedContainer.class.getSimpleName(), + biomeData.getClass().getSimpleName() + ); + } + } + + @Override + public BaseBlock getFullBlock(int x, int y, int z) { + BlockState state = BlockTypesCache.states[get(x, y, z)]; + return state.toBaseBlock(this, x, y, z); + } + + @Override + public boolean hasSection(int layer) { + layer -= getMinSectionPosition(); + return blocks[layer] != null; + } + + @Override + public char[] load(int layer) { + layer -= getMinSectionPosition(); + if (blocks[layer] == null) { + blocks[layer] = new char[4096]; + Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); + } + return blocks[layer]; + } + + @Override + public char[] loadIfPresent(int layer) { + layer -= getMinSectionPosition(); + return blocks[layer]; + } + + @Override + public BlockState getBlock(int x, int y, int z) { + return BlockTypesCache.states[get(x, y, z)]; + } + + @Override + public int getSkyLight(int x, int y, int z) { + return 0; + } + + @Override + public int getEmittedLight(int x, int y, int z) { + return 0; + } + + @Override + public int[] getHeightMap(HeightMapType type) { + return new int[0]; + } + + @Override + public > T call(IChunkSet set, Runnable finalize) { + return null; + } + + public char get(int x, int y, int z) { + final int layer = (y >> 4) - getMinSectionPosition(); + final int index = (y & 15) << 8 | z << 4 | x; + return blocks[layer][index]; + } + + + @Override + public boolean trim(boolean aggressive) { + return false; + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightMapChunkUtil.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightMapChunkUtil.java new file mode 100644 index 000000000..6819e5466 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightMapChunkUtil.java @@ -0,0 +1,34 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1; + +import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil; +import com.sk89q.worldedit.bukkit.adapter.Refraction; +import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData; +import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; + +//TODO un-very-break-this +public class PaperweightMapChunkUtil extends MapChunkUtil { + + public PaperweightMapChunkUtil() throws NoSuchFieldException { + fieldX = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("TWO_MEGABYTES", "a")); + fieldZ = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("x", "b")); + fieldBitMask = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("z", "c")); + fieldHeightMap = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("heightmaps", "b")); + fieldChunkData = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("chunkData", "d")); + fieldBlockEntities = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("buffer", "c")); + fieldFull = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("blockEntitiesData", "d")); + fieldX.setAccessible(true); + fieldZ.setAccessible(true); + fieldBitMask.setAccessible(true); + fieldHeightMap.setAccessible(true); + fieldChunkData.setAccessible(true); + fieldBlockEntities.setAccessible(true); + fieldFull.setAccessible(true); + } + + @Override + public ClientboundLevelChunkWithLightPacket createPacket() { + // TODO ??? return new ClientboundLevelChunkPacket(); + throw new UnsupportedOperationException(); + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java new file mode 100644 index 000000000..33c7a8597 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java @@ -0,0 +1,727 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1; + +import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager; +import com.destroystokyo.paper.util.maplist.EntityList; +import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter; +import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; +import com.fastasyncworldedit.bukkit.adapter.NMSAdapter; +import com.fastasyncworldedit.core.Fawe; +import com.fastasyncworldedit.core.FaweCache; +import com.fastasyncworldedit.core.math.BitArrayUnstretched; +import com.fastasyncworldedit.core.util.MathMan; +import com.fastasyncworldedit.core.util.ReflectionUtils; +import com.fastasyncworldedit.core.util.TaskManager; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; +import com.sk89q.worldedit.bukkit.adapter.Refraction; +import com.sk89q.worldedit.internal.util.LogManagerCompat; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.biome.BiomeTypes; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockTypesCache; +import io.papermc.lib.PaperLib; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.IdMap; +import net.minecraft.core.Registry; +import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ChunkMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.BitStorage; +import net.minecraft.util.ExceptionCollector; +import net.minecraft.util.SimpleBitStorage; +import net.minecraft.util.ThreadingDetector; +import net.minecraft.util.Unit; +import net.minecraft.util.ZeroBitStorage; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.GlobalPalette; +import net.minecraft.world.level.chunk.HashMapPalette; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.LinearPalette; +import net.minecraft.world.level.chunk.Palette; +import net.minecraft.world.level.chunk.PalettedContainer; +import net.minecraft.world.level.chunk.SingleValuePalette; +import net.minecraft.world.level.chunk.status.ChunkStatus; +import net.minecraft.world.level.entity.PersistentEntitySectionManager; +import org.apache.logging.log4j.Logger; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.CraftChunk; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.Function; + +import static java.lang.invoke.MethodType.methodType; +import static net.minecraft.core.registries.Registries.BIOME; + +public final class PaperweightPlatformAdapter extends NMSAdapter { + + public static final Field fieldData; + + public static final Constructor dataConstructor; + + public static final Field fieldStorage; + public static final Field fieldPalette; + + private static final Field fieldTickingFluidCount; + private static final Field fieldTickingBlockCount; + private static final Field fieldBiomes; + + private static final MethodHandle methodGetVisibleChunk; + + private static final Field fieldThreadingDetector; + private static final Field fieldLock; + + private static final MethodHandle methodRemoveGameEventListener; + private static final MethodHandle methodremoveTickingBlockEntity; + + /* + * This is a workaround for the changes from https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/1fddefce1cdce44010927b888432bf70c0e88cde#src/main/java/org/bukkit/craftbukkit/CraftChunk.java + * and is only needed to support 1.19.4 versions before *and* after this change. + */ + private static final MethodHandle CRAFT_CHUNK_GET_HANDLE; + + private static final Field fieldRemove; + + private static final Logger LOGGER = LogManagerCompat.getLogger(); + + static final boolean POST_CHUNK_REWRITE; + private static Method PAPER_CHUNK_GEN_ALL_ENTITIES; + private static Field LEVEL_CHUNK_ENTITIES; + private static Field SERVER_LEVEL_ENTITY_MANAGER; + + static { + final MethodHandles.Lookup lookup = MethodHandles.lookup(); + try { + fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d")); + fieldData.setAccessible(true); + + Class dataClazz = fieldData.getType(); + dataConstructor = dataClazz.getDeclaredConstructors()[0]; + dataConstructor.setAccessible(true); + + fieldStorage = dataClazz.getDeclaredField(Refraction.pickName("storage", "b")); + fieldStorage.setAccessible(true); + fieldPalette = dataClazz.getDeclaredField(Refraction.pickName("palette", "c")); + fieldPalette.setAccessible(true); + + fieldTickingFluidCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "g")); + fieldTickingFluidCount.setAccessible(true); + fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); + fieldTickingBlockCount.setAccessible(true); + fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i")); + fieldBiomes.setAccessible(true); + + Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( + "getVisibleChunkIfPresent", + "b" + ), long.class); + getVisibleChunkIfPresent.setAccessible(true); + methodGetVisibleChunk = lookup.unreflect(getVisibleChunkIfPresent); + + if (!PaperLib.isPaper()) { + fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f")); + fieldThreadingDetector.setAccessible(true); + fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c")); + fieldLock.setAccessible(true); + } else { + // in paper, the used methods are synchronized properly + fieldThreadingDetector = null; + fieldLock = null; + } + + Method removeGameEventListener = LevelChunk.class.getDeclaredMethod( + Refraction.pickName("removeGameEventListener", "a"), + BlockEntity.class, + ServerLevel.class + ); + removeGameEventListener.setAccessible(true); + methodRemoveGameEventListener = lookup.unreflect(removeGameEventListener); + + Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod( + Refraction.pickName( + "removeBlockEntityTicker", + "k" + ), BlockPos.class + ); + removeBlockEntityTicker.setAccessible(true); + methodremoveTickingBlockEntity = lookup.unreflect(removeBlockEntityTicker); + + fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p")); + fieldRemove.setAccessible(true); + + boolean chunkRewrite; + try { + Level.class.getDeclaredMethod("moonrise$getEntityLookup"); + chunkRewrite = true; + PAPER_CHUNK_GEN_ALL_ENTITIES = ChunkEntitySlices.class.getDeclaredMethod("getAllEntities"); + PAPER_CHUNK_GEN_ALL_ENTITIES.setAccessible(true); + } catch (NoSuchMethodException ignored) { + chunkRewrite = false; + } + try { + // Paper - Pre-Chunk-Update + LEVEL_CHUNK_ENTITIES = LevelChunk.class.getDeclaredField("entities"); + LEVEL_CHUNK_ENTITIES.setAccessible(true); + } catch (NoSuchFieldException ignored) { + } + try { + // Non-Paper + SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField(Refraction.pickName("entityManager", "N")); + SERVER_LEVEL_ENTITY_MANAGER.setAccessible(true); + } catch (NoSuchFieldException ignored) { + } + POST_CHUNK_REWRITE = chunkRewrite; + } catch (RuntimeException | Error e) { + throw e; + } catch (Exception e) { + throw new RuntimeException(e); + } + MethodHandle craftChunkGetHandle; + final MethodType type = methodType(LevelChunk.class); + try { + craftChunkGetHandle = lookup.findVirtual(CraftChunk.class, "getHandle", type); + } catch (NoSuchMethodException | IllegalAccessException e) { + try { + final MethodType newType = methodType(ChunkAccess.class, ChunkStatus.class); + craftChunkGetHandle = lookup.findVirtual(CraftChunk.class, "getHandle", newType); + craftChunkGetHandle = MethodHandles.insertArguments(craftChunkGetHandle, 1, ChunkStatus.FULL); + } catch (NoSuchMethodException | IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + CRAFT_CHUNK_GET_HANDLE = craftChunkGetHandle; + } + + static boolean setSectionAtomic( + LevelChunkSection[] sections, + LevelChunkSection expected, + LevelChunkSection value, + int layer + ) { + if (layer >= 0 && layer < sections.length) { + return ReflectionUtils.compareAndSet(sections, expected, value, layer); + } + return false; + } + + // There is no point in having a functional semaphore for paper servers. + private static final ThreadLocal SEMAPHORE_THREAD_LOCAL = + ThreadLocal.withInitial(() -> new DelegateSemaphore(1, null)); + + static DelegateSemaphore applyLock(LevelChunkSection section) { + if (PaperLib.isPaper()) { + return SEMAPHORE_THREAD_LOCAL.get(); + } + try { + synchronized (section) { + PalettedContainer blocks = section.getStates(); + ThreadingDetector currentThreadingDetector = (ThreadingDetector) fieldThreadingDetector.get(blocks); + synchronized (currentThreadingDetector) { + Semaphore currentLock = (Semaphore) fieldLock.get(currentThreadingDetector); + if (currentLock instanceof DelegateSemaphore delegateSemaphore) { + return delegateSemaphore; + } + DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); + fieldLock.set(currentThreadingDetector, newLock); + return newLock; + } + } + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + public static LevelChunk ensureLoaded(ServerLevel serverLevel, int chunkX, int chunkZ) { + if (!PaperLib.isPaper()) { + LevelChunk nmsChunk = serverLevel.getChunkSource().getChunk(chunkX, chunkZ, false); + if (nmsChunk != null) { + return nmsChunk; + } + if (Fawe.isMainThread()) { + return serverLevel.getChunk(chunkX, chunkZ); + } + } else { + LevelChunk nmsChunk = serverLevel.getChunkSource().getChunkAtIfCachedImmediately(chunkX, chunkZ); + if (nmsChunk != null) { + addTicket(serverLevel, chunkX, chunkZ); + return nmsChunk; + } + nmsChunk = serverLevel.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ); + if (nmsChunk != null) { + addTicket(serverLevel, chunkX, chunkZ); + return nmsChunk; + } + // Avoid "async" methods from the main thread. + if (Fawe.isMainThread()) { + return serverLevel.getChunk(chunkX, chunkZ); + } + CompletableFuture future = serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true); + try { + CraftChunk chunk; + try { + chunk = (CraftChunk) future.get(10, TimeUnit.SECONDS); + } catch (TimeoutException e) { + String world = serverLevel.getWorld().getName(); + // We've already taken 10 seconds we can afford to wait a little here. + boolean loaded = TaskManager.taskManager().sync(() -> Bukkit.getWorld(world) != null); + if (loaded) { + LOGGER.warn("Chunk {},{} failed to load in 10 seconds in world {}. Retrying...", chunkX, chunkZ, world); + // Retry chunk load + chunk = (CraftChunk) serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true).get(); + } else { + throw new UnsupportedOperationException("Cannot load chunk from unloaded world " + world + "!"); + } + } + addTicket(serverLevel, chunkX, chunkZ); + return (LevelChunk) CRAFT_CHUNK_GET_HANDLE.invoke(chunk); + } catch (Throwable e) { + e.printStackTrace(); + } + } + return TaskManager.taskManager().sync(() -> serverLevel.getChunk(chunkX, chunkZ)); + } + + private static void addTicket(ServerLevel serverLevel, int chunkX, int chunkZ) { + // Ensure chunk is definitely loaded before applying a ticket + io.papermc.paper.util.MCUtil.MAIN_EXECUTOR.execute(() -> serverLevel + .getChunkSource() + .addRegionTicket(ChunkHolderManager.UNLOAD_COOLDOWN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE)); + } + + public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) { + ChunkMap chunkMap = nmsWorld.getChunkSource().chunkMap; + try { + return (ChunkHolder) methodGetVisibleChunk.invoke(chunkMap, ChunkPos.asLong(chunkX, chunkZ)); + } catch (Throwable thr) { + throw new RuntimeException(thr); + } + } + + @SuppressWarnings("deprecation") + public static void sendChunk(Object chunk, ServerLevel nmsWorld, int chunkX, int chunkZ) { + ChunkHolder chunkHolder = getPlayerChunk(nmsWorld, chunkX, chunkZ); + if (chunkHolder == null) { + return; + } + ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ); + LevelChunk levelChunk; + if (PaperLib.isPaper()) { + // getChunkAtIfLoadedImmediately is paper only + levelChunk = nmsWorld + .getChunkSource() + .getChunkAtIfLoadedImmediately(chunkX, chunkZ); + } else { + levelChunk = chunkHolder.getTickingChunkFuture() + .getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK).orElse(null); + } + if (levelChunk == null) { + return; + } + MinecraftServer.getServer().execute(() -> { + ClientboundLevelChunkWithLightPacket packet; + if (PaperLib.isPaper()) { + synchronized (chunk) { + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null, + false // last false is to not bother with x-ray + ); + } + } else { + synchronized (chunk) { + // deprecated on paper - deprecation suppressed + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null + ); + } + } + nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); + }); + } + + private static List nearbyPlayers(ServerLevel serverLevel, ChunkPos coordIntPair) { + return serverLevel.getChunkSource().chunkMap.getPlayers(coordIntPair, false); + } + + /* + NMS conversion + */ + public static LevelChunkSection newChunkSection( + final int layer, + final char[] blocks, + CachedBukkitAdapter adapter, + Registry biomeRegistry, + @Nullable PalettedContainer> biomes + ) { + return newChunkSection(layer, null, blocks, adapter, biomeRegistry, biomes); + } + + public static LevelChunkSection newChunkSection( + final int layer, + final Function get, + char[] set, + CachedBukkitAdapter adapter, + Registry biomeRegistry, + @Nullable PalettedContainer> biomes + ) { + if (set == null) { + return newChunkSection(biomeRegistry, biomes); + } + final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); + final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); + final long[] blockStates = FaweCache.INSTANCE.BLOCK_STATES.get(); + final int[] blocksCopy = FaweCache.INSTANCE.SECTION_BLOCKS.get(); + try { + int num_palette; + if (get == null) { + num_palette = createPalette(blockToPalette, paletteToBlock, blocksCopy, set, adapter, null); + } else { + num_palette = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, get, set, adapter, null); + } + + int bitsPerEntry = MathMan.log2nlz(num_palette - 1); + if (bitsPerEntry > 0 && bitsPerEntry < 5) { + bitsPerEntry = 4; + } else if (bitsPerEntry > 8) { + bitsPerEntry = MathMan.log2nlz(Block.BLOCK_STATE_REGISTRY.size() - 1); + } + + int bitsPerEntryNonZero = Math.max(bitsPerEntry, 1); // We do want to use zero sometimes + final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntryNonZero); + final int blockBitArrayEnd = MathMan.ceilZero((float) 4096 / blocksPerLong); + + if (num_palette == 1) { + for (int i = 0; i < blockBitArrayEnd; i++) { + blockStates[i] = 0; + } + } else { + final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntryNonZero, 4096, blockStates); + bitArray.fromRaw(blocksCopy); + } + + final long[] bits = Arrays.copyOfRange(blockStates, 0, blockBitArrayEnd); + final BitStorage nmsBits; + if (bitsPerEntry == 0) { + nmsBits = new ZeroBitStorage(4096); + } else { + nmsBits = new SimpleBitStorage(bitsPerEntry, 4096, bits); + } + List palette; + if (bitsPerEntry < 9) { + palette = new ArrayList<>(); + for (int i = 0; i < num_palette; i++) { + int ordinal = paletteToBlock[i]; + blockToPalette[ordinal] = Integer.MAX_VALUE; + final BlockState state = BlockTypesCache.states[ordinal]; + palette.add(((PaperweightBlockMaterial) state.getMaterial()).getState()); + } + } else { + palette = List.of(); + } + + // Create palette with data + @SuppressWarnings("deprecation") // constructor is deprecated on paper, but needed to keep compatibility with spigot + final PalettedContainer blockStatePalettedContainer = + new PalettedContainer<>( + Block.BLOCK_STATE_REGISTRY, + PalettedContainer.Strategy.SECTION_STATES, + PalettedContainer.Strategy.SECTION_STATES.getConfiguration(Block.BLOCK_STATE_REGISTRY, bitsPerEntry), + nmsBits, + palette + ); + if (biomes == null) { + IdMap> biomeHolderIdMap = biomeRegistry.asHolderIdMap(); + biomes = new PalettedContainer<>( + biomeHolderIdMap, + biomeHolderIdMap.byIdOrThrow(WorldEditPlugin + .getInstance() + .getBukkitImplAdapter() + .getInternalBiomeId( + BiomeTypes.PLAINS)), + PalettedContainer.Strategy.SECTION_BIOMES + ); + } + + return new LevelChunkSection(blockStatePalettedContainer, biomes); + } catch (final Throwable e) { + throw e; + } finally { + Arrays.fill(blockToPalette, Integer.MAX_VALUE); + Arrays.fill(paletteToBlock, Integer.MAX_VALUE); + Arrays.fill(blockStates, 0); + Arrays.fill(blocksCopy, 0); + } + } + + @SuppressWarnings("deprecation") // Only deprecated in paper + private static LevelChunkSection newChunkSection( + Registry biomeRegistry, + @Nullable PalettedContainer> biomes + ) { + if (biomes == null) { + return new LevelChunkSection(biomeRegistry); + } + PalettedContainer dataPaletteBlocks = new PalettedContainer<>( + Block.BLOCK_STATE_REGISTRY, + Blocks.AIR.defaultBlockState(), + PalettedContainer.Strategy.SECTION_STATES + ); + return new LevelChunkSection(dataPaletteBlocks, biomes); + } + + public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { + try { + fieldBiomes.set(section, biomes); + } catch (IllegalAccessException e) { + LOGGER.error("Could not set biomes to chunk section", e); + } + } + + /** + * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. + */ + public static PalettedContainer> getBiomePalettedContainer( + BiomeType[] biomes, + IdMap> biomeRegistry + ) { + if (biomes == null) { + return null; + } + BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); + // Don't stream this as typically will see 1-4 biomes; stream overhead is large for the small length + Map> palette = new HashMap<>(); + for (BiomeType biomeType : new LinkedList<>(Arrays.asList(biomes))) { + Holder biome; + if (biomeType == null) { + biome = biomeRegistry.byId(adapter.getInternalBiomeId(BiomeTypes.PLAINS)); + } else { + biome = biomeRegistry.byId(adapter.getInternalBiomeId(biomeType)); + } + palette.put(biomeType, biome); + } + int biomeCount = palette.size(); + int bitsPerEntry = MathMan.log2nlz(biomeCount - 1); + Object configuration = PalettedContainer.Strategy.SECTION_STATES.getConfiguration( + new FakeIdMapBiome(biomeCount), + bitsPerEntry + ); + if (bitsPerEntry > 3) { + bitsPerEntry = MathMan.log2nlz(biomeRegistry.size() - 1); + } + PalettedContainer> biomePalettedContainer = new PalettedContainer<>( + biomeRegistry, + biomeRegistry.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), + PalettedContainer.Strategy.SECTION_BIOMES + ); + + final Palette> biomePalette; + if (bitsPerEntry == 0) { + biomePalette = new SingleValuePalette<>( + biomePalettedContainer.registry, + biomePalettedContainer, + new ArrayList<>(palette.values()) // Must be modifiable + ); + } else if (bitsPerEntry == 4) { + biomePalette = LinearPalette.create( + 4, + biomePalettedContainer.registry, + biomePalettedContainer, + new ArrayList<>(palette.values()) // Must be modifiable + ); + } else if (bitsPerEntry < 9) { + biomePalette = HashMapPalette.create( + bitsPerEntry, + biomePalettedContainer.registry, + biomePalettedContainer, + new ArrayList<>(palette.values()) // Must be modifiable + ); + } else { + biomePalette = GlobalPalette.create( + bitsPerEntry, + biomePalettedContainer.registry, + biomePalettedContainer, + null // unused + ); + } + + int bitsPerEntryNonZero = Math.max(bitsPerEntry, 1); // We do want to use zero sometimes + final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntryNonZero); + final int arrayLength = MathMan.ceilZero(64f / blocksPerLong); + + + BitStorage bitStorage = bitsPerEntry == 0 ? new ZeroBitStorage(64) : new SimpleBitStorage( + bitsPerEntry, + 64, + new long[arrayLength] + ); + + try { + Object data = dataConstructor.newInstance(configuration, bitStorage, biomePalette); + fieldData.set(biomePalettedContainer, data); + int index = 0; + for (int y = 0; y < 4; y++) { + for (int z = 0; z < 4; z++) { + for (int x = 0; x < 4; x++, index++) { + BiomeType biomeType = biomes[index]; + if (biomeType == null) { + continue; + } + Holder biome = biomeRegistry.byId(WorldEditPlugin + .getInstance() + .getBukkitImplAdapter() + .getInternalBiomeId(biomeType)); + if (biome == null) { + continue; + } + biomePalettedContainer.set(x, y, z, biome); + } + } + } + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + return biomePalettedContainer; + } + + public static void clearCounts(final LevelChunkSection section) throws IllegalAccessException { + fieldTickingFluidCount.setShort(section, (short) 0); + fieldTickingBlockCount.setShort(section, (short) 0); + } + + public static BiomeType adapt(Holder biome, LevelAccessor levelAccessor) { + final Registry biomeRegistry = levelAccessor.registryAccess().registryOrThrow(BIOME); + if (biomeRegistry.getKey(biome.value()) == null) { + return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN + : null; + } + return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString()); + } + + static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { + try { + if (levelChunk.loaded || levelChunk.level.isClientSide()) { + BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos()); + if (blockEntity != null) { + if (!levelChunk.level.isClientSide) { + methodRemoveGameEventListener.invoke(levelChunk, beacon, levelChunk.level); + } + fieldRemove.set(beacon, true); + } + } + methodremoveTickingBlockEntity.invoke(levelChunk, beacon.getBlockPos()); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + } + + static List getEntities(LevelChunk chunk) { + ExceptionCollector collector = new ExceptionCollector<>(); + if (PaperLib.isPaper()) { + if (POST_CHUNK_REWRITE) { + try { + //noinspection unchecked + return (List) PAPER_CHUNK_GEN_ALL_ENTITIES.invoke(chunk.level.moonrise$getEntityLookup().getChunk(chunk.locX, chunk.locZ)); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=true]", e); + } + } + try { + EntityList entityList = (EntityList) LEVEL_CHUNK_ENTITIES.get(chunk); + return List.of(entityList.getRawData()); + } catch (IllegalAccessException e) { + collector.add(new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=false]", e)); + // fall through + } + } + try { + //noinspection unchecked + return ((PersistentEntitySectionManager) (SERVER_LEVEL_ENTITY_MANAGER.get(chunk.level))).getEntities(chunk.getPos()); + } catch (IllegalAccessException e) { + collector.add(new RuntimeException("Failed to lookup entities [PAPER=false]", e)); + } + collector.throwIfPresent(); + return List.of(); + } + + record FakeIdMapBlock(int size) implements IdMap { + + @Override + public int getId(final net.minecraft.world.level.block.state.BlockState entry) { + return 0; + } + + @Nullable + @Override + public net.minecraft.world.level.block.state.BlockState byId(final int index) { + return null; + } + + @Nonnull + @Override + public Iterator iterator() { + return Collections.emptyIterator(); + } + + } + + record FakeIdMapBiome(int size) implements IdMap { + + @Override + public int getId(final Biome entry) { + return 0; + } + + @Nullable + @Override + public Biome byId(final int index) { + return null; + } + + @Nonnull + @Override + public Iterator iterator() { + return Collections.emptyIterator(); + } + + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPostProcessor.java new file mode 100644 index 000000000..3b4c47087 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPostProcessor.java @@ -0,0 +1,175 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1; + +import com.fastasyncworldedit.core.configuration.Settings; +import com.fastasyncworldedit.core.extent.processor.ProcessorScope; +import com.fastasyncworldedit.core.queue.IBatchProcessor; +import com.fastasyncworldedit.core.queue.IChunk; +import com.fastasyncworldedit.core.queue.IChunkGet; +import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.registry.state.PropertyKey; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockTypes; +import com.sk89q.worldedit.world.block.BlockTypesCache; +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.Fluids; + +import javax.annotation.Nullable; + +public class PaperweightPostProcessor implements IBatchProcessor { + + @Override + public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { + return set; + } + + @SuppressWarnings("deprecation") + @Override + public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final IChunkSet iChunkSet) { + boolean tickFluid = Settings.settings().EXPERIMENTAL.ALLOW_TICK_FLUIDS; + // The PostProcessor shouldn't be added, but just in case + if (!tickFluid) { + return; + } + PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; + layer: + for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { + char[] set = iChunkSet.loadIfPresent(layer); + if (set == null) { + // No edit means no need to process + continue; + } + char[] get = null; + for (int i = 0; i < 4096; i++) { + char ordinal = set[i]; + char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; + boolean fromGet = false; // Used for liquids + if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { + if (get == null) { + get = getBlocks.load(layer); + } + // If this is null, then it's because we're loading a layer in the range of 0->15, but blocks aren't + // actually being set + if (get == null) { + continue layer; + } + fromGet = true; + ordinal = replacedOrdinal = get[i]; + } + if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { + continue; + } else if (!fromGet) { // if fromGet, don't do the same again + if (get == null) { + get = getBlocks.load(layer); + } + replacedOrdinal = get[i]; + } + boolean ticking = BlockTypesCache.ticking[ordinal]; + boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; + boolean replacedWasLiquid = false; + BlockState replacedState = null; + if (!ticking) { + // If the block being replaced was not ticking, it cannot be a liquid + if (!replacedWasTicking) { + continue; + } + // If the block being replaced is not fluid, we do not need to worry + if (!(replacedWasLiquid = + (replacedState = BlockState.getFromOrdinal(replacedOrdinal)).getMaterial().isLiquid())) { + continue; + } + } + BlockState state = BlockState.getFromOrdinal(ordinal); + boolean liquid = state.getMaterial().isLiquid(); + int x = i & 15; + int y = (i >> 8) & 15; + int z = (i >> 4) & 15; + BlockPos position = new BlockPos((chunk.getX() << 4) + x, (layer << 4) + y, (chunk.getZ() << 4) + z); + if (liquid || replacedWasLiquid) { + if (liquid) { + addFluid(getBlocks.serverLevel, state, position); + continue; + } + // If the replaced fluid (is?) adjacent to water. Do not bother to check adjacent chunks(sections) as this + // may be time consuming. Chances are any fluid blocks in adjacent chunks are being replaced or will end up + // being ticked anyway. We only need it to be "hit" once. + if (!wasAdjacentToWater(get, set, i, x, y, z)) { + continue; + } + addFluid(getBlocks.serverLevel, replacedState, position); + } + } + } + } + + @Nullable + @Override + public Extent construct(final Extent child) { + throw new UnsupportedOperationException("Processing only"); + } + + @Override + public ProcessorScope getScope() { + return ProcessorScope.READING_SET_BLOCKS; + } + + private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { + if (set == null || get == null) { + return false; + } + char ordinal; + char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; + if (x > 0 && set[i - 1] != reserved) { + if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { + return true; + } + } + if (x < 15 && set[i + 1] != reserved) { + if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { + return true; + } + } + if (z > 0 && set[i - 16] != reserved) { + if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { + return true; + } + } + if (z < 15 && set[i + 16] != reserved) { + if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { + return true; + } + } + if (y > 0 && set[i - 256] != reserved) { + if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { + return true; + } + } + if (y < 15 && set[i + 256] != reserved) { + return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); + } + return false; + } + + @SuppressWarnings("deprecation") + private boolean isFluid(char ordinal) { + return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); + } + + @SuppressWarnings("deprecation") + private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { + Fluid type; + if (replacedState.getBlockType() == BlockTypes.LAVA) { + type = (int) replacedState.getState(PropertyKey.LEVEL) == 0 ? Fluids.LAVA : Fluids.FLOWING_LAVA; + } else { + type = (int) replacedState.getState(PropertyKey.LEVEL) == 0 ? Fluids.WATER : Fluids.FLOWING_WATER; + } + serverLevel.scheduleTick( + position, + type, + type.getTickDelay(serverLevel) + ); + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightStarlightRelighter.java new file mode 100644 index 000000000..f9d06922e --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightStarlightRelighter.java @@ -0,0 +1,79 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1; + +import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter; +import com.fastasyncworldedit.core.configuration.Settings; +import com.fastasyncworldedit.core.queue.IQueueExtent; +import net.minecraft.server.level.ChunkMap; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.TicketType; +import net.minecraft.util.Unit; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.chunk.status.ChunkPyramid; +import net.minecraft.world.level.chunk.status.ChunkStatus; + +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; +import java.util.function.IntConsumer; + +public class PaperweightStarlightRelighter extends StarlightRelighter { + + private static final TicketType FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0); + private static final int LIGHT_LEVEL = ChunkMap.MAX_VIEW_DISTANCE + ChunkPyramid.LOADING_PYRAMID + .getStepTo(ChunkStatus.FULL) + .getAccumulatedRadiusOf(ChunkStatus.LIGHT); + + public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent queue) { + super(serverLevel, queue); + } + + @Override + protected ChunkPos createChunkPos(final long chunkKey) { + return new ChunkPos(chunkKey); + } + + @Override + protected long asLong(final int chunkX, final int chunkZ) { + return ChunkPos.asLong(chunkX, chunkZ); + } + + @Override + protected CompletableFuture chunkLoadFuture(final ChunkPos chunkPos) { + return serverLevel.getWorld().getChunkAtAsync(chunkPos.x, chunkPos.z) + .thenAccept(c -> serverLevel.getChunkSource().addTicketAtLevel( + FAWE_TICKET, + chunkPos, + LIGHT_LEVEL, + Unit.INSTANCE + )); + } + + protected void invokeRelight( + Set coords, + Consumer chunkCallback, + IntConsumer processCallback + ) { + try { + serverLevel.getChunkSource().getLightEngine().starlight$serverRelightChunks(coords, chunkCallback, processCallback); + } catch (Exception e) { + LOGGER.error("Error occurred on relighting", e); + } + } + + /* + * Allow the server to unload the chunks again. + * Also, if chunk packets are sent delayed, we need to do that here + */ + protected void postProcessChunks(Set coords) { + boolean delay = Settings.settings().LIGHTING.DELAY_PACKET_SENDING; + for (ChunkPos pos : coords) { + int x = pos.x; + int z = pos.z; + if (delay) { // we still need to send the block changes of that chunk + PaperweightPlatformAdapter.sendChunk(pos, serverLevel, x, z); + } + serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE); + } + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightStarlightRelighterFactory.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightStarlightRelighterFactory.java new file mode 100644 index 000000000..beaffc9a6 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightStarlightRelighterFactory.java @@ -0,0 +1,25 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1; + +import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter; +import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode; +import com.fastasyncworldedit.core.extent.processor.lighting.Relighter; +import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; +import com.fastasyncworldedit.core.queue.IQueueExtent; +import com.sk89q.worldedit.world.World; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.CraftWorld; + +import javax.annotation.Nonnull; + +public class PaperweightStarlightRelighterFactory implements RelighterFactory { + + @Override + public @Nonnull Relighter createRelighter(RelightMode relightMode, World world, IQueueExtent queue) { + org.bukkit.World w = Bukkit.getWorld(world.getName()); + if (w == null) { + return NullRelighter.INSTANCE; + } + return new PaperweightStarlightRelighter(((CraftWorld) w).getHandle(), queue); + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/nbt/PaperweightLazyCompoundTag.java new file mode 100644 index 000000000..e2ed21584 --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/nbt/PaperweightLazyCompoundTag.java @@ -0,0 +1,161 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1.nbt; + +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.LazyCompoundTag; +import com.sk89q.jnbt.ListTag; +import com.sk89q.jnbt.StringTag; +import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import net.minecraft.nbt.NumericTag; +import org.enginehub.linbus.tree.LinCompoundTag; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; + +public class PaperweightLazyCompoundTag extends LazyCompoundTag { + + private final Supplier compoundTagSupplier; + private CompoundTag compoundTag; + + public PaperweightLazyCompoundTag(Supplier compoundTagSupplier) { + super(new HashMap<>()); + this.compoundTagSupplier = compoundTagSupplier; + } + + public PaperweightLazyCompoundTag(net.minecraft.nbt.CompoundTag compoundTag) { + this(() -> compoundTag); + } + + public net.minecraft.nbt.CompoundTag get() { + return compoundTagSupplier.get(); + } + + @Override + @SuppressWarnings("unchecked") + public Map> getValue() { + if (compoundTag == null) { + compoundTag = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(compoundTagSupplier.get()); + } + return compoundTag.getValue(); + } + + @Override + public LinCompoundTag toLinTag() { + getValue(); + return compoundTag.toLinTag(); + } + + public boolean containsKey(String key) { + return compoundTagSupplier.get().contains(key); + } + + public byte[] getByteArray(String key) { + return compoundTagSupplier.get().getByteArray(key); + } + + public byte getByte(String key) { + return compoundTagSupplier.get().getByte(key); + } + + public double getDouble(String key) { + return compoundTagSupplier.get().getDouble(key); + } + + public double asDouble(String key) { + net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); + if (tag instanceof NumericTag numTag) { + return numTag.getAsDouble(); + } + return 0; + } + + public float getFloat(String key) { + return compoundTagSupplier.get().getFloat(key); + } + + public int[] getIntArray(String key) { + return compoundTagSupplier.get().getIntArray(key); + } + + public int getInt(String key) { + return compoundTagSupplier.get().getInt(key); + } + + public int asInt(String key) { + net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); + if (tag instanceof NumericTag numTag) { + return numTag.getAsInt(); + } + return 0; + } + + @SuppressWarnings("unchecked") + public List> getList(String key) { + net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); + if (tag instanceof net.minecraft.nbt.ListTag nbtList) { + ArrayList> list = new ArrayList<>(); + for (net.minecraft.nbt.Tag elem : nbtList) { + if (elem instanceof net.minecraft.nbt.CompoundTag compoundTag) { + list.add(new PaperweightLazyCompoundTag(compoundTag)); + } else { + list.add(WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(elem)); + } + } + return list; + } + return Collections.emptyList(); + } + + @SuppressWarnings("unchecked") + public ListTag getListTag(String key) { + net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); + if (tag instanceof net.minecraft.nbt.ListTag) { + return (ListTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(tag); + } + return new ListTag(StringTag.class, Collections.emptyList()); + } + + @SuppressWarnings("unchecked") + public > List getList(String key, Class listType) { + ListTag listTag = getListTag(key); + if (listTag.getType().equals(listType)) { + return (List) listTag.getValue(); + } else { + return Collections.emptyList(); + } + } + + public long[] getLongArray(String key) { + return compoundTagSupplier.get().getLongArray(key); + } + + public long getLong(String key) { + return compoundTagSupplier.get().getLong(key); + } + + public long asLong(String key) { + net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); + if (tag instanceof NumericTag numTag) { + return numTag.getAsLong(); + } + return 0; + } + + public short getShort(String key) { + return compoundTagSupplier.get().getShort(key); + } + + public String getString(String key) { + return compoundTagSupplier.get().getString(key); + } + + @Override + public String toString() { + return compoundTagSupplier.get().toString(); + } + +} diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/regen/PaperweightRegen.java new file mode 100644 index 000000000..07933adfa --- /dev/null +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/regen/PaperweightRegen.java @@ -0,0 +1,623 @@ +package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1.regen; + +import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkHolderManager; +import com.fastasyncworldedit.bukkit.adapter.Regenerator; +import com.fastasyncworldedit.core.Fawe; +import com.fastasyncworldedit.core.queue.IChunkCache; +import com.fastasyncworldedit.core.queue.IChunkGet; +import com.fastasyncworldedit.core.util.TaskManager; +import com.google.common.collect.ImmutableList; +import com.mojang.serialization.Lifecycle; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; +import com.sk89q.worldedit.bukkit.adapter.Refraction; +import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1.PaperweightGetBlocks; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.internal.util.LogManagerCompat; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.io.file.SafeFiles; +import com.sk89q.worldedit.world.RegenOptions; +import io.papermc.lib.PaperLib; +import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.server.level.ChunkHolder; +import net.minecraft.server.level.ChunkMap; +import net.minecraft.server.level.ChunkTaskPriorityQueueSorter.Message; +import net.minecraft.server.level.GenerationChunkHolder; +import net.minecraft.server.level.ServerChunkCache; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ThreadedLevelLightEngine; +import net.minecraft.server.level.progress.ChunkProgressListener; +import net.minecraft.util.StaticCache2D; +import net.minecraft.util.thread.ProcessorHandle; +import net.minecraft.util.thread.ProcessorMailbox; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.LevelSettings; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.biome.FixedBiomeSource; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.chunk.ChunkGeneratorStructureState; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.ProtoChunk; +import net.minecraft.world.level.chunk.UpgradeData; +import net.minecraft.world.level.chunk.status.ChunkPyramid; +import net.minecraft.world.level.chunk.status.ChunkStatus; +import net.minecraft.world.level.chunk.status.WorldGenContext; +import net.minecraft.world.level.dimension.LevelStem; +import net.minecraft.world.level.levelgen.FlatLevelSource; +import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; +import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; +import net.minecraft.world.level.levelgen.WorldOptions; +import net.minecraft.world.level.levelgen.blending.BlendingData; +import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; +import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; +import net.minecraft.world.level.storage.LevelStorageSource; +import net.minecraft.world.level.storage.PrimaryLevelData; +import org.apache.logging.log4j.Logger; +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.generator.CustomChunkGenerator; +import org.bukkit.generator.BiomeProvider; +import org.bukkit.generator.BlockPopulator; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; +import java.lang.reflect.Field; +import java.nio.file.Path; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.OptionalLong; +import java.util.Random; +import java.util.concurrent.CompletableFuture; +import java.util.function.BooleanSupplier; +import java.util.function.Supplier; + +import static net.minecraft.core.registries.Registries.BIOME; + +public class PaperweightRegen extends Regenerator { + + private static final Logger LOGGER = LogManagerCompat.getLogger(); + + private static final Field serverWorldsField; + private static final Field paperConfigField; + private static final Field flatBedrockField; + private static final Field generatorSettingFlatField; + private static final Field generatorSettingBaseSupplierField; + private static final Field delegateField; + private static final Field chunkSourceField; + private static final Field generatorStructureStateField; + private static final Field ringPositionsField; + private static final Field hasGeneratedPositionsField; + + //list of chunk stati in correct order without FULL + private static final Map chunkStati = new LinkedHashMap<>(); + + static { + chunkStati.put(ChunkStatus.EMPTY, Concurrency.FULL); // empty: radius -1, does nothing + chunkStati.put(ChunkStatus.STRUCTURE_STARTS, Concurrency.NONE); // structure starts: uses unsynchronized maps + chunkStati.put( + ChunkStatus.STRUCTURE_REFERENCES, + Concurrency.NONE + ); // structure refs: radius 8, but only writes to current chunk + chunkStati.put(ChunkStatus.BIOMES, Concurrency.NONE); // biomes: radius 0 + chunkStati.put(ChunkStatus.NOISE, Concurrency.RADIUS); // noise: radius 8 + chunkStati.put(ChunkStatus.SURFACE, Concurrency.NONE); // surface: radius 0, requires NONE + chunkStati.put(ChunkStatus.CARVERS, Concurrency.NONE); // carvers: radius 0, but RADIUS and FULL change results + chunkStati.put(ChunkStatus.FEATURES, Concurrency.NONE); // features: uses unsynchronized maps + chunkStati.put( + ChunkStatus.INITIALIZE_LIGHT, + Concurrency.FULL + ); // initialize_light: radius 0 + chunkStati.put( + ChunkStatus.LIGHT, + Concurrency.FULL + ); // light: radius 1, but no writes to other chunks, only current chunk + chunkStati.put(ChunkStatus.SPAWN, Concurrency.NONE); // spawn: radius 0 + + try { + serverWorldsField = CraftServer.class.getDeclaredField("worlds"); + serverWorldsField.setAccessible(true); + + Field tmpPaperConfigField; + Field tmpFlatBedrockField; + try { //only present on paper + tmpPaperConfigField = Level.class.getDeclaredField("paperConfig"); + tmpPaperConfigField.setAccessible(true); + + tmpFlatBedrockField = tmpPaperConfigField.getType().getDeclaredField("generateFlatBedrock"); + tmpFlatBedrockField.setAccessible(true); + } catch (Exception e) { + tmpPaperConfigField = null; + tmpFlatBedrockField = null; + } + paperConfigField = tmpPaperConfigField; + flatBedrockField = tmpFlatBedrockField; + + generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName( + "settings", "e")); + generatorSettingBaseSupplierField.setAccessible(true); + + generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "d")); + generatorSettingFlatField.setAccessible(true); + + delegateField = CustomChunkGenerator.class.getDeclaredField("delegate"); + delegateField.setAccessible(true); + + chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "I")); + chunkSourceField.setAccessible(true); + + generatorStructureStateField = ChunkMap.class.getDeclaredField(Refraction.pickName("chunkGeneratorState", "w")); + generatorStructureStateField.setAccessible(true); + + ringPositionsField = ChunkGeneratorStructureState.class.getDeclaredField(Refraction.pickName("ringPositions", "g")); + ringPositionsField.setAccessible(true); + + hasGeneratedPositionsField = ChunkGeneratorStructureState.class.getDeclaredField( + Refraction.pickName("hasGeneratedPositions", "h") + ); + hasGeneratedPositionsField.setAccessible(true); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + //runtime + private ServerLevel originalServerWorld; + private ServerChunkCache originalChunkProvider; + private ServerLevel freshWorld; + private ServerChunkCache freshChunkProvider; + private LevelStorageSource.LevelStorageAccess session; + private StructureTemplateManager structureTemplateManager; + private ThreadedLevelLightEngine threadedLevelLightEngine; + private ChunkGenerator chunkGenerator; + private WorldGenContext worldGenContext; + + private Path tempDir; + + private boolean generateFlatBedrock = false; + + public PaperweightRegen(org.bukkit.World originalBukkitWorld, Region region, Extent target, RegenOptions options) { + super(originalBukkitWorld, region, target, options); + if (PaperLib.isPaper()) { + throw new UnsupportedOperationException("Regeneration currently not support on Paper due to the new generation system"); + } + } + + @Override + protected boolean prepare() { + this.originalServerWorld = ((CraftWorld) originalBukkitWorld).getHandle(); + originalChunkProvider = originalServerWorld.getChunkSource(); + + //flat bedrock? (only on paper) + if (paperConfigField != null) { + try { + generateFlatBedrock = flatBedrockField.getBoolean(paperConfigField.get(originalServerWorld)); + } catch (Exception ignored) { + } + } + + seed = options.getSeed().orElse(originalServerWorld.getSeed()); + chunkStati.forEach((s, c) -> super.chunkStatuses.put(new ChunkStatusWrap(s), c)); + + return true; + } + + @Override + @SuppressWarnings("unchecked") + protected boolean initNewWorld() throws Exception { + //world folder + tempDir = java.nio.file.Files.createTempDirectory("FastAsyncWorldEditWorldGen"); + + //prepare for world init (see upstream implementation for reference) + org.bukkit.World.Environment environment = originalBukkitWorld.getEnvironment(); + org.bukkit.generator.ChunkGenerator generator = originalBukkitWorld.getGenerator(); + LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(tempDir); + ResourceKey levelStemResourceKey = getWorldDimKey(environment); + session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey); + PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData; + + MinecraftServer server = originalServerWorld.getCraftServer().getServer(); + WorldOptions originalOpts = originalWorldData.worldGenOptions(); + WorldOptions newOpts = options.getSeed().isPresent() + ? originalOpts.withSeed(OptionalLong.of(seed)) + : originalOpts; + LevelSettings newWorldSettings = new LevelSettings( + "faweregentempworld", + originalWorldData.settings.gameType(), + originalWorldData.settings.hardcore(), + originalWorldData.settings.difficulty(), + originalWorldData.settings.allowCommands(), + originalWorldData.settings.gameRules(), + originalWorldData.settings.getDataConfiguration() + ); + + PrimaryLevelData.SpecialWorldProperty specialWorldProperty = + originalWorldData.isFlatWorld() + ? PrimaryLevelData.SpecialWorldProperty.FLAT + : originalWorldData.isDebugWorld() + ? PrimaryLevelData.SpecialWorldProperty.DEBUG + : PrimaryLevelData.SpecialWorldProperty.NONE; + PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, specialWorldProperty, Lifecycle.stable()); + + BiomeProvider biomeProvider = getBiomeProvider(); + + + //init world + freshWorld = Fawe.instance().getQueueHandler().sync((Supplier) () -> new ServerLevel( + server, + server.executor, + session, + newWorldData, + originalServerWorld.dimension(), + DedicatedServer.getServer().registryAccess().registry(Registries.LEVEL_STEM).orElseThrow() + .getOrThrow(levelStemResourceKey), + new RegenNoOpWorldLoadListener(), + originalServerWorld.isDebug(), + seed, + ImmutableList.of(), + false, + originalServerWorld.getRandomSequences(), + environment, + generator, + biomeProvider + ) { + + private final Holder singleBiome = options.hasBiomeType() ? DedicatedServer.getServer().registryAccess() + .registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow( + WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) + ) : null; + + @Override + public void tick(@NotNull BooleanSupplier shouldKeepTicking) { //no ticking + } + + @Override + public @NotNull Holder getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) { + if (options.hasBiomeType()) { + return singleBiome; + } + return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome( + biomeX, biomeY, biomeZ, getChunkSource().randomState().sampler() + ); + } + + }).get(); + freshWorld.noSave = true; + removeWorldFromWorldsMap(); + newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name + if (paperConfigField != null) { + paperConfigField.set(freshWorld, originalServerWorld.paperConfig()); + } + + ChunkGenerator originalGenerator = originalChunkProvider.getGenerator(); + if (originalGenerator instanceof FlatLevelSource flatLevelSource) { + FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings(); + chunkGenerator = new FlatLevelSource(generatorSettingFlat); + } else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) { + Holder generatorSettingBaseSupplier = (Holder) + generatorSettingBaseSupplierField.get(noiseBasedChunkGenerator); + BiomeSource biomeSource; + if (options.hasBiomeType()) { + biomeSource = new FixedBiomeSource( + DedicatedServer.getServer().registryAccess() + .registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow( + WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) + ) + ); + } else { + biomeSource = originalGenerator.getBiomeSource(); + } + chunkGenerator = new NoiseBasedChunkGenerator( + biomeSource, + generatorSettingBaseSupplier + ); + } else if (originalGenerator instanceof CustomChunkGenerator customChunkGenerator) { + chunkGenerator = customChunkGenerator.getDelegate(); + } else { + LOGGER.error("Unsupported generator type {}", originalGenerator.getClass().getName()); + return false; + } + if (generator != null) { + chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator); + generateConcurrent = generator.isParallelCapable(); + } +// chunkGenerator.conf = freshWorld.spigotConfig; - Does not exist anymore, may need to be re-addressed + + freshChunkProvider = new ServerChunkCache( + freshWorld, + session, + server.getFixerUpper(), + server.getStructureManager(), + server.executor, + chunkGenerator, + freshWorld.spigotConfig.viewDistance, + freshWorld.spigotConfig.simulationDistance, + server.forceSynchronousWrites(), + new RegenNoOpWorldLoadListener(), + (chunkCoordIntPair, state) -> { + }, + () -> server.overworld().getDataStorage() + ) { + // redirect to LevelChunks created in #createChunks + @Override + public ChunkAccess getChunk(int x, int z, @NotNull ChunkStatus chunkstatus, boolean create) { + ChunkAccess chunkAccess = getChunkAt(x, z); + if (chunkAccess == null && create) { + chunkAccess = createChunk(getProtoChunkAt(x, z)); + } + return chunkAccess; + } + }; + + if (seed == originalOpts.seed() && !options.hasBiomeType()) { + // Optimisation for needless ring position calculation when the seed and biome is the same. + ChunkGeneratorStructureState state = (ChunkGeneratorStructureState) generatorStructureStateField.get( + originalChunkProvider.chunkMap); + boolean hasGeneratedPositions = hasGeneratedPositionsField.getBoolean(state); + if (hasGeneratedPositions) { + Map>> origPositions = + (Map>>) ringPositionsField.get(state); + Map>> copy = new Object2ObjectArrayMap<>( + origPositions); + ChunkGeneratorStructureState newState = (ChunkGeneratorStructureState) generatorStructureStateField.get( + freshChunkProvider.chunkMap); + ringPositionsField.set(newState, copy); + hasGeneratedPositionsField.setBoolean(newState, true); + } + } + + + chunkSourceField.set(freshWorld, freshChunkProvider); + //let's start then + structureTemplateManager = server.getStructureManager(); + threadedLevelLightEngine = new NoOpLightEngine(freshChunkProvider); + + this.worldGenContext = new WorldGenContext( + freshWorld, + chunkGenerator, + structureTemplateManager, + threadedLevelLightEngine, + originalChunkProvider.chunkMap.worldGenContext.mainThreadMailBox() + ); + return true; + } + + @Override + protected void cleanup() { + try { + session.close(); + } catch (Exception ignored) { + } + + //shutdown chunk provider + try { + Fawe.instance().getQueueHandler().sync(() -> { + try { + freshChunkProvider.close(false); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + } catch (Exception ignored) { + } + + //remove world from server + try { + Fawe.instance().getQueueHandler().sync(this::removeWorldFromWorldsMap); + } catch (Exception ignored) { + } + + //delete directory + try { + SafeFiles.tryHardToDeleteDir(tempDir); + } catch (Exception ignored) { + } + } + + @Override + protected ProtoChunk createProtoChunk(int x, int z) { + return new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld, + this.freshWorld.registryAccess().registryOrThrow(BIOME), null + ); + } + + @Override + protected LevelChunk createChunk(ProtoChunk protoChunk) { + return new LevelChunk( + freshWorld, + protoChunk, + null // we don't want to add entities + ); + } + + @Override + protected ChunkStatusWrap getFullChunkStatus() { + return new ChunkStatusWrap(ChunkStatus.FULL); + } + + @Override + protected List getBlockPopulators() { + return originalServerWorld.getWorld().getPopulators(); + } + + @Override + protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) { + // BlockPopulator#populate has to be called synchronously for TileEntity access + TaskManager.taskManager().task(() -> { + final CraftWorld world = freshWorld.getWorld(); + final Chunk chunk = world.getChunkAt(levelChunk.locX, levelChunk.locZ); + blockPopulator.populate(world, random, chunk); + }); + } + + @Override + protected IChunkCache initSourceQueueCache() { + return (chunkX, chunkZ) -> new PaperweightGetBlocks(freshWorld, chunkX, chunkZ) { + @Override + public LevelChunk ensureLoaded(ServerLevel nmsWorld, int x, int z) { + return getChunkAt(x, z); + } + }; + } + + //util + @SuppressWarnings("unchecked") + private void removeWorldFromWorldsMap() { + try { + Map map = (Map) serverWorldsField.get(Bukkit.getServer()); + map.remove("faweregentempworld"); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private ResourceKey getWorldDimKey(org.bukkit.World.Environment env) { + return switch (env) { + case NETHER -> LevelStem.NETHER; + case THE_END -> LevelStem.END; + default -> LevelStem.OVERWORLD; + }; + } + + private static class RegenNoOpWorldLoadListener implements ChunkProgressListener { + + private RegenNoOpWorldLoadListener() { + } + + @Override + public void updateSpawnPos(@NotNull ChunkPos spawnPos) { + } + + @Override + public void onStatusChange( + final @NotNull ChunkPos pos, + @org.jetbrains.annotations.Nullable final net.minecraft.world.level.chunk.status.ChunkStatus status + ) { + + } + + @Override + public void start() { + + } + + @Override + public void stop() { + } + + // TODO Paper only(?) @Override + public void setChunkRadius(int radius) { + } + + } + + private class FastProtoChunk extends ProtoChunk { + + public FastProtoChunk( + final ChunkPos pos, + final UpgradeData upgradeData, + final LevelHeightAccessor world, + final Registry biomeRegistry, + @Nullable final BlendingData blendingData + ) { + super(pos, upgradeData, world, biomeRegistry, blendingData); + } + + // avoid warning on paper + + @SuppressWarnings("unused") // compatibility with spigot + public boolean generateFlatBedrock() { + return generateFlatBedrock; + } + + // no one will ever see the entities! + @Override + public @NotNull List getEntities() { + return Collections.emptyList(); + } + + } + + protected class ChunkStatusWrap extends ChunkStatusWrapper { + + private final ChunkStatus chunkStatus; + + public ChunkStatusWrap(ChunkStatus chunkStatus) { + this.chunkStatus = chunkStatus; + } + + @Override + public int requiredNeighborChunkRadius() { + return ChunkPyramid.GENERATION_PYRAMID.getStepTo(ChunkStatus.FULL).getAccumulatedRadiusOf(chunkStatus); + } + + @Override + public String name() { + return chunkStatus.toString(); + } + + @Override + public CompletableFuture processChunk(List accessibleChunks) { + ChunkAccess chunkAccess = accessibleChunks.get(accessibleChunks.size() / 2); + int chunkX = chunkAccess.getPos().x; + int chunkZ = chunkAccess.getPos().z; + getProtoChunkAt(chunkX, chunkZ); + StaticCache2D neighbours = StaticCache2D + .create( + chunkX, + chunkZ, + requiredNeighborChunkRadius(), + (final int nx, final int nz) -> new ChunkHolder(new ChunkPos(nx, nz), + ChunkHolderManager.MAX_TICKET_LEVEL, + freshWorld, + threadedLevelLightEngine, + null, + freshChunkProvider.chunkMap + ) + ); + return ChunkPyramid.GENERATION_PYRAMID.getStepTo(chunkStatus).apply( + worldGenContext, + neighbours, + chunkAccess + ); + } + + } + + /** + * A light engine that does nothing. As light is calculated after pasting anyway, we can avoid + * work this way. + */ + static class NoOpLightEngine extends ThreadedLevelLightEngine { + + private static final ProcessorMailbox MAILBOX = ProcessorMailbox.create(task -> { + }, "fawe-no-op"); + private static final ProcessorHandle> HANDLE = ProcessorHandle.of("fawe-no-op", m -> { + }); + + public NoOpLightEngine(final ServerChunkCache chunkProvider) { + super(chunkProvider, chunkProvider.chunkMap, false, MAILBOX, HANDLE); + } + + @Override + public @NotNull CompletableFuture lightChunk(final @NotNull ChunkAccess chunk, final boolean excludeBlocks) { + return CompletableFuture.completedFuture(chunk); + } + + } + +} diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index 258d9b83e..088ab22a0 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -208,7 +208,7 @@ tasks { versionNumber.set("${project.version}") versionType.set("release") uploadFile.set(file("build/libs/${rootProject.name}-Bukkit-${project.version}.jar")) - gameVersions.addAll(listOf("1.20.6", "1.20.5", "1.20.3", "1.20.2", "1.20.1", "1.20", "1.19.4")) + gameVersions.addAll(listOf("1.21", "1.20.6", "1.20.5", "1.20.3", "1.20.2", "1.20.1", "1.20", "1.19.4")) loaders.addAll(listOf("paper", "spigot")) changelog.set("The changelog is available on GitHub: https://github.com/IntellectualSites/" + "FastAsyncWorldEdit/releases/tag/${project.version}") From 4590dcb00624c045001485b930364644e7245490 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 30 Jun 2024 08:51:05 +0000 Subject: [PATCH 185/220] Update auto.value to v1.11.0 (#2811) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b02ec474b..d3c7ef643 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -25,7 +25,7 @@ adventure = "4.17.0" adventure-bukkit = "4.3.3" checkerqual = "3.43.0" truezip = "6.8.4" -auto-value = "1.10.4" +auto-value = "1.11.0" findbugs = "3.0.2" rhino-runtime = "1.7.15" zstd-jni = "1.4.8-1" # Not latest as it can be difficult to obtain latest ZSTD libs From 1db7df2e2c51eb12b5637fecf5bb149016c15e8e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 30 Jun 2024 08:51:20 +0000 Subject: [PATCH 186/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.3.3 (#2809) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d3c7ef643..0b88f66c6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.3.2" +towny = "0.100.3.3" plotsquared = "7.3.8" # Third party From 270e1a82a73340babe16929f698ed79b0f8b0592 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 30 Jun 2024 08:51:37 +0000 Subject: [PATCH 187/220] Update dependency org.enginehub.lin-bus:lin-bus-bom to v0.1.2 (#2810) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0b88f66c6..8fb4a51eb 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,7 +40,7 @@ paperlib = "1.0.8" paster = "1.1.6" vault = "1.7.1" serverlib = "2.3.6" -linbus = "0.1.0" +linbus = "0.1.2" ## Internal text-adapter = "3.0.6" text = "3.0.4" From e8d17fbcd9deec90562807d51765c5b44615cc23 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 30 Jun 2024 08:55:04 +0000 Subject: [PATCH 188/220] Update dependency org.checkerframework:checker-qual to v3.44.0 (#2813) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8fb4a51eb..5c82ca09d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,7 +23,7 @@ sparsebitset = "1.3" parallelgzip = "1.0.5" adventure = "4.17.0" adventure-bukkit = "4.3.3" -checkerqual = "3.43.0" +checkerqual = "3.44.0" truezip = "6.8.4" auto-value = "1.11.0" findbugs = "3.0.2" From 04fb55d4911db5b47776cb1ca1094540ab9a8744 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 30 Jun 2024 09:00:41 +0000 Subject: [PATCH 189/220] Update dependency gradle to v8.8 (#2812) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b82aa23a4..a4413138c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From c82ab99a22440b0101f03aa281e7782e5ed7ddb4 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Sun, 30 Jun 2024 11:14:40 +0200 Subject: [PATCH 190/220] Release 2.11.0 Signed-off-by: Alexander Brandes --- build.gradle.kts | 4 ++-- .../core/configuration/Config.java | 2 +- .../core/function/mask/BlockMaskBuilder.java | 4 ++-- .../java/com/sk89q/worldedit/LocalSession.java | 6 +++--- .../java/com/sk89q/worldedit/WorldEdit.java | 10 +++++----- .../worldedit/command/ClipboardCommands.java | 2 +- .../history/change/BiomeChange3D.java | 6 +++--- .../worldedit/history/change/BlockChange.java | 6 +++--- .../internal/registry/AbstractFactory.java | 2 +- .../com/sk89q/worldedit/math/BlockVector2.java | 12 ++++++------ .../com/sk89q/worldedit/math/BlockVector3.java | 18 +++++++++--------- .../java/com/sk89q/worldedit/math/Vector2.java | 8 ++++---- .../java/com/sk89q/worldedit/math/Vector3.java | 12 ++++++------ .../com/sk89q/worldedit/registry/Keyed.java | 4 ++-- .../com/sk89q/worldedit/util/LocatedBlock.java | 4 ++-- .../sk89q/worldedit/world/biome/BiomeType.java | 4 ++-- .../worldedit/world/entity/EntityType.java | 4 ++-- .../sk89q/worldedit/world/fluid/FluidType.java | 4 ++-- .../worldedit/world/registry/ItemMaterial.java | 8 ++++---- 19 files changed, 60 insertions(+), 60 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 0f188deeb..14be0a0a2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,7 +34,7 @@ logger.lifecycle(""" ******************************************* """) -var rootVersion by extra("2.10.1") +var rootVersion by extra("2.11.0") var snapshot by extra("SNAPSHOT") var revision: String by extra("") var buildNumber by extra("") @@ -52,7 +52,7 @@ ext { } } -version = String.format("%s-%s", rootVersion, buildNumber) +version = String.format("%s", rootVersion) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java index 1d6f8d146..880b4cdf7 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java @@ -224,7 +224,7 @@ public class Config { /** * Indicates that a field's default value should match another input if the config is otherwise already generated * - * @since TODO + * @since 2.11.0 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java index 33ea8e3f7..7ca60bdd1 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java @@ -65,7 +65,7 @@ public class BlockMaskBuilder { /** * Create a new instance with a given {@link ParserContext} to use if parsing regex * - * @since TODO + * @since 2.11.0 */ public BlockMaskBuilder(ParserContext context) { this(new long[BlockTypes.size()][], context); @@ -79,7 +79,7 @@ public class BlockMaskBuilder { /** * Create a new instance with a given {@link ParserContext} to use if parsing regex * - * @since TODO + * @since 2.11.0 */ protected BlockMaskBuilder(long[][] bitSets, ParserContext context) { this.bitSets = bitSets; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index be1740dc4..48e2a8078 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -1352,7 +1352,7 @@ public class LocalSession implements TextureHolder { * @param item the item type * @param tool the tool to set, which can be {@code null} * @throws InvalidToolBindException if the item can't be bound to that item - * @since TODO + * @since 2.11.0 */ public void setTool(BaseItem item, @Nullable Tool tool) throws InvalidToolBindException { if (item.getType().hasBlockType()) { @@ -1919,7 +1919,7 @@ public class LocalSession implements TextureHolder { * Get the preferred wand item for this user, or {@code null} to use the default * * @return item id of wand item, or {@code null} - * @since TODO + * @since 2.11.0 */ public BaseItem getWandBaseItem() { return wandItem == null ? null : new BaseItem(wandItem.getType(), wandItem.getNbtReference()); @@ -1929,7 +1929,7 @@ public class LocalSession implements TextureHolder { * Get the preferred navigation wand item for this user, or {@code null} to use the default * * @return item id of nav wand item, or {@code null} - * @since TODO + * @since 2.11.0 */ public BaseItem getNavWandBaseItem() { return navWandItem == null ? null : new BaseItem(navWandItem.getType(), navWandItem.getNbtReference()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java index 402310def..8fbf61436 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java @@ -468,7 +468,7 @@ public final class WorldEdit { /** * @deprecated Use {@link WorldEdit#checkMaxBrushRadius(Expression, Actor)} */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public void checkMaxBrushRadius(Expression radius) throws MaxBrushRadiusException { double val = radius.evaluate(); checkArgument(val >= 0, "Radius must be a positive number."); @@ -485,7 +485,7 @@ public final class WorldEdit { * @param radius Radius to check * @param actor Actor to check for * @throws MaxRadiusException If given radius larger than allowed - * @since TODO + * @since 2.11.0 */ public void checkMaxRadius(double radius, Actor actor) { int max = actor.getLimit().MAX_RADIUS; @@ -500,7 +500,7 @@ public final class WorldEdit { * @param radius Radius to check * @param actor Actor to check for * @throws MaxRadiusException If given radius larger than allowed - * @since TODO + * @since 2.11.0 */ public void checkMaxBrushRadius(double radius, Actor actor) { int max = actor.getLimit().MAX_BRUSH_RADIUS; @@ -515,7 +515,7 @@ public final class WorldEdit { * @param expression Radius to check * @param actor Actor to check for * @throws BrushRadiusLimitException If given radius larger than allowed - * @since TODO + * @since 2.11.0 */ public void checkMaxBrushRadius(Expression expression, Actor actor) { double radius = expression.evaluate(); @@ -532,7 +532,7 @@ public final class WorldEdit { * @param position Position to check * @param extent Extent to check in * @throws OutsideWorldBoundsException If the position is outside the world height limits - * @since TODO + * @since 2.11.0 */ public void checkExtentHeightBounds(BlockVector3 position, Extent extent) { if (position.y() < extent.getMinY() || position.y() > extent.getMaxY()) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index 8c0b69ec9..378449755 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -340,7 +340,7 @@ public class ClipboardCommands { aliases = {"/download"}, desc = "Downloads your clipboard through the configured web interface" ) - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") @CommandPermissions({"worldedit.clipboard.download"}) public void download( final Actor actor, diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BiomeChange3D.java b/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BiomeChange3D.java index 1106899f8..4bdbddb4d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BiomeChange3D.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BiomeChange3D.java @@ -56,7 +56,7 @@ public record BiomeChange3D(BlockVector3 position, BiomeType previous, BiomeType * @return the position * @deprecated Use {@link #position()}. */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public BlockVector3 getPosition() { return position; } @@ -67,7 +67,7 @@ public record BiomeChange3D(BlockVector3 position, BiomeType previous, BiomeType * @return the previous biome * @deprecated Use {@link #previous()}. */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public BiomeType getPrevious() { return previous; } @@ -78,7 +78,7 @@ public record BiomeChange3D(BlockVector3 position, BiomeType previous, BiomeType * @return the current biome * @deprecated Use {@link #current()}. */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public BiomeType getCurrent() { return current; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BlockChange.java b/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BlockChange.java index 16fc50e0d..ecde7967f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BlockChange.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/history/change/BlockChange.java @@ -71,7 +71,7 @@ public record BlockChange(BlockVector3 position, BaseBlock previous, BaseBlock c * @return the position * @deprecated use {@link #position()} */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public BlockVector3 getPosition() { return position; } @@ -82,7 +82,7 @@ public record BlockChange(BlockVector3 position, BaseBlock previous, BaseBlock c * @return the previous block * @deprecated use {@link #previous()} */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public BaseBlock getPrevious() { return previous; } @@ -93,7 +93,7 @@ public record BlockChange(BlockVector3 position, BaseBlock previous, BaseBlock c * @return the current block * @deprecated use {@link #current()} */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public BaseBlock getCurrent() { return current; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java index 0934627b9..75fae8ca2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java @@ -68,7 +68,7 @@ public abstract class AbstractFactory { * @param worldEdit the WorldEdit instance * @param defaultParser the parser to fall back to * @param richParser the rich parser - * @since TODO + * @since 2.11.0 */ protected AbstractFactory(WorldEdit worldEdit, InputParser defaultParser, FaweParser richParser) { checkNotNull(worldEdit); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java index baed5ffde..7db9cd7e2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector2.java @@ -122,7 +122,7 @@ public class BlockVector2 { * Get the X coordinate. * * @return the x coordinate - * @since TODO + * @since 2.11.0 */ public int x() { return x; @@ -134,7 +134,7 @@ public class BlockVector2 { * @return the x coordinate * @deprecated use {@link #x()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public int getX() { return x; } @@ -145,7 +145,7 @@ public class BlockVector2 { * @return the x coordinate * @deprecated use {@link #x()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public int getBlockX() { return x; } @@ -164,7 +164,7 @@ public class BlockVector2 { * Get the Z coordinate. * * @return the z coordinate - * @since TODO + * @since 2.11.0 */ public int z() { return z; @@ -176,7 +176,7 @@ public class BlockVector2 { * @return the z coordinate * @deprecated use {@link #z()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public int getZ() { return z; } @@ -187,7 +187,7 @@ public class BlockVector2 { * @return the z coordinate * @deprecated use {@link #z()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public int getBlockZ() { return z; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java index 3d239b352..ee2789a33 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java @@ -174,7 +174,7 @@ public abstract class BlockVector3 { * Get the X coordinate. * * @return the x coordinate - * @since TODO + * @since 2.11.0 */ public abstract int x(); //FAWE end @@ -185,7 +185,7 @@ public abstract class BlockVector3 { * @return the x coordinate * @deprecated use {@link #x()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public int getX() { return this.x(); //FAWE - access abstract getter instead of local field } @@ -196,7 +196,7 @@ public abstract class BlockVector3 { * @return the x coordinate * @deprecated use {@link #x()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public int getBlockX() { return this.x(); //FAWE - access abstract getter instead of local field } @@ -219,7 +219,7 @@ public abstract class BlockVector3 { * Get the Y coordinate. * * @return the y coordinate - * @since TODO + * @since 2.11.0 */ public abstract int y(); //FAWE end @@ -230,7 +230,7 @@ public abstract class BlockVector3 { * @return the y coordinate * @deprecated use {@link #y()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public int getY() { return this.y(); //FAWE - access abstract getter instead of local field } @@ -241,7 +241,7 @@ public abstract class BlockVector3 { * @return the y coordinate * @deprecated use {@link #y()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public int getBlockY() { return this.y(); //FAWE - access abstract getter instead of local field } @@ -263,7 +263,7 @@ public abstract class BlockVector3 { * Get the Z coordinate. * * @return the Z coordinate - * @since TODO + * @since 2.11.0 */ public abstract int z(); //FAWE end @@ -274,7 +274,7 @@ public abstract class BlockVector3 { * @return the z coordinate * @deprecated use {@link #z()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public int getZ() { return this.z(); //FAWE - access abstract getter instead of local field } @@ -285,7 +285,7 @@ public abstract class BlockVector3 { * @return the z coordinate * @deprecated use {@link #z()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public int getBlockZ() { return this.z(); //FAWE - access abstract getter instead of local field } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java index 9d08676f9..089ed62ca 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector2.java @@ -57,7 +57,7 @@ public record Vector2(double x, double z) { * @return the x coordinate * @deprecated use {@link #x()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public double getX() { return x; } @@ -66,7 +66,7 @@ public record Vector2(double x, double z) { * Get the X coordinate, aligned to the block grid. * * @return the block-aligned x coordinate - * @since TODO + * @since 2.11.0 */ public int blockX() { return MathMan.roundInt(x); @@ -86,7 +86,7 @@ public record Vector2(double x, double z) { * Get the Z coordinate, aligned to the block grid. * * @return the block-aligned z coordinate - * @since TODO + * @since 2.11.0 */ public int blockZ() { return MathMan.roundInt(z); @@ -98,7 +98,7 @@ public record Vector2(double x, double z) { * @return the z coordinate * @deprecated use {@link #z()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public double getZ() { return z; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java index 898bb5241..3b359920b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/Vector3.java @@ -160,7 +160,7 @@ public abstract class Vector3 { * Get the X coordinate. * * @return the x coordinate - * @since TODO + * @since 2.11.0 */ public abstract double x(); @@ -179,7 +179,7 @@ public abstract class Vector3 { * @return the x coordinate * @deprecated use {@link #x()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public double getX() { return this.x(); } @@ -201,7 +201,7 @@ public abstract class Vector3 { * Get the Y coordinate. * * @return the y coordinate - * @since TODO + * @since 2.11.0 */ public abstract double y(); @@ -220,7 +220,7 @@ public abstract class Vector3 { * @return the y coordinate * @deprecated use {@link #y()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public double getY() { return this.y(); } @@ -241,7 +241,7 @@ public abstract class Vector3 { * Get the Z coordinate. * * @return the z coordinate - * @since TODO + * @since 2.11.0 */ public abstract double z(); @@ -260,7 +260,7 @@ public abstract class Vector3 { * @return the z coordinate * @deprecated use {@link #z()} instead */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public double getZ() { return this.z(); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Keyed.java b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Keyed.java index b31e62d7f..dfce5f833 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Keyed.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Keyed.java @@ -33,7 +33,7 @@ public interface Keyed { * @return an id * @deprecated Use {@link #id()} instead. */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") default String getId() { return id(); } @@ -43,7 +43,7 @@ public interface Keyed { * may have additional restrictions. * * @return an id - * @since TODO + * @since 2.11.0 */ @NonAbstractForCompatibility(delegateName = "getId", delegateParams = {}) default String id() { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/LocatedBlock.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/LocatedBlock.java index ff946e458..042f435e0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/LocatedBlock.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/LocatedBlock.java @@ -40,7 +40,7 @@ public record LocatedBlock(BlockVector3 location, BaseBlock block) { * @return The location * @deprecated This class is now a record. Use {@link #location()} instead. */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public BlockVector3 getLocation() { return this.location; } @@ -51,7 +51,7 @@ public record LocatedBlock(BlockVector3 location, BaseBlock block) { * @return The block * @deprecated This class is now a record. Use {@link #block()} instead. */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") public BaseBlock getBlock() { return this.block; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java index e7ec152a9..d49289093 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeType.java @@ -47,7 +47,7 @@ public class BiomeType implements RegistryItem, Keyed, BiomePattern { * Gets the ID of this biome. * * @return The id - * @since TODO + * @since 2.11.0 */ @Override public String id() { @@ -78,7 +78,7 @@ public class BiomeType implements RegistryItem, Keyed, BiomePattern { * @return The id * @deprecated use {@link #id()} */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") @Override public String getId() { return this.id; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java index 1faf3bc4c..aba23b636 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java @@ -45,7 +45,7 @@ public class EntityType implements RegistryItem, Keyed { * Gets the id of this entity type. * * @return the id - * @since TODO + * @since 2.11.0 */ public String id() { return this.id; @@ -57,7 +57,7 @@ public class EntityType implements RegistryItem, Keyed { * @return the id * @deprecated use {@link #id()} */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") @Override public String getId() { return this.id; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java index 1642ed4e9..1b191f07f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidType.java @@ -43,7 +43,7 @@ public class FluidType implements RegistryItem, Keyed { * Gets the ID of this block. * * @return The id - * @since TODO + * @since 2.11.0 */ public String id() { return this.id; @@ -55,7 +55,7 @@ public class FluidType implements RegistryItem, Keyed { * @return The id * @deprecated use {@link #id()} */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") @Override public String getId() { return this.id; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/ItemMaterial.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/ItemMaterial.java index db63b53a4..45071859c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/ItemMaterial.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/ItemMaterial.java @@ -29,7 +29,7 @@ public interface ItemMaterial { * @return the maximum quantity * @deprecated Use {@link #maxStackSize()} instead. */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") default int getMaxStackSize() { return maxStackSize(); } @@ -38,7 +38,7 @@ public interface ItemMaterial { * Gets the the maximum quantity of this item that can be in a single stack. * * @return the maximum quantity - * @since TODO + * @since 2.11.0 */ @NonAbstractForCompatibility(delegateName = "getMaxStackSize", delegateParams = {}) default int maxStackSize() { @@ -52,7 +52,7 @@ public interface ItemMaterial { * @return the maximum damage, or 0 if not applicable * @deprecated Use {@link #maxDamage()} instead. */ - @Deprecated(forRemoval = true, since = "TODO") + @Deprecated(forRemoval = true, since = "2.11.0") default int getMaxDamage() { return maxDamage(); } @@ -61,7 +61,7 @@ public interface ItemMaterial { * Gets the the maximum damage this item can take before being broken. * * @return the maximum damage, or 0 if not applicable - * @since TODO + * @since 2.11.0 */ @NonAbstractForCompatibility(delegateName = "getMaxDamage", delegateParams = {}) default int maxDamage() { From e3fde6cf82cf7194427320da6085292d609b55be Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Sun, 30 Jun 2024 11:27:51 +0200 Subject: [PATCH 191/220] Back to snapshot for development Signed-off-by: Alexander Brandes --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 14be0a0a2..4dd632c1d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,7 +34,7 @@ logger.lifecycle(""" ******************************************* """) -var rootVersion by extra("2.11.0") +var rootVersion by extra("2.11.1") var snapshot by extra("SNAPSHOT") var revision: String by extra("") var buildNumber by extra("") @@ -52,7 +52,7 @@ ext { } } -version = String.format("%s", rootVersion) +version = String.format("%s-%s", rootVersion, buildNumber) if (!project.hasProperty("gitCommitHash")) { apply(plugin = "org.ajoberstar.grgit") From d9e69cfd58f6626f060ab3f38fdc7436ea6049bd Mon Sep 17 00:00:00 2001 From: Jordan Date: Sun, 30 Jun 2024 21:59:06 +0200 Subject: [PATCH 192/220] fix: do not bother with refraction for biomes/i field, this just fixes it now --- .../impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java index 33c7a8597..8c7da74fa 100644 --- a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java @@ -141,7 +141,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i")); + Field tmpFieldBiomes; + try { + // Seems it's sometimes biomes and sometimes "i". Idk this is just easier than having to try to deal with it + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); // apparently unobf + } catch (NoSuchFieldException ignored) { + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("i"); // apparently obf + } + fieldBiomes = tmpFieldBiomes; fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( From 15c60279585dac9752328f9beec0842186356c3a Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 1 Jul 2024 16:19:28 +0200 Subject: [PATCH 193/220] fix: override min/max pos methods from SimpleClipboard (#2803) - fixes #2800 --- .../core/extent/clipboard/ReadOnlyClipboard.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/ReadOnlyClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/ReadOnlyClipboard.java index 4f7245d27..2edb9cb51 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/ReadOnlyClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/ReadOnlyClipboard.java @@ -2,13 +2,10 @@ package com.fastasyncworldedit.core.extent.clipboard; import com.fastasyncworldedit.core.Fawe; import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.NBTUtils; -import com.sk89q.jnbt.Tag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.session.request.Request; @@ -18,9 +15,7 @@ import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockStateHolder; import javax.annotation.Nullable; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.UUID; import java.util.function.Supplier; @@ -77,6 +72,16 @@ public abstract class ReadOnlyClipboard extends SimpleClipboard { }; } + @Override + public BlockVector3 getMinimumPoint() { + return region.getMinimumPoint(); + } + + @Override + public BlockVector3 getMaximumPoint() { + return region.getMaximumPoint(); + } + @Override public Region getRegion() { return region; From a14bb7ed2cfdf2beda60ebc38f2f5a7bede6f64e Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 2 Jul 2024 18:51:11 +0100 Subject: [PATCH 194/220] fix: remove synchronisation on chunk GET when sending packet --- .../v1_19_R3/PaperweightPlatformAdapter.java | 36 +++++++++---------- .../v1_20_R2/PaperweightPlatformAdapter.java | 32 ++++++++--------- .../v1_20_R3/PaperweightPlatformAdapter.java | 32 ++++++++--------- .../v1_20_R4/PaperweightPlatformAdapter.java | 32 ++++++++--------- .../v1_21_R1/PaperweightPlatformAdapter.java | 32 ++++++++--------- 5 files changed, 72 insertions(+), 92 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java index 334289b08..aec3cfd24 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java @@ -350,27 +350,23 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { MinecraftServer.getServer().execute(() -> { ClientboundLevelChunkWithLightPacket packet; if (PaperLib.isPaper()) { - synchronized (chunk) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - true, - false // last false is to not bother with x-ray - ); - } + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null, + true, + false // last false is to not bother with x-ray + ); } else { - synchronized (chunk) { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - true - ); - } + // deprecated on paper - deprecation suppressed + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null, + true + ); } nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); }); diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java index 91dcfe24e..23f59e8bf 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java @@ -364,25 +364,21 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { MinecraftServer.getServer().execute(() -> { ClientboundLevelChunkWithLightPacket packet; if (PaperLib.isPaper()) { - synchronized (chunk) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - false // last false is to not bother with x-ray - ); - } + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null, + false // last false is to not bother with x-ray + ); } else { - synchronized (chunk) { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - ); - } + // deprecated on paper - deprecation suppressed + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null + ); } nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); }); diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java index f2f78eb7d..b69f476d3 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java @@ -364,25 +364,21 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { MinecraftServer.getServer().execute(() -> { ClientboundLevelChunkWithLightPacket packet; if (PaperLib.isPaper()) { - synchronized (chunk) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - false // last false is to not bother with x-ray - ); - } + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null, + false // last false is to not bother with x-ray + ); } else { - synchronized (chunk) { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - ); - } + // deprecated on paper - deprecation suppressed + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null + ); } nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); }); diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java index 6c0f72590..1389cdda3 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java @@ -353,25 +353,21 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { MinecraftServer.getServer().execute(() -> { ClientboundLevelChunkWithLightPacket packet; if (PaperLib.isPaper()) { - synchronized (chunk) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - false // last false is to not bother with x-ray - ); - } + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null, + false // last false is to not bother with x-ray + ); } else { - synchronized (chunk) { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - ); - } + // deprecated on paper - deprecation suppressed + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null + ); } nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); }); diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java index 8c7da74fa..c2931d7ff 100644 --- a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java @@ -361,25 +361,21 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { MinecraftServer.getServer().execute(() -> { ClientboundLevelChunkWithLightPacket packet; if (PaperLib.isPaper()) { - synchronized (chunk) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - false // last false is to not bother with x-ray - ); - } + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null, + false // last false is to not bother with x-ray + ); } else { - synchronized (chunk) { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - ); - } + // deprecated on paper - deprecation suppressed + packet = new ClientboundLevelChunkWithLightPacket( + levelChunk, + nmsWorld.getChunkSource().getLightEngine(), + null, + null + ); } nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); }); From 75d9475cf77bd06932c775a626b50202068b2c6c Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 2 Jul 2024 19:33:35 +0100 Subject: [PATCH 195/220] Disable regen completely on 1.21 for now --- .../impl/fawe/v1_21_R1/PaperweightFaweAdapter.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java index e0dae1b2f..0a2fe6f60 100644 --- a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java @@ -18,7 +18,6 @@ import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1.regen.PaperweightRegen; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.internal.block.BlockStateIdAccess; @@ -556,10 +555,10 @@ public final class PaperweightFaweAdapter extends FaweAdapter Date: Tue, 2 Jul 2024 20:34:02 +0200 Subject: [PATCH 196/220] Use isMovementBlocker() instead of isSolid() in heightmap calculation (#2822) --- .../core/extent/processor/heightmap/HeightMapType.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/heightmap/HeightMapType.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/heightmap/HeightMapType.java index d49644f24..cb5339737 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/heightmap/HeightMapType.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/heightmap/HeightMapType.java @@ -17,19 +17,19 @@ public enum HeightMapType { MOTION_BLOCKING { @Override public boolean includes(BlockState state) { - return state.getMaterial().isSolid() || HeightMapType.hasFluid(state); + return state.getMaterial().isMovementBlocker() || HeightMapType.hasFluid(state); } }, MOTION_BLOCKING_NO_LEAVES { @Override public boolean includes(BlockState state) { - return (state.getMaterial().isSolid() || HeightMapType.hasFluid(state)) && !HeightMapType.isLeaf(state); + return (state.getMaterial().isMovementBlocker() || HeightMapType.hasFluid(state)) && !HeightMapType.isLeaf(state); } }, OCEAN_FLOOR { @Override public boolean includes(BlockState state) { - return state.getMaterial().isSolid(); + return state.getMaterial().isMovementBlocker(); } }, WORLD_SURFACE { From c3bb567ea7da2087dfb2ca1507dc2d5c0d6174c7 Mon Sep 17 00:00:00 2001 From: Jordan Date: Tue, 2 Jul 2024 20:34:11 +0200 Subject: [PATCH 197/220] fix: switch to 3d where 2d biomes still remain in a couple of places (#2816) --- .../com/fastasyncworldedit/core/extent/FaweRegionExtent.java | 2 +- .../com/fastasyncworldedit/core/extent/TransformExtent.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/FaweRegionExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/FaweRegionExtent.java index 103dd8824..4f4cce126 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/FaweRegionExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/FaweRegionExtent.java @@ -101,7 +101,7 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc @Override public BiomeType getBiomeType(int x, int y, int z) { - if (!contains(x, z)) { + if (!contains(x, y, z)) { if (!limit.MAX_FAILS()) { WEManager.weManager().cancelEditSafe(this, FaweCache.OUTSIDE_REGION); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java index c424c0f8c..daa731d3c 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java @@ -93,7 +93,7 @@ public class TransformExtent extends BlockTransformExtent { @Override public BiomeType getBiomeType(int x, int y, int z) { BlockVector3 p = getPos(x, y, z); - return super.getBiomeType(p.x(), y, p.z()); + return super.getBiomeType(p.x(), p.y(), p.z()); } @Override From b511e878a48e8b725af5ad8d6cc8cca39211d678 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 2 Jul 2024 19:46:03 +0100 Subject: [PATCH 198/220] chore: throw exception on 1.21 regen --- .../impl/fawe/v1_21_R1/PaperweightFaweAdapter.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java index 0a2fe6f60..757ba0e29 100644 --- a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java @@ -555,10 +555,10 @@ public final class PaperweightFaweAdapter extends FaweAdapter Date: Fri, 5 Jul 2024 15:05:55 +0200 Subject: [PATCH 199/220] fix: clone polyhedral region last triangle too if present (#2807) --- .../com/fastasyncworldedit/core/regions/PolyhedralRegion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java index a1471c9d8..675e8efb6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java @@ -77,7 +77,7 @@ public class PolyhedralRegion extends AbstractRegion { minimumPoint = region.minimumPoint; maximumPoint = region.maximumPoint; centerAccum = region.centerAccum; - lastTriangle = region.lastTriangle; + lastTriangle = lastTriangle == null ? null : region.lastTriangle.clone(); } /** From 5341b06813f75ffbee767896288aa7c77d948bb9 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 5 Jul 2024 17:20:13 +0100 Subject: [PATCH 200/220] Apply hack-fix for biomes to 1.20.6 as well --- .../impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java index 1389cdda3..03eabc698 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java @@ -140,7 +140,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i")); + Field tmpFieldBiomes; + try { + // Seems it's sometimes biomes and sometimes "i". Idk this is just easier than having to try to deal with it + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); // apparently unobf + } catch (NoSuchFieldException ignored) { + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("i"); // apparently obf + } + fieldBiomes = tmpFieldBiomes; fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( From ef064cbccfb4d4d22e70d8f0f89af8fed8714fbe Mon Sep 17 00:00:00 2001 From: RadND <69626236+RadND@users.noreply.github.com> Date: Sun, 7 Jul 2024 21:16:39 +0800 Subject: [PATCH 201/220] Add worldedit.tool.none to fawe.permpack.basic (#2827) Add missing permission node in fawe.permpack.basic in bukkit If node "fawe.permpack.basic" exist in other platform than bukkit,this minor bug would exist here too,but i lack the knowledge of finding it out. --- worldedit-bukkit/src/main/resources/plugin.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/worldedit-bukkit/src/main/resources/plugin.yml b/worldedit-bukkit/src/main/resources/plugin.yml index cd12b1008..282587ce8 100644 --- a/worldedit-bukkit/src/main/resources/plugin.yml +++ b/worldedit-bukkit/src/main/resources/plugin.yml @@ -135,6 +135,7 @@ permissions: worldedit.brush.options.transform: true worldedit.brush.options.scroll: true worldedit.brush.options.visualize: true + worldedit.tool.none: true worldedit.tool.deltree: true worldedit.tool.farwand: true worldedit.tool.lrbuild: true From 1917406334ff39305639e94c740fe5c1d1377a8e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 02:12:18 +0000 Subject: [PATCH 202/220] Update dependency paperweight-userdev to v1.20.6-R0.1-20240702.153951-123 (#2830) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts index 34e3569eb..1512dca87 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/ - the().paperDevBundle("1.20.6-R0.1-20240617.192752-122") + the().paperDevBundle("1.20.6-R0.1-20240702.153951-123") compileOnly(libs.paperlib) } From 514da16d193ac26154d795e4f77a6b688da085e3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 02:12:58 +0000 Subject: [PATCH 203/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.3.4 (#2829) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5c82ca09d..48f436e07 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.3.3" +towny = "0.100.3.4" plotsquared = "7.3.8" # Third party From 1ec87e7092d9bddf246713e49efc1e3036af1257 Mon Sep 17 00:00:00 2001 From: Pierre Maurice Schwang Date: Sat, 13 Jul 2024 14:30:34 +0200 Subject: [PATCH 204/220] Support Sponge Schematic v3 (#2776) * Update to Sponge Schematic 3 Includes a major refactoring of how schematics are read. (cherry picked from commit bd475b1d4acbcf2a95e5a8f3aee50d2fb2100ae8) * Licenses lol (cherry picked from commit a5ce8a47657aa987da8ca625cd658856d2eb3477) * Fix imports (cherry picked from commit e1892b7bd4ff0ca4592f8cb4e1b2d9363c4cd6ff) * Update for final changes (cherry picked from commit 2f6b50a4276b33b615d9dbc52e73e958308735f9) * chore: ensure flushed clipboard in spongev2 writer * feat: initial work on FastSchematicWriterV2 * fix: only write into palette once, write into data as varint * chore: more work on FastSchematicWriterV3 * fix: make FastSchematicWriterV3 work * fix/chore: write pos as doubles * chore: start on reader (class exists at least) * chore: replace while loop with simple if as char can be max 2 bytes * chore/feat: more work on the fast v3 reader * fix: offset must be inverted for origin * chore: use the actual FileChannel for mark / reset (if present) * chore: add null check again * chore: buffer streams in isFormat check * chore/feat: read schematic fully * chore: don't hold a lazyreference (seems harder to gc with already computed value?) * chore: remove debugs * chore: optimize FastSchematicReaderV3 * chore: remove logger warn for now * chore: constant not required anymore * chore/feat: support non-file based inputstreams (using in memory LZ4 cache) * chore: don't wrap streams unnecessary * chore: cleanup * chore: since comment for reader + writer * chore: FAST_V3 not for testing anymore * chore: update schematic and clipboard logic for linbus changes * chore: undo format check on load * fix: remove usages of old nbt types * fix: use LinBus in FaweDelegateSchematicHandler * fix: use ReaderUtil again * chore: update supported schematic types for Arkitektonika * chore: check for magic bytes in schematic (not tested yet) * revert: magic bytes check * fix: fix paletteAlreadyInitialized + biome placement on linear clipboards * Update worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV3.java --------- Co-authored-by: Octavia Togami Co-authored-by: Hannes Greule --- .../FaweDelegateSchematicHandler.java | 16 +- .../bukkit/util/DoNotMiniseThese.java | 4 + ...Reader.java => FastSchematicReaderV2.java} | 4 +- .../clipboard/io/FastSchematicReaderV3.java | 818 ++++++++++++++++++ ...Writer.java => FastSchematicWriterV2.java} | 8 +- .../clipboard/io/FastSchematicWriterV3.java | 295 +++++++ .../internal/io/VarIntStreamIterator.java | 70 ++ .../core/jnbt/CompressedSchematicTag.java | 4 +- .../java/com/sk89q/jnbt/NBTInputStream.java | 2 +- .../clipboard/io/BuiltInClipboardFormat.java | 280 ++++-- .../extent/clipboard/io/ClipboardFormat.java | 25 +- .../clipboard/io/NBTSchematicReader.java | 4 + .../extent/clipboard/io/SchematicNbtUtil.java | 61 ++ .../clipboard/io/SpongeSchematicReader.java | 453 ---------- .../BuiltInClipboardShareDestinations.java | 11 +- .../clipboard/io/sponge/ReaderUtil.java | 283 ++++++ .../io/sponge/SpongeSchematicV1Reader.java | 134 +++ .../io/sponge/SpongeSchematicV2Reader.java | 144 +++ .../SpongeSchematicV2Writer.java} | 188 ++-- .../io/sponge/SpongeSchematicV3Reader.java | 168 ++++ .../io/sponge/SpongeSchematicV3Writer.java | 233 +++++ .../io/sponge/VersionedDataFixer.java | 47 + .../clipboard/io/sponge/WriterUtil.java | 91 ++ .../clipboard/io/sponge/package-info.java | 26 + .../internal/util/VarIntIterator.java | 81 ++ 25 files changed, 2815 insertions(+), 635 deletions(-) rename worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/{FastSchematicReader.java => FastSchematicReaderV2.java} (99%) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV3.java rename worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/{FastSchematicWriter.java => FastSchematicWriterV2.java} (98%) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV3.java create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/io/VarIntStreamIterator.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicNbtUtil.java delete mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/ReaderUtil.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV1Reader.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV2Reader.java rename worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/{SpongeSchematicWriter.java => sponge/SpongeSchematicV2Writer.java} (51%) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV3Reader.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV3Writer.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/VersionedDataFixer.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/WriterUtil.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/package-info.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/VarIntIterator.java diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java index 4b798981e..5c6f97d21 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquared/FaweDelegateSchematicHandler.java @@ -3,8 +3,8 @@ package com.fastasyncworldedit.bukkit.regions.plotsquared; import com.fastasyncworldedit.core.Fawe; import com.fastasyncworldedit.core.FaweAPI; import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicReader; -import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriter; +import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicReaderV2; +import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriterV2; import com.fastasyncworldedit.core.jnbt.CompressedCompoundTag; import com.fastasyncworldedit.core.jnbt.CompressedSchematicTag; import com.fastasyncworldedit.core.util.IOUtil; @@ -29,17 +29,19 @@ import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat; import com.sk89q.worldedit.extent.clipboard.io.MCEditSchematicReader; -import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicReader; +import com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV3Reader; import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import net.jpountz.lz4.LZ4BlockInputStream; import org.anarres.parallelgzip.ParallelGZIPOutputStream; import org.apache.logging.log4j.Logger; +import org.enginehub.linbus.stream.LinBinaryIO; import javax.annotation.Nonnull; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.DataInputStream; import java.io.EOFException; import java.io.File; import java.io.FileNotFoundException; @@ -182,7 +184,7 @@ public class FaweDelegateSchematicHandler { try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream( new BufferedOutputStream(new ParallelGZIPOutputStream(stream)))) { - new FastSchematicWriter(output).write(clipboard); + new FastSchematicWriterV2(output).write(clipboard); } } else { try (OutputStream stream = new FileOutputStream(tmp); @@ -239,7 +241,7 @@ public class FaweDelegateSchematicHandler { public Schematic getSchematic(@Nonnull InputStream is) { try { - FastSchematicReader schematicReader = new FastSchematicReader( + FastSchematicReaderV2 schematicReader = new FastSchematicReaderV2( new NBTInputStream(new BufferedInputStream(new GZIPInputStream(new BufferedInputStream(is))))); Clipboard clip = schematicReader.read(); return new Schematic(clip); @@ -249,8 +251,8 @@ public class FaweDelegateSchematicHandler { return null; } try { - SpongeSchematicReader schematicReader = - new SpongeSchematicReader(new NBTInputStream(new GZIPInputStream(is))); + SpongeSchematicV3Reader schematicReader = + new SpongeSchematicV3Reader(LinBinaryIO.read(new DataInputStream(new GZIPInputStream(is)))); Clipboard clip = schematicReader.read(); return new Schematic(clip); } catch (IOException e2) { diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/util/DoNotMiniseThese.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/util/DoNotMiniseThese.java index 9916a7d9f..28fb6d990 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/util/DoNotMiniseThese.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/util/DoNotMiniseThese.java @@ -1,6 +1,8 @@ package com.fastasyncworldedit.bukkit.util; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.io.FastBufferedInputStream; +import it.unimi.dsi.fastutil.io.FastBufferedOutputStream; import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; import it.unimi.dsi.fastutil.longs.LongArraySet; import it.unimi.dsi.fastutil.longs.LongIterator; @@ -19,5 +21,7 @@ final class DoNotMiniseThese { private final LongSet d = null; private final Int2ObjectMap e = null; private final Object2ObjectArrayMap f = null; + private final FastBufferedInputStream g = null; + private final FastBufferedOutputStream h = null; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV2.java similarity index 99% rename from worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java rename to worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV2.java index 71d139789..97fdd1f27 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReader.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV2.java @@ -53,7 +53,7 @@ import static com.google.common.base.Preconditions.checkNotNull; /** * Reads schematic files using the Sponge Schematic Specification. */ -public class FastSchematicReader extends NBTSchematicReader { +public class FastSchematicReaderV2 extends NBTSchematicReader { private static final Logger LOGGER = LogManagerCompat.getLogger(); private final NBTInputStream inputStream; @@ -88,7 +88,7 @@ public class FastSchematicReader extends NBTSchematicReader { * * @param inputStream the input stream to read from */ - public FastSchematicReader(NBTInputStream inputStream) { + public FastSchematicReaderV2(NBTInputStream inputStream) { checkNotNull(inputStream); this.inputStream = inputStream; this.fixer = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataFixer(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV3.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV3.java new file mode 100644 index 000000000..db98d2203 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV3.java @@ -0,0 +1,818 @@ +package com.fastasyncworldedit.core.extent.clipboard.io; + +import com.fastasyncworldedit.core.extent.clipboard.LinearClipboard; +import com.fastasyncworldedit.core.extent.clipboard.SimpleClipboard; +import com.fastasyncworldedit.core.internal.io.ResettableFileInputStream; +import com.fastasyncworldedit.core.internal.io.VarIntStreamIterator; +import com.fastasyncworldedit.core.math.MutableBlockVector3; +import com.fastasyncworldedit.core.util.IOUtil; +import com.fastasyncworldedit.core.util.MathMan; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.NBTConstants; +import com.sk89q.jnbt.NBTInputStream; +import com.sk89q.jnbt.NBTOutputStream; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader; +import com.sk89q.worldedit.extent.clipboard.io.sponge.ReaderUtil; +import com.sk89q.worldedit.extent.clipboard.io.sponge.VersionedDataFixer; +import com.sk89q.worldedit.internal.util.LogManagerCompat; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.util.concurrency.LazyReference; +import com.sk89q.worldedit.world.DataFixer; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.biome.BiomeTypes; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockTypes; +import com.sk89q.worldedit.world.block.BlockTypesCache; +import com.sk89q.worldedit.world.entity.EntityType; +import it.unimi.dsi.fastutil.io.FastBufferedInputStream; +import it.unimi.dsi.fastutil.io.FastBufferedOutputStream; +import net.jpountz.lz4.LZ4BlockInputStream; +import net.jpountz.lz4.LZ4BlockOutputStream; +import org.apache.logging.log4j.Logger; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.jetbrains.annotations.ApiStatus; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.OptionalInt; +import java.util.Set; +import java.util.UUID; +import java.util.function.BooleanSupplier; +import java.util.function.Function; +import java.util.zip.GZIPInputStream; + +/** + * ClipboardReader for the Sponge Schematic Format v3. + * Not necessarily much faster than {@link com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV3Reader}, but uses a + * stream based approach to keep the memory overhead minimal (especially in larger schematics) + * + * @since TODO + */ +@SuppressWarnings("removal") // JNBT +public class FastSchematicReaderV3 implements ClipboardReader { + + private static final Logger LOGGER = LogManagerCompat.getLogger(); + private static final byte CACHE_IDENTIFIER_END = 0x00; + private static final byte CACHE_IDENTIFIER_BLOCK = 0x01; + private static final byte CACHE_IDENTIFIER_BIOMES = 0x02; + private static final byte CACHE_IDENTIFIER_ENTITIES = 0x03; + private static final byte CACHE_IDENTIFIER_BLOCK_TILE_ENTITIES = 0x04; + + private final InputStream parentStream; + private final MutableBlockVector3 dimensions = MutableBlockVector3.at(0, 0, 0); + private final Set remainingTags; + + private DataInputStream dataInputStream; + private NBTInputStream nbtInputStream; + + private VersionedDataFixer dataFixer; + private BlockVector3 offset; + private BlockState[] blockPalette; + private BiomeType[] biomePalette; + private int dataVersion = -1; + + // Only used if the InputStream is not file based (and therefor does not support resets based on FileChannels) + // and the file is unordered + // Data and Palette cache is separated, as the data requires a fully populated palette - and the order is not guaranteed + private byte[] dataCache; + private byte[] paletteCache; + private OutputStream dataCacheWriter; + private OutputStream paletteCacheWriter; + + + public FastSchematicReaderV3(@NonNull InputStream stream) { + Objects.requireNonNull(stream, "stream"); + if (stream instanceof ResettableFileInputStream) { + stream.mark(Integer.MAX_VALUE); + this.remainingTags = new HashSet<>(); + } else if (stream instanceof FileInputStream fileInputStream) { + stream = new ResettableFileInputStream(fileInputStream); + stream.mark(Integer.MAX_VALUE); + this.remainingTags = new HashSet<>(); + } else if (stream instanceof FastBufferedInputStream || stream instanceof BufferedInputStream) { + this.remainingTags = null; + } else { + stream = new FastBufferedInputStream(stream); + this.remainingTags = null; + } + this.parentStream = stream; + } + + @Override + public Clipboard read(final UUID uuid, final Function createOutput) throws IOException { + Clipboard clipboard = null; + + this.setSubStreams(); + skipHeader(this.dataInputStream); + + byte type; + String tag; + while ((type = dataInputStream.readByte()) != NBTConstants.TYPE_END) { + tag = this.dataInputStream.readUTF(); + switch (tag) { + case "DataVersion" -> { + final Platform platform = + WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING); + this.dataVersion = this.dataInputStream.readInt(); + this.dataFixer = ReaderUtil.getVersionedDataFixer(this.dataVersion, platform, platform.getDataVersion()); + } + case "Offset" -> { + this.dataInputStream.skipNBytes(4); // Array Length field (4 byte int) + this.offset = BlockVector3.at( + this.dataInputStream.readInt(), + this.dataInputStream.readInt(), + this.dataInputStream.readInt() + ); + } + case "Width" -> this.dimensions.mutX(this.dataInputStream.readShort() & 0xFFFF); + case "Height" -> this.dimensions.mutY(this.dataInputStream.readShort() & 0xFFFF); + case "Length" -> this.dimensions.mutZ(this.dataInputStream.readShort() & 0xFFFF); + case "Blocks" -> readBlocks(clipboard); + case "Biomes" -> readBiomes(clipboard); + case "Entities" -> readEntities(clipboard); + default -> this.nbtInputStream.readTagPayloadLazy(type, 0); + } + if (clipboard == null && this.areDimensionsAvailable()) { + clipboard = createOutput.apply(this.dimensions); + } + } + + if (clipboard == null) { + throw new IOException("Invalid schematic - missing dimensions"); + } + if (dataFixer == null) { + throw new IOException("Invalid schematic - missing DataVersion"); + } + + if (this.supportsReset() && !remainingTags.isEmpty()) { + readRemainingDataReset(clipboard); + } else if (this.dataCacheWriter != null || this.paletteCacheWriter != null) { + readRemainingDataCache(clipboard); + } + + clipboard.setOrigin(this.offset.multiply(-1)); + if (clipboard instanceof SimpleClipboard simpleClipboard && !this.offset.equals(BlockVector3.ZERO)) { + clipboard = new BlockArrayClipboard(simpleClipboard, this.offset); + } + return clipboard; + } + + + /** + * Reads all locally cached data (due to reset not being available) and applies them to the clipboard. + *

    + * Firstly, closes all cache writers (which adds the END identifier to each and fills the cache byte arrays on this instance) + * If required, creates all missing palettes first (as needed by all remaining data). + * At last writes all missing data (block states, tile entities, biomes, entities). + * + * @param clipboard The clipboard to write into. + * @throws IOException on I/O error. + */ + private void readRemainingDataCache(Clipboard clipboard) throws IOException { + byte identifier; + if (this.paletteCacheWriter != null) { + this.paletteCacheWriter.close(); + } + if (this.dataCacheWriter != null) { + this.dataCacheWriter.close(); + } + if (this.paletteCache != null) { + try (final DataInputStream cacheStream = new DataInputStream(new FastBufferedInputStream( + new LZ4BlockInputStream(new FastBufferedInputStream(new ByteArrayInputStream(this.paletteCache)))))) { + while ((identifier = cacheStream.readByte()) != CACHE_IDENTIFIER_END) { + if (identifier == CACHE_IDENTIFIER_BLOCK) { + this.readPaletteMap(cacheStream, this.provideBlockPaletteInitializer()); + continue; + } + if (identifier == CACHE_IDENTIFIER_BIOMES) { + this.readPaletteMap(cacheStream, this.provideBiomePaletteInitializer()); + continue; + } + throw new IOException("invalid cache state - got identifier: 0x" + identifier); + } + } + } + try (final DataInputStream cacheStream = new DataInputStream(new FastBufferedInputStream( + new LZ4BlockInputStream(new FastBufferedInputStream(new ByteArrayInputStream(this.dataCache))))); + final NBTInputStream cacheNbtIn = new NBTInputStream(cacheStream)) { + while ((identifier = cacheStream.readByte()) != CACHE_IDENTIFIER_END) { + switch (identifier) { + case CACHE_IDENTIFIER_BLOCK -> this.readPaletteData(cacheStream, this.getBlockWriter(clipboard)); + case CACHE_IDENTIFIER_BIOMES -> this.readPaletteData(cacheStream, this.getBiomeWriter(clipboard)); + case CACHE_IDENTIFIER_ENTITIES -> { + cacheStream.skipNBytes(1); // list child type (TAG_Compound) + this.readEntityContainers( + cacheStream, + cacheNbtIn, + DataFixer.FixTypes.ENTITY, + this.provideEntityTransformer(clipboard) + ); + } + case CACHE_IDENTIFIER_BLOCK_TILE_ENTITIES -> { + cacheStream.skipNBytes(1); // list child type (TAG_Compound) + this.readEntityContainers( + cacheStream, + cacheNbtIn, + DataFixer.FixTypes.BLOCK_ENTITY, + this.provideTileEntityTransformer(clipboard) + ); + } + default -> throw new IOException("invalid cache state - got identifier: 0x" + identifier); + } + } + } + } + + /** + * Reset the main stream of this clipboard and reads all remaining data that could not be read or fixed yet. + * Might need two iterations if the DataVersion tag is after the Blocks tag while the Palette inside the Blocks tag is not + * at the first position. + * + * @param clipboard The clipboard to write into. + * @throws IOException on I/O error. + */ + private void readRemainingDataReset(Clipboard clipboard) throws IOException { + byte type; + String tag; + outer: + while (!this.remainingTags.isEmpty()) { + this.reset(); + skipHeader(this.dataInputStream); + while ((type = dataInputStream.readByte()) != NBTConstants.TYPE_END) { + tag = dataInputStream.readUTF(); + byte b = tag.equals("Blocks") ? CACHE_IDENTIFIER_BLOCK : + tag.equals("Biomes") ? CACHE_IDENTIFIER_BIOMES : + tag.equals("Entities") ? CACHE_IDENTIFIER_ENTITIES : + CACHE_IDENTIFIER_END; + if (!this.remainingTags.remove(b)) { + this.nbtInputStream.readTagPayloadLazy(type, 0); + continue; + } + switch (tag) { + case "Blocks" -> readBlocks(clipboard); + case "Biomes" -> readBiomes(clipboard); + case "Entities" -> readEntities(clipboard); + default -> this.nbtInputStream.readTagPayloadLazy(type, 0); // Should never happen, but just in case + } + if (this.remainingTags.isEmpty()) { + break outer; + } + } + } + } + + /** + * {@inheritDoc} + *

    + * Requires {@link #read()}, {@link #read(UUID)} or {@link #read(UUID, Function)} to be called before. + */ + @Override + public OptionalInt getDataVersion() { + return this.dataVersion > -1 ? OptionalInt.of(this.dataVersion) : OptionalInt.empty(); + } + + private void readBlocks(Clipboard target) throws IOException { + this.blockPalette = new BlockState[BlockTypesCache.states.length]; + readPalette( + target != null, + CACHE_IDENTIFIER_BLOCK, + () -> this.blockPalette[0] != null, + this.provideBlockPaletteInitializer(), + this.getBlockWriter(target), + (type, tag) -> { + if (!tag.equals("BlockEntities")) { + try { + this.nbtInputStream.readTagPayloadLazy(NBTConstants.TYPE_LIST, 0); + } catch (IOException e) { + LOGGER.error("Failed to skip additional tag", e); + } + return; + } + try { + this.readTileEntities(target); + } catch (IOException e) { + LOGGER.warn("Failed to read tile entities", e); + } + } + ); + } + + private void readBiomes(Clipboard target) throws IOException { + this.biomePalette = new BiomeType[BiomeType.REGISTRY.size()]; + readPalette( + target != null, + CACHE_IDENTIFIER_BIOMES, + () -> this.biomePalette[0] != null, + this.provideBiomePaletteInitializer(), + this.getBiomeWriter(target), + (type, tag) -> { + try { + this.nbtInputStream.readTagPayloadLazy(type, 0); + } catch (IOException e) { + LOGGER.error("Failed to skip additional tag in biome container: {}", tag, e); + } + } + ); + } + + private void readEntities(@Nullable Clipboard target) throws IOException { + if (target == null || this.dataFixer == null) { + if (supportsReset()) { + this.remainingTags.add(CACHE_IDENTIFIER_ENTITIES); + this.nbtInputStream.readTagPayloadLazy(NBTConstants.TYPE_LIST, 0); + return; + } + // Easier than streaming for now + final NBTOutputStream cacheStream = new NBTOutputStream(this.getDataCacheWriter()); + cacheStream.writeByte(CACHE_IDENTIFIER_ENTITIES); + cacheStream.writeTagPayload(this.nbtInputStream.readTagPayload(NBTConstants.TYPE_LIST, 0)); + return; + } + if (this.dataInputStream.read() != NBTConstants.TYPE_COMPOUND) { + throw new IOException("Expected a compound block for entity"); + } + this.readEntityContainers( + this.dataInputStream, this.nbtInputStream, DataFixer.FixTypes.ENTITY, this.provideEntityTransformer(target) + ); + } + + private void readTileEntities(Clipboard target) throws IOException { + if (target == null || this.dataFixer == null) { + if (supportsReset()) { + this.remainingTags.add(CACHE_IDENTIFIER_BLOCK); // use block identifier, as this method will be called by + // readBlocks again + this.nbtInputStream.readTagPayloadLazy(NBTConstants.TYPE_LIST, 0); + return; + } + // Easier than streaming for now + final NBTOutputStream cacheStream = new NBTOutputStream(this.getDataCacheWriter()); + cacheStream.writeByte(CACHE_IDENTIFIER_BLOCK_TILE_ENTITIES); + cacheStream.writeTagPayload(this.nbtInputStream.readTagPayload(NBTConstants.TYPE_LIST, 0)); + return; + } + if (this.dataInputStream.read() != NBTConstants.TYPE_COMPOUND) { + throw new IOException("Expected a compound block for tile entity"); + } + this.readEntityContainers( + this.dataInputStream, + this.nbtInputStream, + DataFixer.FixTypes.BLOCK_ENTITY, + this.provideTileEntityTransformer(target) + ); + } + + private void readEntityContainers( + DataInputStream stream, + NBTInputStream nbtStream, + DataFixer.FixType fixType, + EntityTransformer transformer + ) throws IOException { + double x, y, z; + LinCompoundTag tag; + String id; + byte type; + int count = stream.readInt(); + while (count-- > 0) { + x = -1; + y = -1; + z = -1; + tag = null; + id = null; + while ((type = stream.readByte()) != NBTConstants.TYPE_END) { + switch (type) { + // Depending on the type of entity container (tile vs "normal") the pos consists of either doubles or ints + case NBTConstants.TYPE_INT_ARRAY -> { + if (!stream.readUTF().equals("Pos")) { + throw new IOException("Expected INT_ARRAY tag to be Pos"); + } + stream.skipNBytes(4); // count of following ints - for pos = 3 + x = stream.readInt(); + y = stream.readInt(); + z = stream.readInt(); + } + case NBTConstants.TYPE_LIST -> { + if (!stream.readUTF().equals("Pos")) { + throw new IOException("Expected LIST tag to be Pos"); + } + if (stream.readByte() != NBTConstants.TYPE_DOUBLE) { + throw new IOException("Expected LIST Pos tag to contain DOUBLE"); + } + stream.skipNBytes(4); // count of following doubles - for pos = 3 + x = stream.readDouble(); + y = stream.readDouble(); + z = stream.readDouble(); + } + case NBTConstants.TYPE_STRING -> { + if (!stream.readUTF().equals("Id")) { + throw new IOException("Expected STRING tag to be Id"); + } + id = stream.readUTF(); + } + case NBTConstants.TYPE_COMPOUND -> { + if (!stream.readUTF().equals("Data")) { + throw new IOException("Expected COMPOUND tag to be Data"); + } + if (!(nbtStream.readTagPayload(NBTConstants.TYPE_COMPOUND, 0).toLinTag() instanceof LinCompoundTag lin)) { + throw new IOException("Data tag could not be read into LinCompoundTag"); + } + tag = lin; + } + default -> throw new IOException("Unexpected tag in compound: " + type); + } + } + if (id == null) { + throw new IOException("Missing Id tag in compound"); + } + if (x < 0 || y < 0 || z < 0) { + throw new IOException("Missing position for entity " + id); + } + if (tag == null) { + transformer.transform(x, y, z, id, LinCompoundTag.of(Map.of())); + continue; + } + tag = this.dataFixer.fixUp(fixType, tag); + if (tag == null) { + LOGGER.warn("Failed to fix-up entity for {} @ {},{},{} - skipping", id, x, y, z); + continue; + } + transformer.transform(x, y, z, id, tag); + } + } + + /** + * The `Palette` tag is required first, as that contains the information of the actual palette size. + * Keeping the whole Data block in memory - which *could* be compressed - is just not it + * + * @param paletteInitializer Invoked for each 'Palette' entry using the actual palette value (e.g. block state) + index + * @param paletteDataApplier Invoked for each 'Data' entry using the data index and the palette index at the data index + */ + private void readPalette( + boolean hasClipboard, + byte paletteType, + BooleanSupplier paletteAlreadyInitialized, + PaletteInitializer paletteInitializer, + PaletteDataApplier paletteDataApplier, + AdditionalTagConsumer additionalTag + ) throws IOException { + boolean hasPalette = paletteAlreadyInitialized.getAsBoolean(); + byte type; + String tag; + while ((type = this.dataInputStream.readByte()) != NBTConstants.TYPE_END) { + tag = this.dataInputStream.readUTF(); + if (tag.equals("Palette")) { + if (hasPalette) { + // Skip palette, as already exists + this.nbtInputStream.readTagPayloadLazy(NBTConstants.TYPE_COMPOUND, 0); + continue; + } + if (!this.readPaletteMap(this.dataInputStream, paletteInitializer)) { + if (this.supportsReset()) { + // Couldn't read - skip palette for now + this.remainingTags.add(paletteType); + this.nbtInputStream.readTagPayloadLazy(NBTConstants.TYPE_COMPOUND, 0); + continue; + } + // Reset not possible, write into cache + final NBTOutputStream cacheWriter = new NBTOutputStream(this.getPaletteCacheWriter()); + cacheWriter.write(paletteType); + cacheWriter.writeTagPayload(this.nbtInputStream.readTagPayload(NBTConstants.TYPE_COMPOUND, 0)); + continue; + } + hasPalette = true; + continue; + } + if (tag.equals("Data")) { + // No palette or dimensions are yet available + if (!hasPalette || this.dataFixer == null || !hasClipboard) { + if (this.supportsReset()) { + this.remainingTags.add(paletteType); + this.nbtInputStream.readTagPayloadLazy(NBTConstants.TYPE_BYTE_ARRAY, 0); + continue; + } + // Reset not possible, write into cache + int byteLen = this.dataInputStream.readInt(); + final DataOutputStream cacheWriter = new DataOutputStream(this.getDataCacheWriter()); + cacheWriter.write(paletteType); + cacheWriter.writeInt(byteLen); + IOUtil.copy(this.dataInputStream, cacheWriter, byteLen); + continue; + } + this.readPaletteData(this.dataInputStream, paletteDataApplier); + continue; + } + additionalTag.accept(type, tag); + } + } + + private void readPaletteData(DataInputStream stream, PaletteDataApplier applier) throws IOException { + int length = stream.readInt(); + // Write data into clipboard + int i = 0; + if (needsVarIntReading(length)) { + for (var iter = new VarIntStreamIterator(stream, length); iter.hasNext(); i++) { + applier.apply(i, (char) iter.nextInt()); + } + return; + } + while (i < length) { + applier.apply(i++, (char) stream.readUnsignedByte()); + } + } + + /** + * Reads the CompoundTag containing the palette mapping ({@code index: value}) and passes each entry to the + * {@link PaletteInitializer}. + *

    + * This method expects that the identifier ({@link NBTConstants#TYPE_COMPOUND}) is already consumed from the stream. + * + * @param stream The stream to read the data from. + * @param initializer The initializer called for each entry with its index and backed value. + * @return {@code true} if the mapping could be read, {@code false} otherwise (e.g. DataFixer is not yet available). + * @throws IOException on I/O error. + */ + private boolean readPaletteMap(DataInputStream stream, PaletteInitializer initializer) throws IOException { + if (this.dataFixer == null) { + return false; + } + while (stream.readByte() != NBTConstants.TYPE_END) { + String value = stream.readUTF(); + char index = (char) stream.readInt(); + initializer.initialize(index, value); + } + return true; + } + + private void indexToPosition(int index, PositionConsumer supplier) { + int y = index / (dimensions.x() * dimensions.z()); + int remainder = index - (y * dimensions.x() * dimensions.z()); + int z = remainder / dimensions.x(); + int x = remainder - z * dimensions.x(); + supplier.accept(x, y, z); + } + + private PaletteDataApplier getBlockWriter(Clipboard target) { + if (target instanceof LinearClipboard linearClipboard) { + return (index, ordinal) -> linearClipboard.setBlock(index, this.blockPalette[ordinal]); + } + return (index, ordinal) -> indexToPosition(index, (x, y, z) -> target.setBlock(x, y, z, this.blockPalette[ordinal])); + } + + private PaletteDataApplier getBiomeWriter(Clipboard target) { + return (index, ordinal) -> indexToPosition(index, (x, y, z) -> target.setBiome(x, y, z, this.biomePalette[ordinal])); + } + + private PaletteInitializer provideBlockPaletteInitializer() { + return (index, value) -> { + if (this.dataFixer == null) { + throw new IllegalStateException("Can't read block palette map if DataFixer is not yet available"); + } + value = dataFixer.fixUp(DataFixer.FixTypes.BLOCK_STATE, value); + try { + this.blockPalette[index] = BlockState.get(value); + } catch (InputParseException e) { + LOGGER.warn("Invalid BlockState in palette: {}. Block will be replaced with air.", value); + this.blockPalette[index] = BlockTypes.AIR.getDefaultState(); + } + }; + } + + private PaletteInitializer provideBiomePaletteInitializer() { + return (index, value) -> { + if (this.dataFixer == null) { + throw new IllegalStateException("Can't read biome palette map if DataFixer is not yet available"); + } + value = dataFixer.fixUp(DataFixer.FixTypes.BIOME, value); + BiomeType biomeType = BiomeTypes.get(value); + if (biomeType == null) { + biomeType = BiomeTypes.PLAINS; + LOGGER.warn("Invalid biome type in palette: {}. Biome will be replaced with plains.", value); + } + this.biomePalette[index] = biomeType; + }; + } + + private EntityTransformer provideEntityTransformer(Clipboard clipboard) { + return (x, y, z, id, tag) -> { + EntityType type = EntityType.REGISTRY.get(id); + if (type == null) { + LOGGER.warn("Invalid entity id: {} - skipping", id); + return; + } + clipboard.createEntity( + new Location(clipboard, Location.at(x, y, z).add(clipboard.getMinimumPoint().toVector3())), + new BaseEntity(type, LazyReference.computed(tag)) + ); + }; + } + + private EntityTransformer provideTileEntityTransformer(Clipboard clipboard) { + //noinspection deprecation + return (x, y, z, id, tag) -> clipboard.setTile( + MathMan.roundInt(x + clipboard.getMinimumPoint().x()), + MathMan.roundInt(y + clipboard.getMinimumPoint().y()), + MathMan.roundInt(z + clipboard.getMinimumPoint().z()), + new CompoundTag(tag) + ); + } + + /** + * @return {@code true} if {@code Width}, {@code Length} and {@code Height} are already read from the stream + */ + private boolean areDimensionsAvailable() { + return this.dimensions.x() != 0 && this.dimensions.y() != 0 && this.dimensions.z() != 0; + } + + /** + * Closes this reader instance and all underlying resources. + * + * @throws IOException on I/O error. + */ + @Override + public void close() throws IOException { + parentStream.close(); // closes all underlying resources implicitly + } + + /** + * Resets the main stream to the previously marked position ({@code 0}), if supported (see {@link #supportsReset()}). + * If the stream is reset, the sub streams (for DataInput and NBT) are re-created to respect the new position. + * + * @throws IOException on I/O error. + */ + private void reset() throws IOException { + if (this.supportsReset()) { + this.parentStream.reset(); + this.parentStream.mark(Integer.MAX_VALUE); + this.setSubStreams(); + } + } + + /** + * @return {@code true} if the stream used while instantiating the reader supports resets (without memory overhead). + */ + private boolean supportsReset() { + return this.remainingTags != null; + } + + /** + * Overwrites the DataInput- and NBT-InputStreams (e.g. when the marker of the backed stream updated). + * + * @throws IOException on I/O error. + */ + private void setSubStreams() throws IOException { + final FastBufferedInputStream buffer = new FastBufferedInputStream(new GZIPInputStream(this.parentStream)); + this.dataInputStream = new DataInputStream(buffer); + this.nbtInputStream = new NBTInputStream(buffer); + } + + /** + * Creates a new cache writer for non-palette data, if none exists yet. + * Returns either the already created or new one. + * + * @return the output stream for non-palette cache data. + */ + private OutputStream getDataCacheWriter() { + if (this.dataCacheWriter == null) { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(512); + this.dataCacheWriter = new FastBufferedOutputStream(new LZ4BlockOutputStream(byteArrayOutputStream)) { + @Override + public void close() throws IOException { + this.write(CACHE_IDENTIFIER_END); + super.close(); + FastSchematicReaderV3.this.dataCache = byteArrayOutputStream.toByteArray(); + } + }; + } + return this.dataCacheWriter; + } + + /** + * Creates a new cache writer for palette data, if none exists yet. + * Returns either the already created or new one. + * + * @return the output stream for palette cache data. + */ + private OutputStream getPaletteCacheWriter() { + if (this.paletteCacheWriter == null) { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(256); + this.paletteCacheWriter = new FastBufferedOutputStream(new LZ4BlockOutputStream(byteArrayOutputStream)) { + @Override + public void close() throws IOException { + this.write(CACHE_IDENTIFIER_END); + super.close(); + FastSchematicReaderV3.this.paletteCache = byteArrayOutputStream.toByteArray(); + } + }; + } + return this.paletteCacheWriter; + } + + private boolean needsVarIntReading(int byteArrayLength) { + return byteArrayLength > this.dimensions.x() * this.dimensions.y() * this.dimensions.z(); + } + + /** + * Skips the schematic header including the root compound (empty name) and the root's child compound ("Schematic") + * + * @param dataInputStream The stream containing the schematic data to skip + * @throws IOException on I/O error + */ + private static void skipHeader(DataInputStream dataInputStream) throws IOException { + dataInputStream.skipNBytes(1 + 2); // 1 Byte = TAG_Compound, 2 Bytes = Short (Length of tag name = "") + dataInputStream.skipNBytes(1 + 2 + 9); // as above + 9 bytes = "Schematic" + } + + @ApiStatus.Internal + @FunctionalInterface + private interface PositionConsumer { + + /** + * Called with block location coordinates. + * + * @param x the x coordinate. + * @param y the y coordinate. + * @param z the z coordinate. + */ + void accept(int x, int y, int z); + + } + + @ApiStatus.Internal + @FunctionalInterface + private interface EntityTransformer { + + /** + * Called for each entity from the Schematics {@code Entities} compound list. + * + * @param x the relative x coordinate of the entity. + * @param y the relative y coordinate of the entity. + * @param z the relative z coordinate of the entity. + * @param id the entity id as a resource location (e.g. {@code minecraft:sheep}). + * @param tag the - already fixed, if required - nbt data of the entity. + */ + void transform(double x, double y, double z, String id, LinCompoundTag tag); + + } + + @ApiStatus.Internal + @FunctionalInterface + private interface PaletteInitializer { + + /** + * Called for each palette entry (the mapping part, not data). + * + * @param index the index of the entry, as used in the Data byte array. + * @param value the value for this entry (either biome type as resource location or the block state as a string). + */ + void initialize(char index, String value); + + } + + @ApiStatus.Internal + @FunctionalInterface + private interface PaletteDataApplier { + + /** + * Called for each palette data entry (not the mapping part, but the var-int byte array). + * + * @param index The index of this data entry (due to var-int behaviour not necessarily the index in the data byte array). + * @param ordinal The ordinal of this entry as defined in the palette mapping. + */ + void apply(int index, char ordinal); + + } + + @ApiStatus.Internal + @FunctionalInterface + private interface AdditionalTagConsumer { + + /** + * Called for each unknown nbt tag. + * + * @param type The type of the tag (as defined by the constants in {@link NBTConstants}). + * @param name The name of the tag. + */ + void accept(byte type, String name); + + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV2.java similarity index 98% rename from worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java rename to worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV2.java index ac86fb249..3bd302876 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV2.java @@ -48,9 +48,9 @@ import static com.google.common.base.Preconditions.checkNotNull; /** * Writes schematic files using the Sponge schematic format. */ -public class FastSchematicWriter implements ClipboardWriter { +public class FastSchematicWriterV2 implements ClipboardWriter { - private static final int CURRENT_VERSION = 2; + public static final int CURRENT_VERSION = 2; private static final int MAX_SIZE = Short.MAX_VALUE - Short.MIN_VALUE; private final NBTOutputStream outputStream; @@ -61,7 +61,7 @@ public class FastSchematicWriter implements ClipboardWriter { * * @param outputStream the output stream to write to */ - public FastSchematicWriter(NBTOutputStream outputStream) { + public FastSchematicWriterV2(NBTOutputStream outputStream) { checkNotNull(outputStream); this.outputStream = outputStream; } @@ -103,11 +103,11 @@ public class FastSchematicWriter implements ClipboardWriter { final DataOutput rawStream = outputStream.getOutputStream(); outputStream.writeLazyCompoundTag("Schematic", out -> { + out.writeNamedTag("Version", CURRENT_VERSION); out.writeNamedTag( "DataVersion", WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion() ); - out.writeNamedTag("Version", CURRENT_VERSION); out.writeNamedTag("Width", (short) width); out.writeNamedTag("Height", (short) height); out.writeNamedTag("Length", (short) length); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV3.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV3.java new file mode 100644 index 000000000..e00839eb0 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriterV3.java @@ -0,0 +1,295 @@ +package com.fastasyncworldedit.core.extent.clipboard.io; + +import com.fastasyncworldedit.core.function.visitor.Order; +import com.fastasyncworldedit.core.util.IOUtil; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.NBTConstants; +import com.sk89q.jnbt.NBTOutputStream; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockStateHolder; +import com.sk89q.worldedit.world.block.BlockTypesCache; +import net.jpountz.lz4.LZ4BlockInputStream; +import net.jpountz.lz4.LZ4BlockOutputStream; +import org.enginehub.linbus.tree.LinCompoundTag; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.function.Function; + +/** + * Faster, stream-based implementation of {@link com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV3Writer} for + * writing schematics conforming the sponge schematic v3 format. + * + * @since TODO + */ +@SuppressWarnings("removal") // Yes, JNBT is deprecated - we know +public class FastSchematicWriterV3 implements ClipboardWriter { + + public static final int CURRENT_VERSION = 3; + + private static final int MAX_SIZE = Short.MAX_VALUE - Short.MIN_VALUE; + private final NBTOutputStream outputStream; + + + public FastSchematicWriterV3(final NBTOutputStream outputStream) { + this.outputStream = Objects.requireNonNull(outputStream, "outputStream"); + } + + @Override + public void write(final Clipboard clipboard) throws IOException { + clipboard.flush(); + + // Validate dimensions before starting to write into stream + final Region region = clipboard.getRegion(); + if (region.getWidth() > MAX_SIZE) { + throw new IllegalArgumentException("Region width too large for schematic: " + region.getWidth()); + } + if (region.getHeight() > MAX_SIZE) { + throw new IllegalArgumentException("Region height too large for schematic: " + region.getHeight()); + } + if (region.getLength() > MAX_SIZE) { + throw new IllegalArgumentException("Region length too large for schematic: " + region.getLength()); + } + + this.outputStream.writeLazyCompoundTag( + "", root -> root.writeLazyCompoundTag("Schematic", out -> this.write2(out, clipboard)) + ); + } + + private void write2(NBTOutputStream schematic, Clipboard clipboard) throws IOException { + final Region region = clipboard.getRegion(); + final BlockVector3 origin = clipboard.getOrigin(); + final BlockVector3 min = clipboard.getMinimumPoint(); + final BlockVector3 offset = min.subtract(origin); + + schematic.writeNamedTag("Version", CURRENT_VERSION); + schematic.writeNamedTag( + "DataVersion", + WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion() + ); + schematic.writeLazyCompoundTag("Metadata", out -> this.writeMetadata(out, clipboard)); + + schematic.writeNamedTag("Width", (short) region.getWidth()); + schematic.writeNamedTag("Height", (short) region.getHeight()); + schematic.writeNamedTag("Length", (short) region.getLength()); + + schematic.writeNamedTag("Offset", new int[]{ + offset.x(), offset.y(), offset.z() + }); + + schematic.writeLazyCompoundTag("Blocks", out -> this.writeBlocks(out, clipboard)); + if (clipboard.hasBiomes()) { + schematic.writeLazyCompoundTag("Biomes", out -> this.writeBiomes(out, clipboard)); + } + // Some clipboards have quite heavy operations on the getEntities method - only call once + List entities; + if (!(entities = clipboard.getEntities()).isEmpty()) { + schematic.writeNamedTagName("Entities", NBTConstants.TYPE_LIST); + schematic.write(NBTConstants.TYPE_COMPOUND); + schematic.writeInt(entities.size()); + for (final Entity entity : entities) { + this.writeEntity(schematic, clipboard, entity); + } + } + } + + private void writeBlocks(NBTOutputStream blocks, Clipboard clipboard) throws IOException { + final int[] tiles = new int[]{0}; + final ByteArrayOutputStream tileBytes = new ByteArrayOutputStream(); + try (LZ4BlockOutputStream lz4Stream = new LZ4BlockOutputStream(tileBytes); + NBTOutputStream tileOut = new NBTOutputStream(lz4Stream)) { + this.writePalette( + blocks, + BlockTypesCache.states.length, + pos -> { + BaseBlock block = pos.getFullBlock(clipboard); + LinCompoundTag tag; + if ((tag = block.getNbt()) != null) { + tiles[0]++; + try { + tileOut.writeNamedTag("Id", block.getNbtId()); + tileOut.writeNamedTag("Pos", new int[]{ + pos.x() - clipboard.getMinimumPoint().x(), + pos.y() - clipboard.getMinimumPoint().y(), + pos.z() - clipboard.getMinimumPoint().z() + }); + //noinspection deprecation + tileOut.writeNamedTag("Data", new CompoundTag(tag)); + tileOut.write(NBTConstants.TYPE_END); + } catch (IOException e) { + throw new RuntimeException("Failed to write tile data", e); + } + } + return block; + }, + block -> { + char ordinal = block.getOrdinalChar(); + if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { + ordinal = BlockTypesCache.ReservedIDs.AIR; + } + return ordinal; + }, + BlockStateHolder::getAsString, + clipboard + ); + lz4Stream.finish(); + } finally { + // Write Tiles + if (tiles[0] > 0) { + blocks.writeNamedTagName("BlockEntities", NBTConstants.TYPE_LIST); + blocks.write(NBTConstants.TYPE_COMPOUND); + blocks.writeInt(tiles[0]); + // Decompress cached data again + try (LZ4BlockInputStream reader = new LZ4BlockInputStream(new ByteArrayInputStream(tileBytes.toByteArray()))) { + IOUtil.copy(reader, blocks.getOutputStream()); + } + } + } + } + + private void writeBiomes(NBTOutputStream biomes, Clipboard clipboard) throws IOException { + this.writePalette( + biomes, BiomeType.REGISTRY.size(), + pos -> pos.getBiome(clipboard), + biome -> (char) biome.getInternalId(), + BiomeType::id, + clipboard + ); + } + + private void writeEntity(NBTOutputStream out, Clipboard clipboard, Entity entity) throws IOException { + final BaseEntity state = entity.getState(); + if (state == null) { + throw new IOException("Entity has no state"); + } + out.writeNamedTag("Id", state.getType().id()); + + out.writeNamedTagName("Pos", NBTConstants.TYPE_LIST); + out.write(NBTConstants.TYPE_DOUBLE); + out.writeInt(3); + out.writeDouble(entity.getLocation().x() - clipboard.getMinimumPoint().x()); + out.writeDouble(entity.getLocation().y() - clipboard.getMinimumPoint().y()); + out.writeDouble(entity.getLocation().z() - clipboard.getMinimumPoint().z()); + + out.writeLazyCompoundTag("Data", data -> { + //noinspection deprecation + CompoundTag nbt = state.getNbtData(); + if (nbt != null) { + nbt.getValue().forEach((s, tag) -> { + if (s.equals("id") || s.equals("Rotation")) { + return; + } + try { + data.writeNamedTag(s, tag); + } catch (IOException e) { + throw new RuntimeException("failed to write entity data", e); + } + }); + } + + // Write rotation list + data.writeNamedTagName("Rotation", NBTConstants.TYPE_LIST); + data.write(NBTConstants.TYPE_FLOAT); + data.writeInt(2); + data.writeFloat(entity.getLocation().getYaw()); + data.writeFloat(entity.getLocation().getPitch()); + }); + + out.write(NBTConstants.TYPE_END); // End the compound + } + + private void writePalette( + NBTOutputStream out, int capacity, + Function objectResolver, + Function ordinalResolver, + Function paletteEntryResolver, + Clipboard clipboard + ) throws IOException { + int dataBytesUsed = 0; + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + try (LZ4BlockOutputStream dataOut = new LZ4BlockOutputStream(bytes)) { + int index = 0; + char[] palette = new char[capacity]; + Arrays.fill(palette, Character.MAX_VALUE); + final Iterator iterator = clipboard.iterator(Order.YZX); + // Start Palette tag + out.writeNamedTagName("Palette", NBTConstants.TYPE_COMPOUND); + while (iterator.hasNext()) { + BlockVector3 pos = iterator.next(); + T obj = objectResolver.apply(pos); + char ordinal = ordinalResolver.apply(obj); + char value = palette[ordinal]; + if (value == Character.MAX_VALUE) { + palette[ordinal] = value = (char) index++; + if (index >= palette.length) { + throw new IOException("insufficient palette capacity: " + palette.length + ", index: " + index); + } + out.writeNamedTag(paletteEntryResolver.apply(obj), value); + } + if ((value & -128) != 0) { + dataBytesUsed++; + dataOut.write(value & 127 | 128); + value >>>= 7; + } + dataOut.write(value); + dataBytesUsed++; + } + // End Palette tag + out.write(NBTConstants.TYPE_END); + dataOut.finish(); + } finally { + // Write Data tag + if (dataBytesUsed > 0) { + try (LZ4BlockInputStream reader = new LZ4BlockInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { + out.writeNamedTagName("Data", NBTConstants.TYPE_BYTE_ARRAY); + out.writeInt(dataBytesUsed); + IOUtil.copy(reader, (DataOutput) out); + } + } + } + } + + private void writeMetadata(NBTOutputStream metadata, Clipboard clipboard) throws IOException { + metadata.writeNamedTag("Date", System.currentTimeMillis()); + metadata.writeLazyCompoundTag("WorldEdit", out -> { + out.writeNamedTag("Version", WorldEdit.getVersion()); + out.writeNamedTag( + "EditingPlatform", + WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getId() + ); + out.writeNamedTag("Origin", new int[]{ + clipboard.getOrigin().x(), clipboard.getOrigin().y(), clipboard.getOrigin().z() + }); + out.writeLazyCompoundTag("Platforms", platforms -> { + for (final Platform platform : WorldEdit.getInstance().getPlatformManager().getPlatforms()) { + platforms.writeLazyCompoundTag(platform.getId(), p -> { + p.writeNamedTag("Name", platform.getPlatformName()); + p.writeNamedTag("Version", platform.getPlatformVersion()); + }); + } + }); + }); + } + + @Override + public void close() throws IOException { + this.outputStream.close(); + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/io/VarIntStreamIterator.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/io/VarIntStreamIterator.java new file mode 100644 index 000000000..17f4b9f0a --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/io/VarIntStreamIterator.java @@ -0,0 +1,70 @@ +package com.fastasyncworldedit.core.internal.io; + +import java.io.IOException; +import java.io.InputStream; +import java.util.NoSuchElementException; +import java.util.PrimitiveIterator; + +/** + * Basically {@link com.sk89q.worldedit.internal.util.VarIntIterator} but backed by {@link java.io.InputStream} + */ +public class VarIntStreamIterator implements PrimitiveIterator.OfInt { + + private final InputStream parent; + private final int limit; + private int index; + private boolean hasNextInt; + private int nextInt; + + public VarIntStreamIterator(final InputStream parent, int limit) { + this.parent = parent; + this.limit = limit; + } + + @Override + public boolean hasNext() { + if (hasNextInt) { + return true; + } + if (index >= limit) { + return false; + } + + try { + nextInt = readNextInt(); + } catch (IOException e) { + throw new RuntimeException(e); + } + return hasNextInt = true; + } + + @Override + public int nextInt() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + hasNextInt = false; + return nextInt; + } + + + private int readNextInt() throws IOException { + int value = 0; + for (int bitsRead = 0; ; bitsRead += 7) { + if (index >= limit) { + throw new IllegalStateException("Ran out of bytes while reading VarInt (probably corrupted data)"); + } + byte next = (byte) this.parent.read(); + index++; + value |= (next & 0x7F) << bitsRead; + if (bitsRead > 7 * 5) { + throw new IllegalStateException("VarInt too big (probably corrupted data)"); + } + if ((next & 0x80) == 0) { + break; + } + } + return value; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/CompressedSchematicTag.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/CompressedSchematicTag.java index e622b1501..3c569f913 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/CompressedSchematicTag.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/jnbt/CompressedSchematicTag.java @@ -1,6 +1,6 @@ package com.fastasyncworldedit.core.jnbt; -import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriter; +import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriterV2; import com.fastasyncworldedit.core.internal.io.FastByteArrayOutputStream; import com.fastasyncworldedit.core.internal.io.FastByteArraysInputStream; import com.sk89q.jnbt.NBTOutputStream; @@ -21,7 +21,7 @@ public class CompressedSchematicTag extends CompressedCompoundTag { FastByteArrayOutputStream blocksOut = new FastByteArrayOutputStream(); try (LZ4BlockOutputStream lz4out = new LZ4BlockOutputStream(blocksOut)) { NBTOutputStream nbtOut = new NBTOutputStream(lz4out); - new FastSchematicWriter(nbtOut).write(getSource()); + new FastSchematicWriterV2(nbtOut).write(getSource()); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java index 806168327..080ab3bea 100644 --- a/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java +++ b/worldedit-core/src/main/java/com/sk89q/jnbt/NBTInputStream.java @@ -572,7 +572,7 @@ public final class NBTInputStream implements Closeable { * @return the tag * @throws IOException if an I/O error occurs. */ - private Tag readTagPayload(int type, int depth) throws IOException { + public Tag readTagPayload(int type, int depth) throws IOException { //FAWE - public switch (type) { case NBTConstants.TYPE_END: if (depth == 0) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java index 1fd9dda9a..8a57411d6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java @@ -19,28 +19,38 @@ package com.sk89q.worldedit.extent.clipboard.io; -import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicReader; -import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriter; +import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicReaderV2; +import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicReaderV3; +import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriterV2; +import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriterV3; import com.fastasyncworldedit.core.extent.clipboard.io.schematic.MinecraftStructure; import com.fastasyncworldedit.core.extent.clipboard.io.schematic.PNGWriter; import com.fastasyncworldedit.core.internal.io.ResettableFileInputStream; import com.google.common.collect.ImmutableSet; -import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.NBTConstants; import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.NBTOutputStream; import com.sk89q.jnbt.NamedTag; -import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV1Reader; +import com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV2Reader; +import com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV2Writer; +import com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV3Reader; +import com.sk89q.worldedit.extent.clipboard.io.sponge.SpongeSchematicV3Writer; +import it.unimi.dsi.fastutil.io.FastBufferedInputStream; import org.anarres.parallelgzip.ParallelGZIPOutputStream; +import org.enginehub.linbus.stream.LinBinaryIO; +import org.enginehub.linbus.tree.LinRootEntry; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Locale; -import java.util.Map; import java.util.Set; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; @@ -48,23 +58,14 @@ import java.util.zip.GZIPOutputStream; /** * A collection of supported clipboard formats. */ +@SuppressWarnings("removal") //FAWE: suppress JNBT deprecations public enum BuiltInClipboardFormat implements ClipboardFormat { //FAWE start - register fast clipboard io - FAST("fast", "fawe", "sponge", "schem") { - @Override - public String getPrimaryFileExtension() { - return "schem"; - } - + FAST_V3("fast", "fawe", "schem") { @Override public ClipboardReader getReader(InputStream inputStream) throws IOException { - if (inputStream instanceof FileInputStream) { - inputStream = new ResettableFileInputStream((FileInputStream) inputStream); - } - BufferedInputStream buffered = new BufferedInputStream(inputStream); - NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered))); - return new FastSchematicReader(nbtStream); + return new FastSchematicReaderV3(inputStream); } @Override @@ -77,13 +78,77 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { gzip = new ParallelGZIPOutputStream(outputStream); } NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip)); - return new FastSchematicWriter(nbtStream); + return new FastSchematicWriterV3(nbtStream); } @Override - public boolean isFormat(File file) { - String name = file.getName().toLowerCase(Locale.ROOT); - return name.endsWith(".schem") || name.endsWith(".sponge"); + public boolean isFormat(final InputStream inputStream) { + try (final DataInputStream stream = new DataInputStream(new FastBufferedInputStream(new GZIPInputStream(inputStream))); + final NBTInputStream nbt = new NBTInputStream(stream)) { + if (stream.readByte() != NBTConstants.TYPE_COMPOUND) { + return false; + } + stream.skipNBytes(2); // TAG name length ("" = 0), no need to read name as no bytes are written for root tag + if (stream.readByte() != NBTConstants.TYPE_COMPOUND) { + return false; + } + stream.skipNBytes(2); // TAG name length ("Schematic" = 9) + stream.skipNBytes(9); // "Schematic" + + // We can't guarantee the specific order of nbt data, so scan and skip, if required + do { + byte type = stream.readByte(); + String name = stream.readUTF(); + if (type == NBTConstants.TYPE_END) { + return false; + } + if (type == NBTConstants.TYPE_INT && name.equals("Version")) { + return stream.readInt() == FastSchematicWriterV3.CURRENT_VERSION; + } + nbt.readTagPayloadLazy(type, 0); + } while (true); + } catch (IOException ignored) { + } + return false; + } + + @Override + public String getPrimaryFileExtension() { + return "schem"; + } + }, + FAST_V2("fast.2", "fawe.2", "schem.2") { + @Override + public String getPrimaryFileExtension() { + return "schem"; + } + + @Override + public ClipboardReader getReader(InputStream inputStream) throws IOException { + if (inputStream instanceof FileInputStream) { + inputStream = new ResettableFileInputStream((FileInputStream) inputStream); + } + BufferedInputStream buffered = new BufferedInputStream(inputStream); + NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered))); + return new FastSchematicReaderV2(nbtStream); + } + + @Override + public ClipboardWriter getWriter(OutputStream outputStream) throws IOException { + OutputStream gzip; + if (outputStream instanceof ParallelGZIPOutputStream || outputStream instanceof GZIPOutputStream) { + gzip = outputStream; + } else { + outputStream = new BufferedOutputStream(outputStream); + gzip = new ParallelGZIPOutputStream(outputStream); + } + NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip)); + return new FastSchematicWriterV2(nbtStream); + } + + @Override + public boolean isFormat(InputStream inputStream) { + return detectOldSpongeSchematic(inputStream, FastSchematicWriterV2.CURRENT_VERSION); } }, @@ -113,9 +178,39 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { } @Override - public boolean isFormat(File file) { - String name = file.getName().toLowerCase(Locale.ROOT); - return name.endsWith(".schematic") || name.endsWith(".mcedit") || name.endsWith(".mce"); + public boolean isFormat(InputStream inputStream) { + LinRootEntry rootEntry; + try { + DataInputStream stream = new DataInputStream(new GZIPInputStream(inputStream)); + rootEntry = LinBinaryIO.readUsing(stream, LinRootEntry::readFrom); + } catch (Exception e) { + return false; + } + if (!rootEntry.name().equals("Schematic")) { + return false; + } + return rootEntry.value().value().containsKey("Materials"); + } + }, + SPONGE_V1_SCHEMATIC("sponge.1") { + @Override + public String getPrimaryFileExtension() { + return "schem"; + } + + @Override + public ClipboardReader getReader(InputStream inputStream) throws IOException { + return new SpongeSchematicV1Reader(LinBinaryIO.read(new DataInputStream(new GZIPInputStream(inputStream)))); + } + + @Override + public ClipboardWriter getWriter(OutputStream outputStream) throws IOException { + throw new IOException("This format does not support saving"); + } + + @Override + public boolean isFormat(InputStream inputStream) { + return detectOldSpongeSchematic(inputStream, 1); } }, @@ -125,7 +220,8 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { * Avoid using with any large schematics/clipboards for reading/writing. */ @Deprecated - SPONGE_SCHEMATIC("slow", "safe") { + SPONGE_V2_SCHEMATIC("slow.2", "safe.2", "sponge.2") { // FAWE - edit aliases for fast + @Override public String getPrimaryFileExtension() { return "schem"; @@ -133,38 +229,43 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { @Override public ClipboardReader getReader(InputStream inputStream) throws IOException { - NBTInputStream nbtStream = new NBTInputStream(new GZIPInputStream(inputStream)); - return new SpongeSchematicReader(nbtStream); + return new SpongeSchematicV2Reader(LinBinaryIO.read(new DataInputStream(new GZIPInputStream(inputStream)))); } @Override public ClipboardWriter getWriter(OutputStream outputStream) throws IOException { - NBTOutputStream nbtStream = new NBTOutputStream(new GZIPOutputStream(outputStream)); - return new SpongeSchematicWriter(nbtStream); + return new SpongeSchematicV2Writer(new DataOutputStream(new GZIPOutputStream(outputStream))); + } + + @Override + public boolean isFormat(InputStream inputStream) { + return detectOldSpongeSchematic(inputStream, 2); + } + }, + SPONGE_V3_SCHEMATIC("sponge.3", "slow", "safe") { // FAWE - edit aliases for fast + + @Override + public String getPrimaryFileExtension() { + return "schem"; + } + + @Override + public ClipboardReader getReader(InputStream inputStream) throws IOException { + return new SpongeSchematicV3Reader(LinBinaryIO.read(new DataInputStream(new GZIPInputStream(inputStream)))); + } + + @Override + public ClipboardWriter getWriter(OutputStream outputStream) throws IOException { + return new SpongeSchematicV3Writer(new DataOutputStream(new GZIPOutputStream(outputStream))); } @Override public boolean isFormat(File file) { - try (NBTInputStream str = new NBTInputStream(new GZIPInputStream(new FileInputStream(file)))) { - NamedTag rootTag = str.readNamedTag(); - if (!rootTag.getName().equals("Schematic")) { - return false; - } - CompoundTag schematicTag = (CompoundTag) rootTag.getTag(); - - // Check - Map> schematic = schematicTag.getValue(); - if (!schematic.containsKey("Version")) { - return false; - } - } catch (Exception e) { - return false; - } - - return true; + //FAWE start - delegate to stream-based isFormat approach of fast impl + return FAST_V3.isFormat(file); + //FAWE end } }, - //FAWE start - recover schematics with bad entity data & register other clipboard formats BROKENENTITY("brokenentity", "legacyentity", "le", "be", "brokenentities", "legacyentities") { @Override @@ -179,7 +280,7 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { } BufferedInputStream buffered = new BufferedInputStream(inputStream); NBTInputStream nbtStream = new NBTInputStream(new BufferedInputStream(new GZIPInputStream(buffered))); - FastSchematicReader reader = new FastSchematicReader(nbtStream); + FastSchematicReaderV2 reader = new FastSchematicReaderV2(nbtStream); reader.setBrokenEntities(true); return reader; } @@ -194,7 +295,7 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { gzip = new ParallelGZIPOutputStream(outputStream); } NBTOutputStream nbtStream = new NBTOutputStream(new BufferedOutputStream(gzip)); - FastSchematicWriter writer = new FastSchematicWriter(nbtStream); + FastSchematicWriterV2 writer = new FastSchematicWriterV2(nbtStream); writer.setBrokenEntities(true); return writer; } @@ -232,9 +333,37 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { } @Override - public boolean isFormat(File file) { - String name = file.getName().toLowerCase(Locale.ROOT); - return name.endsWith(".nbt"); + public boolean isFormat(InputStream inputStream) { + try (final DataInputStream stream = new DataInputStream(new FastBufferedInputStream(new GZIPInputStream(inputStream))); + final NBTInputStream nbt = new NBTInputStream(stream)) { + if (stream.readByte() != NBTConstants.TYPE_COMPOUND) { + return false; + } + NamedTag namedTag = nbt.readNamedTag(); + if (!namedTag.getName().isEmpty()) { + return false; + } + + // We can't guarantee the specific order of nbt data, so scan and skip, if required + do { + byte type = stream.readByte(); + String name = stream.readUTF(); + if (type == NBTConstants.TYPE_END) { + return false; + } + if (type == NBTConstants.TYPE_LIST && name.equals("size")) { + return true; + } + nbt.readTagPayloadLazy(type, 0); + } while (true); + } catch (IOException ignored) { + } + return false; + } + + @Override + public boolean isFormat(final File file) { + return file.getName().toLowerCase(Locale.ROOT).endsWith(".nbt") && super.isFormat(file); } }, @@ -265,6 +394,53 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { }; //FAWE end + private static boolean detectOldSpongeSchematic(InputStream inputStream, int version) { + //FAWE start - dont utilize linbus - WorldEdit approach is not really streamed + try (final DataInputStream stream = new DataInputStream(new FastBufferedInputStream(new GZIPInputStream(inputStream))); + final NBTInputStream nbt = new NBTInputStream(stream)) { + if (stream.readByte() != NBTConstants.TYPE_COMPOUND) { + return false; + } + stream.skipNBytes(2); // TAG name length ("Schematic" = 9) + stream.skipNBytes(9); // "Schematic" + + // We can't guarantee the specific order of nbt data, so scan and skip, if required + do { + byte type = stream.readByte(); + String name = stream.readUTF(); + if (type == NBTConstants.TYPE_END) { + return false; + } + if (type == NBTConstants.TYPE_INT && name.equals("Version")) { + return stream.readInt() == version; + } + nbt.readTagPayloadLazy(type, 0); + } while (true); + } catch (IOException ignored) { + } + return false; + } + + /** + * For backwards compatibility, this points to the Sponge Schematic Specification (Version 2) + * format. This should not be used going forwards. + * + * @deprecated Use {@link #SPONGE_V2_SCHEMATIC} or {@link #SPONGE_V3_SCHEMATIC} + */ + @Deprecated + public static final BuiltInClipboardFormat SPONGE_SCHEMATIC = SPONGE_V2_SCHEMATIC; + + //FAWE start + /** + * For backwards compatibility, this points to the fast implementation of the Sponge Schematic Specification (Version 2) + * format. This should not be used going forwards. + * + * @deprecated Use {@link #FAST_V2} or {@link #FAST_V3} + */ + @Deprecated + public static final BuiltInClipboardFormat FAST = FAST_V2; + //FAWE end + private final ImmutableSet aliases; BuiltInClipboardFormat(String... aliases) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java index cb5cd1b7a..7b4b1bf3b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java @@ -35,6 +35,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.net.URL; +import java.nio.file.Files; import java.util.Set; import static com.google.common.base.Preconditions.checkNotNull; @@ -82,7 +83,29 @@ public interface ClipboardFormat { * @param file the file * @return true if the given file is of this format */ - boolean isFormat(File file); + default boolean isFormat(File file) { + try (InputStream stream = Files.newInputStream(file.toPath())) { + return isFormat(stream); + } catch (IOException e) { + return false; + } + } + + /** + * Return whether the given stream is of this format. + * + * @apiNote The caller is responsible for the following: + *

      + *
    • Closing the input stream
    • + *
    + * + * @param inputStream The stream + * @return true if the given stream is of this format + * @since TODO + */ + default boolean isFormat(InputStream inputStream) { + return false; + } /** * Get the file extension this format primarily uses. diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/NBTSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/NBTSchematicReader.java index a6b9c1400..017f07e9c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/NBTSchematicReader.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/NBTSchematicReader.java @@ -20,6 +20,7 @@ package com.sk89q.worldedit.extent.clipboard.io; import com.sk89q.jnbt.Tag; +import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nullable; import java.io.IOException; @@ -27,7 +28,10 @@ import java.util.Map; /** * Base class for NBT schematic readers. + * + * @deprecated These utility methods are provided by {@link LinCompoundTag} now. */ +@Deprecated public abstract class NBTSchematicReader implements ClipboardReader { protected static > T requireTag(Map> items, String key, Class expected) throws IOException { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicNbtUtil.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicNbtUtil.java new file mode 100644 index 000000000..7da0aa164 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SchematicNbtUtil.java @@ -0,0 +1,61 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io; + +import com.sk89q.jnbt.Tag; + +import java.io.IOException; +import java.util.Map; +import javax.annotation.Nullable; + +// note, when clearing deprecations these methods don't need to remain -- they're introduced in 7.3.0 +public class SchematicNbtUtil { + public static T requireTag(Map items, String key, Class expected) throws IOException { + if (!items.containsKey(key)) { + throw new IOException("Schematic file is missing a \"" + key + "\" tag of type " + + expected.getName()); + } + + Tag tag = items.get(key); + if (!expected.isInstance(tag)) { + throw new IOException(key + " tag is not of tag type " + expected.getName() + ", got " + + tag.getClass().getName() + " instead"); + } + + return expected.cast(tag); + } + + @Nullable + public static T getTag(Map items, String key, Class expected) { + if (!items.containsKey(key)) { + return null; + } + + Tag test = items.get(key); + if (!expected.isInstance(test)) { + return null; + } + + return expected.cast(test); + } + + private SchematicNbtUtil() { + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java deleted file mode 100644 index ec82be228..000000000 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicReader.java +++ /dev/null @@ -1,453 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.extent.clipboard.io; - -import com.fastasyncworldedit.core.configuration.Caption; -import com.google.common.collect.Maps; -import com.sk89q.jnbt.LinBusConverter; -import com.sk89q.jnbt.ByteArrayTag; -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.NamedTag; -import com.sk89q.jnbt.ShortTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.extension.input.InputParseException; -import com.sk89q.worldedit.extension.input.ParserContext; -import com.sk89q.worldedit.extension.platform.Capability; -import com.sk89q.worldedit.extension.platform.Platform; -import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; -import com.sk89q.worldedit.extent.clipboard.Clipboard; -import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.CuboidRegion; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.util.formatting.text.TextComponent; -import com.sk89q.worldedit.world.DataFixer; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypes; -import com.sk89q.worldedit.world.entity.EntityType; -import com.sk89q.worldedit.world.entity.EntityTypes; -import com.sk89q.worldedit.world.storage.NBTConversions; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.OptionalInt; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * Reads schematic files using the Sponge Schematic Specification. - * - * @deprecated Slow, resource intensive, but sometimes safer than using the recommended - * {@link com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicReader}. - * Avoid reading large schematics with this reader. - */ -@Deprecated -public class SpongeSchematicReader extends NBTSchematicReader { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - private final NBTInputStream inputStream; - private DataFixer fixer = null; - private int schematicVersion = -1; - private int dataVersion = -1; - - /** - * Create a new instance. - * - * @param inputStream the input stream to read from - */ - public SpongeSchematicReader(NBTInputStream inputStream) { - checkNotNull(inputStream); - this.inputStream = inputStream; - } - - @Override - public Clipboard read() throws IOException { - CompoundTag schematicTag = getBaseTag(); - Map> schematic = schematicTag.getValue(); - - final Platform platform = WorldEdit.getInstance().getPlatformManager() - .queryCapability(Capability.WORLD_EDITING); - int liveDataVersion = platform.getDataVersion(); - - if (schematicVersion == 1) { - dataVersion = Constants.DATA_VERSION_MC_1_13_2; // this is a relatively safe assumption unless someone imports a schematic from 1.12, e.g. sponge 7.1- - fixer = platform.getDataFixer(); - return readVersion1(schematicTag); - } else if (schematicVersion == 2) { - dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue(); - if (dataVersion < 0) { - LOGGER.warn( - "Schematic has an unknown data version ({}). Data may be incompatible.", - dataVersion - ); - // Do not DFU unknown data - dataVersion = liveDataVersion; - } - if (dataVersion > liveDataVersion) { - LOGGER.warn("Schematic was made in a newer Minecraft version ({} > {}). Data may be incompatible.", - dataVersion, liveDataVersion - ); - } else if (dataVersion < liveDataVersion) { - fixer = platform.getDataFixer(); - if (fixer != null) { - LOGGER.info("Schematic was made in an older Minecraft version ({} < {}), will attempt DFU.", - dataVersion, liveDataVersion - ); - } else { - LOGGER.info( - "Schematic was made in an older Minecraft version ({} < {}), but DFU is not available. Data may be incompatible.", - dataVersion, - liveDataVersion - ); - } - } - - BlockArrayClipboard clip = readVersion1(schematicTag); - return readVersion2(clip, schematicTag); - } - throw new SchematicLoadException(Caption.of("worldedit.schematic.load.unsupported-version", - TextComponent.of(schematicVersion))); - } - - @Override - public OptionalInt getDataVersion() { - try { - CompoundTag schematicTag = getBaseTag(); - Map> schematic = schematicTag.getValue(); - if (schematicVersion == 1) { - return OptionalInt.of(Constants.DATA_VERSION_MC_1_13_2); - } else if (schematicVersion == 2) { - int dataVersion = requireTag(schematic, "DataVersion", IntTag.class).getValue(); - if (dataVersion < 0) { - return OptionalInt.empty(); - } - return OptionalInt.of(dataVersion); - } - return OptionalInt.empty(); - } catch (IOException e) { - return OptionalInt.empty(); - } - } - - private CompoundTag getBaseTag() throws IOException { - NamedTag rootTag = inputStream.readNamedTag(); - CompoundTag schematicTag = (CompoundTag) rootTag.getTag(); - - // Check - Map> schematic = schematicTag.getValue(); - - // Be lenient about the specific nesting level of the Schematic tag - // Also allows checking the version from newer versions of the specification - if (schematic.size() == 1 && schematic.containsKey("Schematic")) { - schematicTag = requireTag(schematic, "Schematic", CompoundTag.class); - schematic = schematicTag.getValue(); - } - - schematicVersion = requireTag(schematic, "Version", IntTag.class).getValue(); - return schematicTag; - } - - private BlockArrayClipboard readVersion1(CompoundTag schematicTag) throws IOException { - BlockVector3 origin; - Region region; - Map> schematic = schematicTag.getValue(); - - int width = requireTag(schematic, "Width", ShortTag.class).getValue(); - int height = requireTag(schematic, "Height", ShortTag.class).getValue(); - int length = requireTag(schematic, "Length", ShortTag.class).getValue(); - - IntArrayTag offsetTag = getTag(schematic, "Offset", IntArrayTag.class); - int[] offsetParts; - if (offsetTag != null) { - offsetParts = offsetTag.getValue(); - if (offsetParts.length != 3) { - throw new IOException("Invalid offset specified in schematic."); - } - } else { - offsetParts = new int[]{0, 0, 0}; - } - - BlockVector3 min = BlockVector3.at(offsetParts[0], offsetParts[1], offsetParts[2]); - - CompoundTag metadataTag = getTag(schematic, "Metadata", CompoundTag.class); - if (metadataTag != null && metadataTag.containsKey("WEOffsetX")) { - // We appear to have WorldEdit Metadata - Map> metadata = metadataTag.getValue(); - int offsetX = requireTag(metadata, "WEOffsetX", IntTag.class).getValue(); - int offsetY = requireTag(metadata, "WEOffsetY", IntTag.class).getValue(); - int offsetZ = requireTag(metadata, "WEOffsetZ", IntTag.class).getValue(); - BlockVector3 offset = BlockVector3.at(offsetX, offsetY, offsetZ); - origin = min.subtract(offset); - region = new CuboidRegion(min, min.add(width, height, length).subtract(BlockVector3.ONE)); - } else { - origin = min; - region = new CuboidRegion(origin, origin.add(width, height, length).subtract(BlockVector3.ONE)); - } - - IntTag paletteMaxTag = getTag(schematic, "PaletteMax", IntTag.class); - Map> paletteObject = requireTag(schematic, "Palette", CompoundTag.class).getValue(); - if (paletteMaxTag != null && paletteObject.size() != paletteMaxTag.getValue()) { - throw new IOException("Block palette size does not match expected size."); - } - - Map palette = new HashMap<>(); - - ParserContext parserContext = new ParserContext(); - parserContext.setRestricted(false); - parserContext.setTryLegacy(false); - parserContext.setPreferringWildcard(false); - - for (String palettePart : paletteObject.keySet()) { - int id = requireTag(paletteObject, palettePart, IntTag.class).getValue(); - if (fixer != null) { - palettePart = fixer.fixUp(DataFixer.FixTypes.BLOCK_STATE, palettePart, dataVersion); - } - BlockState state; - try { - state = WorldEdit.getInstance().getBlockFactory().parseFromInput(palettePart, parserContext).toImmutableState(); - } catch (InputParseException e) { - LOGGER.warn("Invalid BlockState in palette: " + palettePart + ". Block will be replaced with air."); - state = BlockTypes.AIR.getDefaultState(); - } - palette.put(id, state); - } - - byte[] blocks = requireTag(schematic, "BlockData", ByteArrayTag.class).getValue(); - - Map>> tileEntitiesMap = new HashMap<>(); - ListTag tileEntities = getTag(schematic, "BlockEntities", ListTag.class); - if (tileEntities == null) { - tileEntities = getTag(schematic, "TileEntities", ListTag.class); - } - if (tileEntities != null) { - for (Object tileTag : tileEntities.getValue()) { - Map> tileEntity = ((CompoundTag) tileTag).getValue(); - int[] pos = requireTag(tileEntity, "Pos", IntArrayTag.class).getValue(); - final BlockVector3 pt = BlockVector3.at(pos[0], pos[1], pos[2]); - Map> values = Maps.newHashMap(tileEntity); - values.put("x", new IntTag(pt.x())); - values.put("y", new IntTag(pt.y())); - values.put("z", new IntTag(pt.z())); - //FAWE start - support old, corrupt schematics - Tag id = values.get("Id"); - if (id == null) { - id = values.get("id"); - } - if (id == null) { - continue; - } - values.put("id", id); - //FAWE end - values.remove("Id"); - values.remove("Pos"); - if (fixer != null) { - //FAWE start - LinTag - tileEntity = ((CompoundTag) LinBusConverter.fromLinBus(fixer.fixUp( - DataFixer.FixTypes.BLOCK_ENTITY, - new CompoundTag(values).toLinTag(), - dataVersion - ))).getValue(); - //FAWE end - } else { - tileEntity = values; - } - tileEntitiesMap.put(pt, tileEntity); - } - } - - BlockArrayClipboard clipboard = new BlockArrayClipboard(region); - clipboard.setOrigin(origin); - - int index = 0; - int i = 0; - int value; - int varintLength; - while (i < blocks.length) { - value = 0; - varintLength = 0; - - while (true) { - value |= (blocks[i] & 127) << (varintLength++ * 7); - if (varintLength > 5) { - throw new IOException("VarInt too big (probably corrupted data)"); - } - if ((blocks[i] & 128) != 128) { - i++; - break; - } - i++; - } - // index = (y * length * width) + (z * width) + x - int y = index / (width * length); - int z = (index % (width * length)) / width; - int x = (index % (width * length)) % width; - BlockState state = palette.get(value); - BlockVector3 pt = BlockVector3.at(x, y, z); - try { - if (tileEntitiesMap.containsKey(pt)) { - clipboard.setBlock( - clipboard.getMinimumPoint().add(pt), - state.toBaseBlock(new CompoundTag(tileEntitiesMap.get(pt))) - ); - } else { - clipboard.setBlock(clipboard.getMinimumPoint().add(pt), state); - } - } catch (WorldEditException e) { - throw new IOException("Failed to load a block in the schematic"); - } - - index++; - } - - return clipboard; - } - - private Clipboard readVersion2(BlockArrayClipboard version1, CompoundTag schematicTag) throws IOException { - Map> schematic = schematicTag.getValue(); - if (schematic.containsKey("BiomeData")) { - readBiomes(version1, schematic); - } - if (schematic.containsKey("Entities")) { - readEntities(version1, schematic); - } - return version1; - } - - private void readBiomes(BlockArrayClipboard clipboard, Map> schematic) throws IOException { - ByteArrayTag dataTag = requireTag(schematic, "BiomeData", ByteArrayTag.class); - IntTag maxTag = requireTag(schematic, "BiomePaletteMax", IntTag.class); - CompoundTag paletteTag = requireTag(schematic, "BiomePalette", CompoundTag.class); - - Map palette = new HashMap<>(); - if (maxTag.getValue() != paletteTag.getValue().size()) { - throw new IOException("Biome palette size does not match expected size."); - } - - for (Entry> palettePart : paletteTag.getValue().entrySet()) { - String key = palettePart.getKey(); - if (fixer != null) { - key = fixer.fixUp(DataFixer.FixTypes.BIOME, key, dataVersion); - } - BiomeType biome = BiomeTypes.get(key); - if (biome == null) { - LOGGER.warn("Unknown biome type :" + key - + " in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?"); - } - Tag idTag = palettePart.getValue(); - if (!(idTag instanceof IntTag)) { - throw new IOException("Biome mapped to non-Int tag."); - } - palette.put(((IntTag) idTag).getValue(), biome); - } - - int width = clipboard.getDimensions().x(); - - byte[] biomes = dataTag.getValue(); - int biomeIndex = 0; - int biomeJ = 0; - int bVal; - int varIntLength; - BlockVector3 min = clipboard.getMinimumPoint(); - while (biomeJ < biomes.length) { - bVal = 0; - varIntLength = 0; - - while (true) { - bVal |= (biomes[biomeJ] & 127) << (varIntLength++ * 7); - if (varIntLength > 5) { - throw new IOException("VarInt too big (probably corrupted data)"); - } - if (((biomes[biomeJ] & 128) != 128)) { - biomeJ++; - break; - } - biomeJ++; - } - int z = biomeIndex / width; - int x = biomeIndex % width; - BiomeType type = palette.get(bVal); - for (int y = 0; y < clipboard.getRegion().getHeight(); y++) { - clipboard.setBiome(min.add(x, y, z), type); - } - biomeIndex++; - } - } - - private void readEntities(BlockArrayClipboard clipboard, Map> schematic) throws IOException { - List entList = requireTag(schematic, "Entities", ListTag.class).getValue(); - if (entList.isEmpty()) { - return; - } - for (Tag et : entList) { - if (!(et instanceof CompoundTag)) { - continue; - } - CompoundTag entityTag = (CompoundTag) et; - Map> tags = entityTag.getValue(); - String id = requireTag(tags, "Id", StringTag.class).getValue(); - entityTag = entityTag.createBuilder().putString("id", id).remove("Id").build(); - - if (fixer != null) { - //FAWE start - LinTag - entityTag = (CompoundTag) LinBusConverter.fromLinBus(fixer.fixUp( - DataFixer.FixTypes.ENTITY, - entityTag.toLinTag(), - dataVersion - )); - //FAWE end - } - - EntityType entityType = EntityTypes.get(id); - if (entityType != null) { - Location location = NBTConversions.toLocation( - clipboard, - requireTag(tags, "Pos", ListTag.class), - requireTag(tags, "Rotation", ListTag.class) - ); - BaseEntity state = new BaseEntity(entityType, entityTag); - clipboard.createEntity(location, state); - } else { - LOGGER.warn("Unknown entity when pasting schematic: " + id); - } - } - } - - @Override - public void close() throws IOException { - inputStream.close(); - } - -} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/BuiltInClipboardShareDestinations.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/BuiltInClipboardShareDestinations.java index 981debe4b..551ac5dd7 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/BuiltInClipboardShareDestinations.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/share/BuiltInClipboardShareDestinations.java @@ -61,7 +61,7 @@ public enum BuiltInClipboardShareDestinations implements ClipboardShareDestinati PasteMetadata pasteMetadata = new PasteMetadata(); pasteMetadata.author = metadata.author(); - pasteMetadata.extension = "schem"; + pasteMetadata.extension = metadata.format().getPrimaryFileExtension(); pasteMetadata.name = metadata.name(); EngineHubPaste pasteService = new EngineHubPaste(); @@ -75,7 +75,7 @@ public enum BuiltInClipboardShareDestinations implements ClipboardShareDestinati @Override public ClipboardFormat getDefaultFormat() { - return BuiltInClipboardFormat.SPONGE_SCHEMATIC; + return BuiltInClipboardFormat.SPONGE_V2_SCHEMATIC; } @Override @@ -119,13 +119,14 @@ public enum BuiltInClipboardShareDestinations implements ClipboardShareDestinati @Override public ClipboardFormat getDefaultFormat() { - return BuiltInClipboardFormat.FAST; + return BuiltInClipboardFormat.FAST_V3; } @Override public boolean supportsFormat(final ClipboardFormat format) { - return format == BuiltInClipboardFormat.SPONGE_SCHEMATIC || - format == BuiltInClipboardFormat.FAST || + return format == BuiltInClipboardFormat.SPONGE_V2_SCHEMATIC || + format == BuiltInClipboardFormat.FAST_V3 || + format == BuiltInClipboardFormat.FAST_V2 || format == BuiltInClipboardFormat.MCEDIT_SCHEMATIC; } }; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/ReaderUtil.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/ReaderUtil.java new file mode 100644 index 000000000..5c4e90264 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/ReaderUtil.java @@ -0,0 +1,283 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io.sponge; + + +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.input.ParserContext; +import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.internal.util.LogManagerCompat; +import com.sk89q.worldedit.internal.util.VarIntIterator; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.util.concurrency.LazyReference; +import com.sk89q.worldedit.world.DataFixer; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.biome.BiomeTypes; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockTypes; +import com.sk89q.worldedit.world.entity.EntityType; +import com.sk89q.worldedit.world.entity.EntityTypes; +import com.sk89q.worldedit.world.storage.NBTConversions; +import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.apache.logging.log4j.Logger; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinIntArrayTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinTagType; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Nullable; + +import static com.google.common.base.Preconditions.checkState; + +/** + * Common code shared between schematic readers. + */ +public class ReaderUtil { //FAWE - make public + + private static final Logger LOGGER = LogManagerCompat.getLogger(); + + static void checkSchematicVersion(int version, LinCompoundTag schematicTag) throws IOException { + int schematicVersion = getSchematicVersion(schematicTag); + + checkState( + version == schematicVersion, + "Schematic is not version %s, but %s", version, schematicVersion + ); + } + + public static int getSchematicVersion(LinCompoundTag schematicTag) throws IOException { + return schematicTag.getTag("Version", LinTagType.intTag()).valueAsInt(); + } + + static VersionedDataFixer getVersionedDataFixer( + LinCompoundTag schematic, Platform platform, + int liveDataVersion + ) { + //FAWE start - call fawe method without NBT component requirement + return getVersionedDataFixer(schematic.getTag("DataVersion", LinTagType.intTag()).valueAsInt(), platform, + liveDataVersion + ); + //FAWE end + } + + //FAWE start - make getVersionedDataFixer without schematic compound + public + public static VersionedDataFixer getVersionedDataFixer(int schematicDataVersion, Platform platform, int liveDataVersion) { + DataFixer fixer = null; + if (schematicDataVersion < 0) { + LOGGER.warn( + "Schematic has an unknown data version ({}). Data may be incompatible.", + schematicDataVersion + ); + } else if (schematicDataVersion > liveDataVersion) { + LOGGER.warn( + "Schematic was made in a newer Minecraft version ({} > {})." + + " Data may be incompatible.", + schematicDataVersion, liveDataVersion + ); + } else if (schematicDataVersion < liveDataVersion) { + fixer = platform.getDataFixer(); + if (fixer != null) { + LOGGER.debug( + "Schematic was made in an older Minecraft version ({} < {})," + + " will attempt DFU.", + schematicDataVersion, liveDataVersion + ); + } else { + LOGGER.info( + "Schematic was made in an older Minecraft version ({} < {})," + + " but DFU is not available. Data may be incompatible.", + schematicDataVersion, liveDataVersion + ); + } + } + return new VersionedDataFixer(schematicDataVersion, fixer); + } + //FAWE end + + static Map decodePalette( + LinCompoundTag paletteObject, VersionedDataFixer fixer + ) throws IOException { + Map palette = new HashMap<>(); + + ParserContext parserContext = new ParserContext(); + parserContext.setRestricted(false); + parserContext.setTryLegacy(false); + parserContext.setPreferringWildcard(false); + + for (var palettePart : paletteObject.value().entrySet()) { + if (!(palettePart.getValue() instanceof LinIntTag idTag)) { + throw new IOException("Invalid palette entry: " + palettePart); + } + int id = idTag.valueAsInt(); + String paletteName = fixer.fixUp(DataFixer.FixTypes.BLOCK_STATE, palettePart.getKey()); + BlockState state; + try { + state = WorldEdit.getInstance().getBlockFactory().parseFromInput(paletteName, parserContext).toImmutableState(); + } catch (InputParseException e) { + LOGGER.warn("Invalid BlockState in palette: " + palettePart + ". Block will be replaced with air."); + state = BlockTypes.AIR.getDefaultState(); + } + palette.put(id, state); + } + return palette; + } + + static void initializeClipboardFromBlocks( + Clipboard clipboard, Map palette, byte[] blocks, LinListTag tileEntities, + VersionedDataFixer fixer, boolean dataIsNested + ) throws IOException { + Map tileEntitiesMap = new HashMap<>(); + if (tileEntities != null) { + for (LinCompoundTag tileEntity : tileEntities.value()) { + final BlockVector3 pt = clipboard.getMinimumPoint().add( + decodeBlockVector3(tileEntity.getTag("Pos", LinTagType.intArrayTag())) + ); + LinCompoundTag.Builder values = extractData(dataIsNested, tileEntity); + values.putInt("x", pt.x()); + values.putInt("y", pt.y()); + values.putInt("z", pt.z()); + values.put("id", tileEntity.value().get("Id")); + if (fixer.isActive()) { + tileEntity = fixer.fixUp(DataFixer.FixTypes.BLOCK_ENTITY, values.build()); + } else { + tileEntity = values.build(); + } + tileEntitiesMap.put(pt, tileEntity); + } + } + + int width = clipboard.getRegion().getWidth(); + int length = clipboard.getRegion().getLength(); + + int index = 0; + for (VarIntIterator iter = new VarIntIterator(blocks); iter.hasNext(); index++) { + int nextBlockId = iter.nextInt(); + BlockState state = palette.get(nextBlockId); + BlockVector3 rawPos = decodePositionFromDataIndex(width, length, index); + try { + BlockVector3 offsetPos = clipboard.getMinimumPoint().add(rawPos); + LinCompoundTag tileEntity = tileEntitiesMap.get(offsetPos); + clipboard.setBlock(offsetPos, state.toBaseBlock(tileEntity)); + } catch (WorldEditException e) { + throw new IOException("Failed to load a block in the schematic", e); + } + } + } + + private static LinCompoundTag.Builder extractData(boolean dataIsNested, LinCompoundTag tag) { + if (dataIsNested) { + LinCompoundTag dataTag = tag.findTag("Data", LinTagType.compoundTag()); + return dataTag != null ? dataTag.toBuilder() : LinCompoundTag.builder(); + } else { + LinCompoundTag.Builder values = tag.toBuilder(); + values.remove("Id"); + values.remove("Pos"); + return values; + } + } + + static BlockVector3 decodePositionFromDataIndex(int width, int length, int index) { + // index = (y * width * length) + (z * width) + x + int y = index / (width * length); + int remainder = index - (y * width * length); + int z = remainder / width; + int x = remainder - z * width; + return BlockVector3.at(x, y, z); + } + + static BlockVector3 decodeBlockVector3(@Nullable LinIntArrayTag tag) throws IOException { + if (tag == null) { + return BlockVector3.ZERO; + } + int[] parts = tag.value(); + if (parts.length != 3) { + throw new IOException("Invalid block vector specified in schematic."); + } + return BlockVector3.at(parts[0], parts[1], parts[2]); + } + + static void readEntities( + BlockArrayClipboard clipboard, List entList, + VersionedDataFixer fixer, boolean positionIsRelative + ) { + if (entList.isEmpty()) { + return; + } + for (LinCompoundTag entityTag : entList) { + String id = entityTag.getTag("Id", LinTagType.stringTag()).value(); + LinCompoundTag.Builder values = extractData(positionIsRelative, entityTag); + LinCompoundTag dataTag = values.putString("id", id).build(); + dataTag = fixer.fixUp(DataFixer.FixTypes.ENTITY, dataTag); + + EntityType entityType = EntityTypes.get(id); + if (entityType != null) { + Location location = NBTConversions.toLocation( + clipboard, + entityTag.getListTag("Pos", LinTagType.doubleTag()), + dataTag.getListTag("Rotation", LinTagType.floatTag()) + ); + BaseEntity state = new BaseEntity(entityType, LazyReference.computed(dataTag)); + if (positionIsRelative) { + location = location.setPosition( + location.toVector().add(clipboard.getMinimumPoint().toVector3()) + ); + } + clipboard.createEntity(location, state); + } else { + LOGGER.warn("Unknown entity when pasting schematic: " + id); + } + } + } + + static Int2ObjectMap readBiomePalette(VersionedDataFixer fixer, LinCompoundTag paletteTag, Logger logger) throws + IOException { + Int2ObjectMap palette = new Int2ObjectLinkedOpenHashMap<>(paletteTag.value().size()); + for (var palettePart : paletteTag.value().entrySet()) { + String key = palettePart.getKey(); + key = fixer.fixUp(DataFixer.FixTypes.BIOME, key); + BiomeType biome = BiomeTypes.get(key); + if (biome == null) { + logger.warn("Unknown biome type :" + key + + " in palette. Are you missing a mod or using a schematic made in a newer version of Minecraft?"); + } + if (!(palettePart.getValue() instanceof LinIntTag idTag)) { + throw new IOException("Biome mapped to non-Int tag."); + } + palette.put(idTag.valueAsInt(), biome); + } + return palette; + } + + private ReaderUtil() { + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV1Reader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV1Reader.java new file mode 100644 index 000000000..7574bfe4c --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV1Reader.java @@ -0,0 +1,134 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io.sponge; + +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader; +import com.sk89q.worldedit.internal.Constants; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.block.BlockState; +import org.enginehub.linbus.stream.LinStream; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinRootEntry; +import org.enginehub.linbus.tree.LinTagType; + +import java.io.IOException; +import java.util.Map; +import java.util.OptionalInt; + +/** + * Reads schematic files using the Sponge Schematic Specification (Version 1). + */ +public class SpongeSchematicV1Reader implements ClipboardReader { + + private final LinStream rootStream; + + public SpongeSchematicV1Reader(LinStream rootStream) { + this.rootStream = rootStream; + } + + @Override + public Clipboard read() throws IOException { + LinCompoundTag schematicTag = getBaseTag(); + ReaderUtil.checkSchematicVersion(1, schematicTag); + + return doRead(schematicTag); + } + + // For legacy SpongeSchematicReader, can be inlined in WorldEdit 8 + public static BlockArrayClipboard doRead(LinCompoundTag schematicTag) throws IOException { + final Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING); + + // this is a relatively safe assumption unless someone imports a schematic from 1.12 + // e.g. sponge 7.1- + VersionedDataFixer fixer = new VersionedDataFixer(Constants.DATA_VERSION_MC_1_13_2, platform.getDataFixer()); + return readVersion1(schematicTag, fixer); + } + + @Override + public OptionalInt getDataVersion() { + try { + // Validate schematic version to be sure + ReaderUtil.checkSchematicVersion(1, getBaseTag()); + return OptionalInt.of(Constants.DATA_VERSION_MC_1_13_2); + } catch (IOException e) { + return OptionalInt.empty(); + } + } + + private LinCompoundTag getBaseTag() throws IOException { + return LinRootEntry.readFrom(rootStream).value(); + } + + static BlockArrayClipboard readVersion1(LinCompoundTag schematicTag, VersionedDataFixer fixer) throws IOException { + int width = schematicTag.getTag("Width", LinTagType.shortTag()).valueAsShort() & 0xFFFF; + int height = schematicTag.getTag("Height", LinTagType.shortTag()).valueAsShort() & 0xFFFF; + int length = schematicTag.getTag("Length", LinTagType.shortTag()).valueAsShort() & 0xFFFF; + + BlockVector3 min = ReaderUtil.decodeBlockVector3(schematicTag.findTag("Offset", LinTagType.intArrayTag())); + + BlockVector3 offset = BlockVector3.ZERO; + LinCompoundTag metadataTag = schematicTag.findTag("Metadata", LinTagType.compoundTag()); + if (metadataTag != null) { + LinIntTag offsetX = metadataTag.findTag("WEOffsetX", LinTagType.intTag()); + if (offsetX != null) { + int offsetY = metadataTag.getTag("WEOffsetY", LinTagType.intTag()).valueAsInt(); + int offsetZ = metadataTag.getTag("WEOffsetZ", LinTagType.intTag()).valueAsInt(); + offset = BlockVector3.at(offsetX.valueAsInt(), offsetY, offsetZ); + } + } + + BlockVector3 origin = min.subtract(offset); + Region region = new CuboidRegion(min, min.add(width, height, length).subtract(BlockVector3.ONE)); + + LinIntTag paletteMaxTag = schematicTag.findTag("PaletteMax", LinTagType.intTag()); + LinCompoundTag paletteObject = schematicTag.getTag("Palette", LinTagType.compoundTag()); + if (paletteMaxTag != null && paletteObject.value().size() != paletteMaxTag.valueAsInt()) { + throw new IOException("Block palette size does not match expected size."); + } + + Map palette = ReaderUtil.decodePalette(paletteObject, fixer); + + byte[] blocks = schematicTag.getTag("BlockData", LinTagType.byteArrayTag()).value(); + + LinListTag tileEntities = schematicTag.findListTag("BlockEntities", LinTagType.compoundTag()); + if (tileEntities == null) { + tileEntities = schematicTag.findListTag("TileEntities", LinTagType.compoundTag()); + } + + BlockArrayClipboard clipboard = new BlockArrayClipboard(region); + clipboard.setOrigin(origin); + ReaderUtil.initializeClipboardFromBlocks(clipboard, palette, blocks, tileEntities, fixer, false); + return clipboard; + } + + @Override + public void close() throws IOException { + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV2Reader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV2Reader.java new file mode 100644 index 000000000..2cd7bb1e1 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV2Reader.java @@ -0,0 +1,144 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io.sponge; + +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader; +import com.sk89q.worldedit.internal.util.LogManagerCompat; +import com.sk89q.worldedit.internal.util.VarIntIterator; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.biome.BiomeType; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.apache.logging.log4j.Logger; +import org.enginehub.linbus.stream.LinStream; +import org.enginehub.linbus.tree.LinByteArrayTag; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinIntTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinRootEntry; +import org.enginehub.linbus.tree.LinTagType; + +import java.io.IOException; +import java.util.OptionalInt; + +/** + * Reads schematic files using the Sponge Schematic Specification (Version 2). + */ +public class SpongeSchematicV2Reader implements ClipboardReader { + + private static final Logger LOGGER = LogManagerCompat.getLogger(); + + private final LinStream rootStream; + + public SpongeSchematicV2Reader(LinStream rootStream) { + this.rootStream = rootStream; + } + + @Override + public Clipboard read() throws IOException { + LinCompoundTag schematicTag = getBaseTag(); + ReaderUtil.checkSchematicVersion(2, schematicTag); + + return doRead(schematicTag); + } + + // For legacy SpongeSchematicReader, can be inlined in WorldEdit 8 + public static Clipboard doRead(LinCompoundTag schematicTag) throws IOException { + final Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING); + int liveDataVersion = platform.getDataVersion(); + + VersionedDataFixer fixer = ReaderUtil.getVersionedDataFixer(schematicTag, platform, liveDataVersion); + BlockArrayClipboard clip = SpongeSchematicV1Reader.readVersion1(schematicTag, fixer); + return readVersion2(clip, schematicTag, fixer); + } + + @Override + public OptionalInt getDataVersion() { + try { + LinCompoundTag schematicTag = getBaseTag(); + ReaderUtil.checkSchematicVersion(2, schematicTag); + + int dataVersion = schematicTag.getTag("DataVersion", LinTagType.intTag()).valueAsInt(); + if (dataVersion < 0) { + return OptionalInt.empty(); + } + return OptionalInt.of(dataVersion); + } catch (IOException e) { + return OptionalInt.empty(); + } + } + + private LinCompoundTag getBaseTag() throws IOException { + return LinRootEntry.readFrom(rootStream).value(); + } + + private static Clipboard readVersion2( + BlockArrayClipboard version1, LinCompoundTag schematicTag, VersionedDataFixer fixer + ) throws IOException { + if (schematicTag.value().containsKey("BiomeData")) { + readBiomes2(version1, schematicTag, fixer); + } + LinListTag entities = schematicTag.findListTag("Entities", LinTagType.compoundTag()); + if (entities != null) { + ReaderUtil.readEntities(version1, entities.value(), fixer, false); + } + return version1; + } + + private static void readBiomes2( + BlockArrayClipboard clipboard, LinCompoundTag schematic, VersionedDataFixer fixer + ) throws IOException { + LinByteArrayTag dataTag = schematic.getTag("BiomeData", LinTagType.byteArrayTag()); + LinIntTag maxTag = schematic.getTag("BiomePaletteMax", LinTagType.intTag()); + LinCompoundTag paletteTag = schematic.getTag("BiomePalette", LinTagType.compoundTag()); + + if (maxTag.valueAsInt() != paletteTag.value().size()) { + throw new IOException("Biome palette size does not match expected size."); + } + + Int2ObjectMap palette = ReaderUtil.readBiomePalette(fixer, paletteTag, LOGGER); + + int width = clipboard.getDimensions().x(); + + byte[] biomes = dataTag.value(); + BlockVector3 min = clipboard.getMinimumPoint(); + int index = 0; + for (VarIntIterator iter = new VarIntIterator(biomes); iter.hasNext(); index++) { + int nextBiomeId = iter.nextInt(); + BiomeType type = palette.get(nextBiomeId); + // hack -- the x and y values from the 3d decode with length == 1 are equivalent + BlockVector3 hackDecode = ReaderUtil.decodePositionFromDataIndex(width, 1, index); + int x = hackDecode.x(); + int z = hackDecode.y(); + for (int y = 0; y < clipboard.getRegion().getHeight(); y++) { + clipboard.setBiome(min.add(x, y, z), type); + } + } + } + + @Override + public void close() throws IOException { + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV2Writer.java similarity index 51% rename from worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java rename to worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV2Writer.java index 38c0115e5..8504f0fe8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV2Writer.java @@ -17,62 +17,41 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.extent.clipboard.io; +package com.sk89q.worldedit.extent.clipboard.io.sponge; -import com.fastasyncworldedit.core.Fawe; -import com.google.common.collect.Maps; -import com.sk89q.jnbt.ByteArrayTag; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.IntArrayTag; -import com.sk89q.jnbt.IntTag; -import com.sk89q.jnbt.ListTag; -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.entity.BaseEntity; import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; +import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntMaps; +import org.enginehub.linbus.stream.LinBinaryIO; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinRootEntry; +import org.enginehub.linbus.tree.LinTagType; import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -import static com.google.common.base.Preconditions.checkNotNull; /** - * Writes schematic files using the Sponge schematic format. - * - * @deprecated Slow, resource intensive, but sometimes safer than using the recommended - * {@link com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriter}. - * Avoid using large clipboards to create schematics with this writer. + * Writes schematic files using the Sponge Schematic Specification (Version 2). */ -@Deprecated -public class SpongeSchematicWriter implements ClipboardWriter { +public class SpongeSchematicV2Writer implements ClipboardWriter { private static final int CURRENT_VERSION = 2; private static final int MAX_SIZE = Short.MAX_VALUE - Short.MIN_VALUE; - private final NBTOutputStream outputStream; + private final DataOutputStream outputStream; - /** - * Create a new schematic writer. - * - * @param outputStream the output stream to write to - */ - public SpongeSchematicWriter(NBTOutputStream outputStream) { - checkNotNull(outputStream); + public SpongeSchematicV2Writer(DataOutputStream outputStream) { this.outputStream = outputStream; } @@ -82,17 +61,16 @@ public class SpongeSchematicWriter implements ClipboardWriter { // between upstream and FAWE clipboard.flush(); //FAWE end - // For now always write the latest version. Maybe provide support for earlier if more appear. - outputStream.writeNamedTag("Schematic", new CompoundTag(write2(clipboard))); + LinBinaryIO.write(outputStream, new LinRootEntry("Schematic", write2(clipboard))); } /** * Writes a version 2 schematic file. * * @param clipboard The clipboard - * @return The schematic map + * @return the schematic tag */ - private Map> write2(Clipboard clipboard) { + private LinCompoundTag write2(Clipboard clipboard) { Region region = clipboard.getRegion(); BlockVector3 origin = clipboard.getOrigin(); BlockVector3 min = region.getMinimumPoint(); @@ -111,34 +89,49 @@ public class SpongeSchematicWriter implements ClipboardWriter { throw new IllegalArgumentException("Length of region too large for a .schematic"); } - Map> schematic = new HashMap<>(); - schematic.put("Version", new IntTag(CURRENT_VERSION)); - schematic.put("DataVersion", new IntTag( - WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion())); + LinCompoundTag.Builder schematic = LinCompoundTag.builder(); + schematic.putInt("Version", CURRENT_VERSION); + schematic.putInt("DataVersion", + WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion() + ); - Map> metadata = new HashMap<>(); - metadata.put("WEOffsetX", new IntTag(offset.x())); - metadata.put("WEOffsetY", new IntTag(offset.y())); - metadata.put("WEOffsetZ", new IntTag(offset.z())); - metadata.put("FAWEVersion", new IntTag(Fawe.instance().getVersion().build)); + LinCompoundTag.Builder metadata = LinCompoundTag.builder(); + metadata.putInt("WEOffsetX", offset.x()); + metadata.putInt("WEOffsetY", offset.y()); + metadata.putInt("WEOffsetZ", offset.z()); - schematic.put("Metadata", new CompoundTag(metadata)); + LinCompoundTag.Builder worldEditSection = LinCompoundTag.builder(); + worldEditSection.putString("Version", WorldEdit.getVersion()); + worldEditSection.putString("EditingPlatform", + WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).id() + ); + worldEditSection.putIntArray("Offset", new int[]{offset.x(), offset.y(), offset.z()}); - schematic.put("Width", new ShortTag((short) width)); - schematic.put("Height", new ShortTag((short) height)); - schematic.put("Length", new ShortTag((short) length)); + LinCompoundTag.Builder platformsSection = LinCompoundTag.builder(); + for (Platform platform : WorldEdit.getInstance().getPlatformManager().getPlatforms()) { + platformsSection.put(platform.id(), LinCompoundTag + .builder() + .putString("Name", platform.getPlatformName()) + .putString("Version", platform.getPlatformVersion()) + .build()); + } + worldEditSection.put("Platforms", platformsSection.build()); + + metadata.put("WorldEdit", worldEditSection.build()); + + schematic.put("Metadata", metadata.build()); + + schematic.putShort("Width", (short) width); + schematic.putShort("Height", (short) height); + schematic.putShort("Length", (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[]{ - min.x(), - min.y(), - min.z(), - })); + schematic.putIntArray("Offset", new int[]{min.x(), min.y(), min.z(),}); int paletteMax = 0; - Map palette = new HashMap<>(); + Object2IntMap palette = new Object2IntLinkedOpenHashMap<>(); - List tileEntities = new ArrayList<>(); + LinListTag.Builder tileEntities = LinListTag.builder(LinTagType.compoundTag()); ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length); @@ -150,8 +143,9 @@ public class SpongeSchematicWriter implements ClipboardWriter { int x0 = min.x() + x; BlockVector3 point = BlockVector3.at(x0, y0, z0); BaseBlock block = clipboard.getFullBlock(point); - if (block.getNbtData() != null) { - Map> values = new HashMap<>(block.getNbtData().getValue()); + LinCompoundTag nbt = block.getNbt(); + if (nbt != null) { + LinCompoundTag.Builder values = nbt.toBuilder(); values.remove("id"); // Remove 'id' if it exists. We want 'Id' @@ -160,16 +154,16 @@ public class SpongeSchematicWriter implements ClipboardWriter { values.remove("y"); values.remove("z"); - values.put("Id", new StringTag(block.getNbtId())); - values.put("Pos", new IntArrayTag(new int[]{x, y, z})); + values.putString("Id", block.getNbtId()); + values.putIntArray("Pos", new int[]{x, y, z}); - tileEntities.add(new CompoundTag(values)); + tileEntities.add(values.build()); } String blockKey = block.toImmutableState().getAsString(); int blockId; if (palette.containsKey(blockKey)) { - blockId = palette.get(blockKey); + blockId = palette.getInt(blockKey); } else { blockId = paletteMax; palette.put(blockKey, blockId); @@ -185,14 +179,14 @@ public class SpongeSchematicWriter implements ClipboardWriter { } } - schematic.put("PaletteMax", new IntTag(paletteMax)); + schematic.putInt("PaletteMax", paletteMax); - Map> paletteTag = new HashMap<>(); - palette.forEach((key, value) -> paletteTag.put(key, new IntTag(value))); + LinCompoundTag.Builder paletteTag = LinCompoundTag.builder(); + Object2IntMaps.fastForEach(palette, e -> paletteTag.putInt(e.getKey(), e.getIntValue())); - schematic.put("Palette", new CompoundTag(paletteTag)); - schematic.put("BlockData", new ByteArrayTag(buffer.toByteArray())); - schematic.put("BlockEntities", new ListTag(CompoundTag.class, tileEntities)); + schematic.put("Palette", paletteTag.build()); + schematic.putByteArray("BlockData", buffer.toByteArray()); + schematic.put("BlockEntities", tileEntities.build()); // version 2 stuff if (clipboard.hasBiomes()) { @@ -200,13 +194,16 @@ public class SpongeSchematicWriter implements ClipboardWriter { } if (!clipboard.getEntities().isEmpty()) { - writeEntities(clipboard, schematic); + LinListTag value = WriterUtil.encodeEntities(clipboard, false); + if (value != null) { + schematic.put("Entities", value); + } } - return schematic; + return schematic.build(); } - private void writeBiomes(Clipboard clipboard, Map> schematic) { + private void writeBiomes(Clipboard clipboard, LinCompoundTag.Builder schematic) { BlockVector3 min = clipboard.getMinimumPoint(); int width = clipboard.getRegion().getWidth(); int length = clipboard.getRegion().getLength(); @@ -214,7 +211,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * length); int paletteMax = 0; - Map palette = new HashMap<>(); + Object2IntMap palette = new Object2IntLinkedOpenHashMap<>(); for (int z = 0; z < length; z++) { int z0 = min.z() + z; @@ -226,7 +223,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { String biomeKey = biome.id(); int biomeId; if (palette.containsKey(biomeKey)) { - biomeId = palette.get(biomeKey); + biomeId = palette.getInt(biomeKey); } else { biomeId = paletteMax; palette.put(biomeKey, biomeId); @@ -241,38 +238,13 @@ public class SpongeSchematicWriter implements ClipboardWriter { } } - schematic.put("BiomePaletteMax", new IntTag(paletteMax)); + schematic.putInt("BiomePaletteMax", paletteMax); - Map> paletteTag = new HashMap<>(); - palette.forEach((key, value) -> paletteTag.put(key, new IntTag(value))); + LinCompoundTag.Builder paletteTag = LinCompoundTag.builder(); + Object2IntMaps.fastForEach(palette, e -> paletteTag.putInt(e.getKey(), e.getIntValue())); - schematic.put("BiomePalette", new CompoundTag(paletteTag)); - schematic.put("BiomeData", new ByteArrayTag(buffer.toByteArray())); - } - - private void writeEntities(Clipboard clipboard, Map> schematic) { - List entities = clipboard.getEntities().stream().map(e -> { - BaseEntity state = e.getState(); - if (state == null) { - return null; - } - Map> values = Maps.newHashMap(); - CompoundTag rawData = state.getNbtData(); - if (rawData != null) { - values.putAll(rawData.getValue()); - } - values.remove("id"); - values.put("Id", new StringTag(state.getType().id())); - final Location location = e.getLocation(); - values.put("Pos", writeVector(location.toVector())); - values.put("Rotation", writeRotation(location)); - - return new CompoundTag(values); - }).filter(Objects::nonNull).collect(Collectors.toList()); - if (entities.isEmpty()) { - return; - } - schematic.put("Entities", new ListTag(CompoundTag.class, entities)); + schematic.put("BiomePalette", paletteTag.build()); + schematic.putByteArray("BiomeData", buffer.toByteArray()); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV3Reader.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV3Reader.java new file mode 100644 index 000000000..978cb8ba5 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV3Reader.java @@ -0,0 +1,168 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io.sponge; + +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader; +import com.sk89q.worldedit.internal.util.LogManagerCompat; +import com.sk89q.worldedit.internal.util.VarIntIterator; +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.BlockState; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import org.apache.logging.log4j.Logger; +import org.enginehub.linbus.stream.LinStream; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinRootEntry; +import org.enginehub.linbus.tree.LinTagType; + +import java.io.IOException; +import java.util.Map; +import java.util.OptionalInt; + +/** + * Reads schematic files using the Sponge Schematic Specification. + */ +public class SpongeSchematicV3Reader implements ClipboardReader { + + private static final Logger LOGGER = LogManagerCompat.getLogger(); + + private final LinStream rootStream; + + public SpongeSchematicV3Reader(LinStream rootStream) { + this.rootStream = rootStream; + } + + @Override + public Clipboard read() throws IOException { + LinCompoundTag schematicTag = getBaseTag(); + ReaderUtil.checkSchematicVersion(3, schematicTag); + + final Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING); + int liveDataVersion = platform.getDataVersion(); + + VersionedDataFixer fixer = ReaderUtil.getVersionedDataFixer(schematicTag, platform, liveDataVersion); + return readVersion3(schematicTag, fixer); + } + + @Override + public OptionalInt getDataVersion() { + try { + LinCompoundTag schematicTag = getBaseTag(); + ReaderUtil.checkSchematicVersion(3, schematicTag); + + int dataVersion = schematicTag.getTag("DataVersion", LinTagType.intTag()).valueAsInt(); + if (dataVersion < 0) { + return OptionalInt.empty(); + } + return OptionalInt.of(dataVersion); + } catch (IOException e) { + return OptionalInt.empty(); + } + } + + private LinCompoundTag getBaseTag() throws IOException { + return LinRootEntry.readFrom(rootStream).value().getTag("Schematic", LinTagType.compoundTag()); + } + + private Clipboard readVersion3(LinCompoundTag schematicTag, VersionedDataFixer fixer) throws IOException { + int width = schematicTag.getTag("Width", LinTagType.shortTag()).valueAsShort() & 0xFFFF; + int height = schematicTag.getTag("Height", LinTagType.shortTag()).valueAsShort() & 0xFFFF; + int length = schematicTag.getTag("Length", LinTagType.shortTag()).valueAsShort() & 0xFFFF; + + BlockVector3 offset = ReaderUtil.decodeBlockVector3(schematicTag.findTag("Offset", LinTagType.intArrayTag())); + + BlockVector3 origin = BlockVector3.ZERO; + LinCompoundTag metadataTag = schematicTag.findTag("Metadata", LinTagType.compoundTag()); + if (metadataTag != null) { + LinCompoundTag worldeditMeta = metadataTag.findTag("WorldEdit", LinTagType.compoundTag()); + if (worldeditMeta != null) { + origin = ReaderUtil.decodeBlockVector3(worldeditMeta.findTag("Origin", LinTagType.intArrayTag())); + } + } + BlockVector3 min = offset.add(origin); + + BlockArrayClipboard clipboard = new BlockArrayClipboard(new CuboidRegion( + min, + min.add(width, height, length).subtract(BlockVector3.ONE) + )); + clipboard.setOrigin(origin); + + decodeBlocksIntoClipboard(fixer, schematicTag, clipboard); + + LinCompoundTag biomeContainer = schematicTag.findTag("Biomes", LinTagType.compoundTag()); + if (biomeContainer != null) { + readBiomes3(clipboard, biomeContainer, fixer); + } + + LinListTag entities = schematicTag.findListTag("Entities", LinTagType.compoundTag()); + if (entities != null) { + ReaderUtil.readEntities(clipboard, entities.value(), fixer, true); + } + + return clipboard; + } + + private void decodeBlocksIntoClipboard( + VersionedDataFixer fixer, LinCompoundTag schematic, BlockArrayClipboard clipboard + ) throws IOException { + LinCompoundTag blockContainer = schematic.getTag("Blocks", LinTagType.compoundTag()); + + LinCompoundTag paletteObject = blockContainer.getTag("Palette", LinTagType.compoundTag()); + Map palette = ReaderUtil.decodePalette(paletteObject, fixer); + + byte[] blocks = blockContainer.getTag("Data", LinTagType.byteArrayTag()).value(); + LinListTag blockEntities = blockContainer.getListTag("BlockEntities", LinTagType.compoundTag()); + + ReaderUtil.initializeClipboardFromBlocks(clipboard, palette, blocks, blockEntities, fixer, true); + } + + private void readBiomes3( + BlockArrayClipboard clipboard, LinCompoundTag biomeContainer, VersionedDataFixer fixer + ) throws IOException { + LinCompoundTag paletteTag = biomeContainer.getTag("Palette", LinTagType.compoundTag()); + + Int2ObjectMap palette = ReaderUtil.readBiomePalette(fixer, paletteTag, LOGGER); + + int width = clipboard.getRegion().getWidth(); + int length = clipboard.getRegion().getLength(); + + byte[] biomes = biomeContainer.getTag("Data", LinTagType.byteArrayTag()).value(); + BlockVector3 min = clipboard.getMinimumPoint(); + int index = 0; + for (VarIntIterator iter = new VarIntIterator(biomes); iter.hasNext(); index++) { + int nextBiomeId = iter.nextInt(); + BiomeType type = palette.get(nextBiomeId); + BlockVector3 pos = ReaderUtil.decodePositionFromDataIndex(width, length, index); + clipboard.setBiome(min.add(pos), type); + } + } + + @Override + public void close() throws IOException { + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV3Writer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV3Writer.java new file mode 100644 index 000000000..4030c2f90 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/SpongeSchematicV3Writer.java @@ -0,0 +1,233 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io.sponge; + +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.block.BaseBlock; +import it.unimi.dsi.fastutil.objects.Object2IntLinkedOpenHashMap; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntMaps; +import org.enginehub.linbus.stream.LinBinaryIO; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinRootEntry; +import org.enginehub.linbus.tree.LinTagType; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.function.Function; + +/** + * Writes schematic files using the Sponge Schematic Specification (Version 3). + */ +public class SpongeSchematicV3Writer implements ClipboardWriter { + + private static final int CURRENT_VERSION = 3; + + private static final int MAX_SIZE = Short.MAX_VALUE - Short.MIN_VALUE; + private final DataOutputStream outputStream; + + public SpongeSchematicV3Writer(DataOutputStream outputStream) { + this.outputStream = outputStream; + } + + @Override + public void write(Clipboard clipboard) throws IOException { + //FAWE start - ensure clipboard is flushed in case of using clipboard-on-disk. Maintains allowing of the same code + // between upstream and FAWE + clipboard.flush(); + //FAWE end + LinBinaryIO.write(outputStream, + new LinRootEntry("", LinCompoundTag.builder().put("Schematic", write3(clipboard)).build()) + ); + } + + /** + * Writes a version 3 schematic file. + * + * @param clipboard The clipboard + * @return The schematic map + */ + private LinCompoundTag write3(Clipboard clipboard) { + Region region = clipboard.getRegion(); + BlockVector3 origin = clipboard.getOrigin(); + BlockVector3 min = region.getMinimumPoint(); + BlockVector3 offset = min.subtract(origin); + int width = region.getWidth(); + int height = region.getHeight(); + int length = region.getLength(); + + if (width > MAX_SIZE) { + throw new IllegalArgumentException("Width of region too large for a .schematic"); + } + if (height > MAX_SIZE) { + throw new IllegalArgumentException("Height of region too large for a .schematic"); + } + if (length > MAX_SIZE) { + throw new IllegalArgumentException("Length of region too large for a .schematic"); + } + + LinCompoundTag.Builder schematic = LinCompoundTag.builder(); + schematic.putInt("Version", CURRENT_VERSION); + schematic.putInt("DataVersion", + WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).getDataVersion() + ); + + LinCompoundTag.Builder metadata = LinCompoundTag.builder(); + metadata.putLong("Date", System.currentTimeMillis()); + + LinCompoundTag.Builder worldEditSection = LinCompoundTag.builder(); + worldEditSection.putString("Version", WorldEdit.getVersion()); + worldEditSection.putString("EditingPlatform", + WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING).id() + ); + worldEditSection.putIntArray("Origin", new int[]{origin.x(), origin.y(), origin.z()}); + + LinCompoundTag.Builder platformsSection = LinCompoundTag.builder(); + for (Platform platform : WorldEdit.getInstance().getPlatformManager().getPlatforms()) { + platformsSection.put(platform.id(), LinCompoundTag + .builder() + .putString("Name", platform.getPlatformName()) + .putString("Version", platform.getPlatformVersion()) + .build()); + } + worldEditSection.put("Platforms", platformsSection.build()); + + metadata.put("WorldEdit", worldEditSection.build()); + + schematic.put("Metadata", metadata.build()); + + schematic.putShort("Width", (short) width); + schematic.putShort("Height", (short) height); + schematic.putShort("Length", (short) length); + + schematic.putIntArray("Offset", new int[]{offset.x(), offset.y(), offset.z(),}); + + schematic.put("Blocks", encodeBlocks(clipboard)); + + if (clipboard.hasBiomes()) { + schematic.put("Biomes", encodeBiomes(clipboard)); + } + + if (!clipboard.getEntities().isEmpty()) { + LinListTag value = WriterUtil.encodeEntities(clipboard, true); + if (value != null) { + schematic.put("Entities", value); + } + } + + return schematic.build(); + } + + private static final class PaletteMap { + + private final Object2IntMap contents = new Object2IntLinkedOpenHashMap<>(); + private int nextId = 0; + + public int getId(String key) { + int result = contents.getOrDefault(key, -1); + if (result != -1) { + return result; + } + int newValue = nextId; + nextId++; + contents.put(key, newValue); + return newValue; + } + + public LinCompoundTag toNbt() { + LinCompoundTag.Builder result = LinCompoundTag.builder(); + Object2IntMaps.fastForEach(contents, e -> result.putInt(e.getKey(), e.getIntValue())); + return result.build(); + } + + } + + private LinCompoundTag encodeBlocks(Clipboard clipboard) { + LinListTag.Builder blockEntities = LinListTag.builder(LinTagType.compoundTag()); + LinCompoundTag.Builder result = encodePalettedData(clipboard, point -> { + BaseBlock block = clipboard.getFullBlock(point); + // Also compute block entity side-effect here + LinCompoundTag nbt = block.getNbt(); + if (nbt != null) { + LinCompoundTag.Builder builder = LinCompoundTag.builder(); + + builder.putString("Id", block.getNbtId()); + BlockVector3 adjustedPos = point.subtract(clipboard.getMinimumPoint()); + builder.putIntArray("Pos", new int[]{adjustedPos.x(), adjustedPos.y(), adjustedPos.z()}); + builder.put("Data", nbt); + + blockEntities.add(builder.build()); + } + return block.toImmutableState().getAsString(); + }); + + return result.put("BlockEntities", blockEntities.build()).build(); + } + + private LinCompoundTag encodeBiomes(Clipboard clipboard) { + return encodePalettedData(clipboard, point -> clipboard.getBiome(point).id()).build(); + } + + private LinCompoundTag.Builder encodePalettedData( + Clipboard clipboard, Function keyFunction + ) { + BlockVector3 min = clipboard.getMinimumPoint(); + int width = clipboard.getRegion().getWidth(); + int height = clipboard.getRegion().getHeight(); + int length = clipboard.getRegion().getLength(); + + PaletteMap paletteMap = new PaletteMap(); + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(width * height * length); + + for (int y = 0; y < height; y++) { + for (int z = 0; z < length; z++) { + for (int x = 0; x < width; x++) { + BlockVector3 point = min.add(x, y, z); + + String key = keyFunction.apply(point); + int id = paletteMap.getId(key); + + while ((id & -128) != 0) { + buffer.write(id & 127 | 128); + id >>>= 7; + } + buffer.write(id); + } + } + } + + return LinCompoundTag.builder().put("Palette", paletteMap.toNbt()).putByteArray("Data", buffer.toByteArray()); + } + + @Override + public void close() throws IOException { + outputStream.close(); + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/VersionedDataFixer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/VersionedDataFixer.java new file mode 100644 index 000000000..35f6d58bc --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/VersionedDataFixer.java @@ -0,0 +1,47 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io.sponge; + + +import com.sk89q.worldedit.world.DataFixer; + +import javax.annotation.Nullable; + +public final class VersionedDataFixer { //FAWE - public + private final int dataVersion; + @Nullable + private final DataFixer fixer; + + public VersionedDataFixer(int dataVersion, @Nullable DataFixer fixer) { //FAWE - public + this.dataVersion = dataVersion; + this.fixer = fixer; + } + + public boolean isActive() { + return fixer != null; + } + + public T fixUp(DataFixer.FixType type, T original) { + if (!isActive()) { + return original; + } + return fixer.fixUp(type, original, dataVersion); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/WriterUtil.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/WriterUtil.java new file mode 100644 index 000000000..17ff5004d --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/WriterUtil.java @@ -0,0 +1,91 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.clipboard.io.sponge; + +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.math.Vector3; +import com.sk89q.worldedit.util.Location; +import org.enginehub.linbus.tree.LinCompoundTag; +import org.enginehub.linbus.tree.LinDoubleTag; +import org.enginehub.linbus.tree.LinFloatTag; +import org.enginehub.linbus.tree.LinListTag; +import org.enginehub.linbus.tree.LinTagType; + +class WriterUtil { + + static LinListTag encodeEntities(Clipboard clipboard, boolean positionIsRelative) { + LinListTag.Builder entities = LinListTag.builder(LinTagType.compoundTag()); + for (Entity entity : clipboard.getEntities()) { + LinCompoundTag encoded = encodeEntity(clipboard, positionIsRelative, entity); + if (encoded != null) { + entities.add(encoded); + } + } + var result = entities.build(); + if (result.value().isEmpty()) { + return null; + } + return result; + } + + private static LinCompoundTag encodeEntity(Clipboard clipboard, boolean positionIsRelative, Entity e) { + BaseEntity state = e.getState(); + if (state == null) { + return null; + } + LinCompoundTag.Builder fullTagBuilder = LinCompoundTag.builder(); + LinCompoundTag.Builder dataTagBuilder = LinCompoundTag.builder(); + LinCompoundTag rawData = state.getNbt(); + if (rawData != null) { + dataTagBuilder.putAll(rawData.value()); + dataTagBuilder.remove("id"); + } + final Location location = e.getLocation(); + Vector3 pos = location.toVector(); + dataTagBuilder.put("Rotation", encodeRotation(location)); + if (positionIsRelative) { + pos = pos.subtract(clipboard.getMinimumPoint().toVector3()); + + fullTagBuilder.put("Data", dataTagBuilder.build()); + } else { + fullTagBuilder.putAll(dataTagBuilder.build().value()); + } + fullTagBuilder.putString("Id", state.getType().id()); + fullTagBuilder.put("Pos", encodeVector(pos)); + + return fullTagBuilder.build(); + } + + static LinListTag encodeVector(Vector3 vector) { + return LinListTag.builder(LinTagType.doubleTag()).add(LinDoubleTag.of(vector.x())).add(LinDoubleTag.of(vector.y())).add( + LinDoubleTag.of(vector.z())).build(); + } + + static LinListTag encodeRotation(Location location) { + return LinListTag + .builder(LinTagType.floatTag()) + .add(LinFloatTag.of(location.getYaw())) + .add(LinFloatTag.of(location.getPitch())) + .build(); + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/package-info.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/package-info.java new file mode 100644 index 000000000..930ae5efb --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/sponge/package-info.java @@ -0,0 +1,26 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * This package is internal, containing implementation details of the Sponge Schematic + * Specification. Use the {@link com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats} or + * {@link com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat} classes to + * acquire readers and writers instead. + */ +package com.sk89q.worldedit.extent.clipboard.io.sponge; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/VarIntIterator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/VarIntIterator.java new file mode 100644 index 000000000..ac91c8365 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/VarIntIterator.java @@ -0,0 +1,81 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.internal.util; + +import it.unimi.dsi.fastutil.ints.IntIterator; + +import java.util.NoSuchElementException; +import java.util.PrimitiveIterator; + +/** + * Simple class to transform a {@code byte[]} into an iterator of the VarInts encoded in it. + */ +public class VarIntIterator implements PrimitiveIterator.OfInt { + + private final byte[] source; + private int index; + private boolean hasNextInt; + private int nextInt; + + public VarIntIterator(byte[] source) { + this.source = source; + } + + @Override + public boolean hasNext() { + if (hasNextInt) { + return true; + } + if (index >= source.length) { + return false; + } + + nextInt = readNextInt(); + return hasNextInt = true; + } + + private int readNextInt() { + int value = 0; + for (int bitsRead = 0; ; bitsRead += 7) { + if (index >= source.length) { + throw new IllegalStateException("Ran out of bytes while reading VarInt (probably corrupted data)"); + } + byte next = source[index]; + index++; + value |= (next & 0x7F) << bitsRead; + if (bitsRead > 7 * 5) { + throw new IllegalStateException("VarInt too big (probably corrupted data)"); + } + if ((next & 0x80) == 0) { + break; + } + } + return value; + } + + @Override + public int nextInt() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + hasNextInt = false; + return nextInt; + } +} From 528d2632fa6702cd8fe39946b403cdc33ac2c9bf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 00:56:55 +0000 Subject: [PATCH 205/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.3.7 (#2833) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 48f436e07..79d9258b8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.3.4" +towny = "0.100.3.7" plotsquared = "7.3.8" # Third party From d4dd3638ffdd8b073557bbf1cfca5a59691c239f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 15 Jul 2024 01:00:58 +0000 Subject: [PATCH 206/220] Update dependency gradle to v8.9 (#2834) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a4413138c..09523c0e5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From b2f36facd861d72f61ae9193e5fcf8b532d9519e Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Tue, 16 Jul 2024 14:50:41 +0100 Subject: [PATCH 207/220] fix: identify schematic format by file if not specified --- .../java/com/sk89q/worldedit/command/SchematicCommands.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java index 920a24901..8a7751bd4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java @@ -356,7 +356,7 @@ public class SchematicCommands { File dir = Settings.settings().PATHS.PER_PLAYER_SCHEMATICS ? new File(saveDir, actor.getUniqueId().toString()) : saveDir; File file; if (filename.startsWith("#")) { - format = ClipboardFormats.findByAlias(formatName); + format = noExplicitFormat ? null : ClipboardFormats.findByAlias(formatName); String[] extensions; if (format != null) { extensions = format.getFileExtensions().toArray(new String[0]); @@ -396,7 +396,7 @@ public class SchematicCommands { .isInSubDirectory(saveDir, file)) + ")")); return; } - if (format == null) { + if (format == null || noExplicitFormat) { format = ClipboardFormats.findByFile(file); if (format == null) { actor.print(Caption.of("worldedit.schematic.unknown-format", TextComponent.of(formatName))); From bf07548695a05796f56a4118792af34561d3e103 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 17 Jul 2024 20:41:28 +0100 Subject: [PATCH 208/220] fix: add some file-extension bounds to schematic loading --- .../clipboard/io/BuiltInClipboardFormat.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java index 8a57411d6..736167056 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java @@ -112,6 +112,15 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { return false; } + @Override + public boolean isFormat(File file) { + String name = file.getName().toLowerCase(Locale.ROOT); + if (name.endsWith(".schematic") || name.endsWith(".mcedit") || name.endsWith(".mce")) { + return false; + } + return super.isFormat(file); + } + @Override public String getPrimaryFileExtension() { return "schem"; @@ -151,6 +160,15 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { return detectOldSpongeSchematic(inputStream, FastSchematicWriterV2.CURRENT_VERSION); } + @Override + public boolean isFormat(File file) { + String name = file.getName().toLowerCase(Locale.ROOT); + if (name.endsWith(".schematic") || name.endsWith(".mcedit") || name.endsWith(".mce")) { + return false; + } + return super.isFormat(file); + } + }, //FAWE end @@ -177,6 +195,15 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { //FAWE end } + @Override + public boolean isFormat(File file) { + String name = file.getName().toLowerCase(Locale.ROOT); + if (!name.endsWith(".schematic") && !name.endsWith(".mcedit") && !name.endsWith(".mce")) { + return false; + } + return super.isFormat(file); + } + @Override public boolean isFormat(InputStream inputStream) { LinRootEntry rootEntry; From 561ef4afdd3dd717d1f040b6440af39354d5826f Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Wed, 17 Jul 2024 20:45:20 +0100 Subject: [PATCH 209/220] chore: delegate to fast for checking if sponge schematic clipboard format --- .../extent/clipboard/io/BuiltInClipboardFormat.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java index 736167056..bfd6b2029 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java @@ -168,7 +168,6 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { } return super.isFormat(file); } - }, //FAWE end @@ -239,6 +238,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { public boolean isFormat(InputStream inputStream) { return detectOldSpongeSchematic(inputStream, 1); } + + @Override + public boolean isFormat(File file) { + return MCEDIT_SCHEMATIC.isFormat(file); + } }, /** @@ -268,6 +272,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { public boolean isFormat(InputStream inputStream) { return detectOldSpongeSchematic(inputStream, 2); } + + @Override + public boolean isFormat(File file) { + return FAST_V2.isFormat(file); + } }, SPONGE_V3_SCHEMATIC("sponge.3", "slow", "safe") { // FAWE - edit aliases for fast From 2e1a8f96652cc58e47b78a4a039bdbd786ac2243 Mon Sep 17 00:00:00 2001 From: Hannes Greule Date: Sun, 21 Jul 2024 09:19:59 +0200 Subject: [PATCH 210/220] Compile with target java 21, remove unsupported MC versions (#2836) * Compile with target java 21, remove unsupported MC versions * update bug report template --- .github/ISSUE_TEMPLATE/bug_report.yml | 7 +- buildSrc/src/main/kotlin/CommonJavaConfig.kt | 2 +- settings.gradle.kts | 2 +- .../adapters/adapter-1_19_4/build.gradle.kts | 17 - .../ext/fawe/v1_19_R3/PaperweightAdapter.java | 1077 ------- .../v1_19_R3/PaperweightDataConverters.java | 2799 ----------------- .../fawe/v1_19_R3/PaperweightFakePlayer.java | 93 - .../PaperweightWorldNativeAccess.java | 196 -- .../v1_19_R3/PaperweightBlockMaterial.java | 189 -- .../fawe/v1_19_R3/PaperweightFaweAdapter.java | 614 ---- .../PaperweightFaweWorldNativeAccess.java | 292 -- .../fawe/v1_19_R3/PaperweightGetBlocks.java | 1187 ------- .../v1_19_R3/PaperweightGetBlocks_Copy.java | 259 -- .../v1_19_R3/PaperweightMapChunkUtil.java | 34 - .../v1_19_R3/PaperweightPlatformAdapter.java | 748 ----- .../v1_19_R3/PaperweightPostProcessor.java | 175 -- .../PaperweightStarlightRelighter.java | 76 - .../PaperweightStarlightRelighterFactory.java | 25 - .../nbt/PaperweightLazyCompoundTag.java | 161 - .../fawe/v1_19_R3/regen/PaperweightRegen.java | 596 ---- .../adapters/adapter-1_20/build.gradle.kts | 17 - .../ext/fawe/v1_20_R1/PaperweightAdapter.java | 1131 ------- .../v1_20_R1/PaperweightDataConverters.java | 2798 ---------------- .../fawe/v1_20_R1/PaperweightFakePlayer.java | 93 - .../PaperweightWorldNativeAccess.java | 197 -- .../v1_20_R1/PaperweightBlockMaterial.java | 185 -- .../fawe/v1_20_R1/PaperweightFaweAdapter.java | 614 ---- .../PaperweightFaweWorldNativeAccess.java | 292 -- .../fawe/v1_20_R1/PaperweightGetBlocks.java | 1184 ------- .../v1_20_R1/PaperweightGetBlocks_Copy.java | 259 -- .../v1_20_R1/PaperweightMapChunkUtil.java | 34 - .../v1_20_R1/PaperweightPlatformAdapter.java | 764 ----- .../v1_20_R1/PaperweightPostProcessor.java | 175 -- .../PaperweightStarlightRelighter.java | 76 - .../PaperweightStarlightRelighterFactory.java | 25 - .../nbt/PaperweightLazyCompoundTag.java | 161 - .../fawe/v1_20_R1/regen/PaperweightRegen.java | 591 ---- 37 files changed, 6 insertions(+), 17139 deletions(-) delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/build.gradle.kts delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightDataConverters.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightFakePlayer.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightBlockMaterial.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightMapChunkUtil.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPostProcessor.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighterFactory.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/nbt/PaperweightLazyCompoundTag.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightDataConverters.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightFakePlayer.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightBlockMaterial.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweWorldNativeAccess.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightMapChunkUtil.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPostProcessor.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighterFactory.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/nbt/PaperweightLazyCompoundTag.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/regen/PaperweightRegen.java diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 1de1aa8df..c223aae35 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -27,9 +27,10 @@ body: description: Which server version version you using? If your server version is not listed, it is not supported. Update to a supported version first. multiple: false options: - - '1.20.5/6' - - '1.20' - - '1.19.4' + - '1.21' + - '1.20.6' + - '1.20.4' + - '1.20.2' validations: required: true diff --git a/buildSrc/src/main/kotlin/CommonJavaConfig.kt b/buildSrc/src/main/kotlin/CommonJavaConfig.kt index 60860f7f7..d221a98d2 100644 --- a/buildSrc/src/main/kotlin/CommonJavaConfig.kt +++ b/buildSrc/src/main/kotlin/CommonJavaConfig.kt @@ -23,7 +23,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean val disabledLint = listOf( "processing", "path", "fallthrough", "serial", "overloads", "this-escape", ) - options.release.set(17) + options.release.set(21) options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" }) options.isDeprecation = true options.encoding = "UTF-8" diff --git a/settings.gradle.kts b/settings.gradle.kts index de52de2f9..4e1b292c5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,7 +2,7 @@ rootProject.name = "FastAsyncWorldEdit" include("worldedit-libs") -listOf("1_19_4", "1_20", "1_20_2", "1_20_4", "1_20_5", "1_21").forEach { +listOf("1_20_2", "1_20_4", "1_20_5", "1_21").forEach { include("worldedit-bukkit:adapters:adapter-$it") } diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_19_4/build.gradle.kts deleted file mode 100644 index e53d2497e..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/build.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension - -plugins { - java -} - -applyPaperweightAdapterConfiguration() - -repositories { - gradlePluginPortal() -} - -dependencies { - // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.19.4-R0.1-SNAPSHOT - the().paperDevBundle("1.19.4-R0.1-20230608.201059-104") - compileOnly(libs.paperlib) -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java deleted file mode 100644 index 87135fa86..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java +++ /dev/null @@ -1,1077 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_19_R3; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Sets; -import com.google.common.util.concurrent.Futures; -import com.mojang.datafixers.util.Either; -import com.mojang.serialization.Lifecycle; -import com.sk89q.jnbt.NBTConstants; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.blocks.BaseItem; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.PaperweightPlatformAdapter; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.extension.platform.Watchdog; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.math.BlockVector2; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.registry.state.BooleanProperty; -import com.sk89q.worldedit.registry.state.DirectionalProperty; -import com.sk89q.worldedit.registry.state.EnumProperty; -import com.sk89q.worldedit.registry.state.IntegerProperty; -import com.sk89q.worldedit.registry.state.Property; -import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; -import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.world.DataFixer; -import com.sk89q.worldedit.world.RegenOptions; -import com.sk89q.worldedit.world.biome.BiomeCategory; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockStateHolder; -import com.sk89q.worldedit.world.block.BlockType; -import com.sk89q.worldedit.world.block.BlockTypes; -import com.sk89q.worldedit.world.item.ItemType; -import net.minecraft.Util; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.HolderSet; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; -import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.util.StringRepresentable; -import net.minecraft.util.thread.BlockableEventLoop; -import net.minecraft.world.Clearable; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.UseOnContext; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.LevelSettings; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.StructureBlockEntity; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.dimension.LevelStem; -import net.minecraft.world.level.levelgen.WorldOptions; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraft.world.level.storage.PrimaryLevelData; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.Vec3; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World.Environment; -import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.v1_19_R3.CraftServer; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_19_R3.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_19_R3.util.CraftMagicNumbers; -import org.bukkit.entity.Player; -import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; -import org.bukkit.generator.ChunkGenerator; -import org.enginehub.linbus.common.LinTagId; -import org.enginehub.linbus.tree.LinByteArrayTag; -import org.enginehub.linbus.tree.LinByteTag; -import org.enginehub.linbus.tree.LinCompoundTag; -import org.enginehub.linbus.tree.LinDoubleTag; -import org.enginehub.linbus.tree.LinEndTag; -import org.enginehub.linbus.tree.LinFloatTag; -import org.enginehub.linbus.tree.LinIntArrayTag; -import org.enginehub.linbus.tree.LinIntTag; -import org.enginehub.linbus.tree.LinListTag; -import org.enginehub.linbus.tree.LinLongArrayTag; -import org.enginehub.linbus.tree.LinLongTag; -import org.enginehub.linbus.tree.LinShortTag; -import org.enginehub.linbus.tree.LinStringTag; -import org.enginehub.linbus.tree.LinTag; -import org.enginehub.linbus.tree.LinTagType; -import org.spigotmc.SpigotConfig; -import org.spigotmc.WatchdogThread; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.OptionalInt; -import java.util.OptionalLong; -import java.util.Set; -import java.util.TreeMap; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -public final class PaperweightAdapter implements BukkitImplAdapter { - - private final Logger logger = Logger.getLogger(getClass().getCanonicalName()); - - private final Field serverWorldsField; - private final Method getChunkFutureMethod; - private final Field chunkProviderExecutorField; - private final Watchdog watchdog; - - // ------------------------------------------------------------------------ - // Code that may break between versions of Minecraft - // ------------------------------------------------------------------------ - - public PaperweightAdapter() throws NoSuchFieldException, NoSuchMethodException { - // A simple test - CraftServer.class.cast(Bukkit.getServer()); - - int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion(); - if (dataVersion != 3337) { - throw new UnsupportedClassVersionError("Not 1.19.4!"); - } - - serverWorldsField = CraftServer.class.getDeclaredField("worlds"); - serverWorldsField.setAccessible(true); - - getChunkFutureMethod = ServerChunkCache.class.getDeclaredMethod( - Refraction.pickName("getChunkFutureMainThread", "c"), - int.class, int.class, ChunkStatus.class, boolean.class - ); - getChunkFutureMethod.setAccessible(true); - - chunkProviderExecutorField = ServerChunkCache.class.getDeclaredField( - Refraction.pickName("mainThreadProcessor", "g") - ); - chunkProviderExecutorField.setAccessible(true); - - new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this).buildUnoptimized(); - - Watchdog watchdog; - try { - Class.forName("org.spigotmc.WatchdogThread"); - watchdog = new SpigotWatchdog(); - } catch (ClassNotFoundException | NoSuchFieldException e) { - try { - watchdog = new MojangWatchdog(((CraftServer) Bukkit.getServer()).getServer()); - } catch (NoSuchFieldException ex) { - watchdog = null; - } - } - this.watchdog = watchdog; - - try { - Class.forName("org.spigotmc.SpigotConfig"); - SpigotConfig.config.set("world-settings.faweregentempworld.verbose", false); - } catch (ClassNotFoundException ignored) { - } - } - - @Override - public DataFixer getDataFixer() { - return PaperweightDataConverters.INSTANCE; - } - - /** - * Read the given NBT data into the given tile entity. - * - * @param tileEntity the tile entity - * @param tag the tag - */ - static void readTagIntoTileEntity(net.minecraft.nbt.CompoundTag tag, BlockEntity tileEntity) { - tileEntity.load(tag); - tileEntity.setChanged(); - } - - /** - * Get the ID string of the given entity. - * - * @param entity the entity - * @return the entity ID - */ - private static String getEntityId(Entity entity) { - return EntityType.getKey(entity.getType()).toString(); - } - - /** - * Create an entity using the given entity ID. - * - * @param id the entity ID - * @param world the world - * @return an entity or null - */ - @Nullable - private static Entity createEntityFromId(String id, net.minecraft.world.level.Level world) { - return EntityType.byString(id).map(t -> t.create(world)).orElse(null); - } - - /** - * Write the given NBT data into the given entity. - * - * @param entity the entity - * @param tag the tag - */ - private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) { - entity.load(tag); - } - - /** - * Write the entity's NBT data to the given tag. - * - * @param entity the entity - * @param tag the tag - */ - private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag tag) { - //FAWE start - avoid villager async catcher - PaperweightPlatformAdapter.readEntityIntoTag(entity, tag); - //FAWE end - } - - private static Block getBlockFromType(BlockType blockType) { - - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK).get(ResourceLocation.tryParse(blockType.id())); - } - - private static Item getItemFromType(ItemType itemType) { - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(itemType.id())); - } - - public BiomeType adapt(Biome biome) { - var mcBiome = ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getKey(biome); - if (mcBiome == null) { - return null; - } - return BiomeType.REGISTRY.get(mcBiome.toString()); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockData data) { - net.minecraft.world.level.block.state.BlockState state = ((CraftBlockData) data).getState(); - int combinedId = Block.getId(state); - return combinedId == 0 && state.getBlock() != Blocks.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockState state) { - Block mcBlock = getBlockFromType(state.getBlockType()); - net.minecraft.world.level.block.state.BlockState newState = mcBlock.defaultBlockState(); - Map, Object> states = state.getStates(); - newState = applyProperties(mcBlock.getStateDefinition(), newState, states); - final int combinedId = Block.getId(newState); - return combinedId == 0 && state.getBlockType() != BlockTypes.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId); - } - - @Override - public BlockState getBlock(Location location) { - checkNotNull(location); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - int internalId = Block.getId(blockData); - BlockState state = BlockStateIdAccess.getBlockStateById(internalId); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - - return state; - } - - @Override - public BaseBlock getFullBlock(Location location) { - BlockState state = getBlock(location); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - - // Read the NBT data - BlockEntity te = chunk.getBlockEntity(blockPos); - if (te != null) { - net.minecraft.nbt.CompoundTag tag = te.saveWithId(); - return state.toBaseBlock((LinCompoundTag) toNativeLin(tag)); - } - - return state.toBaseBlock(); - } - - @Override - public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { - return new PaperweightWorldNativeAccess(this, - new WeakReference<>(((CraftWorld) world).getHandle())); - } - - private static net.minecraft.core.Direction adapt(Direction face) { - switch (face) { - case NORTH: - return net.minecraft.core.Direction.NORTH; - case SOUTH: - return net.minecraft.core.Direction.SOUTH; - case WEST: - return net.minecraft.core.Direction.WEST; - case EAST: - return net.minecraft.core.Direction.EAST; - case DOWN: - return net.minecraft.core.Direction.DOWN; - case UP: - default: - return net.minecraft.core.Direction.UP; - } - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - private net.minecraft.world.level.block.state.BlockState applyProperties( - StateDefinition stateContainer, - net.minecraft.world.level.block.state.BlockState newState, - Map, Object> states - ) { - for (Map.Entry, Object> state : states.entrySet()) { - net.minecraft.world.level.block.state.properties.Property property = - stateContainer.getProperty(state.getKey().getName()); - Comparable value = (Comparable) state.getValue(); - // we may need to adapt this value, depending on the source prop - if (property instanceof DirectionProperty) { - Direction dir = (Direction) value; - value = adapt(dir); - } else if (property instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - String enumName = (String) value; - value = ((net.minecraft.world.level.block.state.properties.EnumProperty) property) - .getValue(enumName).orElseThrow(() -> - new IllegalStateException( - "Enum property " + property.getName() + " does not contain " + enumName - ) - ); - } - - newState = newState.setValue( - (net.minecraft.world.level.block.state.properties.Property) property, - (Comparable) value - ); - } - return newState; - } - - @Override - public BaseEntity getEntity(org.bukkit.entity.Entity entity) { - checkNotNull(entity); - - CraftEntity craftEntity = ((CraftEntity) entity); - Entity mcEntity = craftEntity.getHandle(); - - // Do not allow creating of passenger entity snapshots, passengers are included in the vehicle entity - if (mcEntity.isPassenger()) { - return null; - } - - String id = getEntityId(mcEntity); - - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - readEntityIntoTag(mcEntity, tag); - return new BaseEntity( - com.sk89q.worldedit.world.entity.EntityTypes.get(id), - LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)) - ); - } - - @Nullable - @Override - public org.bukkit.entity.Entity createEntity(Location location, BaseEntity state) { - checkNotNull(location); - checkNotNull(state); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - ServerLevel worldServer = craftWorld.getHandle(); - - Entity createdEntity = createEntityFromId(state.getType().id(), craftWorld.getHandle()); - - if (createdEntity != null) { - LinCompoundTag nativeTag = state.getNbt(); - if (nativeTag != null) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeLin(nativeTag); - for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - readTagIntoEntity(tag, createdEntity); - } - - createdEntity.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - - worldServer.addFreshEntity(createdEntity, SpawnReason.CUSTOM); - return createdEntity.getBukkitEntity(); - } else { - return null; - } - } - - // This removes all unwanted tags from the main entity and all its passengers - private void removeUnwantedEntityTagsRecursively(net.minecraft.nbt.CompoundTag tag) { - for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - - // Adapted from net.minecraft.world.entity.EntityType#loadEntityRecursive - if (tag.contains("Passengers", NBTConstants.TYPE_LIST)) { - net.minecraft.nbt.ListTag nbttaglist = tag.getList("Passengers", NBTConstants.TYPE_COMPOUND); - - for (int i = 0; i < nbttaglist.size(); ++i) { - removeUnwantedEntityTagsRecursively(nbttaglist.getCompound(i)); - } - } - } - - @Override - public Component getRichBlockName(BlockType blockType) { - return TranslatableComponent.of(getBlockFromType(blockType).getDescriptionId()); - } - - @Override - public Component getRichItemName(ItemType itemType) { - return TranslatableComponent.of(getItemFromType(itemType).getDescriptionId()); - } - - @Override - public Component getRichItemName(BaseItemStack itemStack) { - return TranslatableComponent.of(CraftItemStack.asNMSCopy(BukkitAdapter.adapt(itemStack)).getDescriptionId()); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private static final LoadingCache> PROPERTY_CACHE = CacheBuilder - .newBuilder() - .build(new CacheLoader<>() { - @Override - public Property load(net.minecraft.world.level.block.state.properties.Property state) { - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else if (state instanceof DirectionProperty) { - return new DirectionalProperty( - state.getName(), - new ArrayList<>((List) state - .getPossibleValues() - .stream() - .map(e -> Direction.valueOf(((StringRepresentable) e) - .getSerializedName() - .toUpperCase(Locale.ROOT))) - .toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - return new EnumProperty( - state.getName(), - new ArrayList<>((List) state - .getPossibleValues() - .stream() - .map(e -> ((StringRepresentable) e).getSerializedName()) - .toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else { - throw new IllegalArgumentException("WorldEdit needs an update to support " + state - .getClass() - .getSimpleName()); - } - } - }); - - @SuppressWarnings({ "rawtypes" }) - @Override - public Map> getProperties(BlockType blockType) { - Map> properties = new TreeMap<>(); - Block block = getBlockFromType(blockType); - StateDefinition blockStateList = - block.getStateDefinition(); - for (net.minecraft.world.level.block.state.properties.Property state : blockStateList.getProperties()) { - Property property = PROPERTY_CACHE.getUnchecked(state); - properties.put(property.getName(), property); - } - return properties; - } - - @Override - public void sendFakeNBT(Player player, BlockVector3 pos, LinCompoundTag nbtData) { - ((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create( - new StructureBlockEntity( - new BlockPos(pos.x(), pos.y(), pos.z()), - Blocks.STRUCTURE_BLOCK.defaultBlockState() - ), - __ -> (net.minecraft.nbt.CompoundTag) fromNativeLin(nbtData) - )); - } - - @Override - public void sendFakeOP(Player player) { - ((CraftPlayer) player).getHandle().connection.send(new ClientboundEntityEventPacket( - ((CraftPlayer) player).getHandle(), (byte) 28 - )); - } - - @Override - public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) { - ItemStack stack = new ItemStack( - DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(item.getType().id())), - item.getAmount() - ); - stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData()))); - return CraftItemStack.asCraftMirror(stack); - } - - @Override - public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { - final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); - weStack.setNbt(((LinCompoundTag) toNativeLin(nmsStack.getTag()))); - return weStack; - } - - private final LoadingCache fakePlayers - = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new)); - - @Override - public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) { - CraftWorld craftWorld = (CraftWorld) world; - ServerLevel worldServer = craftWorld.getHandle(); - ItemStack stack = CraftItemStack.asNMSCopy(BukkitAdapter.adapt(item instanceof BaseItemStack - ? ((BaseItemStack) item) : new BaseItemStack(item.getType(), item.getNbtData(), 1))); - stack.setTag((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData())); - - PaperweightFakePlayer fakePlayer; - try { - fakePlayer = fakePlayers.get(worldServer); - } catch (ExecutionException ignored) { - return false; - } - fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack); - fakePlayer.absMoveTo(position.x(), position.y(), position.z(), - (float) face.toVector().toYaw(), (float) face.toVector().toPitch()); - - final BlockPos blockPos = new BlockPos(position.x(), position.y(), position.z()); - final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos); - final net.minecraft.core.Direction enumFacing = adapt(face); - BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false); - UseOnContext context = new UseOnContext(fakePlayer, InteractionHand.MAIN_HAND, rayTrace); - InteractionResult result = stack.useOn(context, InteractionHand.MAIN_HAND); - if (result != InteractionResult.SUCCESS) { - if (worldServer.getBlockState(blockPos).use(worldServer, fakePlayer, InteractionHand.MAIN_HAND, rayTrace).consumesAction()) { - result = InteractionResult.SUCCESS; - } else { - result = stack.getItem().use(worldServer, fakePlayer, InteractionHand.MAIN_HAND).getResult(); - } - } - - return result == InteractionResult.SUCCESS; - } - - @Override - public boolean canPlaceAt(org.bukkit.World world, BlockVector3 position, BlockState blockState) { - int internalId = BlockStateIdAccess.getBlockStateId(blockState); - net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId); - return blockData.canSurvive(((CraftWorld) world).getHandle(), new BlockPos(position.x(), position.y(), position.z())); - } - - @Override - public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent extent, RegenOptions options) { - try { - doRegen(bukkitWorld, region, extent, options); - } catch (Exception e) { - throw new IllegalStateException("Regen failed.", e); - } - - return true; - } - - private void doRegen(org.bukkit.World bukkitWorld, Region region, Extent extent, RegenOptions options) throws Exception { - Environment env = bukkitWorld.getEnvironment(); - ChunkGenerator gen = bukkitWorld.getGenerator(); - - Path tempDir = Files.createTempDirectory("WorldEditWorldGen"); - LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir); - ResourceKey worldDimKey = getWorldDimKey(env); - try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("faweregentempworld", worldDimKey)) { - ServerLevel originalWorld = ((CraftWorld) bukkitWorld).getHandle(); - PrimaryLevelData levelProperties = (PrimaryLevelData) originalWorld.getServer() - .getWorldData().overworldData(); - WorldOptions originalOpts = levelProperties.worldGenOptions(); - - long seed = options.getSeed().orElse(originalWorld.getSeed()); - WorldOptions newOpts = options.getSeed().isPresent() - ? originalOpts.withSeed(OptionalLong.of(seed)) - : originalOpts; - - LevelSettings newWorldSettings = new LevelSettings( - "faweregentempworld", - levelProperties.settings.gameType(), - levelProperties.settings.hardcore(), - levelProperties.settings.difficulty(), - levelProperties.settings.allowCommands(), - levelProperties.settings.gameRules(), - levelProperties.settings.getDataConfiguration() - ); - - PrimaryLevelData.SpecialWorldProperty specialWorldProperty = - levelProperties.isFlatWorld() - ? PrimaryLevelData.SpecialWorldProperty.FLAT - : levelProperties.isDebugWorld() - ? PrimaryLevelData.SpecialWorldProperty.DEBUG - : PrimaryLevelData.SpecialWorldProperty.NONE; - - PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, specialWorldProperty, Lifecycle.stable()); - - ServerLevel freshWorld = new ServerLevel( - originalWorld.getServer(), - originalWorld.getServer().executor, - session, newWorldData, - originalWorld.dimension(), - new LevelStem( - originalWorld.dimensionTypeRegistration(), - originalWorld.getChunkSource().getGenerator() - ), - new NoOpWorldLoadListener(), - originalWorld.isDebug(), - seed, - ImmutableList.of(), - false, - env, - gen, - bukkitWorld.getBiomeProvider() - ); - try { - regenForWorld(region, extent, freshWorld, options); - } finally { - freshWorld.getChunkSource().close(false); - } - } finally { - try { - @SuppressWarnings("unchecked") - Map map = (Map) serverWorldsField.get(Bukkit.getServer()); - map.remove("faweregentempworld"); - } catch (IllegalAccessException ignored) { - } - SafeFiles.tryHardToDeleteDir(tempDir); - } - } - - private BiomeType adapt(ServerLevel serverWorld, Biome origBiome) { - ResourceLocation key = serverWorld.registryAccess().registryOrThrow(Registries.BIOME).getKey(origBiome); - if (key == null) { - return null; - } - return BiomeTypes.get(key.toString()); - } - - @SuppressWarnings("unchecked") - private void regenForWorld(Region region, Extent extent, ServerLevel serverWorld, RegenOptions options) throws WorldEditException { - List> chunkLoadings = submitChunkLoadTasks(region, serverWorld); - BlockableEventLoop executor; - try { - executor = (BlockableEventLoop) chunkProviderExecutorField.get(serverWorld.getChunkSource()); - } catch (IllegalAccessException e) { - throw new IllegalStateException("Couldn't get executor for chunk loading.", e); - } - executor.managedBlock(() -> { - // bail out early if a future fails - if (chunkLoadings.stream().anyMatch(ftr -> - ftr.isDone() && Futures.getUnchecked(ftr) == null - )) { - return false; - } - return chunkLoadings.stream().allMatch(CompletableFuture::isDone); - }); - Map chunks = new HashMap<>(); - for (CompletableFuture future : chunkLoadings) { - @Nullable - ChunkAccess chunk = future.getNow(null); - checkState(chunk != null, "Failed to generate a chunk, regen failed."); - chunks.put(chunk.getPos(), chunk); - } - - for (BlockVector3 vec : region) { - BlockPos pos = new BlockPos(vec.x(), vec.y(), vec.z()); - ChunkAccess chunk = chunks.get(new ChunkPos(pos)); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos); - int internalId = Block.getId(blockData); - BlockStateHolder state = BlockStateIdAccess.getBlockStateById(internalId); - Objects.requireNonNull(state); - BlockEntity blockEntity = chunk.getBlockEntity(pos); - if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); - state = state.toBaseBlock((LinCompoundTag) toNativeLin(tag)); - } - extent.setBlock(vec, state.toBaseBlock()); - if (options.shouldRegenBiomes()) { - Biome origBiome = chunk.getNoiseBiome(vec.x(), vec.y(), vec.z()).value(); - BiomeType adaptedBiome = adapt(serverWorld, origBiome); - if (adaptedBiome != null) { - extent.setBiome(vec, adaptedBiome); - } - } - } - } - - @SuppressWarnings("unchecked") - private List> submitChunkLoadTasks(Region region, ServerLevel serverWorld) { - ServerChunkCache chunkManager = serverWorld.getChunkSource(); - List> chunkLoadings = new ArrayList<>(); - // Pre-gen all the chunks - for (BlockVector2 chunk : region.getChunks()) { - try { - //noinspection unchecked - chunkLoadings.add( - ((CompletableFuture>) - getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) - .thenApply(either -> either.left().orElse(null)) - ); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new IllegalStateException("Couldn't load chunk for regen.", e); - } - } - return chunkLoadings; - } - - private ResourceKey getWorldDimKey(Environment env) { - switch (env) { - case NETHER: - return LevelStem.NETHER; - case THE_END: - return LevelStem.END; - case NORMAL: - default: - return LevelStem.OVERWORLD; - } - } - - private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( - SideEffect.NEIGHBORS, - SideEffect.LIGHTING, - SideEffect.VALIDATION, - SideEffect.ENTITY_AI, - SideEffect.EVENTS, - SideEffect.UPDATE - ); - - @Override - public Set getSupportedSideEffects() { - return SUPPORTED_SIDE_EFFECTS; - } - - @Override - public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) { - ServerLevel originalWorld = ((CraftWorld) world).getHandle(); - - BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.x(), pt.y(), pt.z())); - if (entity instanceof Clearable) { - ((Clearable) entity).clearContent(); - return true; - } - return false; - } - - @Override - public void initializeRegistries() { - DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer(); - // Biomes - for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.BIOME).keySet()) { - if (BiomeType.REGISTRY.get(name.toString()) == null) { - BiomeType.REGISTRY.register(name.toString(), new BiomeType(name.toString())); - } - } - - // BiomeCategories - Registry biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME); - biomeRegistry.getTagNames().forEach(tagKey -> { - String key = tagKey.location().toString(); - if (BiomeCategory.REGISTRY.get(key) == null) { - BiomeCategory.REGISTRY.register(key, new BiomeCategory( - key, - () -> biomeRegistry.getTag(tagKey) - .stream() - .flatMap(HolderSet.Named::stream) - .map(Holder::value) - .map(this::adapt) - .collect(Collectors.toSet())) - ); - } - }); - } - - // ------------------------------------------------------------------------ - // Code that is less likely to break - // ------------------------------------------------------------------------ - - /** - * Converts from a non-native NMS NBT structure to a native WorldEdit NBT - * structure. - * - * @param foreign non-native NMS NBT structure - * @return native WorldEdit NBT structure - */ - @Override - public LinTag toNativeLin(net.minecraft.nbt.Tag foreign) { - if (foreign == null) { - return null; - } - if (foreign instanceof net.minecraft.nbt.CompoundTag) { - Map> values = new HashMap<>(); - Set foreignKeys = ((net.minecraft.nbt.CompoundTag) foreign).getAllKeys(); - - for (String str : foreignKeys) { - net.minecraft.nbt.Tag base = ((net.minecraft.nbt.CompoundTag) foreign).get(str); - values.put(str, toNativeLin(base)); - } - return LinCompoundTag.of(values); - } else if (foreign instanceof net.minecraft.nbt.ByteTag) { - return LinByteTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); - } else if (foreign instanceof net.minecraft.nbt.ByteArrayTag) { - return LinByteArrayTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); - } else if (foreign instanceof net.minecraft.nbt.DoubleTag) { - return LinDoubleTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); - } else if (foreign instanceof net.minecraft.nbt.FloatTag) { - return LinFloatTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); - } else if (foreign instanceof net.minecraft.nbt.IntTag) { - return LinIntTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); - } else if (foreign instanceof net.minecraft.nbt.IntArrayTag) { - return LinIntArrayTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); - } else if (foreign instanceof net.minecraft.nbt.LongArrayTag) { - return LinLongArrayTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); - } else if (foreign instanceof net.minecraft.nbt.ListTag) { - try { - return toNativeLinList((net.minecraft.nbt.ListTag) foreign); - } catch (Throwable e) { - logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); - } - } else if (foreign instanceof net.minecraft.nbt.LongTag) { - return LinLongTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); - } else if (foreign instanceof net.minecraft.nbt.ShortTag) { - return LinShortTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); - } else if (foreign instanceof net.minecraft.nbt.StringTag) { - return LinStringTag.of(foreign.getAsString()); - } else if (foreign instanceof net.minecraft.nbt.EndTag) { - return LinEndTag.instance(); - } - throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); - } - - /** - * Convert a foreign NBT list tag into a native WorldEdit one. - * - * @param foreign the foreign tag - * @return the converted tag - * @throws SecurityException on error - * @throws IllegalArgumentException on error - */ - private LinListTag toNativeLinList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException { - LinListTag.Builder> builder = LinListTag.builder( - LinTagType.fromId(LinTagId.fromId(foreign.getElementType())) - ); - - for (net.minecraft.nbt.Tag tag : foreign) { - builder.add(toNativeLin(tag)); - } - - return builder.build(); - } - - /** - * Converts a WorldEdit-native NBT structure to a NMS structure. - * - * @param foreign structure to convert - * @return non-native structure - */ - @Override - public net.minecraft.nbt.Tag fromNativeLin(LinTag foreign) { - if (foreign == null) { - return null; - } - if (foreign instanceof LinCompoundTag compoundTag) { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - for (var entry : compoundTag.value().entrySet()) { - tag.put(entry.getKey(), fromNativeLin(entry.getValue())); - } - return tag; - } else if (foreign instanceof LinByteTag byteTag) { - return net.minecraft.nbt.ByteTag.valueOf(byteTag.valueAsByte()); - } else if (foreign instanceof LinByteArrayTag byteArrayTag) { - return new net.minecraft.nbt.ByteArrayTag(byteArrayTag.value()); - } else if (foreign instanceof LinDoubleTag doubleTag) { - return net.minecraft.nbt.DoubleTag.valueOf(doubleTag.valueAsDouble()); - } else if (foreign instanceof LinFloatTag floatTag) { - return net.minecraft.nbt.FloatTag.valueOf(floatTag.valueAsFloat()); - } else if (foreign instanceof LinIntTag intTag) { - return net.minecraft.nbt.IntTag.valueOf(intTag.valueAsInt()); - } else if (foreign instanceof LinIntArrayTag intArrayTag) { - return new net.minecraft.nbt.IntArrayTag(intArrayTag.value()); - } else if (foreign instanceof LinLongArrayTag longArrayTag) { - return new net.minecraft.nbt.LongArrayTag(longArrayTag.value()); - } else if (foreign instanceof LinListTag listTag) { - net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); - for (var t : listTag.value()) { - tag.add(fromNativeLin(t)); - } - return tag; - } else if (foreign instanceof LinLongTag longTag) { - return net.minecraft.nbt.LongTag.valueOf(longTag.valueAsLong()); - } else if (foreign instanceof LinShortTag shortTag) { - return net.minecraft.nbt.ShortTag.valueOf(shortTag.valueAsShort()); - } else if (foreign instanceof LinStringTag stringTag) { - return net.minecraft.nbt.StringTag.valueOf(stringTag.value()); - } else if (foreign instanceof LinEndTag) { - return net.minecraft.nbt.EndTag.INSTANCE; - } else { - throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName()); - } - } - - @Override - public boolean supportsWatchdog() { - return watchdog != null; - } - - @Override - public void tickWatchdog() { - watchdog.tick(); - } - - private class SpigotWatchdog implements Watchdog { - private final Field instanceField; - private final Field lastTickField; - - SpigotWatchdog() throws NoSuchFieldException { - Field instanceField = WatchdogThread.class.getDeclaredField("instance"); - instanceField.setAccessible(true); - this.instanceField = instanceField; - - Field lastTickField = WatchdogThread.class.getDeclaredField("lastTick"); - lastTickField.setAccessible(true); - this.lastTickField = lastTickField; - } - - @Override - public void tick() { - try { - WatchdogThread instance = (WatchdogThread) this.instanceField.get(null); - if ((long) lastTickField.get(instance) != 0) { - WatchdogThread.tick(); - } - } catch (IllegalAccessException e) { - logger.log(Level.WARNING, "Failed to tick watchdog", e); - } - } - } - - private static class MojangWatchdog implements Watchdog { - private final DedicatedServer server; - private final Field tickField; - - MojangWatchdog(DedicatedServer server) throws NoSuchFieldException { - this.server = server; - Field tickField = MinecraftServer.class.getDeclaredField( - Refraction.pickName("nextTickTime", "ah") - ); - if (tickField.getType() != long.class) { - throw new IllegalStateException("nextTickTime is not a long field, mapping is likely incorrect"); - } - tickField.setAccessible(true); - this.tickField = tickField; - } - - @Override - public void tick() { - try { - tickField.set(server, Util.getMillis()); - } catch (IllegalAccessException ignored) { - } - } - } - - private static class NoOpWorldLoadListener implements ChunkProgressListener { - @Override - public void updateSpawnPos(ChunkPos spawnPos) { - } - - @Override - public void onStatusChange(ChunkPos pos, @org.jetbrains.annotations.Nullable ChunkStatus status) { - } - - @Override - public void start() { - } - - @Override - public void stop() { - } - - @Override - public void setChunkRadius(int radius) { - } - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightDataConverters.java deleted file mode 100644 index 50de3467e..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightDataConverters.java +++ /dev/null @@ -1,2799 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_19_R3; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.mojang.datafixers.DSL; -import com.mojang.datafixers.DSL.TypeReference; -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.DataFixerBuilder; -import com.mojang.datafixers.schemas.Schema; -import com.mojang.serialization.Dynamic; -import net.minecraft.core.Direction; -import net.minecraft.nbt.NbtOps; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.GsonHelper; -import net.minecraft.util.StringUtil; -import net.minecraft.util.datafix.DataFixers; -import net.minecraft.util.datafix.fixes.References; -import net.minecraft.world.item.DyeColor; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.enginehub.linbus.tree.LinCompoundTag; - -import javax.annotation.Nullable; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; - -/** - * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2) - * - * We register a DFU Fixer per Legacy Data Version and apply the fixes using legacy strategy - * which is safer, faster and cleaner code. - * - * The pre DFU code did not fail when the Source version was unknown. - * - * This class also provides util methods for converting compounds to wrap the update call to - * receive the source version in the compound - */ -@SuppressWarnings({ "rawtypes", "unchecked" }) -class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.worldedit.world.DataFixer { - - @SuppressWarnings("unchecked") - @Override - public T fixUp(FixType type, T original, int srcVer) { - if (type == FixTypes.CHUNK) { - return (T) fixChunk((LinCompoundTag) original, srcVer); - } else if (type == FixTypes.BLOCK_ENTITY) { - return (T) fixBlockEntity((LinCompoundTag) original, srcVer); - } else if (type == FixTypes.ENTITY) { - return (T) fixEntity((LinCompoundTag) original, srcVer); - } else if (type == FixTypes.BLOCK_STATE) { - return (T) fixBlockState((String) original, srcVer); - } else if (type == FixTypes.ITEM_TYPE) { - return (T) fixItemType((String) original, srcVer); - } else if (type == FixTypes.BIOME) { - return (T) fixBiome((String) original, srcVer); - } - return original; - } - - private LinCompoundTag fixChunk(LinCompoundTag originalChunk, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(originalChunk); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.CHUNK, tag, srcVer); - return (LinCompoundTag) adapter.toNativeLin(fixed); - } - - private LinCompoundTag fixBlockEntity(LinCompoundTag origTileEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origTileEnt); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.BLOCK_ENTITY, tag, srcVer); - return (LinCompoundTag) adapter.toNativeLin(fixed); - } - - private LinCompoundTag fixEntity(LinCompoundTag origEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origEnt); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.ENTITY, tag, srcVer); - return (LinCompoundTag) adapter.toNativeLin(fixed); - } - - private String fixBlockState(String blockState, int srcVer) { - net.minecraft.nbt.CompoundTag stateNBT = stateToNBT(blockState); - Dynamic dynamic = new Dynamic<>(OPS_NBT, stateNBT); - net.minecraft.nbt.CompoundTag fixed = (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update(References.BLOCK_STATE, dynamic, srcVer, DATA_VERSION).getValue(); - return nbtToState(fixed); - } - - private String nbtToState(net.minecraft.nbt.CompoundTag tagCompound) { - StringBuilder sb = new StringBuilder(); - sb.append(tagCompound.getString("Name")); - if (tagCompound.contains("Properties", 10)) { - sb.append('['); - net.minecraft.nbt.CompoundTag props = tagCompound.getCompound("Properties"); - sb.append(props.getAllKeys().stream().map(k -> k + "=" + props.getString(k).replace("\"", "")).collect(Collectors.joining(","))); - sb.append(']'); - } - return sb.toString(); - } - - private static net.minecraft.nbt.CompoundTag stateToNBT(String blockState) { - int propIdx = blockState.indexOf('['); - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - if (propIdx < 0) { - tag.putString("Name", blockState); - } else { - tag.putString("Name", blockState.substring(0, propIdx)); - net.minecraft.nbt.CompoundTag propTag = new net.minecraft.nbt.CompoundTag(); - String props = blockState.substring(propIdx + 1, blockState.length() - 1); - String[] propArr = props.split(","); - for (String pair : propArr) { - final String[] split = pair.split("="); - propTag.putString(split[0], split[1]); - } - tag.put("Properties", propTag); - } - return tag; - } - - private String fixBiome(String key, int srcVer) { - return fixName(key, srcVer, References.BIOME); - } - - private String fixItemType(String key, int srcVer) { - return fixName(key, srcVer, References.ITEM_NAME); - } - - private static String fixName(String key, int srcVer, TypeReference type) { - return INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, net.minecraft.nbt.StringTag.valueOf(key)), srcVer, DATA_VERSION) - .getValue().getAsString(); - } - - private final PaperweightAdapter adapter; - - private static final NbtOps OPS_NBT = NbtOps.INSTANCE; - private static final int LEGACY_VERSION = 1343; - private static int DATA_VERSION; - static PaperweightDataConverters INSTANCE; - - private final Map> converters = new EnumMap<>(LegacyType.class); - private final Map> inspectors = new EnumMap<>(LegacyType.class); - - // Set on build - private DataFixer fixer; - private static final Map DFU_TO_LEGACY = new HashMap<>(); - - public enum LegacyType { - LEVEL(References.LEVEL), - PLAYER(References.PLAYER), - CHUNK(References.CHUNK), - BLOCK_ENTITY(References.BLOCK_ENTITY), - ENTITY(References.ENTITY), - ITEM_INSTANCE(References.ITEM_STACK), - OPTIONS(References.OPTIONS), - STRUCTURE(References.STRUCTURE); - - private final TypeReference type; - - LegacyType(TypeReference type) { - this.type = type; - DFU_TO_LEGACY.put(type.typeName(), this); - } - - public TypeReference getDFUType() { - return type; - } - } - - PaperweightDataConverters(int dataVersion, PaperweightAdapter adapter) { - super(dataVersion); - DATA_VERSION = dataVersion; - INSTANCE = this; - this.adapter = adapter; - registerConverters(); - registerInspectors(); - } - - - // Called after fixers are built and ready for FIXING - @Override - public DataFixer buildUnoptimized() { - return this.fixer = new WrappedDataFixer(DataFixers.getDataFixer()); - } - - @Override - public DataFixer buildOptimized(final Set requiredTypes, Executor executor) { - return buildUnoptimized(); - } - - @SuppressWarnings("unchecked") - private class WrappedDataFixer implements DataFixer { - private final DataFixer realFixer; - - WrappedDataFixer(DataFixer realFixer) { - this.realFixer = realFixer; - } - - @Override - - public Dynamic update(TypeReference type, Dynamic dynamic, int sourceVer, int targetVer) { - LegacyType legacyType = DFU_TO_LEGACY.get(type.typeName()); - if (sourceVer < LEGACY_VERSION && legacyType != null) { - net.minecraft.nbt.CompoundTag cmp = (net.minecraft.nbt.CompoundTag) dynamic.getValue(); - int desiredVersion = Math.min(targetVer, LEGACY_VERSION); - - cmp = convert(legacyType, cmp, sourceVer, desiredVersion); - sourceVer = desiredVersion; - dynamic = new Dynamic(OPS_NBT, cmp); - } - return realFixer.update(type, dynamic, sourceVer, targetVer); - } - - private net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int desiredVersion) { - List converters = PaperweightDataConverters.this.converters.get(type); - if (converters != null && !converters.isEmpty()) { - for (DataConverter converter : converters) { - int dataVersion = converter.getDataVersion(); - if (dataVersion > sourceVer && dataVersion <= desiredVersion) { - cmp = converter.convert(cmp); - } - } - } - - List inspectors = PaperweightDataConverters.this.inspectors.get(type); - if (inspectors != null && !inspectors.isEmpty()) { - for (DataInspector inspector : inspectors) { - cmp = inspector.inspect(cmp, sourceVer, desiredVersion); - } - } - - return cmp; - } - - @Override - public Schema getSchema(int i) { - return realFixer.getSchema(i); - } - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp) { - return convert(type.getDFUType(), cmp); - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { - return convert(type.getDFUType(), cmp, sourceVer); - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - return convert(type.getDFUType(), cmp, sourceVer, targetVer); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp) { - int i = cmp.contains("DataVersion", 99) ? cmp.getInt("DataVersion") : -1; - return convert(type, cmp, i); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { - return convert(type, cmp, sourceVer, DATA_VERSION); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (sourceVer >= targetVer) { - return cmp; - } - return (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, cmp), sourceVer, targetVer).getValue(); - } - - - public interface DataInspector { - net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer); - } - - public interface DataConverter { - - int getDataVersion(); - - net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp); - } - - - private void registerInspector(LegacyType type, DataInspector inspector) { - this.inspectors.computeIfAbsent(type, k -> new ArrayList<>()).add(inspector); - } - - private void registerConverter(LegacyType type, DataConverter converter) { - int version = converter.getDataVersion(); - - List list = this.converters.computeIfAbsent(type, k -> new ArrayList<>()); - if (!list.isEmpty() && list.get(list.size() - 1).getDataVersion() > version) { - for (int j = 0; j < list.size(); ++j) { - if (list.get(j).getDataVersion() > version) { - list.add(j, converter); - break; - } - } - } else { - list.add(converter); - } - } - - private void registerInspectors() { - registerEntityItemList("EntityHorseDonkey", "SaddleItem", "Items"); - registerEntityItemList("EntityHorseMule", "Items"); - registerEntityItemList("EntityMinecartChest", "Items"); - registerEntityItemList("EntityMinecartHopper", "Items"); - registerEntityItemList("EntityVillager", "Inventory"); - registerEntityItemListEquipment("EntityArmorStand"); - registerEntityItemListEquipment("EntityBat"); - registerEntityItemListEquipment("EntityBlaze"); - registerEntityItemListEquipment("EntityCaveSpider"); - registerEntityItemListEquipment("EntityChicken"); - registerEntityItemListEquipment("EntityCow"); - registerEntityItemListEquipment("EntityCreeper"); - registerEntityItemListEquipment("EntityEnderDragon"); - registerEntityItemListEquipment("EntityEnderman"); - registerEntityItemListEquipment("EntityEndermite"); - registerEntityItemListEquipment("EntityEvoker"); - registerEntityItemListEquipment("EntityGhast"); - registerEntityItemListEquipment("EntityGiantZombie"); - registerEntityItemListEquipment("EntityGuardian"); - registerEntityItemListEquipment("EntityGuardianElder"); - registerEntityItemListEquipment("EntityHorse"); - registerEntityItemListEquipment("EntityHorseDonkey"); - registerEntityItemListEquipment("EntityHorseMule"); - registerEntityItemListEquipment("EntityHorseSkeleton"); - registerEntityItemListEquipment("EntityHorseZombie"); - registerEntityItemListEquipment("EntityIronGolem"); - registerEntityItemListEquipment("EntityMagmaCube"); - registerEntityItemListEquipment("EntityMushroomCow"); - registerEntityItemListEquipment("EntityOcelot"); - registerEntityItemListEquipment("EntityPig"); - registerEntityItemListEquipment("EntityPigZombie"); - registerEntityItemListEquipment("EntityRabbit"); - registerEntityItemListEquipment("EntitySheep"); - registerEntityItemListEquipment("EntityShulker"); - registerEntityItemListEquipment("EntitySilverfish"); - registerEntityItemListEquipment("EntitySkeleton"); - registerEntityItemListEquipment("EntitySkeletonStray"); - registerEntityItemListEquipment("EntitySkeletonWither"); - registerEntityItemListEquipment("EntitySlime"); - registerEntityItemListEquipment("EntitySnowman"); - registerEntityItemListEquipment("EntitySpider"); - registerEntityItemListEquipment("EntitySquid"); - registerEntityItemListEquipment("EntityVex"); - registerEntityItemListEquipment("EntityVillager"); - registerEntityItemListEquipment("EntityVindicator"); - registerEntityItemListEquipment("EntityWitch"); - registerEntityItemListEquipment("EntityWither"); - registerEntityItemListEquipment("EntityWolf"); - registerEntityItemListEquipment("EntityZombie"); - registerEntityItemListEquipment("EntityZombieHusk"); - registerEntityItemListEquipment("EntityZombieVillager"); - registerEntityItemSingle("EntityFireworks", "FireworksItem"); - registerEntityItemSingle("EntityHorse", "ArmorItem"); - registerEntityItemSingle("EntityHorse", "SaddleItem"); - registerEntityItemSingle("EntityHorseMule", "SaddleItem"); - registerEntityItemSingle("EntityHorseSkeleton", "SaddleItem"); - registerEntityItemSingle("EntityHorseZombie", "SaddleItem"); - registerEntityItemSingle("EntityItem", "Item"); - registerEntityItemSingle("EntityItemFrame", "Item"); - registerEntityItemSingle("EntityPotion", "Potion"); - - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItem("TileEntityRecordPlayer", "RecordItem")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityBrewingStand", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityChest", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDispenser", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDropper", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityFurnace", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityHopper", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityShulkerBox", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorMobSpawnerMobs()); - registerInspector(LegacyType.CHUNK, new DataInspectorChunks()); - registerInspector(LegacyType.ENTITY, new DataInspectorCommandBlock()); - registerInspector(LegacyType.ENTITY, new DataInspectorEntityPassengers()); - registerInspector(LegacyType.ENTITY, new DataInspectorMobSpawnerMinecart()); - registerInspector(LegacyType.ENTITY, new DataInspectorVillagers()); - registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorBlockEntity()); - registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorEntity()); - registerInspector(LegacyType.LEVEL, new DataInspectorLevelPlayer()); - registerInspector(LegacyType.PLAYER, new DataInspectorPlayer()); - registerInspector(LegacyType.PLAYER, new DataInspectorPlayerVehicle()); - registerInspector(LegacyType.STRUCTURE, new DataInspectorStructure()); - } - - private void registerConverters() { - registerConverter(LegacyType.ENTITY, new DataConverterEquipment()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterSignText()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterMaterialId()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionId()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterSpawnEgg()); - registerConverter(LegacyType.ENTITY, new DataConverterMinecart()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterMobSpawner()); - registerConverter(LegacyType.ENTITY, new DataConverterUUID()); - registerConverter(LegacyType.ENTITY, new DataConverterHealth()); - registerConverter(LegacyType.ENTITY, new DataConverterSaddle()); - registerConverter(LegacyType.ENTITY, new DataConverterHanging()); - registerConverter(LegacyType.ENTITY, new DataConverterDropChances()); - registerConverter(LegacyType.ENTITY, new DataConverterRiding()); - registerConverter(LegacyType.ENTITY, new DataConverterArmorStand()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBook()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterCookedFish()); - registerConverter(LegacyType.ENTITY, new DataConverterZombie()); - registerConverter(LegacyType.OPTIONS, new DataConverterVBO()); - registerConverter(LegacyType.ENTITY, new DataConverterGuardian()); - registerConverter(LegacyType.ENTITY, new DataConverterSkeleton()); - registerConverter(LegacyType.ENTITY, new DataConverterZombieType()); - registerConverter(LegacyType.ENTITY, new DataConverterHorse()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterTileEntity()); - registerConverter(LegacyType.ENTITY, new DataConverterEntity()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBanner()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionWater()); - registerConverter(LegacyType.ENTITY, new DataConverterShulker()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterShulkerBoxItem()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterShulkerBoxBlock()); - registerConverter(LegacyType.OPTIONS, new DataConverterLang()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterTotem()); - registerConverter(LegacyType.CHUNK, new DataConverterBedBlock()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBedItem()); - } - - private void registerEntityItemList(String type, String... keys) { - registerInspector(LegacyType.ENTITY, new DataInspectorItemList(type, keys)); - } - - private void registerEntityItemSingle(String type, String key) { - registerInspector(LegacyType.ENTITY, new DataInspectorItem(type, key)); - } - - private void registerEntityItemListEquipment(String type) { - registerEntityItemList(type, "ArmorItems", "HandItems"); - } - - private static final Map OLD_ID_TO_KEY_MAP = new HashMap<>(); - - static { - final Map map = OLD_ID_TO_KEY_MAP; - map.put("EntityItem", new ResourceLocation("item")); - map.put("EntityExperienceOrb", new ResourceLocation("xp_orb")); - map.put("EntityAreaEffectCloud", new ResourceLocation("area_effect_cloud")); - map.put("EntityGuardianElder", new ResourceLocation("elder_guardian")); - map.put("EntitySkeletonWither", new ResourceLocation("wither_skeleton")); - map.put("EntitySkeletonStray", new ResourceLocation("stray")); - map.put("EntityEgg", new ResourceLocation("egg")); - map.put("EntityLeash", new ResourceLocation("leash_knot")); - map.put("EntityPainting", new ResourceLocation("painting")); - map.put("EntityTippedArrow", new ResourceLocation("arrow")); - map.put("EntitySnowball", new ResourceLocation("snowball")); - map.put("EntityLargeFireball", new ResourceLocation("fireball")); - map.put("EntitySmallFireball", new ResourceLocation("small_fireball")); - map.put("EntityEnderPearl", new ResourceLocation("ender_pearl")); - map.put("EntityEnderSignal", new ResourceLocation("eye_of_ender_signal")); - map.put("EntityPotion", new ResourceLocation("potion")); - map.put("EntityThrownExpBottle", new ResourceLocation("xp_bottle")); - map.put("EntityItemFrame", new ResourceLocation("item_frame")); - map.put("EntityWitherSkull", new ResourceLocation("wither_skull")); - map.put("EntityTNTPrimed", new ResourceLocation("tnt")); - map.put("EntityFallingBlock", new ResourceLocation("falling_block")); - map.put("EntityFireworks", new ResourceLocation("fireworks_rocket")); - map.put("EntityZombieHusk", new ResourceLocation("husk")); - map.put("EntitySpectralArrow", new ResourceLocation("spectral_arrow")); - map.put("EntityShulkerBullet", new ResourceLocation("shulker_bullet")); - map.put("EntityDragonFireball", new ResourceLocation("dragon_fireball")); - map.put("EntityZombieVillager", new ResourceLocation("zombie_villager")); - map.put("EntityHorseSkeleton", new ResourceLocation("skeleton_horse")); - map.put("EntityHorseZombie", new ResourceLocation("zombie_horse")); - map.put("EntityArmorStand", new ResourceLocation("armor_stand")); - map.put("EntityHorseDonkey", new ResourceLocation("donkey")); - map.put("EntityHorseMule", new ResourceLocation("mule")); - map.put("EntityEvokerFangs", new ResourceLocation("evocation_fangs")); - map.put("EntityEvoker", new ResourceLocation("evocation_illager")); - map.put("EntityVex", new ResourceLocation("vex")); - map.put("EntityVindicator", new ResourceLocation("vindication_illager")); - map.put("EntityIllagerIllusioner", new ResourceLocation("illusion_illager")); - map.put("EntityMinecartCommandBlock", new ResourceLocation("commandblock_minecart")); - map.put("EntityBoat", new ResourceLocation("boat")); - map.put("EntityMinecartRideable", new ResourceLocation("minecart")); - map.put("EntityMinecartChest", new ResourceLocation("chest_minecart")); - map.put("EntityMinecartFurnace", new ResourceLocation("furnace_minecart")); - map.put("EntityMinecartTNT", new ResourceLocation("tnt_minecart")); - map.put("EntityMinecartHopper", new ResourceLocation("hopper_minecart")); - map.put("EntityMinecartMobSpawner", new ResourceLocation("spawner_minecart")); - map.put("EntityCreeper", new ResourceLocation("creeper")); - map.put("EntitySkeleton", new ResourceLocation("skeleton")); - map.put("EntitySpider", new ResourceLocation("spider")); - map.put("EntityGiantZombie", new ResourceLocation("giant")); - map.put("EntityZombie", new ResourceLocation("zombie")); - map.put("EntitySlime", new ResourceLocation("slime")); - map.put("EntityGhast", new ResourceLocation("ghast")); - map.put("EntityPigZombie", new ResourceLocation("zombie_pigman")); - map.put("EntityEnderman", new ResourceLocation("enderman")); - map.put("EntityCaveSpider", new ResourceLocation("cave_spider")); - map.put("EntitySilverfish", new ResourceLocation("silverfish")); - map.put("EntityBlaze", new ResourceLocation("blaze")); - map.put("EntityMagmaCube", new ResourceLocation("magma_cube")); - map.put("EntityEnderDragon", new ResourceLocation("ender_dragon")); - map.put("EntityWither", new ResourceLocation("wither")); - map.put("EntityBat", new ResourceLocation("bat")); - map.put("EntityWitch", new ResourceLocation("witch")); - map.put("EntityEndermite", new ResourceLocation("endermite")); - map.put("EntityGuardian", new ResourceLocation("guardian")); - map.put("EntityShulker", new ResourceLocation("shulker")); - map.put("EntityPig", new ResourceLocation("pig")); - map.put("EntitySheep", new ResourceLocation("sheep")); - map.put("EntityCow", new ResourceLocation("cow")); - map.put("EntityChicken", new ResourceLocation("chicken")); - map.put("EntitySquid", new ResourceLocation("squid")); - map.put("EntityWolf", new ResourceLocation("wolf")); - map.put("EntityMushroomCow", new ResourceLocation("mooshroom")); - map.put("EntitySnowman", new ResourceLocation("snowman")); - map.put("EntityOcelot", new ResourceLocation("ocelot")); - map.put("EntityIronGolem", new ResourceLocation("villager_golem")); - map.put("EntityHorse", new ResourceLocation("horse")); - map.put("EntityRabbit", new ResourceLocation("rabbit")); - map.put("EntityPolarBear", new ResourceLocation("polar_bear")); - map.put("EntityLlama", new ResourceLocation("llama")); - map.put("EntityLlamaSpit", new ResourceLocation("llama_spit")); - map.put("EntityParrot", new ResourceLocation("parrot")); - map.put("EntityVillager", new ResourceLocation("villager")); - map.put("EntityEnderCrystal", new ResourceLocation("ender_crystal")); - map.put("TileEntityFurnace", new ResourceLocation("furnace")); - map.put("TileEntityChest", new ResourceLocation("chest")); - map.put("TileEntityEnderChest", new ResourceLocation("ender_chest")); - map.put("TileEntityRecordPlayer", new ResourceLocation("jukebox")); - map.put("TileEntityDispenser", new ResourceLocation("dispenser")); - map.put("TileEntityDropper", new ResourceLocation("dropper")); - map.put("TileEntitySign", new ResourceLocation("sign")); - map.put("TileEntityMobSpawner", new ResourceLocation("mob_spawner")); - map.put("TileEntityNote", new ResourceLocation("noteblock")); - map.put("TileEntityPiston", new ResourceLocation("piston")); - map.put("TileEntityBrewingStand", new ResourceLocation("brewing_stand")); - map.put("TileEntityEnchantTable", new ResourceLocation("enchanting_table")); - map.put("TileEntityEnderPortal", new ResourceLocation("end_portal")); - map.put("TileEntityBeacon", new ResourceLocation("beacon")); - map.put("TileEntitySkull", new ResourceLocation("skull")); - map.put("TileEntityLightDetector", new ResourceLocation("daylight_detector")); - map.put("TileEntityHopper", new ResourceLocation("hopper")); - map.put("TileEntityComparator", new ResourceLocation("comparator")); - map.put("TileEntityFlowerPot", new ResourceLocation("flower_pot")); - map.put("TileEntityBanner", new ResourceLocation("banner")); - map.put("TileEntityStructure", new ResourceLocation("structure_block")); - map.put("TileEntityEndGateway", new ResourceLocation("end_gateway")); - map.put("TileEntityCommand", new ResourceLocation("command_block")); - map.put("TileEntityShulkerBox", new ResourceLocation("shulker_box")); - map.put("TileEntityBed", new ResourceLocation("bed")); - } - - private static ResourceLocation getKey(String type) { - final ResourceLocation key = OLD_ID_TO_KEY_MAP.get(type); - if (key == null) { - throw new IllegalArgumentException("Unknown mapping for " + type); - } - return key; - } - - private static void convertCompound(LegacyType type, net.minecraft.nbt.CompoundTag cmp, String key, int sourceVer, int targetVer) { - cmp.put(key, convert(type, cmp.getCompound(key), sourceVer, targetVer)); - } - - private static void convertItem(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { - if (nbttagcompound.contains(key, 10)) { - convertCompound(LegacyType.ITEM_INSTANCE, nbttagcompound, key, sourceVer, targetVer); - } - } - - private static void convertItems(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { - if (nbttagcompound.contains(key, 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound.getList(key, 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ITEM_INSTANCE, nbttaglist.getCompound(j), sourceVer, targetVer)); - } - } - - } - - private static class DataConverterEquipment implements DataConverter { - - DataConverterEquipment() { - } - - public int getDataVersion() { - return 100; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("Equipment", 10); - net.minecraft.nbt.ListTag nbttaglist1; - - if (!nbttaglist.isEmpty() && !cmp.contains("HandItems", 10)) { - nbttaglist1 = new net.minecraft.nbt.ListTag(); - nbttaglist1.add(nbttaglist.get(0)); - nbttaglist1.add(new net.minecraft.nbt.CompoundTag()); - cmp.put("HandItems", nbttaglist1); - } - - if (nbttaglist.size() > 1 && !cmp.contains("ArmorItem", 10)) { - nbttaglist1 = new net.minecraft.nbt.ListTag(); - nbttaglist1.add(nbttaglist.get(1)); - nbttaglist1.add(nbttaglist.get(2)); - nbttaglist1.add(nbttaglist.get(3)); - nbttaglist1.add(nbttaglist.get(4)); - cmp.put("ArmorItems", nbttaglist1); - } - - cmp.remove("Equipment"); - if (cmp.contains("DropChances", 9)) { - nbttaglist1 = cmp.getList("DropChances", 5); - net.minecraft.nbt.ListTag nbttaglist2; - - if (!cmp.contains("HandDropChances", 10)) { - nbttaglist2 = new net.minecraft.nbt.ListTag(); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(0))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(0.0F)); - cmp.put("HandDropChances", nbttaglist2); - } - - if (!cmp.contains("ArmorDropChances", 10)) { - nbttaglist2 = new net.minecraft.nbt.ListTag(); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(1))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(2))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(3))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(4))); - cmp.put("ArmorDropChances", nbttaglist2); - } - - cmp.remove("DropChances"); - } - - return cmp; - } - } - - private static class DataInspectorBlockEntity implements DataInspector { - - private static final Map b = Maps.newHashMap(); - private static final Map c = Maps.newHashMap(); - - DataInspectorBlockEntity() { - } - - @Nullable - private static String convertEntityId(int i, String s) { - String key = new ResourceLocation(s).toString(); - if (i < 515 && DataInspectorBlockEntity.b.containsKey(key)) { - return DataInspectorBlockEntity.b.get(key); - } else { - return DataInspectorBlockEntity.c.get(key); - } - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (!cmp.contains("tag", 10)) { - return cmp; - } else { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - String s = cmp.getString("id"); - String s1 = convertEntityId(sourceVer, s); - boolean flag; - - if (s1 == null) { - // CraftBukkit - Remove unnecessary warning (occurs when deserializing a Shulker Box item) - // DataInspectorBlockEntity.a.warn("Unable to resolve BlockEntity for ItemInstance: {}", s); - flag = false; - } else { - flag = !nbttagcompound2.contains("id"); - nbttagcompound2.putString("id", s1); - } - - convert(LegacyType.BLOCK_ENTITY, nbttagcompound2, sourceVer, targetVer); - if (flag) { - nbttagcompound2.remove("id"); - } - } - - return cmp; - } - } - - static { - Map map = DataInspectorBlockEntity.b; - - map.put("minecraft:furnace", "Furnace"); - map.put("minecraft:lit_furnace", "Furnace"); - map.put("minecraft:chest", "Chest"); - map.put("minecraft:trapped_chest", "Chest"); - map.put("minecraft:ender_chest", "EnderChest"); - map.put("minecraft:jukebox", "RecordPlayer"); - map.put("minecraft:dispenser", "Trap"); - map.put("minecraft:dropper", "Dropper"); - map.put("minecraft:sign", "Sign"); - map.put("minecraft:mob_spawner", "MobSpawner"); - map.put("minecraft:noteblock", "Music"); - map.put("minecraft:brewing_stand", "Cauldron"); - map.put("minecraft:enhanting_table", "EnchantTable"); - map.put("minecraft:command_block", "CommandBlock"); - map.put("minecraft:beacon", "Beacon"); - map.put("minecraft:skull", "Skull"); - map.put("minecraft:daylight_detector", "DLDetector"); - map.put("minecraft:hopper", "Hopper"); - map.put("minecraft:banner", "Banner"); - map.put("minecraft:flower_pot", "FlowerPot"); - map.put("minecraft:repeating_command_block", "CommandBlock"); - map.put("minecraft:chain_command_block", "CommandBlock"); - map.put("minecraft:standing_sign", "Sign"); - map.put("minecraft:wall_sign", "Sign"); - map.put("minecraft:piston_head", "Piston"); - map.put("minecraft:daylight_detector_inverted", "DLDetector"); - map.put("minecraft:unpowered_comparator", "Comparator"); - map.put("minecraft:powered_comparator", "Comparator"); - map.put("minecraft:wall_banner", "Banner"); - map.put("minecraft:standing_banner", "Banner"); - map.put("minecraft:structure_block", "Structure"); - map.put("minecraft:end_portal", "Airportal"); - map.put("minecraft:end_gateway", "EndGateway"); - map.put("minecraft:shield", "Shield"); - map = DataInspectorBlockEntity.c; - map.put("minecraft:furnace", "minecraft:furnace"); - map.put("minecraft:lit_furnace", "minecraft:furnace"); - map.put("minecraft:chest", "minecraft:chest"); - map.put("minecraft:trapped_chest", "minecraft:chest"); - map.put("minecraft:ender_chest", "minecraft:enderchest"); - map.put("minecraft:jukebox", "minecraft:jukebox"); - map.put("minecraft:dispenser", "minecraft:dispenser"); - map.put("minecraft:dropper", "minecraft:dropper"); - map.put("minecraft:sign", "minecraft:sign"); - map.put("minecraft:mob_spawner", "minecraft:mob_spawner"); - map.put("minecraft:noteblock", "minecraft:noteblock"); - map.put("minecraft:brewing_stand", "minecraft:brewing_stand"); - map.put("minecraft:enhanting_table", "minecraft:enchanting_table"); - map.put("minecraft:command_block", "minecraft:command_block"); - map.put("minecraft:beacon", "minecraft:beacon"); - map.put("minecraft:skull", "minecraft:skull"); - map.put("minecraft:daylight_detector", "minecraft:daylight_detector"); - map.put("minecraft:hopper", "minecraft:hopper"); - map.put("minecraft:banner", "minecraft:banner"); - map.put("minecraft:flower_pot", "minecraft:flower_pot"); - map.put("minecraft:repeating_command_block", "minecraft:command_block"); - map.put("minecraft:chain_command_block", "minecraft:command_block"); - map.put("minecraft:shulker_box", "minecraft:shulker_box"); - map.put("minecraft:white_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:orange_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:magenta_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:light_blue_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:yellow_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:lime_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:pink_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:gray_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:silver_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:cyan_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:purple_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:blue_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:brown_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:green_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:red_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:black_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:bed", "minecraft:bed"); - map.put("minecraft:standing_sign", "minecraft:sign"); - map.put("minecraft:wall_sign", "minecraft:sign"); - map.put("minecraft:piston_head", "minecraft:piston"); - map.put("minecraft:daylight_detector_inverted", "minecraft:daylight_detector"); - map.put("minecraft:unpowered_comparator", "minecraft:comparator"); - map.put("minecraft:powered_comparator", "minecraft:comparator"); - map.put("minecraft:wall_banner", "minecraft:banner"); - map.put("minecraft:standing_banner", "minecraft:banner"); - map.put("minecraft:structure_block", "minecraft:structure_block"); - map.put("minecraft:end_portal", "minecraft:end_portal"); - map.put("minecraft:end_gateway", "minecraft:end_gateway"); - map.put("minecraft:shield", "minecraft:shield"); - } - } - - private static class DataInspectorEntity implements DataInspector { - - DataInspectorEntity() { - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("EntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); - String s = cmp.getString("id"); - String s1; - - if ("minecraft:armor_stand".equals(s)) { - s1 = sourceVer < 515 ? "ArmorStand" : "minecraft:armor_stand"; - } else { - if (!"minecraft:spawn_egg".equals(s)) { - return cmp; - } - - s1 = nbttagcompound2.getString("id"); - } - - boolean flag; - - flag = !nbttagcompound2.contains("id", 8); - nbttagcompound2.putString("id", s1); - - convert(LegacyType.ENTITY, nbttagcompound2, sourceVer, targetVer); - if (flag) { - nbttagcompound2.remove("id"); - } - } - - return cmp; - } - } - - - private abstract static class DataInspectorTagged implements DataInspector { - - private final ResourceLocation key; - - DataInspectorTagged(String type) { - this.key = getKey(type); - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (this.key.equals(new ResourceLocation(cmp.getString("id")))) { - cmp = this.inspectChecked(cmp, sourceVer, targetVer); - } - - return cmp; - } - - abstract net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer); - } - - private static class DataInspectorItemList extends DataInspectorTagged { - - private final String[] keys; - - DataInspectorItemList(String oclass, String... astring) { - super(oclass); - this.keys = astring; - } - - net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer) { - for (String s : this.keys) { - PaperweightDataConverters.convertItems(nbttagcompound, s, sourceVer, targetVer); - } - - return nbttagcompound; - } - } - - private static class DataInspectorItem extends DataInspectorTagged { - - private final String[] keys; - - DataInspectorItem(String oclass, String... astring) { - super(oclass); - this.keys = astring; - } - - net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer) { - for (String key : this.keys) { - PaperweightDataConverters.convertItem(nbttagcompound, key, sourceVer, targetVer); - } - - return nbttagcompound; - } - } - - private static class DataConverterMaterialId implements DataConverter { - - private static final String[] materials = new String[2268]; - - DataConverterMaterialId() { - } - - public int getDataVersion() { - return 102; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("id", 99)) { - short short0 = cmp.getShort("id"); - - if (short0 > 0 && short0 < materials.length && materials[short0] != null) { - cmp.putString("id", materials[short0]); - } - } - - return cmp; - } - - static { - materials[1] = "minecraft:stone"; - materials[2] = "minecraft:grass"; - materials[3] = "minecraft:dirt"; - materials[4] = "minecraft:cobblestone"; - materials[5] = "minecraft:planks"; - materials[6] = "minecraft:sapling"; - materials[7] = "minecraft:bedrock"; - materials[8] = "minecraft:flowing_water"; - materials[9] = "minecraft:water"; - materials[10] = "minecraft:flowing_lava"; - materials[11] = "minecraft:lava"; - materials[12] = "minecraft:sand"; - materials[13] = "minecraft:gravel"; - materials[14] = "minecraft:gold_ore"; - materials[15] = "minecraft:iron_ore"; - materials[16] = "minecraft:coal_ore"; - materials[17] = "minecraft:log"; - materials[18] = "minecraft:leaves"; - materials[19] = "minecraft:sponge"; - materials[20] = "minecraft:glass"; - materials[21] = "minecraft:lapis_ore"; - materials[22] = "minecraft:lapis_block"; - materials[23] = "minecraft:dispenser"; - materials[24] = "minecraft:sandstone"; - materials[25] = "minecraft:noteblock"; - materials[27] = "minecraft:golden_rail"; - materials[28] = "minecraft:detector_rail"; - materials[29] = "minecraft:sticky_piston"; - materials[30] = "minecraft:web"; - materials[31] = "minecraft:tallgrass"; - materials[32] = "minecraft:deadbush"; - materials[33] = "minecraft:piston"; - materials[35] = "minecraft:wool"; - materials[37] = "minecraft:yellow_flower"; - materials[38] = "minecraft:red_flower"; - materials[39] = "minecraft:brown_mushroom"; - materials[40] = "minecraft:red_mushroom"; - materials[41] = "minecraft:gold_block"; - materials[42] = "minecraft:iron_block"; - materials[43] = "minecraft:double_stone_slab"; - materials[44] = "minecraft:stone_slab"; - materials[45] = "minecraft:brick_block"; - materials[46] = "minecraft:tnt"; - materials[47] = "minecraft:bookshelf"; - materials[48] = "minecraft:mossy_cobblestone"; - materials[49] = "minecraft:obsidian"; - materials[50] = "minecraft:torch"; - materials[51] = "minecraft:fire"; - materials[52] = "minecraft:mob_spawner"; - materials[53] = "minecraft:oak_stairs"; - materials[54] = "minecraft:chest"; - materials[56] = "minecraft:diamond_ore"; - materials[57] = "minecraft:diamond_block"; - materials[58] = "minecraft:crafting_table"; - materials[60] = "minecraft:farmland"; - materials[61] = "minecraft:furnace"; - materials[62] = "minecraft:lit_furnace"; - materials[65] = "minecraft:ladder"; - materials[66] = "minecraft:rail"; - materials[67] = "minecraft:stone_stairs"; - materials[69] = "minecraft:lever"; - materials[70] = "minecraft:stone_pressure_plate"; - materials[72] = "minecraft:wooden_pressure_plate"; - materials[73] = "minecraft:redstone_ore"; - materials[76] = "minecraft:redstone_torch"; - materials[77] = "minecraft:stone_button"; - materials[78] = "minecraft:snow_layer"; - materials[79] = "minecraft:ice"; - materials[80] = "minecraft:snow"; - materials[81] = "minecraft:cactus"; - materials[82] = "minecraft:clay"; - materials[84] = "minecraft:jukebox"; - materials[85] = "minecraft:fence"; - materials[86] = "minecraft:pumpkin"; - materials[87] = "minecraft:netherrack"; - materials[88] = "minecraft:soul_sand"; - materials[89] = "minecraft:glowstone"; - materials[90] = "minecraft:portal"; - materials[91] = "minecraft:lit_pumpkin"; - materials[95] = "minecraft:stained_glass"; - materials[96] = "minecraft:trapdoor"; - materials[97] = "minecraft:monster_egg"; - materials[98] = "minecraft:stonebrick"; - materials[99] = "minecraft:brown_mushroom_block"; - materials[100] = "minecraft:red_mushroom_block"; - materials[101] = "minecraft:iron_bars"; - materials[102] = "minecraft:glass_pane"; - materials[103] = "minecraft:melon_block"; - materials[106] = "minecraft:vine"; - materials[107] = "minecraft:fence_gate"; - materials[108] = "minecraft:brick_stairs"; - materials[109] = "minecraft:stone_brick_stairs"; - materials[110] = "minecraft:mycelium"; - materials[111] = "minecraft:waterlily"; - materials[112] = "minecraft:nether_brick"; - materials[113] = "minecraft:nether_brick_fence"; - materials[114] = "minecraft:nether_brick_stairs"; - materials[116] = "minecraft:enchanting_table"; - materials[119] = "minecraft:end_portal"; - materials[120] = "minecraft:end_portal_frame"; - materials[121] = "minecraft:end_stone"; - materials[122] = "minecraft:dragon_egg"; - materials[123] = "minecraft:redstone_lamp"; - materials[125] = "minecraft:double_wooden_slab"; - materials[126] = "minecraft:wooden_slab"; - materials[127] = "minecraft:cocoa"; - materials[128] = "minecraft:sandstone_stairs"; - materials[129] = "minecraft:emerald_ore"; - materials[130] = "minecraft:ender_chest"; - materials[131] = "minecraft:tripwire_hook"; - materials[133] = "minecraft:emerald_block"; - materials[134] = "minecraft:spruce_stairs"; - materials[135] = "minecraft:birch_stairs"; - materials[136] = "minecraft:jungle_stairs"; - materials[137] = "minecraft:command_block"; - materials[138] = "minecraft:beacon"; - materials[139] = "minecraft:cobblestone_wall"; - materials[141] = "minecraft:carrots"; - materials[142] = "minecraft:potatoes"; - materials[143] = "minecraft:wooden_button"; - materials[145] = "minecraft:anvil"; - materials[146] = "minecraft:trapped_chest"; - materials[147] = "minecraft:light_weighted_pressure_plate"; - materials[148] = "minecraft:heavy_weighted_pressure_plate"; - materials[151] = "minecraft:daylight_detector"; - materials[152] = "minecraft:redstone_block"; - materials[153] = "minecraft:quartz_ore"; - materials[154] = "minecraft:hopper"; - materials[155] = "minecraft:quartz_block"; - materials[156] = "minecraft:quartz_stairs"; - materials[157] = "minecraft:activator_rail"; - materials[158] = "minecraft:dropper"; - materials[159] = "minecraft:stained_hardened_clay"; - materials[160] = "minecraft:stained_glass_pane"; - materials[161] = "minecraft:leaves2"; - materials[162] = "minecraft:log2"; - materials[163] = "minecraft:acacia_stairs"; - materials[164] = "minecraft:dark_oak_stairs"; - materials[170] = "minecraft:hay_block"; - materials[171] = "minecraft:carpet"; - materials[172] = "minecraft:hardened_clay"; - materials[173] = "minecraft:coal_block"; - materials[174] = "minecraft:packed_ice"; - materials[175] = "minecraft:double_plant"; - materials[256] = "minecraft:iron_shovel"; - materials[257] = "minecraft:iron_pickaxe"; - materials[258] = "minecraft:iron_axe"; - materials[259] = "minecraft:flint_and_steel"; - materials[260] = "minecraft:apple"; - materials[261] = "minecraft:bow"; - materials[262] = "minecraft:arrow"; - materials[263] = "minecraft:coal"; - materials[264] = "minecraft:diamond"; - materials[265] = "minecraft:iron_ingot"; - materials[266] = "minecraft:gold_ingot"; - materials[267] = "minecraft:iron_sword"; - materials[268] = "minecraft:wooden_sword"; - materials[269] = "minecraft:wooden_shovel"; - materials[270] = "minecraft:wooden_pickaxe"; - materials[271] = "minecraft:wooden_axe"; - materials[272] = "minecraft:stone_sword"; - materials[273] = "minecraft:stone_shovel"; - materials[274] = "minecraft:stone_pickaxe"; - materials[275] = "minecraft:stone_axe"; - materials[276] = "minecraft:diamond_sword"; - materials[277] = "minecraft:diamond_shovel"; - materials[278] = "minecraft:diamond_pickaxe"; - materials[279] = "minecraft:diamond_axe"; - materials[280] = "minecraft:stick"; - materials[281] = "minecraft:bowl"; - materials[282] = "minecraft:mushroom_stew"; - materials[283] = "minecraft:golden_sword"; - materials[284] = "minecraft:golden_shovel"; - materials[285] = "minecraft:golden_pickaxe"; - materials[286] = "minecraft:golden_axe"; - materials[287] = "minecraft:string"; - materials[288] = "minecraft:feather"; - materials[289] = "minecraft:gunpowder"; - materials[290] = "minecraft:wooden_hoe"; - materials[291] = "minecraft:stone_hoe"; - materials[292] = "minecraft:iron_hoe"; - materials[293] = "minecraft:diamond_hoe"; - materials[294] = "minecraft:golden_hoe"; - materials[295] = "minecraft:wheat_seeds"; - materials[296] = "minecraft:wheat"; - materials[297] = "minecraft:bread"; - materials[298] = "minecraft:leather_helmet"; - materials[299] = "minecraft:leather_chestplate"; - materials[300] = "minecraft:leather_leggings"; - materials[301] = "minecraft:leather_boots"; - materials[302] = "minecraft:chainmail_helmet"; - materials[303] = "minecraft:chainmail_chestplate"; - materials[304] = "minecraft:chainmail_leggings"; - materials[305] = "minecraft:chainmail_boots"; - materials[306] = "minecraft:iron_helmet"; - materials[307] = "minecraft:iron_chestplate"; - materials[308] = "minecraft:iron_leggings"; - materials[309] = "minecraft:iron_boots"; - materials[310] = "minecraft:diamond_helmet"; - materials[311] = "minecraft:diamond_chestplate"; - materials[312] = "minecraft:diamond_leggings"; - materials[313] = "minecraft:diamond_boots"; - materials[314] = "minecraft:golden_helmet"; - materials[315] = "minecraft:golden_chestplate"; - materials[316] = "minecraft:golden_leggings"; - materials[317] = "minecraft:golden_boots"; - materials[318] = "minecraft:flint"; - materials[319] = "minecraft:porkchop"; - materials[320] = "minecraft:cooked_porkchop"; - materials[321] = "minecraft:painting"; - materials[322] = "minecraft:golden_apple"; - materials[323] = "minecraft:sign"; - materials[324] = "minecraft:wooden_door"; - materials[325] = "minecraft:bucket"; - materials[326] = "minecraft:water_bucket"; - materials[327] = "minecraft:lava_bucket"; - materials[328] = "minecraft:minecart"; - materials[329] = "minecraft:saddle"; - materials[330] = "minecraft:iron_door"; - materials[331] = "minecraft:redstone"; - materials[332] = "minecraft:snowball"; - materials[333] = "minecraft:boat"; - materials[334] = "minecraft:leather"; - materials[335] = "minecraft:milk_bucket"; - materials[336] = "minecraft:brick"; - materials[337] = "minecraft:clay_ball"; - materials[338] = "minecraft:reeds"; - materials[339] = "minecraft:paper"; - materials[340] = "minecraft:book"; - materials[341] = "minecraft:slime_ball"; - materials[342] = "minecraft:chest_minecart"; - materials[343] = "minecraft:furnace_minecart"; - materials[344] = "minecraft:egg"; - materials[345] = "minecraft:compass"; - materials[346] = "minecraft:fishing_rod"; - materials[347] = "minecraft:clock"; - materials[348] = "minecraft:glowstone_dust"; - materials[349] = "minecraft:fish"; - materials[350] = "minecraft:cooked_fish"; // Paper - cooked_fished -> cooked_fish - materials[351] = "minecraft:dye"; - materials[352] = "minecraft:bone"; - materials[353] = "minecraft:sugar"; - materials[354] = "minecraft:cake"; - materials[355] = "minecraft:bed"; - materials[356] = "minecraft:repeater"; - materials[357] = "minecraft:cookie"; - materials[358] = "minecraft:filled_map"; - materials[359] = "minecraft:shears"; - materials[360] = "minecraft:melon"; - materials[361] = "minecraft:pumpkin_seeds"; - materials[362] = "minecraft:melon_seeds"; - materials[363] = "minecraft:beef"; - materials[364] = "minecraft:cooked_beef"; - materials[365] = "minecraft:chicken"; - materials[366] = "minecraft:cooked_chicken"; - materials[367] = "minecraft:rotten_flesh"; - materials[368] = "minecraft:ender_pearl"; - materials[369] = "minecraft:blaze_rod"; - materials[370] = "minecraft:ghast_tear"; - materials[371] = "minecraft:gold_nugget"; - materials[372] = "minecraft:nether_wart"; - materials[373] = "minecraft:potion"; - materials[374] = "minecraft:glass_bottle"; - materials[375] = "minecraft:spider_eye"; - materials[376] = "minecraft:fermented_spider_eye"; - materials[377] = "minecraft:blaze_powder"; - materials[378] = "minecraft:magma_cream"; - materials[379] = "minecraft:brewing_stand"; - materials[380] = "minecraft:cauldron"; - materials[381] = "minecraft:ender_eye"; - materials[382] = "minecraft:speckled_melon"; - materials[383] = "minecraft:spawn_egg"; - materials[384] = "minecraft:experience_bottle"; - materials[385] = "minecraft:fire_charge"; - materials[386] = "minecraft:writable_book"; - materials[387] = "minecraft:written_book"; - materials[388] = "minecraft:emerald"; - materials[389] = "minecraft:item_frame"; - materials[390] = "minecraft:flower_pot"; - materials[391] = "minecraft:carrot"; - materials[392] = "minecraft:potato"; - materials[393] = "minecraft:baked_potato"; - materials[394] = "minecraft:poisonous_potato"; - materials[395] = "minecraft:map"; - materials[396] = "minecraft:golden_carrot"; - materials[397] = "minecraft:skull"; - materials[398] = "minecraft:carrot_on_a_stick"; - materials[399] = "minecraft:nether_star"; - materials[400] = "minecraft:pumpkin_pie"; - materials[401] = "minecraft:fireworks"; - materials[402] = "minecraft:firework_charge"; - materials[403] = "minecraft:enchanted_book"; - materials[404] = "minecraft:comparator"; - materials[405] = "minecraft:netherbrick"; - materials[406] = "minecraft:quartz"; - materials[407] = "minecraft:tnt_minecart"; - materials[408] = "minecraft:hopper_minecart"; - materials[417] = "minecraft:iron_horse_armor"; - materials[418] = "minecraft:golden_horse_armor"; - materials[419] = "minecraft:diamond_horse_armor"; - materials[420] = "minecraft:lead"; - materials[421] = "minecraft:name_tag"; - materials[422] = "minecraft:command_block_minecart"; - materials[2256] = "minecraft:record_13"; - materials[2257] = "minecraft:record_cat"; - materials[2258] = "minecraft:record_blocks"; - materials[2259] = "minecraft:record_chirp"; - materials[2260] = "minecraft:record_far"; - materials[2261] = "minecraft:record_mall"; - materials[2262] = "minecraft:record_mellohi"; - materials[2263] = "minecraft:record_stal"; - materials[2264] = "minecraft:record_strad"; - materials[2265] = "minecraft:record_ward"; - materials[2266] = "minecraft:record_11"; - materials[2267] = "minecraft:record_wait"; - // Paper start - materials[409] = "minecraft:prismarine_shard"; - materials[410] = "minecraft:prismarine_crystals"; - materials[411] = "minecraft:rabbit"; - materials[412] = "minecraft:cooked_rabbit"; - materials[413] = "minecraft:rabbit_stew"; - materials[414] = "minecraft:rabbit_foot"; - materials[415] = "minecraft:rabbit_hide"; - materials[416] = "minecraft:armor_stand"; - materials[423] = "minecraft:mutton"; - materials[424] = "minecraft:cooked_mutton"; - materials[425] = "minecraft:banner"; - materials[426] = "minecraft:end_crystal"; - materials[427] = "minecraft:spruce_door"; - materials[428] = "minecraft:birch_door"; - materials[429] = "minecraft:jungle_door"; - materials[430] = "minecraft:acacia_door"; - materials[431] = "minecraft:dark_oak_door"; - materials[432] = "minecraft:chorus_fruit"; - materials[433] = "minecraft:chorus_fruit_popped"; - materials[434] = "minecraft:beetroot"; - materials[435] = "minecraft:beetroot_seeds"; - materials[436] = "minecraft:beetroot_soup"; - materials[437] = "minecraft:dragon_breath"; - materials[438] = "minecraft:splash_potion"; - materials[439] = "minecraft:spectral_arrow"; - materials[440] = "minecraft:tipped_arrow"; - materials[441] = "minecraft:lingering_potion"; - materials[442] = "minecraft:shield"; - materials[443] = "minecraft:elytra"; - materials[444] = "minecraft:spruce_boat"; - materials[445] = "minecraft:birch_boat"; - materials[446] = "minecraft:jungle_boat"; - materials[447] = "minecraft:acacia_boat"; - materials[448] = "minecraft:dark_oak_boat"; - materials[449] = "minecraft:totem_of_undying"; - materials[450] = "minecraft:shulker_shell"; - materials[452] = "minecraft:iron_nugget"; - materials[453] = "minecraft:knowledge_book"; - // Paper end - } - } - - private static class DataConverterArmorStand implements DataConverter { - - DataConverterArmorStand() { - } - - public int getDataVersion() { - return 147; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("ArmorStand".equals(cmp.getString("id")) && cmp.getBoolean("Silent") && !cmp.getBoolean("Marker")) { - cmp.remove("Silent"); - } - - return cmp; - } - } - - private static class DataConverterBanner implements DataConverter { - - DataConverterBanner() { - } - - public int getDataVersion() { - return 804; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:banner".equals(cmp.getString("id")) && cmp.contains("tag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - - if (nbttagcompound2.contains("Base", 99)) { - cmp.putShort("Damage", (short) (nbttagcompound2.getShort("Base") & 15)); - if (nbttagcompound1.contains("display", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound3 = nbttagcompound1.getCompound("display"); - - if (nbttagcompound3.contains("Lore", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound3.getList("Lore", 8); - - if (nbttaglist.size() == 1 && "(+NBT)".equals(nbttaglist.getString(0))) { - return cmp; - } - } - } - - nbttagcompound2.remove("Base"); - if (nbttagcompound2.isEmpty()) { - nbttagcompound1.remove("BlockEntityTag"); - } - - if (nbttagcompound1.isEmpty()) { - cmp.remove("tag"); - } - } - } - } - - return cmp; - } - } - - private static class DataConverterPotionId implements DataConverter { - - private static final String[] potions = new String[128]; - - DataConverterPotionId() { - } - - public int getDataVersion() { - return 102; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:potion".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - short short0 = cmp.getShort("Damage"); - - if (!nbttagcompound1.contains("Potion", 8)) { - String s = DataConverterPotionId.potions[short0 & 127]; - - nbttagcompound1.putString("Potion", s == null ? "minecraft:water" : s); - cmp.put("tag", nbttagcompound1); - if ((short0 & 16384) == 16384) { - cmp.putString("id", "minecraft:splash_potion"); - } - } - - if (short0 != 0) { - cmp.putShort("Damage", (short) 0); - } - } - - return cmp; - } - - static { - DataConverterPotionId.potions[0] = "minecraft:water"; - DataConverterPotionId.potions[1] = "minecraft:regeneration"; - DataConverterPotionId.potions[2] = "minecraft:swiftness"; - DataConverterPotionId.potions[3] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[4] = "minecraft:poison"; - DataConverterPotionId.potions[5] = "minecraft:healing"; - DataConverterPotionId.potions[6] = "minecraft:night_vision"; - DataConverterPotionId.potions[7] = null; - DataConverterPotionId.potions[8] = "minecraft:weakness"; - DataConverterPotionId.potions[9] = "minecraft:strength"; - DataConverterPotionId.potions[10] = "minecraft:slowness"; - DataConverterPotionId.potions[11] = "minecraft:leaping"; - DataConverterPotionId.potions[12] = "minecraft:harming"; - DataConverterPotionId.potions[13] = "minecraft:water_breathing"; - DataConverterPotionId.potions[14] = "minecraft:invisibility"; - DataConverterPotionId.potions[15] = null; - DataConverterPotionId.potions[16] = "minecraft:awkward"; - DataConverterPotionId.potions[17] = "minecraft:regeneration"; - DataConverterPotionId.potions[18] = "minecraft:swiftness"; - DataConverterPotionId.potions[19] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[20] = "minecraft:poison"; - DataConverterPotionId.potions[21] = "minecraft:healing"; - DataConverterPotionId.potions[22] = "minecraft:night_vision"; - DataConverterPotionId.potions[23] = null; - DataConverterPotionId.potions[24] = "minecraft:weakness"; - DataConverterPotionId.potions[25] = "minecraft:strength"; - DataConverterPotionId.potions[26] = "minecraft:slowness"; - DataConverterPotionId.potions[27] = "minecraft:leaping"; - DataConverterPotionId.potions[28] = "minecraft:harming"; - DataConverterPotionId.potions[29] = "minecraft:water_breathing"; - DataConverterPotionId.potions[30] = "minecraft:invisibility"; - DataConverterPotionId.potions[31] = null; - DataConverterPotionId.potions[32] = "minecraft:thick"; - DataConverterPotionId.potions[33] = "minecraft:strong_regeneration"; - DataConverterPotionId.potions[34] = "minecraft:strong_swiftness"; - DataConverterPotionId.potions[35] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[36] = "minecraft:strong_poison"; - DataConverterPotionId.potions[37] = "minecraft:strong_healing"; - DataConverterPotionId.potions[38] = "minecraft:night_vision"; - DataConverterPotionId.potions[39] = null; - DataConverterPotionId.potions[40] = "minecraft:weakness"; - DataConverterPotionId.potions[41] = "minecraft:strong_strength"; - DataConverterPotionId.potions[42] = "minecraft:slowness"; - DataConverterPotionId.potions[43] = "minecraft:strong_leaping"; - DataConverterPotionId.potions[44] = "minecraft:strong_harming"; - DataConverterPotionId.potions[45] = "minecraft:water_breathing"; - DataConverterPotionId.potions[46] = "minecraft:invisibility"; - DataConverterPotionId.potions[47] = null; - DataConverterPotionId.potions[48] = null; - DataConverterPotionId.potions[49] = "minecraft:strong_regeneration"; - DataConverterPotionId.potions[50] = "minecraft:strong_swiftness"; - DataConverterPotionId.potions[51] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[52] = "minecraft:strong_poison"; - DataConverterPotionId.potions[53] = "minecraft:strong_healing"; - DataConverterPotionId.potions[54] = "minecraft:night_vision"; - DataConverterPotionId.potions[55] = null; - DataConverterPotionId.potions[56] = "minecraft:weakness"; - DataConverterPotionId.potions[57] = "minecraft:strong_strength"; - DataConverterPotionId.potions[58] = "minecraft:slowness"; - DataConverterPotionId.potions[59] = "minecraft:strong_leaping"; - DataConverterPotionId.potions[60] = "minecraft:strong_harming"; - DataConverterPotionId.potions[61] = "minecraft:water_breathing"; - DataConverterPotionId.potions[62] = "minecraft:invisibility"; - DataConverterPotionId.potions[63] = null; - DataConverterPotionId.potions[64] = "minecraft:mundane"; - DataConverterPotionId.potions[65] = "minecraft:long_regeneration"; - DataConverterPotionId.potions[66] = "minecraft:long_swiftness"; - DataConverterPotionId.potions[67] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[68] = "minecraft:long_poison"; - DataConverterPotionId.potions[69] = "minecraft:healing"; - DataConverterPotionId.potions[70] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[71] = null; - DataConverterPotionId.potions[72] = "minecraft:long_weakness"; - DataConverterPotionId.potions[73] = "minecraft:long_strength"; - DataConverterPotionId.potions[74] = "minecraft:long_slowness"; - DataConverterPotionId.potions[75] = "minecraft:long_leaping"; - DataConverterPotionId.potions[76] = "minecraft:harming"; - DataConverterPotionId.potions[77] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[78] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[79] = null; - DataConverterPotionId.potions[80] = "minecraft:awkward"; - DataConverterPotionId.potions[81] = "minecraft:long_regeneration"; - DataConverterPotionId.potions[82] = "minecraft:long_swiftness"; - DataConverterPotionId.potions[83] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[84] = "minecraft:long_poison"; - DataConverterPotionId.potions[85] = "minecraft:healing"; - DataConverterPotionId.potions[86] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[87] = null; - DataConverterPotionId.potions[88] = "minecraft:long_weakness"; - DataConverterPotionId.potions[89] = "minecraft:long_strength"; - DataConverterPotionId.potions[90] = "minecraft:long_slowness"; - DataConverterPotionId.potions[91] = "minecraft:long_leaping"; - DataConverterPotionId.potions[92] = "minecraft:harming"; - DataConverterPotionId.potions[93] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[94] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[95] = null; - DataConverterPotionId.potions[96] = "minecraft:thick"; - DataConverterPotionId.potions[97] = "minecraft:regeneration"; - DataConverterPotionId.potions[98] = "minecraft:swiftness"; - DataConverterPotionId.potions[99] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[100] = "minecraft:poison"; - DataConverterPotionId.potions[101] = "minecraft:strong_healing"; - DataConverterPotionId.potions[102] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[103] = null; - DataConverterPotionId.potions[104] = "minecraft:long_weakness"; - DataConverterPotionId.potions[105] = "minecraft:strength"; - DataConverterPotionId.potions[106] = "minecraft:long_slowness"; - DataConverterPotionId.potions[107] = "minecraft:leaping"; - DataConverterPotionId.potions[108] = "minecraft:strong_harming"; - DataConverterPotionId.potions[109] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[110] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[111] = null; - DataConverterPotionId.potions[112] = null; - DataConverterPotionId.potions[113] = "minecraft:regeneration"; - DataConverterPotionId.potions[114] = "minecraft:swiftness"; - DataConverterPotionId.potions[115] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[116] = "minecraft:poison"; - DataConverterPotionId.potions[117] = "minecraft:strong_healing"; - DataConverterPotionId.potions[118] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[119] = null; - DataConverterPotionId.potions[120] = "minecraft:long_weakness"; - DataConverterPotionId.potions[121] = "minecraft:strength"; - DataConverterPotionId.potions[122] = "minecraft:long_slowness"; - DataConverterPotionId.potions[123] = "minecraft:leaping"; - DataConverterPotionId.potions[124] = "minecraft:strong_harming"; - DataConverterPotionId.potions[125] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[126] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[127] = null; - } - } - - private static class DataConverterSpawnEgg implements DataConverter { - - private static final String[] eggs = new String[256]; - - DataConverterSpawnEgg() { - } - - public int getDataVersion() { - return 105; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:spawn_egg".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); - short short0 = cmp.getShort("Damage"); - - if (!nbttagcompound2.contains("id", 8)) { - String s = DataConverterSpawnEgg.eggs[short0 & 255]; - - if (s != null) { - nbttagcompound2.putString("id", s); - nbttagcompound1.put("EntityTag", nbttagcompound2); - cmp.put("tag", nbttagcompound1); - } - } - - if (short0 != 0) { - cmp.putShort("Damage", (short) 0); - } - } - - return cmp; - } - - static { - - DataConverterSpawnEgg.eggs[1] = "Item"; - DataConverterSpawnEgg.eggs[2] = "XPOrb"; - DataConverterSpawnEgg.eggs[7] = "ThrownEgg"; - DataConverterSpawnEgg.eggs[8] = "LeashKnot"; - DataConverterSpawnEgg.eggs[9] = "Painting"; - DataConverterSpawnEgg.eggs[10] = "Arrow"; - DataConverterSpawnEgg.eggs[11] = "Snowball"; - DataConverterSpawnEgg.eggs[12] = "Fireball"; - DataConverterSpawnEgg.eggs[13] = "SmallFireball"; - DataConverterSpawnEgg.eggs[14] = "ThrownEnderpearl"; - DataConverterSpawnEgg.eggs[15] = "EyeOfEnderSignal"; - DataConverterSpawnEgg.eggs[16] = "ThrownPotion"; - DataConverterSpawnEgg.eggs[17] = "ThrownExpBottle"; - DataConverterSpawnEgg.eggs[18] = "ItemFrame"; - DataConverterSpawnEgg.eggs[19] = "WitherSkull"; - DataConverterSpawnEgg.eggs[20] = "PrimedTnt"; - DataConverterSpawnEgg.eggs[21] = "FallingSand"; - DataConverterSpawnEgg.eggs[22] = "FireworksRocketEntity"; - DataConverterSpawnEgg.eggs[23] = "TippedArrow"; - DataConverterSpawnEgg.eggs[24] = "SpectralArrow"; - DataConverterSpawnEgg.eggs[25] = "ShulkerBullet"; - DataConverterSpawnEgg.eggs[26] = "DragonFireball"; - DataConverterSpawnEgg.eggs[30] = "ArmorStand"; - DataConverterSpawnEgg.eggs[41] = "Boat"; - DataConverterSpawnEgg.eggs[42] = "MinecartRideable"; - DataConverterSpawnEgg.eggs[43] = "MinecartChest"; - DataConverterSpawnEgg.eggs[44] = "MinecartFurnace"; - DataConverterSpawnEgg.eggs[45] = "MinecartTNT"; - DataConverterSpawnEgg.eggs[46] = "MinecartHopper"; - DataConverterSpawnEgg.eggs[47] = "MinecartSpawner"; - DataConverterSpawnEgg.eggs[40] = "MinecartCommandBlock"; - DataConverterSpawnEgg.eggs[48] = "Mob"; - DataConverterSpawnEgg.eggs[49] = "Monster"; - DataConverterSpawnEgg.eggs[50] = "Creeper"; - DataConverterSpawnEgg.eggs[51] = "Skeleton"; - DataConverterSpawnEgg.eggs[52] = "Spider"; - DataConverterSpawnEgg.eggs[53] = "Giant"; - DataConverterSpawnEgg.eggs[54] = "Zombie"; - DataConverterSpawnEgg.eggs[55] = "Slime"; - DataConverterSpawnEgg.eggs[56] = "Ghast"; - DataConverterSpawnEgg.eggs[57] = "PigZombie"; - DataConverterSpawnEgg.eggs[58] = "Enderman"; - DataConverterSpawnEgg.eggs[59] = "CaveSpider"; - DataConverterSpawnEgg.eggs[60] = "Silverfish"; - DataConverterSpawnEgg.eggs[61] = "Blaze"; - DataConverterSpawnEgg.eggs[62] = "LavaSlime"; - DataConverterSpawnEgg.eggs[63] = "EnderDragon"; - DataConverterSpawnEgg.eggs[64] = "WitherBoss"; - DataConverterSpawnEgg.eggs[65] = "Bat"; - DataConverterSpawnEgg.eggs[66] = "Witch"; - DataConverterSpawnEgg.eggs[67] = "Endermite"; - DataConverterSpawnEgg.eggs[68] = "Guardian"; - DataConverterSpawnEgg.eggs[69] = "Shulker"; - DataConverterSpawnEgg.eggs[90] = "Pig"; - DataConverterSpawnEgg.eggs[91] = "Sheep"; - DataConverterSpawnEgg.eggs[92] = "Cow"; - DataConverterSpawnEgg.eggs[93] = "Chicken"; - DataConverterSpawnEgg.eggs[94] = "Squid"; - DataConverterSpawnEgg.eggs[95] = "Wolf"; - DataConverterSpawnEgg.eggs[96] = "MushroomCow"; - DataConverterSpawnEgg.eggs[97] = "SnowMan"; - DataConverterSpawnEgg.eggs[98] = "Ozelot"; - DataConverterSpawnEgg.eggs[99] = "VillagerGolem"; - DataConverterSpawnEgg.eggs[100] = "EntityHorse"; - DataConverterSpawnEgg.eggs[101] = "Rabbit"; - DataConverterSpawnEgg.eggs[120] = "Villager"; - DataConverterSpawnEgg.eggs[200] = "EnderCrystal"; - } - } - - private static class DataConverterMinecart implements DataConverter { - - private static final List a = Lists.newArrayList("MinecartRideable", "MinecartChest", "MinecartFurnace", "MinecartTNT", "MinecartSpawner", "MinecartHopper", "MinecartCommandBlock"); - - DataConverterMinecart() { - } - - public int getDataVersion() { - return 106; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Minecart".equals(cmp.getString("id"))) { - String s = "MinecartRideable"; - int i = cmp.getInt("Type"); - - if (i > 0 && i < DataConverterMinecart.a.size()) { - s = DataConverterMinecart.a.get(i); - } - - cmp.putString("id", s); - cmp.remove("Type"); - } - - return cmp; - } - } - - private static class DataConverterMobSpawner implements DataConverter { - - DataConverterMobSpawner() { - } - - public int getDataVersion() { - return 107; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (!"MobSpawner".equals(cmp.getString("id"))) { - return cmp; - } else { - if (cmp.contains("EntityId", 8)) { - String s = cmp.getString("EntityId"); - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("SpawnData"); - - nbttagcompound1.putString("id", s.isEmpty() ? "Pig" : s); - cmp.put("SpawnData", nbttagcompound1); - cmp.remove("EntityId"); - } - - if (cmp.contains("SpawnPotentials", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("SpawnPotentials", 10); - - for (int i = 0; i < nbttaglist.size(); ++i) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompound(i); - - if (nbttagcompound2.contains("Type", 8)) { - net.minecraft.nbt.CompoundTag nbttagcompound3 = nbttagcompound2.getCompound("Properties"); - - nbttagcompound3.putString("id", nbttagcompound2.getString("Type")); - nbttagcompound2.put("Entity", nbttagcompound3); - nbttagcompound2.remove("Type"); - nbttagcompound2.remove("Properties"); - } - } - } - - return cmp; - } - } - } - - private static class DataConverterUUID implements DataConverter { - - DataConverterUUID() { - } - - public int getDataVersion() { - return 108; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("UUID", 8)) { - cmp.putUUID("UUID", UUID.fromString(cmp.getString("UUID"))); - } - - return cmp; - } - } - - private static class DataConverterHealth implements DataConverter { - - private static final Set a = Sets.newHashSet("ArmorStand", "Bat", "Blaze", "CaveSpider", "Chicken", "Cow", "Creeper", "EnderDragon", "Enderman", "Endermite", "EntityHorse", "Ghast", "Giant", "Guardian", "LavaSlime", "MushroomCow", "Ozelot", "Pig", "PigZombie", "Rabbit", "Sheep", "Shulker", "Silverfish", "Skeleton", "Slime", "SnowMan", "Spider", "Squid", "Villager", "VillagerGolem", "Witch", "WitherBoss", "Wolf", "Zombie"); - - DataConverterHealth() { - } - - public int getDataVersion() { - return 109; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (DataConverterHealth.a.contains(cmp.getString("id"))) { - float f; - - if (cmp.contains("HealF", 99)) { - f = cmp.getFloat("HealF"); - cmp.remove("HealF"); - } else { - if (!cmp.contains("Health", 99)) { - return cmp; - } - - f = cmp.getFloat("Health"); - } - - cmp.putFloat("Health", f); - } - - return cmp; - } - } - - private static class DataConverterSaddle implements DataConverter { - - DataConverterSaddle() { - } - - public int getDataVersion() { - return 110; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("EntityHorse".equals(cmp.getString("id")) && !cmp.contains("SaddleItem", 10) && cmp.getBoolean("Saddle")) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = new net.minecraft.nbt.CompoundTag(); - - nbttagcompound1.putString("id", "minecraft:saddle"); - nbttagcompound1.putByte("Count", (byte) 1); - nbttagcompound1.putShort("Damage", (short) 0); - cmp.put("SaddleItem", nbttagcompound1); - cmp.remove("Saddle"); - } - - return cmp; - } - } - - private static class DataConverterHanging implements DataConverter { - - DataConverterHanging() { - } - - public int getDataVersion() { - return 111; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - boolean flag = "Painting".equals(s); - boolean flag1 = "ItemFrame".equals(s); - - if ((flag || flag1) && !cmp.contains("Facing", 99)) { - Direction enumdirection; - - if (cmp.contains("Direction", 99)) { - enumdirection = Direction.from2DDataValue(cmp.getByte("Direction")); - cmp.putInt("TileX", cmp.getInt("TileX") + enumdirection.getStepX()); - cmp.putInt("TileY", cmp.getInt("TileY") + enumdirection.getStepY()); - cmp.putInt("TileZ", cmp.getInt("TileZ") + enumdirection.getStepZ()); - cmp.remove("Direction"); - if (flag1 && cmp.contains("ItemRotation", 99)) { - cmp.putByte("ItemRotation", (byte) (cmp.getByte("ItemRotation") * 2)); - } - } else { - enumdirection = Direction.from2DDataValue(cmp.getByte("Dir")); - cmp.remove("Dir"); - } - - cmp.putByte("Facing", (byte) enumdirection.get2DDataValue()); - } - - return cmp; - } - } - - private static class DataConverterDropChances implements DataConverter { - - DataConverterDropChances() { - } - - public int getDataVersion() { - return 113; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - net.minecraft.nbt.ListTag nbttaglist; - - if (cmp.contains("HandDropChances", 9)) { - nbttaglist = cmp.getList("HandDropChances", 5); - if (nbttaglist.size() == 2 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F) { - cmp.remove("HandDropChances"); - } - } - - if (cmp.contains("ArmorDropChances", 9)) { - nbttaglist = cmp.getList("ArmorDropChances", 5); - if (nbttaglist.size() == 4 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F && nbttaglist.getFloat(2) == 0.0F && nbttaglist.getFloat(3) == 0.0F) { - cmp.remove("ArmorDropChances"); - } - } - - return cmp; - } - } - - private static class DataConverterRiding implements DataConverter { - - DataConverterRiding() { - } - - public int getDataVersion() { - return 135; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - while (cmp.contains("Riding", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = this.b(cmp); - - this.convert(cmp, nbttagcompound1); - cmp = nbttagcompound1; - } - - return cmp; - } - - protected void convert(net.minecraft.nbt.CompoundTag nbttagcompound, net.minecraft.nbt.CompoundTag nbttagcompound1) { - net.minecraft.nbt.ListTag nbttaglist = new net.minecraft.nbt.ListTag(); - - nbttaglist.add(nbttagcompound); - nbttagcompound1.put("Passengers", nbttaglist); - } - - protected net.minecraft.nbt.CompoundTag b(net.minecraft.nbt.CompoundTag nbttagcompound) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttagcompound.getCompound("Riding"); - - nbttagcompound.remove("Riding"); - return nbttagcompound1; - } - } - - private static class DataConverterBook implements DataConverter { - - DataConverterBook() { - } - - public int getDataVersion() { - return 165; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:written_book".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("pages", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("pages", 8); - - for (int i = 0; i < nbttaglist.size(); ++i) { - String s = nbttaglist.getString(i); - Component object = null; - - if (!"null".equals(s) && !StringUtil.isNullOrEmpty(s)) { - if ((s.charAt(0) != 34 || s.charAt(s.length() - 1) != 34) && (s.charAt(0) != 123 || s.charAt(s.length() - 1) != 125)) { - object = Component.literal(s); - } else { - try { - object = GsonHelper.fromJson(DataConverterSignText.a, s, Component.class, true); - if (object == null) { - object = Component.literal(""); - } - } catch (JsonParseException jsonparseexception) { - ; - } - - if (object == null) { - try { - object = Component.Serializer.fromJson(s); - } catch (JsonParseException jsonparseexception1) { - ; - } - } - - if (object == null) { - try { - object = Component.Serializer.fromJsonLenient(s); - } catch (JsonParseException jsonparseexception2) { - ; - } - } - - if (object == null) { - object = Component.literal(s); - } - } - } else { - object = Component.literal(""); - } - - nbttaglist.set(i, net.minecraft.nbt.StringTag.valueOf(Component.Serializer.toJson(object))); - } - - nbttagcompound1.put("pages", nbttaglist); - } - } - - return cmp; - } - } - - private static class DataConverterCookedFish implements DataConverter { - - private static final ResourceLocation a = new ResourceLocation("cooked_fished"); - - DataConverterCookedFish() { - } - - public int getDataVersion() { - return 502; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("id", 8) && DataConverterCookedFish.a.equals(new ResourceLocation(cmp.getString("id")))) { - cmp.putString("id", "minecraft:cooked_fish"); - } - - return cmp; - } - } - - private static class DataConverterZombie implements DataConverter { - - private static final Random a = new Random(); - - DataConverterZombie() { - } - - public int getDataVersion() { - return 502; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Zombie".equals(cmp.getString("id")) && cmp.getBoolean("IsVillager")) { - if (!cmp.contains("ZombieType", 99)) { - int i = -1; - - if (cmp.contains("VillagerProfession", 99)) { - try { - i = this.convert(cmp.getInt("VillagerProfession")); - } catch (RuntimeException runtimeexception) { - ; - } - } - - if (i == -1) { - i = this.convert(DataConverterZombie.a.nextInt(6)); - } - - cmp.putInt("ZombieType", i); - } - - cmp.remove("IsVillager"); - } - - return cmp; - } - - private int convert(int i) { - return i >= 0 && i < 6 ? i : -1; - } - } - - private static class DataConverterVBO implements DataConverter { - - DataConverterVBO() { - } - - public int getDataVersion() { - return 505; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - cmp.putString("useVbo", "true"); - return cmp; - } - } - - private static class DataConverterGuardian implements DataConverter { - - DataConverterGuardian() { - } - - public int getDataVersion() { - return 700; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Guardian".equals(cmp.getString("id"))) { - if (cmp.getBoolean("Elder")) { - cmp.putString("id", "ElderGuardian"); - } - - cmp.remove("Elder"); - } - - return cmp; - } - } - - private static class DataConverterSkeleton implements DataConverter { - - DataConverterSkeleton() { - } - - public int getDataVersion() { - return 701; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - - if ("Skeleton".equals(s)) { - int i = cmp.getInt("SkeletonType"); - - if (i == 1) { - cmp.putString("id", "WitherSkeleton"); - } else if (i == 2) { - cmp.putString("id", "Stray"); - } - - cmp.remove("SkeletonType"); - } - - return cmp; - } - } - - private static class DataConverterZombieType implements DataConverter { - - DataConverterZombieType() { - } - - public int getDataVersion() { - return 702; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Zombie".equals(cmp.getString("id"))) { - int i = cmp.getInt("ZombieType"); - - switch (i) { - case 0: - default: - break; - - case 1: - case 2: - case 3: - case 4: - case 5: - cmp.putString("id", "ZombieVillager"); - cmp.putInt("Profession", i - 1); - break; - - case 6: - cmp.putString("id", "Husk"); - } - - cmp.remove("ZombieType"); - } - - return cmp; - } - } - - private static class DataConverterHorse implements DataConverter { - - DataConverterHorse() { - } - - public int getDataVersion() { - return 703; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("EntityHorse".equals(cmp.getString("id"))) { - int i = cmp.getInt("Type"); - - switch (i) { - case 0: - default: - cmp.putString("id", "Horse"); - break; - - case 1: - cmp.putString("id", "Donkey"); - break; - - case 2: - cmp.putString("id", "Mule"); - break; - - case 3: - cmp.putString("id", "ZombieHorse"); - break; - - case 4: - cmp.putString("id", "SkeletonHorse"); - } - - cmp.remove("Type"); - } - - return cmp; - } - } - - private static class DataConverterTileEntity implements DataConverter { - - private static final Map a = Maps.newHashMap(); - - DataConverterTileEntity() { - } - - public int getDataVersion() { - return 704; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = DataConverterTileEntity.a.get(cmp.getString("id")); - - if (s != null) { - cmp.putString("id", s); - } - - return cmp; - } - - static { - DataConverterTileEntity.a.put("Airportal", "minecraft:end_portal"); - DataConverterTileEntity.a.put("Banner", "minecraft:banner"); - DataConverterTileEntity.a.put("Beacon", "minecraft:beacon"); - DataConverterTileEntity.a.put("Cauldron", "minecraft:brewing_stand"); - DataConverterTileEntity.a.put("Chest", "minecraft:chest"); - DataConverterTileEntity.a.put("Comparator", "minecraft:comparator"); - DataConverterTileEntity.a.put("Control", "minecraft:command_block"); - DataConverterTileEntity.a.put("DLDetector", "minecraft:daylight_detector"); - DataConverterTileEntity.a.put("Dropper", "minecraft:dropper"); - DataConverterTileEntity.a.put("EnchantTable", "minecraft:enchanting_table"); - DataConverterTileEntity.a.put("EndGateway", "minecraft:end_gateway"); - DataConverterTileEntity.a.put("EnderChest", "minecraft:ender_chest"); - DataConverterTileEntity.a.put("FlowerPot", "minecraft:flower_pot"); - DataConverterTileEntity.a.put("Furnace", "minecraft:furnace"); - DataConverterTileEntity.a.put("Hopper", "minecraft:hopper"); - DataConverterTileEntity.a.put("MobSpawner", "minecraft:mob_spawner"); - DataConverterTileEntity.a.put("Music", "minecraft:noteblock"); - DataConverterTileEntity.a.put("Piston", "minecraft:piston"); - DataConverterTileEntity.a.put("RecordPlayer", "minecraft:jukebox"); - DataConverterTileEntity.a.put("Sign", "minecraft:sign"); - DataConverterTileEntity.a.put("Skull", "minecraft:skull"); - DataConverterTileEntity.a.put("Structure", "minecraft:structure_block"); - DataConverterTileEntity.a.put("Trap", "minecraft:dispenser"); - } - } - - private static class DataConverterEntity implements DataConverter { - - private static final Map a = Maps.newHashMap(); - - DataConverterEntity() { - } - - public int getDataVersion() { - return 704; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = DataConverterEntity.a.get(cmp.getString("id")); - - if (s != null) { - cmp.putString("id", s); - } - - return cmp; - } - - static { - DataConverterEntity.a.put("AreaEffectCloud", "minecraft:area_effect_cloud"); - DataConverterEntity.a.put("ArmorStand", "minecraft:armor_stand"); - DataConverterEntity.a.put("Arrow", "minecraft:arrow"); - DataConverterEntity.a.put("Bat", "minecraft:bat"); - DataConverterEntity.a.put("Blaze", "minecraft:blaze"); - DataConverterEntity.a.put("Boat", "minecraft:boat"); - DataConverterEntity.a.put("CaveSpider", "minecraft:cave_spider"); - DataConverterEntity.a.put("Chicken", "minecraft:chicken"); - DataConverterEntity.a.put("Cow", "minecraft:cow"); - DataConverterEntity.a.put("Creeper", "minecraft:creeper"); - DataConverterEntity.a.put("Donkey", "minecraft:donkey"); - DataConverterEntity.a.put("DragonFireball", "minecraft:dragon_fireball"); - DataConverterEntity.a.put("ElderGuardian", "minecraft:elder_guardian"); - DataConverterEntity.a.put("EnderCrystal", "minecraft:ender_crystal"); - DataConverterEntity.a.put("EnderDragon", "minecraft:ender_dragon"); - DataConverterEntity.a.put("Enderman", "minecraft:enderman"); - DataConverterEntity.a.put("Endermite", "minecraft:endermite"); - DataConverterEntity.a.put("EyeOfEnderSignal", "minecraft:eye_of_ender_signal"); - DataConverterEntity.a.put("FallingSand", "minecraft:falling_block"); - DataConverterEntity.a.put("Fireball", "minecraft:fireball"); - DataConverterEntity.a.put("FireworksRocketEntity", "minecraft:fireworks_rocket"); - DataConverterEntity.a.put("Ghast", "minecraft:ghast"); - DataConverterEntity.a.put("Giant", "minecraft:giant"); - DataConverterEntity.a.put("Guardian", "minecraft:guardian"); - DataConverterEntity.a.put("Horse", "minecraft:horse"); - DataConverterEntity.a.put("Husk", "minecraft:husk"); - DataConverterEntity.a.put("Item", "minecraft:item"); - DataConverterEntity.a.put("ItemFrame", "minecraft:item_frame"); - DataConverterEntity.a.put("LavaSlime", "minecraft:magma_cube"); - DataConverterEntity.a.put("LeashKnot", "minecraft:leash_knot"); - DataConverterEntity.a.put("MinecartChest", "minecraft:chest_minecart"); - DataConverterEntity.a.put("MinecartCommandBlock", "minecraft:commandblock_minecart"); - DataConverterEntity.a.put("MinecartFurnace", "minecraft:furnace_minecart"); - DataConverterEntity.a.put("MinecartHopper", "minecraft:hopper_minecart"); - DataConverterEntity.a.put("MinecartRideable", "minecraft:minecart"); - DataConverterEntity.a.put("MinecartSpawner", "minecraft:spawner_minecart"); - DataConverterEntity.a.put("MinecartTNT", "minecraft:tnt_minecart"); - DataConverterEntity.a.put("Mule", "minecraft:mule"); - DataConverterEntity.a.put("MushroomCow", "minecraft:mooshroom"); - DataConverterEntity.a.put("Ozelot", "minecraft:ocelot"); - DataConverterEntity.a.put("Painting", "minecraft:painting"); - DataConverterEntity.a.put("Pig", "minecraft:pig"); - DataConverterEntity.a.put("PigZombie", "minecraft:zombie_pigman"); - DataConverterEntity.a.put("PolarBear", "minecraft:polar_bear"); - DataConverterEntity.a.put("PrimedTnt", "minecraft:tnt"); - DataConverterEntity.a.put("Rabbit", "minecraft:rabbit"); - DataConverterEntity.a.put("Sheep", "minecraft:sheep"); - DataConverterEntity.a.put("Shulker", "minecraft:shulker"); - DataConverterEntity.a.put("ShulkerBullet", "minecraft:shulker_bullet"); - DataConverterEntity.a.put("Silverfish", "minecraft:silverfish"); - DataConverterEntity.a.put("Skeleton", "minecraft:skeleton"); - DataConverterEntity.a.put("SkeletonHorse", "minecraft:skeleton_horse"); - DataConverterEntity.a.put("Slime", "minecraft:slime"); - DataConverterEntity.a.put("SmallFireball", "minecraft:small_fireball"); - DataConverterEntity.a.put("SnowMan", "minecraft:snowman"); - DataConverterEntity.a.put("Snowball", "minecraft:snowball"); - DataConverterEntity.a.put("SpectralArrow", "minecraft:spectral_arrow"); - DataConverterEntity.a.put("Spider", "minecraft:spider"); - DataConverterEntity.a.put("Squid", "minecraft:squid"); - DataConverterEntity.a.put("Stray", "minecraft:stray"); - DataConverterEntity.a.put("ThrownEgg", "minecraft:egg"); - DataConverterEntity.a.put("ThrownEnderpearl", "minecraft:ender_pearl"); - DataConverterEntity.a.put("ThrownExpBottle", "minecraft:xp_bottle"); - DataConverterEntity.a.put("ThrownPotion", "minecraft:potion"); - DataConverterEntity.a.put("Villager", "minecraft:villager"); - DataConverterEntity.a.put("VillagerGolem", "minecraft:villager_golem"); - DataConverterEntity.a.put("Witch", "minecraft:witch"); - DataConverterEntity.a.put("WitherBoss", "minecraft:wither"); - DataConverterEntity.a.put("WitherSkeleton", "minecraft:wither_skeleton"); - DataConverterEntity.a.put("WitherSkull", "minecraft:wither_skull"); - DataConverterEntity.a.put("Wolf", "minecraft:wolf"); - DataConverterEntity.a.put("XPOrb", "minecraft:xp_orb"); - DataConverterEntity.a.put("Zombie", "minecraft:zombie"); - DataConverterEntity.a.put("ZombieHorse", "minecraft:zombie_horse"); - DataConverterEntity.a.put("ZombieVillager", "minecraft:zombie_villager"); - } - } - - private static class DataConverterPotionWater implements DataConverter { - - DataConverterPotionWater() { - } - - public int getDataVersion() { - return 806; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - - if ("minecraft:potion".equals(s) || "minecraft:splash_potion".equals(s) || "minecraft:lingering_potion".equals(s) || "minecraft:tipped_arrow".equals(s)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (!nbttagcompound1.contains("Potion", 8)) { - nbttagcompound1.putString("Potion", "minecraft:water"); - } - - if (!cmp.contains("tag", 10)) { - cmp.put("tag", nbttagcompound1); - } - } - - return cmp; - } - } - - private static class DataConverterShulker implements DataConverter { - - DataConverterShulker() { - } - - public int getDataVersion() { - return 808; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker".equals(cmp.getString("id")) && !cmp.contains("Color", 99)) { - cmp.putByte("Color", (byte) 10); - } - - return cmp; - } - } - - private static class DataConverterShulkerBoxItem implements DataConverter { - - public static final String[] a = new String[] { "minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box" }; - - DataConverterShulkerBoxItem() { - } - - public int getDataVersion() { - return 813; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker_box".equals(cmp.getString("id")) && cmp.contains("tag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - - if (nbttagcompound2.getList("Items", 10).isEmpty()) { - nbttagcompound2.remove("Items"); - } - - int i = nbttagcompound2.getInt("Color"); - - nbttagcompound2.remove("Color"); - if (nbttagcompound2.isEmpty()) { - nbttagcompound1.remove("BlockEntityTag"); - } - - if (nbttagcompound1.isEmpty()) { - cmp.remove("tag"); - } - - cmp.putString("id", DataConverterShulkerBoxItem.a[i % 16]); - } - } - - return cmp; - } - } - - private static class DataConverterShulkerBoxBlock implements DataConverter { - - DataConverterShulkerBoxBlock() { - } - - public int getDataVersion() { - return 813; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker".equals(cmp.getString("id"))) { - cmp.remove("Color"); - } - - return cmp; - } - } - - private static class DataConverterLang implements DataConverter { - - DataConverterLang() { - } - - public int getDataVersion() { - return 816; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("lang", 8)) { - cmp.putString("lang", cmp.getString("lang").toLowerCase(Locale.ROOT)); - } - - return cmp; - } - } - - private static class DataConverterTotem implements DataConverter { - - DataConverterTotem() { - } - - public int getDataVersion() { - return 820; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:totem".equals(cmp.getString("id"))) { - cmp.putString("id", "minecraft:totem_of_undying"); - } - - return cmp; - } - } - - private static class DataConverterBedBlock implements DataConverter { - - private static final Logger a = LogManager.getLogger(PaperweightDataConverters.class); - - DataConverterBedBlock() { - } - - public int getDataVersion() { - return 1125; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - try { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Level"); - int i = nbttagcompound1.getInt("xPos"); - int j = nbttagcompound1.getInt("zPos"); - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("TileEntities", 10); - net.minecraft.nbt.ListTag nbttaglist1 = nbttagcompound1.getList("Sections", 10); - - for (int k = 0; k < nbttaglist1.size(); ++k) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist1.getCompound(k); - byte b0 = nbttagcompound2.getByte("Y"); - byte[] abyte = nbttagcompound2.getByteArray("Blocks"); - - for (int l = 0; l < abyte.length; ++l) { - if (416 == (abyte[l] & 255) << 4) { - int i1 = l & 15; - int j1 = l >> 8 & 15; - int k1 = l >> 4 & 15; - net.minecraft.nbt.CompoundTag nbttagcompound3 = new net.minecraft.nbt.CompoundTag(); - - nbttagcompound3.putString("id", "bed"); - nbttagcompound3.putInt("x", i1 + (i << 4)); - nbttagcompound3.putInt("y", j1 + (b0 << 4)); - nbttagcompound3.putInt("z", k1 + (j << 4)); - nbttaglist.add(nbttagcompound3); - } - } - } - } catch (Exception exception) { - DataConverterBedBlock.a.warn("Unable to datafix Bed blocks, level format may be missing tags."); - } - - return cmp; - } - } - - private static class DataConverterBedItem implements DataConverter { - - DataConverterBedItem() { - } - - public int getDataVersion() { - return 1125; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:bed".equals(cmp.getString("id")) && cmp.getShort("Damage") == 0) { - cmp.putShort("Damage", (short) DyeColor.RED.getId()); - } - - return cmp; - } - } - - private static class DataConverterSignText implements DataConverter { - - public static final Gson a = new GsonBuilder().registerTypeAdapter(Component.class, new JsonDeserializer() { - MutableComponent a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { - if (jsonelement.isJsonPrimitive()) { - return Component.literal(jsonelement.getAsString()); - } else if (jsonelement.isJsonArray()) { - JsonArray jsonarray = jsonelement.getAsJsonArray(); - MutableComponent ichatbasecomponent = null; - Iterator iterator = jsonarray.iterator(); - - while (iterator.hasNext()) { - JsonElement jsonelement1 = (JsonElement) iterator.next(); - MutableComponent ichatbasecomponent1 = this.a(jsonelement1, jsonelement1.getClass(), jsondeserializationcontext); - - if (ichatbasecomponent == null) { - ichatbasecomponent = ichatbasecomponent1; - } else { - ichatbasecomponent.append(ichatbasecomponent1); - } - } - - return ichatbasecomponent; - } else { - throw new JsonParseException("Don't know how to turn " + jsonelement + " into a Component"); - } - } - - public Object deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { - return this.a(jsonelement, type, jsondeserializationcontext); - } - }).create(); - - DataConverterSignText() { - } - - public int getDataVersion() { - return 101; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Sign".equals(cmp.getString("id"))) { - this.convert(cmp, "Text1"); - this.convert(cmp, "Text2"); - this.convert(cmp, "Text3"); - this.convert(cmp, "Text4"); - } - - return cmp; - } - - private void convert(net.minecraft.nbt.CompoundTag nbttagcompound, String s) { - String s1 = nbttagcompound.getString(s); - Component object = null; - - if (!"null".equals(s1) && !StringUtil.isNullOrEmpty(s1)) { - if ((s1.charAt(0) != 34 || s1.charAt(s1.length() - 1) != 34) && (s1.charAt(0) != 123 || s1.charAt(s1.length() - 1) != 125)) { - object = Component.literal(s1); - } else { - try { - object = GsonHelper.fromJson(DataConverterSignText.a, s1, Component.class, true); - if (object == null) { - object = Component.literal(""); - } - } catch (JsonParseException jsonparseexception) { - ; - } - - if (object == null) { - try { - object = Component.Serializer.fromJson(s1); - } catch (JsonParseException jsonparseexception1) { - ; - } - } - - if (object == null) { - try { - object = Component.Serializer.fromJsonLenient(s1); - } catch (JsonParseException jsonparseexception2) { - ; - } - } - - if (object == null) { - object = Component.literal(s1); - } - } - } else { - object = Component.literal(""); - } - - nbttagcompound.putString(s, Component.Serializer.toJson(object)); - } - } - - private static class DataInspectorPlayerVehicle implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("RootVehicle", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("RootVehicle"); - - if (nbttagcompound1.contains("Entity", 10)) { - convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer); - } - } - - return cmp; - } - } - - private static class DataInspectorLevelPlayer implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Player", 10)) { - convertCompound(LegacyType.PLAYER, cmp, "Player", sourceVer, targetVer); - } - - return cmp; - } - } - - private static class DataInspectorStructure implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - net.minecraft.nbt.ListTag nbttaglist; - int j; - net.minecraft.nbt.CompoundTag nbttagcompound1; - - if (cmp.contains("entities", 9)) { - nbttaglist = cmp.getList("entities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j); - if (nbttagcompound1.contains("nbt", 10)) { - convertCompound(LegacyType.ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer); - } - } - } - - if (cmp.contains("blocks", 9)) { - nbttaglist = cmp.getList("blocks", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j); - if (nbttagcompound1.contains("nbt", 10)) { - convertCompound(LegacyType.BLOCK_ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer); - } - } - } - - return cmp; - } - } - - private static class DataInspectorChunks implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Level", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Level"); - net.minecraft.nbt.ListTag nbttaglist; - int j; - - if (nbttagcompound1.contains("Entities", 9)) { - nbttaglist = nbttagcompound1.getList("Entities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); - } - } - - if (nbttagcompound1.contains("TileEntities", 9)) { - nbttaglist = nbttagcompound1.getList("TileEntities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.BLOCK_ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); - } - } - } - - return cmp; - } - } - - private static class DataInspectorEntityPassengers implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Passengers", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("Passengers", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ENTITY, nbttaglist.getCompound(j), sourceVer, targetVer)); - } - } - - return cmp; - } - } - - private static class DataInspectorPlayer implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - convertItems(cmp, "Inventory", sourceVer, targetVer); - convertItems(cmp, "EnderItems", sourceVer, targetVer); - if (cmp.contains("ShoulderEntityLeft", 10)) { - convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityLeft", sourceVer, targetVer); - } - - if (cmp.contains("ShoulderEntityRight", 10)) { - convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityRight", sourceVer, targetVer); - } - - return cmp; - } - } - - private static class DataInspectorVillagers implements DataInspector { - ResourceLocation entityVillager = getKey("EntityVillager"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (entityVillager.equals(new ResourceLocation(cmp.getString("id"))) && cmp.contains("Offers", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Offers"); - - if (nbttagcompound1.contains("Recipes", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("Recipes", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompound(j); - - convertItem(nbttagcompound2, "buy", sourceVer, targetVer); - convertItem(nbttagcompound2, "buyB", sourceVer, targetVer); - convertItem(nbttagcompound2, "sell", sourceVer, targetVer); - nbttaglist.set(j, nbttagcompound2); - } - } - } - - return cmp; - } - } - - private static class DataInspectorMobSpawnerMinecart implements DataInspector { - ResourceLocation entityMinecartMobSpawner = getKey("EntityMinecartMobSpawner"); - ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - String s = cmp.getString("id"); - if (entityMinecartMobSpawner.equals(new ResourceLocation(s))) { - cmp.putString("id", tileEntityMobSpawner.toString()); - convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer); - cmp.putString("id", s); - } - - return cmp; - } - } - - private static class DataInspectorMobSpawnerMobs implements DataInspector { - ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (tileEntityMobSpawner.equals(new ResourceLocation(cmp.getString("id")))) { - if (cmp.contains("SpawnPotentials", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("SpawnPotentials", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttaglist.getCompound(j); - - convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer); - } - } - - convertCompound(LegacyType.ENTITY, cmp, "SpawnData", sourceVer, targetVer); - } - - return cmp; - } - } - - private static class DataInspectorCommandBlock implements DataInspector { - ResourceLocation tileEntityCommand = getKey("TileEntityCommand"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (tileEntityCommand.equals(new ResourceLocation(cmp.getString("id")))) { - cmp.putString("id", "Control"); - convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer); - cmp.putString("id", "MinecartCommandBlock"); - } - - return cmp; - } - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightFakePlayer.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightFakePlayer.java deleted file mode 100644 index ee7d82f09..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightFakePlayer.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_19_R3; - -import com.mojang.authlib.GameProfile; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ServerboundClientInformationPacket; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.stats.Stat; -import net.minecraft.world.MenuProvider; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.block.entity.SignBlockEntity; -import net.minecraft.world.phys.Vec3; -import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; - -import java.util.OptionalInt; -import java.util.UUID; - -class PaperweightFakePlayer extends ServerPlayer { - private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]"); - private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D); - - PaperweightFakePlayer(ServerLevel world) { - super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE); - } - - @Override - public Vec3 position() { - return ORIGIN; - } - - @Override - public void tick() { - } - - @Override - public void die(DamageSource damagesource) { - } - - @Override - public Entity changeDimension(ServerLevel worldserver, TeleportCause cause) { - return this; - } - - @Override - public OptionalInt openMenu(MenuProvider factory) { - return OptionalInt.empty(); - } - - @Override - public void updateOptions(ServerboundClientInformationPacket packet) { - } - - @Override - public void displayClientMessage(Component message, boolean actionBar) { - } - - @Override - public void awardStat(Stat stat, int amount) { - } - - @Override - public void awardStat(Stat stat) { - } - - @Override - public boolean isInvulnerableTo(DamageSource damageSource) { - return true; - } - - @Override - public void openTextEdit(SignBlockEntity sign) { - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java deleted file mode 100644 index 424422ce6..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightWorldNativeAccess.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_19_R3; - -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.world.block.BlockState; -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.Tag; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.enginehub.linbus.tree.LinCompoundTag; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.util.Objects; - -public class PaperweightWorldNativeAccess implements WorldNativeAccess { - private static final int UPDATE = 1; - private static final int NOTIFY = 2; - - private final PaperweightAdapter adapter; - private final WeakReference world; - private SideEffectSet sideEffectSet; - - public PaperweightWorldNativeAccess(PaperweightAdapter adapter, WeakReference world) { - this.adapter = adapter; - this.world = world; - } - - private ServerLevel getWorld() { - return Objects.requireNonNull(world.get(), "The reference to the world was lost"); - } - - @Override - public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) { - this.sideEffectSet = sideEffectSet; - } - - @Override - public LevelChunk getChunk(int x, int z) { - return getWorld().getChunk(x, z); - } - - @Override - public net.minecraft.world.level.block.state.BlockState toNative(BlockState state) { - int stateId = BlockStateIdAccess.getBlockStateId(state); - return BlockStateIdAccess.isValidInternalId(stateId) - ? Block.stateById(stateId) - : ((CraftBlockData) BukkitAdapter.adapt(state)).getState(); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk chunk, BlockPos position) { - return chunk.getBlockState(position); - } - - @Nullable - @Override - public net.minecraft.world.level.block.state.BlockState setBlockState(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState state) { - return chunk.setBlockState(position, state, false, this.sideEffectSet.shouldApply(SideEffect.UPDATE)); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition(net.minecraft.world.level.block.state.BlockState block, BlockPos position) { - return Block.updateFromNeighbourShapes(block, getWorld(), position); - } - - @Override - public BlockPos getPosition(int x, int y, int z) { - return new BlockPos(x, y, z); - } - - @Override - public void updateLightingForBlock(BlockPos position) { - getWorld().getChunkSource().getLightEngine().checkBlock(position); - } - - @Override - public boolean updateTileEntity(BlockPos position, LinCompoundTag tag) { - // We will assume that the tile entity was created for us - BlockEntity tileEntity = getWorld().getBlockEntity(position); - if (tileEntity == null) { - return false; - } - Tag nativeTag = adapter.fromNative(new CompoundTag(tag)); - PaperweightAdapter.readTagIntoTileEntity((net.minecraft.nbt.CompoundTag) nativeTag, tileEntity); - return true; - } - - @Override - public void notifyBlockUpdate(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { - getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY); - } - } - - @Override - public boolean isChunkTicking(LevelChunk chunk) { - return chunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING); - } - - @Override - public void markBlockChanged(LevelChunk chunk, BlockPos position) { - if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { - getWorld().getChunkSource().blockChanged(position); - } - } - - @Override - public void notifyNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - ServerLevel world = getWorld(); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - world.updateNeighborsAt(pos, oldState.getBlock()); - } else { - // When we don't want events, manually run the physics without them. - Block block = oldState.getBlock(); - fireNeighborChanged(pos, world, block, pos.west()); - fireNeighborChanged(pos, world, block, pos.east()); - fireNeighborChanged(pos, world, block, pos.below()); - fireNeighborChanged(pos, world, block, pos.above()); - fireNeighborChanged(pos, world, block, pos.north()); - fireNeighborChanged(pos, world, block, pos.south()); - } - if (newState.hasAnalogOutputSignal()) { - world.updateNeighbourForOutputSignal(pos, newState.getBlock()); - } - } - - @Override - public void updateBlock(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - ServerLevel world = getWorld(); - newState.onPlace(world, pos, oldState, false); - } - - // Not sure why neighborChanged is deprecated - @SuppressWarnings("deprecation") - private void fireNeighborChanged(BlockPos pos, ServerLevel world, Block block, BlockPos neighborPos) { - world.getBlockState(neighborPos).neighborChanged(world, neighborPos, block, pos, false); - } - - @Override - public void updateNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState, int recursionLimit) { - ServerLevel world = getWorld(); - // a == updateNeighbors - // b == updateDiagonalNeighbors - oldState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - CraftWorld craftWorld = world.getWorld(); - BlockPhysicsEvent event = new BlockPhysicsEvent(craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), CraftBlockData.fromData(newState)); - world.getCraftServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - } - newState.updateNeighbourShapes(world, pos, NOTIFY, recursionLimit); - newState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); - } - - @Override - public void onBlockStateChange(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - getWorld().onBlockStateChange(pos, oldState, newState); - } - - @Override - public void flush() { - - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightBlockMaterial.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightBlockMaterial.java deleted file mode 100644 index cbd1af53d..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightBlockMaterial.java +++ /dev/null @@ -1,189 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.util.ReflectionUtil; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.world.registry.BlockMaterial; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.EmptyBlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.Material; -import net.minecraft.world.level.material.PushReaction; -import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; - -public class PaperweightBlockMaterial implements BlockMaterial { - - private final Block block; - private final BlockState blockState; - private final Material material; - private final boolean isTranslucent; - private final CraftBlockData craftBlockData; - private final org.bukkit.Material craftMaterial; - private final int opacity; - private final CompoundTag tile; - - public PaperweightBlockMaterial(Block block) { - this(block, block.defaultBlockState()); - } - - public PaperweightBlockMaterial(Block block, BlockState blockState) { - this.block = block; - this.blockState = blockState; - this.material = blockState.getMaterial(); - this.craftBlockData = CraftBlockData.fromData(blockState); - this.craftMaterial = craftBlockData.getMaterial(); - BlockBehaviour.Properties blockInfo = ReflectionUtil.getField(BlockBehaviour.class, block, - Refraction.pickName("properties", "aP")); - this.isTranslucent = !(boolean) ReflectionUtil.getField(BlockBehaviour.Properties.class, blockInfo, - Refraction.pickName("canOcclude", "n") - ); - opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); - BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity( - BlockPos.ZERO, - blockState - ); - tile = tileEntity == null - ? null - : new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); - } - - public Block getBlock() { - return block; - } - - public BlockState getState() { - return blockState; - } - - public CraftBlockData getCraftBlockData() { - return craftBlockData; - } - - public Material getMaterial() { - return material; - } - - @Override - public boolean isAir() { - return blockState.isAir(); - } - - @Override - public boolean isFullCube() { - return craftMaterial.isOccluding(); - } - - @Override - public boolean isOpaque() { - return material.isSolidBlocking(); - } - - @Override - public boolean isPowerSource() { - return blockState.isSignalSource(); - } - - @Override - public boolean isLiquid() { - return material.isLiquid(); - } - - @Override - public boolean isSolid() { - return material.isSolid(); - } - - @Override - public float getHardness() { - return craftBlockData.getState().destroySpeed; - } - - @Override - public float getResistance() { - return block.getExplosionResistance(); - } - - @Override - public float getSlipperiness() { - return block.getFriction(); - } - - @Override - public int getLightValue() { - return blockState.getLightEmission(); - } - - @Override - public int getLightOpacity() { - return opacity; - } - - @Override - public boolean isFragileWhenPushed() { - return material.getPushReaction() == PushReaction.DESTROY; - } - - @Override - public boolean isUnpushable() { - return material.getPushReaction() == PushReaction.BLOCK; - } - - @Override - public boolean isTicksRandomly() { - return block.isRandomlyTicking(blockState); - } - - @Override - public boolean isMovementBlocker() { - return material.isSolid(); - } - - @Override - public boolean isBurnable() { - return material.isFlammable(); - } - - @Override - public boolean isToolRequired() { - // Removed in 1.16.1, this is not present in higher versions - return false; - } - - @Override - public boolean isReplacedDuringPlacement() { - return material.isReplaceable(); - } - - @Override - public boolean isTranslucent() { - return isTranslucent; - } - - @Override - public boolean hasContainer() { - return block instanceof EntityBlock; - } - - @Override - public boolean isTile() { - return block instanceof EntityBlock; - } - - @Override - public CompoundTag getDefaultTile() { - return tile; - } - - @Override - public int getMapColor() { - // rgb field - return material.getColor().col; - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java deleted file mode 100644 index 0b90d942a..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweAdapter.java +++ /dev/null @@ -1,614 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.bukkit.adapter.FaweAdapter; -import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.entity.LazyBaseEntity; -import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; -import com.fastasyncworldedit.core.queue.IBatchProcessor; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket; -import com.fastasyncworldedit.core.util.NbtUtils; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_19_R3.PaperweightAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.regen.PaperweightRegen; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.registry.state.BooleanProperty; -import com.sk89q.worldedit.registry.state.DirectionalProperty; -import com.sk89q.worldedit.registry.state.EnumProperty; -import com.sk89q.worldedit.registry.state.IntegerProperty; -import com.sk89q.worldedit.registry.state.Property; -import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.world.RegenOptions; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockStateHolder; -import com.sk89q.worldedit.world.block.BlockType; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import com.sk89q.worldedit.world.entity.EntityType; -import com.sk89q.worldedit.world.item.ItemType; -import com.sk89q.worldedit.world.registry.BlockMaterial; -import io.papermc.lib.PaperLib; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Registry; -import net.minecraft.core.WritableRegistry; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.util.StringRepresentable; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.chunk.LevelChunk; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.NamespacedKey; -import org.bukkit.World; -import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.v1_19_R3.CraftServer; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_19_R3.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_19_R3.util.CraftNamespacedKey; -import org.bukkit.entity.Player; -import org.enginehub.linbus.tree.LinCompoundTag; -import org.enginehub.linbus.tree.LinStringTag; -import org.enginehub.linbus.tree.LinTag; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.OptionalInt; -import java.util.Set; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static net.minecraft.core.registries.Registries.BIOME; - -public final class PaperweightFaweAdapter extends FaweAdapter { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - private static Method CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE; - - static { - try { - CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE = ChunkHolder.class.getDeclaredMethod("wasAccessibleSinceLastSave"); - } catch (NoSuchMethodException ignored) { // may not be present in newer paper versions - } - } - - private final PaperweightAdapter parent; - // ------------------------------------------------------------------------ - // Code that may break between versions of Minecraft - // ------------------------------------------------------------------------ - private final PaperweightMapChunkUtil mapUtil = new PaperweightMapChunkUtil(); - private char[] ibdToStateOrdinal = null; - private int[] ordinalToIbdID = null; - private boolean initialised = false; - private Map>> allBlockProperties = null; - - public PaperweightFaweAdapter() throws NoSuchFieldException, NoSuchMethodException { - this.parent = new PaperweightAdapter(); - } - - @Nullable - private static String getEntityId(Entity entity) { - ResourceLocation resourceLocation = net.minecraft.world.entity.EntityType.getKey(entity.getType()); - return resourceLocation == null ? null : resourceLocation.toString(); - } - - @Override - public BukkitImplAdapter getParent() { - return parent; - } - - private synchronized boolean init() { - if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) { - return false; - } - ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size - ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size - for (int i = 0; i < ibdToStateOrdinal.length; i++) { - BlockState blockState = BlockTypesCache.states[i]; - PaperweightBlockMaterial material = (PaperweightBlockMaterial) blockState.getMaterial(); - int id = Block.BLOCK_STATE_REGISTRY.getId(material.getState()); - char ordinal = blockState.getOrdinalChar(); - ibdToStateOrdinal[id] = ordinal; - ordinalToIbdID[ordinal] = id; - } - Map>> properties = new HashMap<>(); - try { - for (Field field : BlockStateProperties.class.getDeclaredFields()) { - Object obj = field.get(null); - if (!(obj instanceof net.minecraft.world.level.block.state.properties.Property state)) { - continue; - } - Property property; - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - property = new BooleanProperty( - state.getName(), - (List) ImmutableList.copyOf(state.getPossibleValues()) - ); - } else if (state instanceof DirectionProperty) { - property = new DirectionalProperty( - state.getName(), - state - .getPossibleValues() - .stream() - .map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase())) - .collect(Collectors.toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - property = new EnumProperty( - state.getName(), - state - .getPossibleValues() - .stream() - .map(e -> ((StringRepresentable) e).getSerializedName()) - .collect(Collectors.toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - property = new IntegerProperty( - state.getName(), - (List) ImmutableList.copyOf(state.getPossibleValues()) - ); - } else { - throw new IllegalArgumentException("FastAsyncWorldEdit needs an update to support " + state - .getClass() - .getSimpleName()); - } - properties.compute(property.getName().toLowerCase(Locale.ROOT), (k, v) -> { - if (v == null) { - v = new ArrayList<>(Collections.singletonList(property)); - } else { - v.add(property); - } - return v; - }); - } - } catch (IllegalAccessException e) { - e.printStackTrace(); - } finally { - allBlockProperties = ImmutableMap.copyOf(properties); - } - initialised = true; - return true; - } - - @Override - public BlockMaterial getMaterial(BlockType blockType) { - Block block = getBlock(blockType); - return new PaperweightBlockMaterial(block); - } - - @Override - public synchronized BlockMaterial getMaterial(BlockState state) { - net.minecraft.world.level.block.state.BlockState blockState = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState(); - return new PaperweightBlockMaterial(blockState.getBlock(), blockState); - } - - public Block getBlock(BlockType blockType) { - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK) - .get(new ResourceLocation(blockType.getNamespace(), blockType.getResource())); - } - - @Deprecated - @Override - public BlockState getBlock(Location location) { - Preconditions.checkNotNull(location); - - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - final ServerLevel handle = getServerLevel(location.getWorld()); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - BlockState state = adapt(blockData); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - return state; - } - - @Override - public BaseBlock getFullBlock(final Location location) { - Preconditions.checkNotNull(location); - - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = getServerLevel(location.getWorld()); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - BlockState state = adapt(blockData); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - if (state.getBlockType().getMaterial().hasContainer()) { - - // Read the NBT data - BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK); - if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); - return state.toBaseBlock((LinCompoundTag) toNativeLin(tag)); - } - } - - return state.toBaseBlock(); - } - - @Override - public Set getSupportedSideEffects() { - return SideEffectSet.defaults().getSideEffectsToApply(); - } - - @Override - public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { - return new PaperweightFaweWorldNativeAccess(this, new WeakReference<>(getServerLevel(world))); - } - - @Override - public BaseEntity getEntity(org.bukkit.entity.Entity entity) { - Preconditions.checkNotNull(entity); - - CraftEntity craftEntity = ((CraftEntity) entity); - Entity mcEntity = craftEntity.getHandle(); - - String id = getEntityId(mcEntity); - - if (id != null) { - EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id); - Supplier saveTag = () -> { - final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag); - //add Id for AbstractChangeSet to work - final LinCompoundTag tag = (LinCompoundTag) toNativeLin(minecraftTag); - final Map> tags = NbtUtils.getLinCompoundTagValues(tag); - tags.put("Id", LinStringTag.of(id)); - return LinCompoundTag.of(tags); - }; - return new LazyBaseEntity(type, saveTag); - } else { - return null; - } - } - - @Override - public Component getRichBlockName(BlockType blockType) { - return parent.getRichBlockName(blockType); - } - - @Override - public Component getRichItemName(ItemType itemType) { - return parent.getRichItemName(itemType); - } - - @Override - public Component getRichItemName(BaseItemStack itemStack) { - return parent.getRichItemName(itemStack); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockState state) { - PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial(); - net.minecraft.world.level.block.state.BlockState mcState = material.getCraftBlockData().getState(); - return OptionalInt.of(Block.BLOCK_STATE_REGISTRY.getId(mcState)); - } - - @Override - public BlockState adapt(BlockData blockData) { - CraftBlockData cbd = ((CraftBlockData) blockData); - net.minecraft.world.level.block.state.BlockState ibd = cbd.getState(); - return adapt(ibd); - } - - public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; - } - - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { - int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); - if (initialised) { - return ibdToStateOrdinal[id]; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - try { - init(); - return ibdToStateOrdinal[id]; - } catch (ArrayIndexOutOfBoundsException e1) { - LOGGER.error("Attempted to convert {} with ID {} to char. ibdToStateOrdinal length: {}. Defaulting to air!", - blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToStateOrdinal.length, e1 - ); - return BlockTypesCache.ReservedIDs.AIR; - } - } - } - - public char ibdIDToOrdinal(int id) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - init(); - return ibdToStateOrdinal[id]; - } - } - - @Override - public char[] getIbdToStateOrdinal() { - if (initialised) { - return ibdToStateOrdinal; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal; - } - init(); - return ibdToStateOrdinal; - } - } - - public int ordinalToIbdID(char ordinal) { - if (initialised) { - return ordinalToIbdID[ordinal]; - } - synchronized (this) { - if (initialised) { - return ordinalToIbdID[ordinal]; - } - init(); - return ordinalToIbdID[ordinal]; - } - } - - @Override - public int[] getOrdinalToIbdID() { - if (initialised) { - return ordinalToIbdID; - } - synchronized (this) { - if (initialised) { - return ordinalToIbdID; - } - init(); - return ordinalToIbdID; - } - } - - @Override - public > BlockData adapt(B state) { - PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial(); - return material.getCraftBlockData(); - } - - @Override - public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) { - ServerLevel nmsWorld = getServerLevel(world); - ChunkHolder map = PaperweightPlatformAdapter.getPlayerChunk(nmsWorld, chunkPacket.getChunkX(), chunkPacket.getChunkZ()); - if (map != null && wasAccessibleSinceLastSave(map)) { - boolean flag = false; - // PlayerChunk.d players = map.players; - Stream stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag) - */ Stream.empty(); - - ServerPlayer checkPlayer = player == null ? null : ((CraftPlayer) player).getHandle(); - stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer) - .forEach(entityPlayer -> { - synchronized (chunkPacket) { - ClientboundLevelChunkWithLightPacket nmsPacket = (ClientboundLevelChunkWithLightPacket) chunkPacket.getNativePacket(); - if (nmsPacket == null) { - nmsPacket = mapUtil.create(this, chunkPacket); - chunkPacket.setNativePacket(nmsPacket); - } - try { - FaweCache.INSTANCE.CHUNK_FLAG.get().set(true); - entityPlayer.connection.send(nmsPacket); - } finally { - FaweCache.INSTANCE.CHUNK_FLAG.get().set(false); - } - } - }); - } - } - - @Override - public Map> getProperties(BlockType blockType) { - return getParent().getProperties(blockType); - } - - @Override - public boolean canPlaceAt(org.bukkit.World world, BlockVector3 blockVector3, BlockState blockState) { - int internalId = BlockStateIdAccess.getBlockStateId(blockState); - net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId); - return blockState1.hasPostProcess( - getServerLevel(world), - new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z()) - ); - } - - @Override - public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) { - ItemStack stack = new ItemStack( - DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM) - .get(ResourceLocation.tryParse(baseItemStack.getType().id())), - baseItemStack.getAmount() - ); - stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(baseItemStack.getNbtData()))); - return CraftItemStack.asCraftMirror(stack); - } - - @Override - protected void preCaptureStates(final ServerLevel serverLevel) { - serverLevel.captureTreeGeneration = true; - serverLevel.captureBlockStates = true; - } - - @Override - protected List getCapturedBlockStatesCopy(final ServerLevel serverLevel) { - return new ArrayList<>(serverLevel.capturedBlockStates.values()); - } - - @Override - protected void postCaptureBlockStates(final ServerLevel serverLevel) { - serverLevel.captureBlockStates = false; - serverLevel.captureTreeGeneration = false; - serverLevel.capturedBlockStates.clear(); - } - - @Override - protected ServerLevel getServerLevel(final World world) { - return ((CraftWorld) world).getHandle(); - } - - @Override - public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { - final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); - weStack.setNbt((LinCompoundTag) toNativeLin(nmsStack.getTag())); - return weStack; - } - - @Override - public Tag toNative(net.minecraft.nbt.Tag foreign) { - return parent.toNative(foreign); - } - - @Override - public net.minecraft.nbt.Tag fromNative(Tag foreign) { - if (foreign instanceof PaperweightLazyCompoundTag) { - return ((PaperweightLazyCompoundTag) foreign).get(); - } - return parent.fromNative(foreign); - } - - @Override - public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent target, RegenOptions options) throws Exception { - return new PaperweightRegen(bukkitWorld, region, target, options).regenerate(); - } - - @Override - public IChunkGet get(org.bukkit.World world, int chunkX, int chunkZ) { - return new PaperweightGetBlocks(world, chunkX, chunkZ); - } - - @Override - public int getInternalBiomeId(BiomeType biomeType) { - final Registry registry = MinecraftServer - .getServer() - .registryAccess() - .registryOrThrow(BIOME); - ResourceLocation resourceLocation = ResourceLocation.tryParse(biomeType.id()); - Biome biome = registry.get(resourceLocation); - return registry.getId(biome); - } - - @Override - public Iterable getRegisteredBiomes() { - WritableRegistry biomeRegistry = (WritableRegistry) ((CraftServer) Bukkit.getServer()) - .getServer() - .registryAccess() - .registryOrThrow(BIOME); - List keys = biomeRegistry.stream() - .map(biomeRegistry::getKey).filter(Objects::nonNull).toList(); - List namespacedKeys = new ArrayList<>(); - for (ResourceLocation key : keys) { - try { - namespacedKeys.add(CraftNamespacedKey.fromMinecraft(key)); - } catch (IllegalArgumentException e) { - LOGGER.error("Error converting biome key {}", key.toString(), e); - } - } - return namespacedKeys; - } - - @Override - public RelighterFactory getRelighterFactory() { - if (PaperLib.isPaper()) { - return new PaperweightStarlightRelighterFactory(); - } else { - return new NMSRelighterFactory(); - } - } - - @Override - public Map>> getAllProperties() { - if (initialised) { - return allBlockProperties; - } - synchronized (this) { - if (initialised) { - return allBlockProperties; - } - init(); - return allBlockProperties; - } - } - - @Override - public IBatchProcessor getTickingPostProcessor() { - return new PaperweightPostProcessor(); - } - - private boolean wasAccessibleSinceLastSave(ChunkHolder holder) { - if (!PaperLib.isPaper() || !PaperweightPlatformAdapter.POST_CHUNK_REWRITE) { - try { - return (boolean) CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE.invoke(holder); - } catch (IllegalAccessException | InvocationTargetException ignored) { - // fall-through - } - } - // Papers new chunk system has no related replacement - therefor we assume true. - return true; - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java deleted file mode 100644 index 0c57f9ca6..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightFaweWorldNativeAccess.java +++ /dev/null @@ -1,292 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.math.IntPair; -import com.fastasyncworldedit.core.util.TaskManager; -import com.fastasyncworldedit.core.util.task.RunnableVal; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.world.block.BlockState; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.enginehub.linbus.tree.LinCompoundTag; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; - -public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess { - - private static final int UPDATE = 1; - private static final int NOTIFY = 2; - private static final Direction[] NEIGHBOUR_ORDER = { - Direction.EAST, - Direction.WEST, - Direction.DOWN, - Direction.UP, - Direction.NORTH, - Direction.SOUTH - }; - private final PaperweightFaweAdapter paperweightFaweAdapter; - private final WeakReference level; - private final AtomicInteger lastTick; - private final Set cachedChanges = new HashSet<>(); - private final Set cachedChunksToSend = new HashSet<>(); - private SideEffectSet sideEffectSet; - - public PaperweightFaweWorldNativeAccess(PaperweightFaweAdapter paperweightFaweAdapter, WeakReference level) { - this.paperweightFaweAdapter = paperweightFaweAdapter; - this.level = level; - // Use the actual tick as minecraft-defined so we don't try to force blocks into the world when the server's already lagging. - // - With the caveat that we don't want to have too many cached changed (1024) so we'd flush those at 1024 anyway. - this.lastTick = new AtomicInteger(MinecraftServer.currentTick); - } - - private Level getLevel() { - return Objects.requireNonNull(level.get(), "The reference to the world was lost"); - } - - @Override - public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) { - this.sideEffectSet = sideEffectSet; - } - - @Override - public LevelChunk getChunk(int x, int z) { - return getLevel().getChunk(x, z); - } - - @Override - public net.minecraft.world.level.block.state.BlockState toNative(BlockState blockState) { - int stateId = paperweightFaweAdapter.ordinalToIbdID(blockState.getOrdinalChar()); - return BlockStateIdAccess.isValidInternalId(stateId) - ? Block.stateById(stateId) - : ((CraftBlockData) BukkitAdapter.adapt(blockState)).getState(); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk levelChunk, BlockPos blockPos) { - return levelChunk.getBlockState(blockPos); - } - - @Nullable - @Override - public synchronized net.minecraft.world.level.block.state.BlockState setBlockState( - LevelChunk levelChunk, BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState blockState - ) { - int currentTick = MinecraftServer.currentTick; - if (Fawe.isMainThread()) { - return levelChunk.setBlockState(blockPos, blockState, - this.sideEffectSet != null && this.sideEffectSet.shouldApply(SideEffect.UPDATE) - ); - } - // Since FAWE is.. Async we need to do it on the main thread (wooooo.. :( ) - cachedChanges.add(new CachedChange(levelChunk, blockPos, blockState)); - cachedChunksToSend.add(new IntPair(levelChunk.locX, levelChunk.locZ)); - boolean nextTick = lastTick.get() > currentTick; - if (nextTick || cachedChanges.size() >= 1024) { - if (nextTick) { - lastTick.set(currentTick); - } - flushAsync(nextTick); - } - return blockState; - } - - @Override - public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition( - net.minecraft.world.level.block.state.BlockState blockState, - BlockPos blockPos - ) { - return Block.updateFromNeighbourShapes(blockState, getLevel(), blockPos); - } - - @Override - public BlockPos getPosition(int x, int y, int z) { - return new BlockPos(x, y, z); - } - - @Override - public void updateLightingForBlock(BlockPos blockPos) { - getLevel().getChunkSource().getLightEngine().checkBlock(blockPos); - } - - @Override - public boolean updateTileEntity(BlockPos blockPos, LinCompoundTag tag) { - // We will assume that the tile entity was created for us, - // though we do not do this on the other versions - BlockEntity blockEntity = getLevel().getBlockEntity(blockPos); - if (blockEntity == null) { - return false; - } - net.minecraft.nbt.Tag nativeTag = paperweightFaweAdapter.fromNativeLin(tag); - blockEntity.load((CompoundTag) nativeTag); - return true; - } - - @Override - public void notifyBlockUpdate( - LevelChunk levelChunk, BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) { - getLevel().sendBlockUpdated(blockPos, oldState, newState, UPDATE | NOTIFY); - } - } - - @Override - public boolean isChunkTicking(LevelChunk levelChunk) { - return levelChunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING); - } - - @Override - public void markBlockChanged(LevelChunk levelChunk, BlockPos blockPos) { - if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) { - ((ServerChunkCache) getLevel().getChunkSource()).blockChanged(blockPos); - } - } - - @Override - public void notifyNeighbors( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - Level level = getLevel(); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - level.blockUpdated(blockPos, oldState.getBlock()); - } else { - // When we don't want events, manually run the physics without them. - // Un-nest neighbour updating - for (Direction direction : NEIGHBOUR_ORDER) { - BlockPos shifted = blockPos.relative(direction); - level.getBlockState(shifted).neighborChanged(level, shifted, oldState.getBlock(), blockPos, false); - } - } - if (newState.hasAnalogOutputSignal()) { - level.updateNeighbourForOutputSignal(blockPos, newState.getBlock()); - } - } - - @Override - public void updateNeighbors( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState, - int recursionLimit - ) { - Level level = getLevel(); - // a == updateNeighbors - // b == updateDiagonalNeighbors - oldState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - CraftWorld craftWorld = level.getWorld(); - if (craftWorld != null) { - BlockPhysicsEvent event = new BlockPhysicsEvent( - craftWorld.getBlockAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()), - CraftBlockData.fromData(newState) - ); - level.getCraftServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - } - } - newState.triggerEvent(level, blockPos, NOTIFY, recursionLimit); - newState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit); - } - - @Override - public void updateBlock(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - Level world = getLevel(); - newState.onPlace(world, pos, oldState, false); - } - - @Override - public void onBlockStateChange( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - getLevel().onBlockStateChange(blockPos, oldState, newState); - } - - private synchronized void flushAsync(final boolean sendChunks) { - final Set changes = Set.copyOf(cachedChanges); - cachedChanges.clear(); - final Set toSend; - if (sendChunks) { - toSend = Set.copyOf(cachedChunksToSend); - cachedChunksToSend.clear(); - } else { - toSend = Collections.emptySet(); - } - RunnableVal runnableVal = new RunnableVal<>() { - @Override - public void run(Object value) { - changes.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState, - sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE) - )); - if (!sendChunks) { - return; - } - for (IntPair chunk : toSend) { - PaperweightPlatformAdapter.sendChunk(chunk, getLevel().getWorld().getHandle(), chunk.x(), chunk.z()); - } - } - }; - TaskManager.taskManager().async(() -> TaskManager.taskManager().sync(runnableVal)); - } - - @Override - public synchronized void flush() { - RunnableVal runnableVal = new RunnableVal<>() { - @Override - public void run(Object value) { - cachedChanges.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState, - sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE) - )); - for (IntPair chunk : cachedChunksToSend) { - PaperweightPlatformAdapter.sendChunk(chunk, getLevel().getWorld().getHandle(), chunk.x(), chunk.z()); - } - } - }; - if (Fawe.isMainThread()) { - runnableVal.run(); - } else { - TaskManager.taskManager().sync(runnableVal); - } - cachedChanges.clear(); - cachedChunksToSend.clear(); - } - - private record CachedChange( - LevelChunk levelChunk, - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState blockState - ) { - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java deleted file mode 100644 index c3d4388e9..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java +++ /dev/null @@ -1,1187 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.bukkit.adapter.BukkitGetBlocks; -import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; -import com.fastasyncworldedit.core.math.BitArrayUnstretched; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.fastasyncworldedit.core.queue.implementation.QueueHandler; -import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks; -import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.util.collection.AdaptedMap; -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import io.papermc.lib.PaperLib; -import io.papermc.paper.event.block.BeaconDeactivatedEvent; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.IdMap; -import net.minecraft.core.Registry; -import net.minecraft.core.SectionPos; -import net.minecraft.nbt.IntTag; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.util.BitStorage; -import net.minecraft.util.ZeroBitStorage; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.LightLayer; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.entity.BeaconBlockEntity; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.DataLayer; -import net.minecraft.world.level.chunk.HashMapPalette; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import net.minecraft.world.level.chunk.LinearPalette; -import net.minecraft.world.level.chunk.Palette; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.chunk.PalettedContainerRO; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.lighting.LevelLightEngine; -import org.apache.logging.log4j.Logger; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R3.block.CraftBlock; -import org.bukkit.event.entity.CreatureSpawnEvent; - -import javax.annotation.Nonnull; -import java.util.AbstractSet; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Future; -import java.util.concurrent.Semaphore; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.function.Function; -import java.util.stream.Collectors; - -import static net.minecraft.core.registries.Registries.BIOME; - -public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private static final Function posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ()); - private static final Function nmsTile2We = - tileEntity -> new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); - private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin - .getInstance() - .getBukkitImplAdapter()); - private final ReadWriteLock sectionLock = new ReentrantReadWriteLock(); - private final ReentrantLock callLock = new ReentrantLock(); - private final ServerLevel serverLevel; - private final int chunkX; - private final int chunkZ; - private final int minHeight; - private final int maxHeight; - private final int minSectionPosition; - private final int maxSectionPosition; - private final Registry biomeRegistry; - private final IdMap> biomeHolderIdMap; - private final ConcurrentHashMap copies = new ConcurrentHashMap<>(); - private final Object sendLock = new Object(); - private LevelChunkSection[] sections; - private LevelChunk levelChunk; - private DataLayer[] blockLight; - private DataLayer[] skyLight; - private boolean createCopy = false; - private boolean forceLoadSections = true; - private boolean lightUpdate = false; - private int copyKey = 0; - - public PaperweightGetBlocks(World world, int chunkX, int chunkZ) { - this(((CraftWorld) world).getHandle(), chunkX, chunkZ); - } - - public PaperweightGetBlocks(ServerLevel serverLevel, int chunkX, int chunkZ) { - super(serverLevel.getMinBuildHeight() >> 4, (serverLevel.getMaxBuildHeight() - 1) >> 4); - this.serverLevel = serverLevel; - this.chunkX = chunkX; - this.chunkZ = chunkZ; - this.minHeight = serverLevel.getMinBuildHeight(); - this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.minSectionPosition = minHeight >> 4; - this.maxSectionPosition = maxHeight >> 4; - this.skyLight = new DataLayer[getSectionCount()]; - this.blockLight = new DataLayer[getSectionCount()]; - this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(BIOME); - this.biomeHolderIdMap = biomeRegistry.asHolderIdMap(); - } - - public int getChunkX() { - return chunkX; - } - - public int getChunkZ() { - return chunkZ; - } - - @Override - public boolean isCreateCopy() { - return createCopy; - } - - @Override - public int setCreateCopy(boolean createCopy) { - if (!callLock.isHeldByCurrentThread()) { - throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); - } - this.createCopy = createCopy; - // Increment regardless of whether copy will be created or not to return null from getCopy() - return ++this.copyKey; - } - - @Override - public IChunkGet getCopy(final int key) { - return copies.remove(key); - } - - @Override - public void lockCall() { - this.callLock.lock(); - } - - @Override - public void unlockCall() { - this.callLock.unlock(); - } - - @Override - public void setLightingToGet(char[][] light, int minSectionPosition, int maxSectionPosition) { - if (light != null) { - lightUpdate = true; - try { - fillLightNibble(light, LightLayer.BLOCK, minSectionPosition, maxSectionPosition); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - @Override - public void setSkyLightingToGet(char[][] light, int minSectionPosition, int maxSectionPosition) { - if (light != null) { - lightUpdate = true; - try { - fillLightNibble(light, LightLayer.SKY, minSectionPosition, maxSectionPosition); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - @Override - public void setHeightmapToGet(HeightMapType type, int[] data) { - // height + 1 to match server internal - BitArrayUnstretched bitArray = new BitArrayUnstretched(MathMan.log2nlz(getChunk().getHeight() + 1), 256); - bitArray.fromRaw(data); - Heightmap.Types nativeType = Heightmap.Types.valueOf(type.name()); - Heightmap heightMap = getChunk().heightmaps.get(nativeType); - heightMap.setRawData(getChunk(), nativeType, bitArray.getData()); - } - - @Override - public int getMaxY() { - return maxHeight; - } - - @Override - public int getMinY() { - return minHeight; - } - - @Override - public BiomeType getBiomeType(int x, int y, int z) { - LevelChunkSection section = getSections(false)[(y >> 4) - getMinSectionPosition()]; - Holder biomes = section.getNoiseBiome(x >> 2, (y & 15) >> 2, z >> 2); - return PaperweightPlatformAdapter.adapt(biomes, serverLevel); - } - - @Override - public void removeSectionLighting(int layer, boolean sky) { - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = serverLevel.getChunkSource().getLightEngine().getLayerListener(LightLayer.BLOCK).getDataLayerData( - sectionPos); - if (dataLayer != null) { - lightUpdate = true; - synchronized (dataLayer) { - byte[] bytes = dataLayer.getData(); - Arrays.fill(bytes, (byte) 0); - } - } - if (sky) { - SectionPos sectionPos1 = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer1 = serverLevel - .getChunkSource() - .getLightEngine() - .getLayerListener(LightLayer.SKY) - .getDataLayerData(sectionPos1); - if (dataLayer1 != null) { - lightUpdate = true; - synchronized (dataLayer1) { - byte[] bytes = dataLayer1.getData(); - Arrays.fill(bytes, (byte) 0); - } - } - } - } - - @Override - public CompoundTag getTile(int x, int y, int z) { - BlockEntity blockEntity = getChunk().getBlockEntity(new BlockPos((x & 15) + ( - chunkX << 4), y, (z & 15) + ( - chunkZ << 4))); - if (blockEntity == null) { - return null; - } - return new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)); - } - - @Override - public Map getTiles() { - Map nmsTiles = getChunk().getBlockEntities(); - if (nmsTiles.isEmpty()) { - return Collections.emptyMap(); - } - return AdaptedMap.immutable(nmsTiles, posNms2We, nmsTile2We); - } - - @Override - public int getSkyLight(int x, int y, int z) { - int layer = y >> 4; - int alayer = layer - getMinSectionPosition(); - if (skyLight[alayer] == null) { - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = - serverLevel.getChunkSource().getLightEngine().getLayerListener(LightLayer.SKY).getDataLayerData(sectionPos); - // If the server hasn't generated the section's NibbleArray yet, it will be null - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. - Arrays.fill(LAYER_COUNT, (byte) 15); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( - LightLayer.BLOCK, - sectionPos, - dataLayer, - true - ); - } - skyLight[alayer] = dataLayer; - } - return skyLight[alayer].get(x & 15, y & 15, z & 15); - } - - @Override - public int getEmittedLight(int x, int y, int z) { - int layer = y >> 4; - int alayer = layer - getMinSectionPosition(); - if (blockLight[alayer] == null) { - serverLevel.getRawBrightness(new BlockPos(1, 1, 1), 5); - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = serverLevel - .getChunkSource() - .getLightEngine() - .getLayerListener(LightLayer.BLOCK) - .getDataLayerData(sectionPos); - // If the server hasn't generated the section's DataLayer yet, it will be null - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. - Arrays.fill(LAYER_COUNT, (byte) 15); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(LightLayer.BLOCK, sectionPos, - dataLayer, true - ); - } - blockLight[alayer] = dataLayer; - } - return blockLight[alayer].get(x & 15, y & 15, z & 15); - } - - @Override - public int[] getHeightMap(HeightMapType type) { - long[] longArray = getChunk().heightmaps.get(Heightmap.Types.valueOf(type.name())).getRawData(); - BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256, longArray); - return bitArray.toRaw(new int[256]); - } - - @Override - public CompoundTag getEntity(UUID uuid) { - Entity entity = serverLevel.getEntity(uuid); - if (entity != null) { - org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity(); - return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); - } - for (CompoundTag tag : getEntities()) { - if (uuid.equals(tag.getUUID())) { - return tag; - } - } - return null; - } - - @Override - public Set getEntities() { - ensureLoaded(serverLevel, chunkX, chunkZ); - List entities = PaperweightPlatformAdapter.getEntities(getChunk()); - if (entities.isEmpty()) { - return Collections.emptySet(); - } - int size = entities.size(); - return new AbstractSet<>() { - @Override - public int size() { - return size; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean contains(Object get) { - if (!(get instanceof CompoundTag getTag)) { - return false; - } - UUID getUUID = getTag.getUUID(); - for (Entity entity : entities) { - UUID uuid = entity.getUUID(); - if (uuid.equals(getUUID)) { - return true; - } - } - return false; - } - - @Nonnull - @Override - public Iterator iterator() { - Iterable result = entities.stream().map(input -> { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(input, tag); - return (CompoundTag) adapter.toNative(tag); - }).collect(Collectors.toList()); - return result.iterator(); - } - }; - } - - private void removeEntity(Entity entity) { - entity.discard(); - } - - public LevelChunk ensureLoaded(ServerLevel nmsWorld, int chunkX, int chunkZ) { - return PaperweightPlatformAdapter.ensureLoaded(nmsWorld, chunkX, chunkZ); - } - - @Override - @SuppressWarnings("rawtypes") - public synchronized > T call(IChunkSet set, Runnable finalizer) { - if (!callLock.isHeldByCurrentThread()) { - throw new IllegalStateException("Attempted to call chunk GET but chunk was not call-locked."); - } - forceLoadSections = false; - PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null; - if (createCopy) { - if (copies.containsKey(copyKey)) { - throw new IllegalStateException("Copy key already used."); - } - copies.put(copyKey, copy); - } - try { - ServerLevel nmsWorld = serverLevel; - LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ); - - // Remove existing tiles. Create a copy so that we can remove blocks - Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); - List beacons = null; - if (!chunkTiles.isEmpty()) { - for (Map.Entry entry : chunkTiles.entrySet()) { - final BlockPos pos = entry.getKey(); - final int lx = pos.getX() & 15; - final int ly = pos.getY(); - final int lz = pos.getZ() & 15; - final int layer = ly >> 4; - if (!set.hasSection(layer)) { - continue; - } - - int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { - BlockEntity tile = entry.getValue(); - if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { - if (beacons == null) { - beacons = new ArrayList<>(); - } - beacons.add(tile); - PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); - continue; - } - nmsChunk.removeBlockEntity(tile.getBlockPos()); - if (createCopy) { - copy.storeTile(tile); - } - } - } - } - final BiomeType[][] biomes = set.getBiomes(); - - int bitMask = 0; - synchronized (nmsChunk) { - LevelChunkSection[] levelChunkSections = nmsChunk.getSections(); - - for (int layerNo = getMinSectionPosition(); layerNo <= getMaxSectionPosition(); layerNo++) { - - int getSectionIndex = layerNo - getMinSectionPosition(); - int setSectionIndex = layerNo - set.getMinSectionPosition(); - - if (!set.hasSection(layerNo)) { - // No blocks, but might be biomes present. Handle this lazily. - if (biomes == null) { - continue; - } - if (layerNo < set.getMinSectionPosition() || layerNo > set.getMaxSectionPosition()) { - continue; - } - if (biomes[setSectionIndex] != null) { - synchronized (super.sectionLocks[getSectionIndex]) { - LevelChunkSection existingSection = levelChunkSections[getSectionIndex]; - if (createCopy && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); - } - - if (existingSection == null) { - PalettedContainer> biomeData = PaperweightPlatformAdapter.getBiomePalettedContainer( - biomes[setSectionIndex], - biomeHolderIdMap - ); - LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( - layerNo, - new char[4096], - adapter, - biomeRegistry, - biomeData - ); - if (PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - null, - newSection, - getSectionIndex - )) { - updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); - continue; - } else { - existingSection = levelChunkSections[getSectionIndex]; - if (existingSection == null) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - getSectionIndex - ); - continue; - } - } - } else { - PalettedContainer> paletteBiomes = setBiomesToPalettedContainer( - biomes, - setSectionIndex, - existingSection.getBiomes() - ); - if (paletteBiomes != null) { - PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); - } - } - } - } - continue; - } - - bitMask |= 1 << getSectionIndex; - - // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to - // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); - - // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was - // submitted to keep loaded internal chunks to queue target size. - synchronized (super.sectionLocks[getSectionIndex]) { - - LevelChunkSection newSection; - LevelChunkSection existingSection = levelChunkSections[getSectionIndex]; - // Don't attempt to tick section whilst we're editing - if (existingSection != null) { - PaperweightPlatformAdapter.clearCounts(existingSection); - if (PaperLib.isPaper()) { - existingSection.tickingList.clear(); - } - } - - if (createCopy) { - char[] tmpLoad = loadPrivately(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); - copy.storeSection(getSectionIndex, copyArr); - if (biomes != null && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); - } - } - - if (existingSection == null) { - PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( - biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES, - null - ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); - newSection = PaperweightPlatformAdapter.newChunkSection( - layerNo, - setArr, - adapter, - biomeRegistry, - biomeData - ); - if (PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - null, - newSection, - getSectionIndex - )) { - updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex); - continue; - } else { - existingSection = levelChunkSections[getSectionIndex]; - if (existingSection == null) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - getSectionIndex - ); - continue; - } - } - } - - //ensure that the server doesn't try to tick the chunksection while we're editing it. (Again) - PaperweightPlatformAdapter.clearCounts(existingSection); - if (PaperLib.isPaper()) { - existingSection.tickingList.clear(); - } - DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(existingSection); - - // Synchronize to prevent further acquisitions - synchronized (lock) { - lock.acquire(); // Wait until we have the lock - lock.release(); - try { - sectionLock.writeLock().lock(); - if (this.getChunk() != nmsChunk) { - this.levelChunk = nmsChunk; - this.sections = null; - this.reset(); - } else if (existingSection != getSections(false)[getSectionIndex]) { - this.sections[getSectionIndex] = existingSection; - this.reset(); - } else if (!Arrays.equals( - update(getSectionIndex, new char[4096], true), - loadPrivately(layerNo) - )) { - this.reset(layerNo); - /*} else if (lock.isModified()) { - this.reset(layerNo);*/ - } - } finally { - sectionLock.writeLock().unlock(); - } - - PalettedContainer> biomeData = setBiomesToPalettedContainer( - biomes, - setSectionIndex, - existingSection.getBiomes() - ); - - newSection = PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() - ); - if (!PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - existingSection, - newSection, - getSectionIndex - )) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - getSectionIndex - ); - } else { - updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex); - } - } - } - } - - Map heightMaps = set.getHeightMaps(); - for (Map.Entry entry : heightMaps.entrySet()) { - PaperweightGetBlocks.this.setHeightmapToGet(entry.getKey(), entry.getValue()); - } - PaperweightGetBlocks.this.setLightingToGet( - set.getLight(), - set.getMinSectionPosition(), - set.getMaxSectionPosition() - ); - PaperweightGetBlocks.this.setSkyLightingToGet( - set.getSkyLight(), - set.getMinSectionPosition(), - set.getMaxSectionPosition() - ); - - Runnable[] syncTasks = null; - - int bx = chunkX << 4; - int bz = chunkZ << 4; - - // Call beacon deactivate events here synchronously - // list will be null on spigot, so this is an implicit isPaper check - if (beacons != null && !beacons.isEmpty()) { - final List finalBeacons = beacons; - - syncTasks = new Runnable[4]; - - syncTasks[3] = () -> { - for (BlockEntity beacon : finalBeacons) { - BeaconBlockEntity.playSound(beacon.getLevel(), beacon.getBlockPos(), SoundEvents.BEACON_DEACTIVATE); - new BeaconDeactivatedEvent(CraftBlock.at(beacon.getLevel(), beacon.getBlockPos())).callEvent(); - } - }; - } - - Set entityRemoves = set.getEntityRemoves(); - if (entityRemoves != null && !entityRemoves.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[3]; - } - - syncTasks[2] = () -> { - Set entitiesRemoved = new HashSet<>(); - final List entities = PaperweightPlatformAdapter.getEntities(nmsChunk); - - for (Entity entity : entities) { - UUID uuid = entity.getUUID(); - if (entityRemoves.contains(uuid)) { - if (createCopy) { - copy.storeEntity(entity); - } - removeEntity(entity); - entitiesRemoved.add(uuid); - entityRemoves.remove(uuid); - } - } - if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) { - for (UUID uuid : entityRemoves) { - Entity entity = nmsWorld.getEntities().get(uuid); - if (entity != null) { - removeEntity(entity); - } - } - } - // Only save entities that were actually removed to history - set.getEntityRemoves().clear(); - set.getEntityRemoves().addAll(entitiesRemoved); - }; - } - - Set entities = set.getEntities(); - if (entities != null && !entities.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[2]; - } - - syncTasks[1] = () -> { - Iterator iterator = entities.iterator(); - while (iterator.hasNext()) { - final CompoundTag nativeTag = iterator.next(); - final Map> entityTagMap = nativeTag.getValue(); - final StringTag idTag = (StringTag) entityTagMap.get("Id"); - final ListTag posTag = (ListTag) entityTagMap.get("Pos"); - final ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); - if (idTag == null || posTag == null || rotTag == null) { - LOGGER.error("Unknown entity tag: {}", nativeTag); - continue; - } - final double x = posTag.getDouble(0); - final double y = posTag.getDouble(1); - final double z = posTag.getDouble(2); - final float yaw = rotTag.getFloat(0); - final float pitch = rotTag.getFloat(1); - final String id = idTag.getValue(); - - EntityType type = EntityType.byString(id).orElse(null); - if (type != null) { - Entity entity = type.create(nmsWorld); - if (entity != null) { - final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative( - nativeTag); - for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - entity.load(tag); - entity.absMoveTo(x, y, z, yaw, pitch); - entity.setUUID(nativeTag.getUUID()); - if (!nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) { - LOGGER.warn( - "Error creating entity of type `{}` in world `{}` at location `{},{},{}`", - id, - nmsWorld.getWorld().getName(), - x, - y, - z - ); - // Unsuccessful create should not be saved to history - iterator.remove(); - } - } - } - } - }; - } - - // set tiles - Map tiles = set.getTiles(); - if (tiles != null && !tiles.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[1]; - } - - syncTasks[0] = () -> { - for (final Map.Entry entry : tiles.entrySet()) { - final CompoundTag nativeTag = entry.getValue(); - final BlockVector3 blockHash = entry.getKey(); - final int x = blockHash.x() + bx; - final int y = blockHash.y(); - final int z = blockHash.z() + bz; - final BlockPos pos = new BlockPos(x, y, z); - - synchronized (nmsWorld) { - BlockEntity tileEntity = nmsWorld.getBlockEntity(pos); - if (tileEntity == null || tileEntity.isRemoved()) { - nmsWorld.removeBlockEntity(pos); - tileEntity = nmsWorld.getBlockEntity(pos); - } - if (tileEntity != null) { - final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative( - nativeTag); - tag.put("x", IntTag.valueOf(x)); - tag.put("y", IntTag.valueOf(y)); - tag.put("z", IntTag.valueOf(z)); - tileEntity.load(tag); - } - } - } - }; - } - - Runnable callback; - if (bitMask == 0 && biomes == null && !lightUpdate) { - callback = null; - } else { - int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0; - boolean finalLightUpdate = lightUpdate; - callback = () -> { - // Set Modified - nmsChunk.setLightCorrect(true); // Set Modified - nmsChunk.mustNotSave = false; - nmsChunk.setUnsaved(true); - // send to player - if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) { - this.send(); - } - if (finalizer != null) { - finalizer.run(); - } - }; - } - if (syncTasks != null) { - QueueHandler queueHandler = Fawe.instance().getQueueHandler(); - Runnable[] finalSyncTasks = syncTasks; - - // Chain the sync tasks and the callback - Callable chain = () -> { - try { - // Run the sync tasks - for (Runnable task : finalSyncTasks) { - if (task != null) { - task.run(); - } - } - if (callback == null) { - if (finalizer != null) { - queueHandler.async(finalizer, null); - } - return null; - } else { - return queueHandler.async(callback, null); - } - } catch (Throwable e) { - e.printStackTrace(); - throw e; - } - }; - //noinspection unchecked - required at compile time - return (T) (Future) queueHandler.sync(chain); - } else { - if (callback == null) { - if (finalizer != null) { - finalizer.run(); - } - } else { - callback.run(); - } - } - } - return null; - } catch (Throwable e) { - e.printStackTrace(); - return null; - } finally { - forceLoadSections = true; - } - } - - private void updateGet( - LevelChunk nmsChunk, - LevelChunkSection[] chunkSections, - LevelChunkSection section, - char[] arr, - int layer - ) { - try { - sectionLock.writeLock().lock(); - if (this.getChunk() != nmsChunk) { - this.levelChunk = nmsChunk; - this.sections = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, this.sections, 0, chunkSections.length); - this.reset(); - } - if (this.sections == null) { - this.sections = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, this.sections, 0, chunkSections.length); - } - if (this.sections[layer] != section) { - // Not sure why it's funky, but it's what I did in commit fda7d00747abe97d7891b80ed8bb88d97e1c70d1 and I don't want to touch it >dords - this.sections[layer] = new LevelChunkSection[]{section}.clone()[0]; - } - } finally { - sectionLock.writeLock().unlock(); - } - this.blocks[layer] = arr; - } - - private char[] loadPrivately(int layer) { - layer -= getMinSectionPosition(); - if (super.sections[layer] != null) { - synchronized (super.sectionLocks[layer]) { - if (super.sections[layer].isFull() && super.blocks[layer] != null) { - return super.blocks[layer]; - } - } - } - return PaperweightGetBlocks.this.update(layer, null, true); - } - - @Override - public void send() { - synchronized (sendLock) { - PaperweightPlatformAdapter.sendChunk(this, serverLevel, chunkX, chunkZ); - } - } - - /** - * Update a given (nullable) data array to the current data stored in the server's chunk, associated with this - * {@link PaperweightPlatformAdapter} instance. Not synchronised to the {@link PaperweightPlatformAdapter} instance as synchronisation - * is handled where necessary in the method, and should otherwise be handled correctly by this method's caller. - * - * @param layer layer index (0 may denote a negative layer in the world, e.g. at y=-32) - * @param data array to be updated/filled with data or null - * @param aggressive if the cached section array should be re-acquired. - * @return the given array to be filled with data, or a new array if null is given. - */ - @Override - @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { - LevelChunkSection section = getSections(aggressive)[layer]; - // Section is null, return empty array - if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; - } - if (data != null && data.length != 4096) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - } - Semaphore lock = PaperweightPlatformAdapter.applyLock(section); - synchronized (lock) { - // Efficiently convert ChunkSection to raw data - try { - lock.acquire(); - - final PalettedContainer blocks = section.getStates(); - final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocks); - final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); - - if (bits instanceof ZeroBitStorage) { - Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper - return data; - } - - final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get(dataObject); - - final int bitsPerEntry = bits.getBits(); - final long[] blockStates = bits.getRaw(); - - new BitArrayUnstretched(bitsPerEntry, 4096, blockStates).toRaw(data); - - int num_palette; - if (palette instanceof LinearPalette || palette instanceof HashMapPalette) { - num_palette = palette.getSize(); - } else { - // The section's palette is the global block palette. - for (int i = 0; i < 4096; i++) { - char paletteVal = data[i]; - char ordinal = adapter.ibdIDToOrdinal(paletteVal); - data[i] = ordinal; - } - return data; - } - - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); - try { - if (num_palette != 1) { - for (int i = 0; i < num_palette; i++) { - char ordinal = ordinal(palette.valueFor(i), adapter); - paletteToOrdinal[i] = ordinal; - } - for (int i = 0; i < 4096; i++) { - char paletteVal = data[i]; - char val = paletteToOrdinal[paletteVal]; - if (val == Character.MAX_VALUE) { - val = ordinal(palette.valueFor(i), adapter); - paletteToOrdinal[i] = val; - } - data[i] = val; - } - } else { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); - } - } finally { - for (int i = 0; i < num_palette; i++) { - paletteToOrdinal[i] = Character.MAX_VALUE; - } - } - return data; - } catch (IllegalAccessException | InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } finally { - lock.release(); - } - } - } - - private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { - if (ibd == null) { - return BlockTypesCache.ReservedIDs.AIR; - } else { - return adapter.adaptToChar(ibd); - } - } - - public LevelChunkSection[] getSections(boolean force) { - force &= forceLoadSections; - LevelChunkSection[] tmp = sections; - if (tmp == null || force) { - try { - sectionLock.writeLock().lock(); - tmp = sections; - if (tmp == null || force) { - LevelChunkSection[] chunkSections = getChunk().getSections(); - tmp = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, tmp, 0, chunkSections.length); - sections = tmp; - } - } finally { - sectionLock.writeLock().unlock(); - } - } - return tmp; - } - - public LevelChunk getChunk() { - LevelChunk levelChunk = this.levelChunk; - if (levelChunk == null) { - synchronized (this) { - levelChunk = this.levelChunk; - if (levelChunk == null) { - this.levelChunk = levelChunk = ensureLoaded(this.serverLevel, chunkX, chunkZ); - } - } - } - return levelChunk; - } - - private void fillLightNibble(char[][] light, LightLayer lightLayer, int minSectionPosition, int maxSectionPosition) { - for (int Y = 0; Y <= maxSectionPosition - minSectionPosition; Y++) { - if (light[Y] == null) { - continue; - } - SectionPos sectionPos = SectionPos.of(levelChunk.getPos(), Y + minSectionPosition); - DataLayer dataLayer = serverLevel.getChunkSource().getLightEngine().getLayerListener(lightLayer).getDataLayerData( - sectionPos); - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - Arrays.fill(LAYER_COUNT, lightLayer == LightLayer.SKY ? (byte) 15 : (byte) 0); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( - lightLayer, - sectionPos, - dataLayer, - true - ); - } - synchronized (dataLayer) { - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - int i = y << 8 | z << 4 | x; - if (light[Y][i] < 16) { - dataLayer.set(x, y, z, light[Y][i]); - } - } - } - } - } - } - } - - private PalettedContainer> setBiomesToPalettedContainer( - final BiomeType[][] biomes, - final int sectionIndex, - final PalettedContainerRO> data - ) { - BiomeType[] sectionBiomes; - if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return null; - } - PalettedContainer> biomeData = data.recreate(); - for (int y = 0, index = 0; y < 4; y++) { - for (int z = 0; z < 4; z++) { - for (int x = 0; x < 4; x++, index++) { - BiomeType biomeType = sectionBiomes[index]; - if (biomeType == null) { - biomeData.set(x, y, z, data.get(x, y, z)); - } else { - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) - ); - } - } - } - } - return biomeData; - } - - @Override - public boolean hasSection(int layer) { - layer -= getMinSectionPosition(); - return getSections(false)[layer] != null; - } - - @Override - @SuppressWarnings("unchecked") - public synchronized boolean trim(boolean aggressive) { - skyLight = new DataLayer[getSectionCount()]; - blockLight = new DataLayer[getSectionCount()]; - if (aggressive) { - sectionLock.writeLock().lock(); - sections = null; - levelChunk = null; - sectionLock.writeLock().unlock(); - return super.trim(true); - } else if (sections == null) { - // don't bother trimming if there are no sections stored. - return true; - } else { - for (int i = getMinSectionPosition(); i <= getMaxSectionPosition(); i++) { - int layer = i - getMinSectionPosition(); - if (!hasSection(i) || !super.sections[layer].isFull()) { - continue; - } - LevelChunkSection existing = getSections(true)[layer]; - try { - final PalettedContainer blocksExisting = existing.getStates(); - - final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocksExisting); - final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get( - dataObject); - int paletteSize; - - if (palette instanceof LinearPalette || palette instanceof HashMapPalette) { - paletteSize = palette.getSize(); - } else { - super.trim(false, i); - continue; - } - if (paletteSize == 1) { - //If the cached palette size is 1 then no blocks can have been changed i.e. do not need to update these chunks. - continue; - } - super.trim(false, i); - } catch (IllegalAccessException ignored) { - super.trim(false, i); - } - } - return true; - } - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java deleted file mode 100644 index dd1787868..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; -import com.fastasyncworldedit.core.queue.IBlocks; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import net.minecraft.core.Holder; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.chunk.PalettedContainerRO; -import org.apache.logging.log4j.Logger; - -import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Future; - -public class PaperweightGetBlocks_Copy implements IChunkGet { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private final Map tiles = new HashMap<>(); - private final Set entities = new HashSet<>(); - private final char[][] blocks; - private final int minHeight; - private final int maxHeight; - final ServerLevel serverLevel; - final LevelChunk levelChunk; - private Holder[][] biomes = null; - - protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { - this.levelChunk = levelChunk; - this.serverLevel = levelChunk.level; - this.minHeight = serverLevel.getMinBuildHeight(); - this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; - } - - protected void storeTile(BlockEntity blockEntity) { - tiles.put( - BlockVector3.at( - blockEntity.getBlockPos().getX(), - blockEntity.getBlockPos().getY(), - blockEntity.getBlockPos().getZ() - ), - new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)) - ); - } - - @Override - public Map getTiles() { - return tiles; - } - - @Override - @Nullable - public CompoundTag getTile(int x, int y, int z) { - return tiles.get(BlockVector3.at(x, y, z)); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - protected void storeEntity(Entity entity) { - BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); - net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(entity, compoundTag); - entities.add((CompoundTag) adapter.toNative(compoundTag)); - } - - @Override - public Set getEntities() { - return this.entities; - } - - @Override - public CompoundTag getEntity(UUID uuid) { - for (CompoundTag tag : entities) { - if (uuid.equals(tag.getUUID())) { - return tag; - } - } - return null; - } - - @Override - public boolean isCreateCopy() { - return false; - } - - @Override - public int setCreateCopy(boolean createCopy) { - return -1; - } - - @Override - public void setLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) { - } - - @Override - public void setSkyLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) { - } - - @Override - public void setHeightmapToGet(HeightMapType type, int[] data) { - } - - @Override - public int getMaxY() { - return maxHeight; - } - - @Override - public int getMinY() { - return minHeight; - } - - @Override - public int getMaxSectionPosition() { - return maxHeight >> 4; - } - - @Override - public int getMinSectionPosition() { - return minHeight >> 4; - } - - @Override - public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; - return PaperweightPlatformAdapter.adapt(biome, serverLevel); - } - - @Override - public void removeSectionLighting(int layer, boolean sky) { - } - - @Override - public boolean trim(boolean aggressive, int layer) { - return false; - } - - @Override - public IBlocks reset() { - return null; - } - - @Override - public int getSectionCount() { - return serverLevel.getSectionsCount(); - } - - protected void storeSection(int layer, char[] data) { - blocks[layer] = data; - } - - protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { - if (biomes == null) { - biomes = new Holder[getSectionCount()][]; - } - if (biomes[layer] == null) { - biomes[layer] = new Holder[64]; - } - if (biomeData instanceof PalettedContainer> palettedContainer) { - for (int i = 0; i < 64; i++) { - biomes[layer][i] = palettedContainer.get(i); - } - } else { - LOGGER.error( - "Cannot correctly save biomes to history. Expected class type {} but got {}", - PalettedContainer.class.getSimpleName(), - biomeData.getClass().getSimpleName() - ); - } - } - - @Override - public BaseBlock getFullBlock(int x, int y, int z) { - BlockState state = BlockTypesCache.states[get(x, y, z)]; - return state.toBaseBlock(this, x, y, z); - } - - @Override - public boolean hasSection(int layer) { - layer -= getMinSectionPosition(); - return blocks[layer] != null; - } - - @Override - public char[] load(int layer) { - layer -= getMinSectionPosition(); - if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); - } - return blocks[layer]; - } - - @Override - public char[] loadIfPresent(int layer) { - layer -= getMinSectionPosition(); - return blocks[layer]; - } - - @Override - public BlockState getBlock(int x, int y, int z) { - return BlockTypesCache.states[get(x, y, z)]; - } - - @Override - public int getSkyLight(int x, int y, int z) { - return 0; - } - - @Override - public int getEmittedLight(int x, int y, int z) { - return 0; - } - - @Override - public int[] getHeightMap(HeightMapType type) { - return new int[0]; - } - - @Override - public > T call(IChunkSet set, Runnable finalize) { - return null; - } - - public char get(int x, int y, int z) { - final int layer = (y >> 4) - getMinSectionPosition(); - final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; - } - - - @Override - public boolean trim(boolean aggressive) { - return false; - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightMapChunkUtil.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightMapChunkUtil.java deleted file mode 100644 index 7c7f39d9a..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightMapChunkUtil.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData; -import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; - -//TODO un-very-break-this -public class PaperweightMapChunkUtil extends MapChunkUtil { - - public PaperweightMapChunkUtil() throws NoSuchFieldException { - fieldX = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("TWO_MEGABYTES", "a")); - fieldZ = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("x", "a")); - fieldBitMask = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("z", "b")); - fieldHeightMap = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("heightmaps", "b")); - fieldChunkData = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("chunkData", "c")); - fieldBlockEntities = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("buffer", "c")); - fieldFull = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("blockEntitiesData", "d")); - fieldX.setAccessible(true); - fieldZ.setAccessible(true); - fieldBitMask.setAccessible(true); - fieldHeightMap.setAccessible(true); - fieldChunkData.setAccessible(true); - fieldBlockEntities.setAccessible(true); - fieldFull.setAccessible(true); - } - - @Override - public ClientboundLevelChunkWithLightPacket createPacket() { - // TODO ??? return new ClientboundLevelChunkPacket(); - throw new UnsupportedOperationException(); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java deleted file mode 100644 index aec3cfd24..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java +++ /dev/null @@ -1,748 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.destroystokyo.paper.util.maplist.EntityList; -import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter; -import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; -import com.fastasyncworldedit.bukkit.adapter.NMSAdapter; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.math.BitArrayUnstretched; -import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.util.ReflectionUtils; -import com.fastasyncworldedit.core.util.TaskManager; -import com.mojang.datafixers.util.Either; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import io.papermc.lib.PaperLib; -import io.papermc.paper.world.ChunkEntitySlices; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.IdMap; -import net.minecraft.core.Registry; -import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.level.TicketType; -import net.minecraft.util.BitStorage; -import net.minecraft.util.ExceptionCollector; -import net.minecraft.util.SimpleBitStorage; -import net.minecraft.util.ThreadingDetector; -import net.minecraft.util.Unit; -import net.minecraft.util.ZeroBitStorage; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.npc.AbstractVillager; -import net.minecraft.world.item.trading.MerchantOffers; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.GlobalPalette; -import net.minecraft.world.level.chunk.HashMapPalette; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import net.minecraft.world.level.chunk.LinearPalette; -import net.minecraft.world.level.chunk.Palette; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.chunk.SingleValuePalette; -import net.minecraft.world.level.entity.PersistentEntitySectionManager; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R3.CraftChunk; -import sun.misc.Unsafe; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.function.Function; - -import static net.minecraft.core.registries.Registries.BIOME; - -public final class PaperweightPlatformAdapter extends NMSAdapter { - - public static final Field fieldData; - - public static final Constructor dataConstructor; - - public static final Field fieldStorage; - public static final Field fieldPalette; - - private static final Field fieldTickingFluidCount; - private static final Field fieldTickingBlockCount; - private static final Field fieldBiomes; - - private static final MethodHandle methodGetVisibleChunk; - - private static final Field fieldThreadingDetector; - private static final Field fieldLock; - - private static final MethodHandle methodRemoveGameEventListener; - private static final MethodHandle methodremoveTickingBlockEntity; - - private static final Field fieldOffers; - private static final MerchantOffers OFFERS = new MerchantOffers(); - - private static final Field fieldRemove; - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - static final boolean POST_CHUNK_REWRITE; - private static Method PAPER_CHUNK_GEN_ALL_ENTITIES; - private static Field LEVEL_CHUNK_ENTITIES; - private static Field SERVER_LEVEL_ENTITY_MANAGER; - - static { - final MethodHandles.Lookup lookup = MethodHandles.lookup(); - try { - fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d")); - fieldData.setAccessible(true); - - Class dataClazz = fieldData.getType(); - dataConstructor = dataClazz.getDeclaredConstructors()[0]; - dataConstructor.setAccessible(true); - - fieldStorage = dataClazz.getDeclaredField(Refraction.pickName("storage", "b")); - fieldStorage.setAccessible(true); - fieldPalette = dataClazz.getDeclaredField(Refraction.pickName("palette", "c")); - fieldPalette.setAccessible(true); - - fieldTickingFluidCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "h")); - fieldTickingFluidCount.setAccessible(true); - fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "g")); - fieldTickingBlockCount.setAccessible(true); - Field tmpFieldBiomes; - try { - // It seems to actually be biomes, but is apparently obfuscated to "j" - tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); - } catch (NoSuchFieldException ignored) { - tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("j"); - } - fieldBiomes = tmpFieldBiomes; - fieldBiomes.setAccessible(true); - - Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( - "getVisibleChunkIfPresent", - "b" - ), long.class); - getVisibleChunkIfPresent.setAccessible(true); - methodGetVisibleChunk = lookup.unreflect(getVisibleChunkIfPresent); - - if (!PaperLib.isPaper()) { - fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f")); - fieldThreadingDetector.setAccessible(true); - fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c")); - fieldLock.setAccessible(true); - } else { - // in paper, the used methods are synchronized properly - fieldThreadingDetector = null; - fieldLock = null; - } - - Method removeGameEventListener = LevelChunk.class.getDeclaredMethod( - Refraction.pickName("removeGameEventListener", "a"), - BlockEntity.class, - ServerLevel.class - ); - removeGameEventListener.setAccessible(true); - methodRemoveGameEventListener = lookup.unreflect(removeGameEventListener); - - Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod( - Refraction.pickName( - "removeBlockEntityTicker", - "l" - ), BlockPos.class - ); - removeBlockEntityTicker.setAccessible(true); - methodremoveTickingBlockEntity = lookup.unreflect(removeBlockEntityTicker); - - fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "q")); - fieldRemove.setAccessible(true); - - boolean chunkRewrite; - try { - ServerLevel.class.getDeclaredMethod("getEntityLookup"); - chunkRewrite = true; - PAPER_CHUNK_GEN_ALL_ENTITIES = ChunkEntitySlices.class.getDeclaredMethod("getAllEntities"); - PAPER_CHUNK_GEN_ALL_ENTITIES.setAccessible(true); - } catch (NoSuchMethodException ignored) { - chunkRewrite = false; - } - try { - // Paper - Pre-Chunk-Update - LEVEL_CHUNK_ENTITIES = LevelChunk.class.getDeclaredField("entities"); - LEVEL_CHUNK_ENTITIES.setAccessible(true); - } catch (NoSuchFieldException ignored) { - } - try { - // Non-Paper - SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField(Refraction.pickName("entityManager", "L")); - SERVER_LEVEL_ENTITY_MANAGER.setAccessible(true); - } catch (NoSuchFieldException ignored) { - } - POST_CHUNK_REWRITE = chunkRewrite; - - fieldOffers = AbstractVillager.class.getDeclaredField(Refraction.pickName("offers", "bT")); - fieldOffers.setAccessible(true); - } catch (RuntimeException | Error e) { - throw e; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - static boolean setSectionAtomic( - LevelChunkSection[] sections, - LevelChunkSection expected, - LevelChunkSection value, - int layer - ) { - if (layer >= 0 && layer < sections.length) { - return ReflectionUtils.compareAndSet(sections, expected, value, layer); - } - return false; - } - - // There is no point in having a functional semaphore for paper servers. - private static final ThreadLocal SEMAPHORE_THREAD_LOCAL = - ThreadLocal.withInitial(() -> new DelegateSemaphore(1, null)); - - static DelegateSemaphore applyLock(LevelChunkSection section) { - if (PaperLib.isPaper()) { - return SEMAPHORE_THREAD_LOCAL.get(); - } - try { - synchronized (section) { - PalettedContainer blocks = section.getStates(); - ThreadingDetector currentThreadingDetector = (ThreadingDetector) fieldThreadingDetector.get(blocks); - synchronized (currentThreadingDetector) { - Semaphore currentLock = (Semaphore) fieldLock.get(currentThreadingDetector); - if (currentLock instanceof DelegateSemaphore delegateSemaphore) { - return delegateSemaphore; - } - DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); - fieldLock.set(currentThreadingDetector, newLock); - return newLock; - } - } - } catch (Throwable e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - public static LevelChunk ensureLoaded(ServerLevel serverLevel, int chunkX, int chunkZ) { - if (!PaperLib.isPaper()) { - LevelChunk nmsChunk = serverLevel.getChunkSource().getChunk(chunkX, chunkZ, false); - if (nmsChunk != null) { - return nmsChunk; - } - if (Fawe.isMainThread()) { - return serverLevel.getChunk(chunkX, chunkZ); - } - } else { - LevelChunk nmsChunk = serverLevel.getChunkSource().getChunkAtIfCachedImmediately(chunkX, chunkZ); - if (nmsChunk != null) { - addTicket(serverLevel, chunkX, chunkZ); - return nmsChunk; - } - nmsChunk = serverLevel.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ); - if (nmsChunk != null) { - addTicket(serverLevel, chunkX, chunkZ); - return nmsChunk; - } - // Avoid "async" methods from the main thread. - if (Fawe.isMainThread()) { - return serverLevel.getChunk(chunkX, chunkZ); - } - CompletableFuture future = serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true); - try { - CraftChunk chunk; - try { - chunk = (CraftChunk) future.get(10, TimeUnit.SECONDS); - } catch (TimeoutException e) { - String world = serverLevel.getWorld().getName(); - // We've already taken 10 seconds we can afford to wait a little here. - boolean loaded = TaskManager.taskManager().sync(() -> Bukkit.getWorld(world) != null); - if (loaded) { - LOGGER.warn("Chunk {},{} failed to load in 10 seconds in world {}. Retrying...", chunkX, chunkZ, world); - // Retry chunk load - chunk = (CraftChunk) serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true).get(); - } else { - throw new UnsupportedOperationException("Cannot load chunk from unloaded world " + world + "!"); - } - } - addTicket(serverLevel, chunkX, chunkZ); - return (LevelChunk) chunk.getHandle(ChunkStatus.FULL); - } catch (Throwable e) { - e.printStackTrace(); - } - } - return TaskManager.taskManager().sync(() -> serverLevel.getChunk(chunkX, chunkZ)); - } - - private static void addTicket(ServerLevel serverLevel, int chunkX, int chunkZ) { - // Ensure chunk is definitely loaded before applying a ticket - io.papermc.paper.util.MCUtil.MAIN_EXECUTOR.execute(() -> serverLevel - .getChunkSource() - .addRegionTicket(TicketType.UNLOAD_COOLDOWN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE)); - } - - public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) { - ChunkMap chunkMap = nmsWorld.getChunkSource().chunkMap; - try { - return (ChunkHolder) methodGetVisibleChunk.invoke(chunkMap, ChunkPos.asLong(chunkX, chunkZ)); - } catch (Throwable thr) { - throw new RuntimeException(thr); - } - } - - @SuppressWarnings("deprecation") - public static void sendChunk(Object chunk, ServerLevel nmsWorld, int chunkX, int chunkZ) { - ChunkHolder chunkHolder = getPlayerChunk(nmsWorld, chunkX, chunkZ); - if (chunkHolder == null) { - return; - } - ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ); - LevelChunk levelChunk; - if (PaperLib.isPaper()) { - // getChunkAtIfLoadedImmediately is paper only - levelChunk = nmsWorld - .getChunkSource() - .getChunkAtIfLoadedImmediately(chunkX, chunkZ); - } else { - levelChunk = ((Optional) ((Either) chunkHolder - .getTickingChunkFuture() // method is not present with new paper chunk system - .getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left()) - .orElse(null); - } - if (levelChunk == null) { - return; - } - MinecraftServer.getServer().execute(() -> { - ClientboundLevelChunkWithLightPacket packet; - if (PaperLib.isPaper()) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - true, - false // last false is to not bother with x-ray - ); - } else { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - true - ); - } - nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); - }); - } - - private static List nearbyPlayers(ServerLevel serverLevel, ChunkPos coordIntPair) { - return serverLevel.getChunkSource().chunkMap.getPlayers(coordIntPair, false); - } - - /* - NMS conversion - */ - public static LevelChunkSection newChunkSection( - final int layer, - final char[] blocks, - CachedBukkitAdapter adapter, - Registry biomeRegistry, - @Nullable PalettedContainer> biomes - ) { - return newChunkSection(layer, null, blocks, adapter, biomeRegistry, biomes); - } - - public static LevelChunkSection newChunkSection( - final int layer, - final Function get, - char[] set, - CachedBukkitAdapter adapter, - Registry biomeRegistry, - @Nullable PalettedContainer> biomes - ) { - if (set == null) { - return newChunkSection(layer, biomeRegistry, biomes); - } - final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); - final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); - final long[] blockStates = FaweCache.INSTANCE.BLOCK_STATES.get(); - final int[] blocksCopy = FaweCache.INSTANCE.SECTION_BLOCKS.get(); - try { - int num_palette; - if (get == null) { - num_palette = createPalette(blockToPalette, paletteToBlock, blocksCopy, set, adapter, null); - } else { - num_palette = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, get, set, adapter, null); - } - - int bitsPerEntry = MathMan.log2nlz(num_palette - 1); - if (bitsPerEntry > 0 && bitsPerEntry < 5) { - bitsPerEntry = 4; - } else if (bitsPerEntry > 8) { - bitsPerEntry = MathMan.log2nlz(Block.BLOCK_STATE_REGISTRY.size() - 1); - } - - int bitsPerEntryNonZero = Math.max(bitsPerEntry, 1); // We do want to use zero sometimes - final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntryNonZero); - final int blockBitArrayEnd = MathMan.ceilZero((float) 4096 / blocksPerLong); - - if (num_palette == 1) { - for (int i = 0; i < blockBitArrayEnd; i++) { - blockStates[i] = 0; - } - } else { - final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntryNonZero, 4096, blockStates); - bitArray.fromRaw(blocksCopy); - } - - final long[] bits = Arrays.copyOfRange(blockStates, 0, blockBitArrayEnd); - final BitStorage nmsBits; - if (bitsPerEntry == 0) { - nmsBits = new ZeroBitStorage(4096); - } else { - nmsBits = new SimpleBitStorage(bitsPerEntry, 4096, bits); - } - List palette; - if (bitsPerEntry < 9) { - palette = new ArrayList<>(); - for (int i = 0; i < num_palette; i++) { - int ordinal = paletteToBlock[i]; - blockToPalette[ordinal] = Integer.MAX_VALUE; - final BlockState state = BlockTypesCache.states[ordinal]; - palette.add(((PaperweightBlockMaterial) state.getMaterial()).getState()); - } - } else { - palette = List.of(); - } - - // Create palette with data - @SuppressWarnings("deprecation") // constructor is deprecated on paper, but needed to keep compatibility with spigot - final PalettedContainer blockStatePalettedContainer = - new PalettedContainer<>( - Block.BLOCK_STATE_REGISTRY, - PalettedContainer.Strategy.SECTION_STATES, - PalettedContainer.Strategy.SECTION_STATES.getConfiguration(Block.BLOCK_STATE_REGISTRY, bitsPerEntry), - nmsBits, - palette - ); - if (biomes == null) { - IdMap> biomeHolderIdMap = biomeRegistry.asHolderIdMap(); - biomes = new PalettedContainer<>( - biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES, - null - ); - } - - return new LevelChunkSection(layer, blockStatePalettedContainer, biomes); - } catch (final Throwable e) { - throw e; - } finally { - Arrays.fill(blockToPalette, Integer.MAX_VALUE); - Arrays.fill(paletteToBlock, Integer.MAX_VALUE); - Arrays.fill(blockStates, 0); - Arrays.fill(blocksCopy, 0); - } - } - - @SuppressWarnings("deprecation") // Only deprecated in paper - private static LevelChunkSection newChunkSection( - int layer, - Registry biomeRegistry, - @Nullable PalettedContainer> biomes - ) { - if (biomes == null) { - return new LevelChunkSection(layer, biomeRegistry); - } - PalettedContainer dataPaletteBlocks = new PalettedContainer<>( - Block.BLOCK_STATE_REGISTRY, - Blocks.AIR.defaultBlockState(), - PalettedContainer.Strategy.SECTION_STATES, - null - ); - return new LevelChunkSection(layer, dataPaletteBlocks, biomes); - } - - public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { - try { - fieldBiomes.set(section, biomes); - } catch (IllegalAccessException e) { - LOGGER.error("Could not set biomes to chunk section", e); - } - } - - /** - * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. - */ - public static PalettedContainer> getBiomePalettedContainer( - BiomeType[] biomes, - IdMap> biomeRegistry - ) { - if (biomes == null) { - return null; - } - BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); - // Don't stream this as typically will see 1-4 biomes; stream overhead is large for the small length - Map> palette = new HashMap<>(); - for (BiomeType biomeType : new LinkedList<>(Arrays.asList(biomes))) { - Holder biome; - if (biomeType == null) { - biome = biomeRegistry.byId(adapter.getInternalBiomeId(BiomeTypes.PLAINS)); - } else { - biome = biomeRegistry.byId(adapter.getInternalBiomeId(biomeType)); - } - palette.put(biomeType, biome); - } - int biomeCount = palette.size(); - int bitsPerEntry = MathMan.log2nlz(biomeCount - 1); - Object configuration = PalettedContainer.Strategy.SECTION_STATES.getConfiguration( - new FakeIdMapBiome(biomeCount), - bitsPerEntry - ); - if (bitsPerEntry > 3) { - bitsPerEntry = MathMan.log2nlz(biomeRegistry.size() - 1); - } - PalettedContainer> biomePalettedContainer = new PalettedContainer<>( - biomeRegistry, - biomeRegistry.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES, - null - ); - - final Palette> biomePalette; - if (bitsPerEntry == 0) { - biomePalette = new SingleValuePalette<>( - biomePalettedContainer.registry, - biomePalettedContainer, - new ArrayList<>(palette.values()) // Must be modifiable - ); - } else if (bitsPerEntry == 4) { - biomePalette = LinearPalette.create( - 4, - biomePalettedContainer.registry, - biomePalettedContainer, - new ArrayList<>(palette.values()) // Must be modifiable - ); - } else if (bitsPerEntry < 9) { - biomePalette = HashMapPalette.create( - bitsPerEntry, - biomePalettedContainer.registry, - biomePalettedContainer, - new ArrayList<>(palette.values()) // Must be modifiable - ); - } else { - biomePalette = GlobalPalette.create( - bitsPerEntry, - biomePalettedContainer.registry, - biomePalettedContainer, - null // unused - ); - } - - int bitsPerEntryNonZero = Math.max(bitsPerEntry, 1); // We do want to use zero sometimes - final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntryNonZero); - final int arrayLength = MathMan.ceilZero(64f / blocksPerLong); - - - BitStorage bitStorage = bitsPerEntry == 0 ? new ZeroBitStorage(64) : new SimpleBitStorage( - bitsPerEntry, - 64, - new long[arrayLength] - ); - - try { - Object data = dataConstructor.newInstance(configuration, bitStorage, biomePalette); - fieldData.set(biomePalettedContainer, data); - int index = 0; - for (int y = 0; y < 4; y++) { - for (int z = 0; z < 4; z++) { - for (int x = 0; x < 4; x++, index++) { - BiomeType biomeType = biomes[index]; - if (biomeType == null) { - continue; - } - Holder biome = biomeRegistry.byId(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)); - if (biome == null) { - continue; - } - biomePalettedContainer.set(x, y, z, biome); - } - } - } - } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - return biomePalettedContainer; - } - - public static void clearCounts(final LevelChunkSection section) throws IllegalAccessException { - fieldTickingFluidCount.setShort(section, (short) 0); - fieldTickingBlockCount.setShort(section, (short) 0); - } - - public static BiomeType adapt(Holder biome, LevelAccessor levelAccessor) { - final Registry biomeRegistry = levelAccessor.registryAccess().registryOrThrow(BIOME); - if (biomeRegistry.getKey(biome.value()) == null) { - return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN - : null; - } - return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString()); - } - - static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { - try { - if (levelChunk.loaded || levelChunk.level.isClientSide()) { - BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos()); - if (blockEntity != null) { - if (!levelChunk.level.isClientSide) { - methodRemoveGameEventListener.invoke(levelChunk, beacon, levelChunk.level); - } - fieldRemove.set(beacon, true); - } - } - methodremoveTickingBlockEntity.invoke(levelChunk, beacon.getBlockPos()); - } catch (Throwable throwable) { - throwable.printStackTrace(); - } - } - - static List getEntities(LevelChunk chunk) { - ExceptionCollector collector = new ExceptionCollector<>(); - if (PaperLib.isPaper()) { - if (POST_CHUNK_REWRITE) { - try { - //noinspection unchecked - return (List) PAPER_CHUNK_GEN_ALL_ENTITIES.invoke(chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ)); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=true]", e); - } - } - try { - EntityList entityList = (EntityList) LEVEL_CHUNK_ENTITIES.get(chunk); - return List.of(entityList.getRawData()); - } catch (IllegalAccessException e) { - collector.add(new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=false]", e)); - // fall through - } - } - try { - //noinspection unchecked - return ((PersistentEntitySectionManager) (SERVER_LEVEL_ENTITY_MANAGER.get(chunk.level))).getEntities(chunk.getPos()); - } catch (IllegalAccessException e) { - collector.add(new RuntimeException("Failed to lookup entities [PAPER=false]", e)); - } - collector.throwIfPresent(); - return List.of(); - } - - public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) { - boolean isVillager = entity instanceof AbstractVillager && !Fawe.isMainThread(); - boolean unset = false; - if (isVillager) { - try { - if (fieldOffers.get(entity) != null) { - fieldOffers.set(entity, OFFERS); - unset = true; - } - } catch (IllegalAccessException e) { - throw new RuntimeException("Failed to set offers field to villager to avoid async catcher.", e); - } - } - entity.save(compoundTag); - if (unset) { - try { - fieldOffers.set(entity, null); - } catch (IllegalAccessException e) { - throw new RuntimeException("Failed to set offers field to null again on villager.", e); - } - } - } - - record FakeIdMapBlock(int size) implements IdMap { - - @Override - public int getId(final net.minecraft.world.level.block.state.BlockState entry) { - return 0; - } - - @Nullable - @Override - public net.minecraft.world.level.block.state.BlockState byId(final int index) { - return null; - } - - @Nonnull - @Override - public Iterator iterator() { - return Collections.emptyIterator(); - } - - } - - record FakeIdMapBiome(int size) implements IdMap { - - @Override - public int getId(final Biome entry) { - return 0; - } - - @Nullable - @Override - public Biome byId(final int index) { - return null; - } - - @Nonnull - @Override - public Iterator iterator() { - return Collections.emptyIterator(); - } - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPostProcessor.java deleted file mode 100644 index ac10f2c0a..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPostProcessor.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.ProcessorScope; -import com.fastasyncworldedit.core.queue.IBatchProcessor; -import com.fastasyncworldedit.core.queue.IChunk; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.fastasyncworldedit.core.registry.state.PropertyKey; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypes; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.Fluids; - -import javax.annotation.Nullable; - -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } - - @SuppressWarnings("deprecation") - @Override - public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final IChunkSet iChunkSet) { - boolean tickFluid = Settings.settings().EXPERIMENTAL.ALLOW_TICK_FLUIDS; - // The PostProcessor shouldn't be added, but just in case - if (!tickFluid) { - return; - } - PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; - layer: - for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); - if (set == null) { - // No edit means no need to process - continue; - } - char[] get = null; - for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; - boolean fromGet = false; // Used for liquids - if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { - if (get == null) { - get = getBlocks.load(layer); - } - // If this is null, then it's because we're loading a layer in the range of 0->15, but blocks aren't - // actually being set - if (get == null) { - continue layer; - } - fromGet = true; - ordinal = replacedOrdinal = get[i]; - } - if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { - continue; - } else if (!fromGet) { // if fromGet, don't do the same again - if (get == null) { - get = getBlocks.load(layer); - } - replacedOrdinal = get[i]; - } - boolean ticking = BlockTypesCache.ticking[ordinal]; - boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; - boolean replacedWasLiquid = false; - BlockState replacedState = null; - if (!ticking) { - // If the block being replaced was not ticking, it cannot be a liquid - if (!replacedWasTicking) { - continue; - } - // If the block being replaced is not fluid, we do not need to worry - if (!(replacedWasLiquid = - (replacedState = BlockState.getFromOrdinal(replacedOrdinal)).getMaterial().isLiquid())) { - continue; - } - } - BlockState state = BlockState.getFromOrdinal(ordinal); - boolean liquid = state.getMaterial().isLiquid(); - int x = i & 15; - int y = (i >> 8) & 15; - int z = (i >> 4) & 15; - BlockPos position = new BlockPos((chunk.getX() << 4) + x, (layer << 4) + y, (chunk.getZ() << 4) + z); - if (liquid || replacedWasLiquid) { - if (liquid) { - addFluid(getBlocks.serverLevel, state, position); - continue; - } - // If the replaced fluid (is?) adjacent to water. Do not bother to check adjacent chunks(sections) as this - // may be time consuming. Chances are any fluid blocks in adjacent chunks are being replaced or will end up - // being ticked anyway. We only need it to be "hit" once. - if (!wasAdjacentToWater(get, set, i, x, y, z)) { - continue; - } - addFluid(getBlocks.serverLevel, replacedState, position); - } - } - } - } - - @Nullable - @Override - public Extent construct(final Extent child) { - throw new UnsupportedOperationException("Processing only"); - } - - @Override - public ProcessorScope getScope() { - return ProcessorScope.READING_SET_BLOCKS; - } - - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - - @SuppressWarnings("deprecation") - private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { - Fluid type; - if (replacedState.getBlockType() == BlockTypes.LAVA) { - type = (int) replacedState.getState(PropertyKey.LEVEL) == 0 ? Fluids.LAVA : Fluids.FLOWING_LAVA; - } else { - type = (int) replacedState.getState(PropertyKey.LEVEL) == 0 ? Fluids.WATER : Fluids.FLOWING_WATER; - } - serverLevel.scheduleTick( - position, - type, - type.getTickDelay(serverLevel) - ); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighter.java deleted file mode 100644 index b1e0c5772..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighter.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter; -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.TicketType; -import net.minecraft.util.Unit; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.chunk.ChunkStatus; - -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; -import java.util.function.IntConsumer; - -public class PaperweightStarlightRelighter extends StarlightRelighter { - - private static final TicketType FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0); - private static final int LIGHT_LEVEL = ChunkMap.MAX_VIEW_DISTANCE + ChunkStatus.getDistance(ChunkStatus.LIGHT); - - public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent queue) { - super(serverLevel, queue); - } - - @Override - protected ChunkPos createChunkPos(final long chunkKey) { - return new ChunkPos(chunkKey); - } - - @Override - protected long asLong(final int chunkX, final int chunkZ) { - return ChunkPos.asLong(chunkX, chunkZ); - } - - @Override - protected CompletableFuture chunkLoadFuture(final ChunkPos chunkPos) { - return serverLevel.getWorld().getChunkAtAsync(chunkPos.x, chunkPos.z) - .thenAccept(c -> serverLevel.getChunkSource().addTicketAtLevel( - FAWE_TICKET, - chunkPos, - LIGHT_LEVEL, - Unit.INSTANCE - )); - } - - protected void invokeRelight( - Set coords, - Consumer chunkCallback, - IntConsumer processCallback - ) { - try { - serverLevel.getChunkSource().getLightEngine().relight(coords, chunkCallback, processCallback); - } catch (Exception e) { - LOGGER.error("Error occurred on relighting", e); - } - } - - /* - * Allow the server to unload the chunks again. - * Also, if chunk packets are sent delayed, we need to do that here - */ - protected void postProcessChunks(Set coords) { - boolean delay = Settings.settings().LIGHTING.DELAY_PACKET_SENDING; - for (ChunkPos pos : coords) { - int x = pos.x; - int z = pos.z; - if (delay) { // we still need to send the block changes of that chunk - PaperweightPlatformAdapter.sendChunk(pos, serverLevel, x, z); - } - serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE); - } - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighterFactory.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighterFactory.java deleted file mode 100644 index 78c623c7a..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightStarlightRelighterFactory.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3; - -import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter; -import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode; -import com.fastasyncworldedit.core.extent.processor.lighting.Relighter; -import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import com.sk89q.worldedit.world.World; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; - -import javax.annotation.Nonnull; - -public class PaperweightStarlightRelighterFactory implements RelighterFactory { - - @Override - public @Nonnull Relighter createRelighter(RelightMode relightMode, World world, IQueueExtent queue) { - org.bukkit.World w = Bukkit.getWorld(world.getName()); - if (w == null) { - return NullRelighter.INSTANCE; - } - return new PaperweightStarlightRelighter(((CraftWorld) w).getHandle(), queue); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/nbt/PaperweightLazyCompoundTag.java deleted file mode 100644 index 0026c4c67..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/nbt/PaperweightLazyCompoundTag.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.nbt; - -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.LazyCompoundTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import net.minecraft.nbt.NumericTag; -import org.enginehub.linbus.tree.LinCompoundTag; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; - -public class PaperweightLazyCompoundTag extends LazyCompoundTag { - - private final Supplier compoundTagSupplier; - private CompoundTag compoundTag; - - public PaperweightLazyCompoundTag(Supplier compoundTagSupplier) { - super(new HashMap<>()); - this.compoundTagSupplier = compoundTagSupplier; - } - - public PaperweightLazyCompoundTag(net.minecraft.nbt.CompoundTag compoundTag) { - this(() -> compoundTag); - } - - public net.minecraft.nbt.CompoundTag get() { - return compoundTagSupplier.get(); - } - - @Override - @SuppressWarnings("unchecked") - public Map> getValue() { - if (compoundTag == null) { - compoundTag = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(compoundTagSupplier.get()); - } - return compoundTag.getValue(); - } - - @Override - public LinCompoundTag toLinTag() { - getValue(); - return compoundTag.toLinTag(); - } - - public boolean containsKey(String key) { - return compoundTagSupplier.get().contains(key); - } - - public byte[] getByteArray(String key) { - return compoundTagSupplier.get().getByteArray(key); - } - - public byte getByte(String key) { - return compoundTagSupplier.get().getByte(key); - } - - public double getDouble(String key) { - return compoundTagSupplier.get().getDouble(key); - } - - public double asDouble(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsDouble(); - } - return 0; - } - - public float getFloat(String key) { - return compoundTagSupplier.get().getFloat(key); - } - - public int[] getIntArray(String key) { - return compoundTagSupplier.get().getIntArray(key); - } - - public int getInt(String key) { - return compoundTagSupplier.get().getInt(key); - } - - public int asInt(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsInt(); - } - return 0; - } - - @SuppressWarnings("unchecked") - public List> getList(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof net.minecraft.nbt.ListTag nbtList) { - ArrayList> list = new ArrayList<>(); - for (net.minecraft.nbt.Tag elem : nbtList) { - if (elem instanceof net.minecraft.nbt.CompoundTag compoundTag) { - list.add(new PaperweightLazyCompoundTag(compoundTag)); - } else { - list.add(WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(elem)); - } - } - return list; - } - return Collections.emptyList(); - } - - @SuppressWarnings("unchecked") - public ListTag getListTag(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof net.minecraft.nbt.ListTag) { - return (ListTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(tag); - } - return new ListTag(StringTag.class, Collections.emptyList()); - } - - @SuppressWarnings("unchecked") - public > List getList(String key, Class listType) { - ListTag listTag = getListTag(key); - if (listTag.getType().equals(listType)) { - return (List) listTag.getValue(); - } else { - return Collections.emptyList(); - } - } - - public long[] getLongArray(String key) { - return compoundTagSupplier.get().getLongArray(key); - } - - public long getLong(String key) { - return compoundTagSupplier.get().getLong(key); - } - - public long asLong(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsLong(); - } - return 0; - } - - public short getShort(String key) { - return compoundTagSupplier.get().getShort(key); - } - - public String getString(String key) { - return compoundTagSupplier.get().getString(key); - } - - @Override - public String toString() { - return compoundTagSupplier.get().toString(); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java deleted file mode 100644 index 17b354535..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/regen/PaperweightRegen.java +++ /dev/null @@ -1,596 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.regen; - -import com.fastasyncworldedit.bukkit.adapter.Regenerator; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.queue.IChunkCache; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.util.ReflectionUtils; -import com.fastasyncworldedit.core.util.TaskManager; -import com.google.common.collect.ImmutableList; -import com.mojang.datafixers.util.Either; -import com.mojang.serialization.Lifecycle; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R3.PaperweightGetBlocks; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.world.RegenOptions; -import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.Registries; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ChunkTaskPriorityQueueSorter.Message; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ThreadedLevelLightEngine; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.util.thread.ProcessorHandle; -import net.minecraft.util.thread.ProcessorMailbox; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.LevelSettings; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.FixedBiomeSource; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.chunk.ChunkGeneratorStructureState; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.ProtoChunk; -import net.minecraft.world.level.chunk.UpgradeData; -import net.minecraft.world.level.dimension.LevelStem; -import net.minecraft.world.level.levelgen.FlatLevelSource; -import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; -import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; -import net.minecraft.world.level.levelgen.WorldOptions; -import net.minecraft.world.level.levelgen.blending.BlendingData; -import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; -import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraft.world.level.storage.PrimaryLevelData; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.craftbukkit.v1_19_R3.CraftServer; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R3.generator.CustomChunkGenerator; -import org.bukkit.generator.BiomeProvider; -import org.bukkit.generator.BlockPopulator; - -import javax.annotation.Nullable; -import java.lang.reflect.Field; -import java.nio.file.Path; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.OptionalLong; -import java.util.Random; -import java.util.concurrent.CompletableFuture; -import java.util.function.BooleanSupplier; -import java.util.function.Supplier; - -import static net.minecraft.core.registries.Registries.BIOME; - -public class PaperweightRegen extends Regenerator { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private static final Field serverWorldsField; - private static final Field paperConfigField; - private static final Field flatBedrockField; - private static final Field generatorSettingFlatField; - private static final Field generatorSettingBaseSupplierField; - private static final Field delegateField; - private static final Field chunkSourceField; - private static final Field generatorStructureStateField; - private static final Field ringPositionsField; - private static final Field hasGeneratedPositionsField; - - //list of chunk stati in correct order without FULL - private static final Map chunkStati = new LinkedHashMap<>(); - - static { - chunkStati.put(ChunkStatus.EMPTY, Concurrency.FULL); // empty: radius -1, does nothing - chunkStati.put(ChunkStatus.STRUCTURE_STARTS, Concurrency.NONE); // structure starts: uses unsynchronized maps - chunkStati.put( - ChunkStatus.STRUCTURE_REFERENCES, - Concurrency.FULL - ); // structure refs: radius 8, but only writes to current chunk - chunkStati.put(ChunkStatus.BIOMES, Concurrency.FULL); // biomes: radius 0 - chunkStati.put(ChunkStatus.NOISE, Concurrency.RADIUS); // noise: radius 8 - chunkStati.put(ChunkStatus.SURFACE, Concurrency.NONE); // surface: radius 0, requires NONE - chunkStati.put(ChunkStatus.CARVERS, Concurrency.NONE); // carvers: radius 0, but RADIUS and FULL change results - chunkStati.put( - ChunkStatus.LIQUID_CARVERS, - Concurrency.NONE - ); // liquid carvers: radius 0, but RADIUS and FULL change results - chunkStati.put(ChunkStatus.FEATURES, Concurrency.NONE); // features: uses unsynchronized maps - chunkStati.put( - ChunkStatus.LIGHT, - Concurrency.FULL - ); // light: radius 1, but no writes to other chunks, only current chunk - chunkStati.put(ChunkStatus.SPAWN, Concurrency.FULL); // spawn: radius 0 - chunkStati.put(ChunkStatus.HEIGHTMAPS, Concurrency.FULL); // heightmaps: radius 0 - - try { - serverWorldsField = CraftServer.class.getDeclaredField("worlds"); - serverWorldsField.setAccessible(true); - - Field tmpPaperConfigField; - Field tmpFlatBedrockField; - try { //only present on paper - tmpPaperConfigField = Level.class.getDeclaredField("paperConfig"); - tmpPaperConfigField.setAccessible(true); - - tmpFlatBedrockField = tmpPaperConfigField.getType().getDeclaredField("generateFlatBedrock"); - tmpFlatBedrockField.setAccessible(true); - } catch (Exception e) { - tmpPaperConfigField = null; - tmpFlatBedrockField = null; - } - paperConfigField = tmpPaperConfigField; - flatBedrockField = tmpFlatBedrockField; - - generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName( - "settings", "e")); - generatorSettingBaseSupplierField.setAccessible(true); - - generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "d")); - generatorSettingFlatField.setAccessible(true); - - delegateField = CustomChunkGenerator.class.getDeclaredField("delegate"); - delegateField.setAccessible(true); - - chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "H")); - chunkSourceField.setAccessible(true); - - generatorStructureStateField = ChunkMap.class.getDeclaredField(Refraction.pickName("chunkGeneratorState", "w")); - generatorStructureStateField.setAccessible(true); - - ringPositionsField = ChunkGeneratorStructureState.class.getDeclaredField(Refraction.pickName("ringPositions", "g")); - ringPositionsField.setAccessible(true); - - hasGeneratedPositionsField = ChunkGeneratorStructureState.class.getDeclaredField( - Refraction.pickName("hasGeneratedPositions", "h") - ); - hasGeneratedPositionsField.setAccessible(true); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - //runtime - private ServerLevel originalServerWorld; - private ServerChunkCache originalChunkProvider; - private ServerLevel freshWorld; - private ServerChunkCache freshChunkProvider; - private LevelStorageSource.LevelStorageAccess session; - private StructureTemplateManager structureTemplateManager; - private ThreadedLevelLightEngine threadedLevelLightEngine; - private ChunkGenerator chunkGenerator; - - private Path tempDir; - - private boolean generateFlatBedrock = false; - - public PaperweightRegen(org.bukkit.World originalBukkitWorld, Region region, Extent target, RegenOptions options) { - super(originalBukkitWorld, region, target, options); - } - - @Override - protected boolean prepare() { - this.originalServerWorld = ((CraftWorld) originalBukkitWorld).getHandle(); - originalChunkProvider = originalServerWorld.getChunkSource(); - - //flat bedrock? (only on paper) - if (paperConfigField != null) { - try { - generateFlatBedrock = flatBedrockField.getBoolean(paperConfigField.get(originalServerWorld)); - } catch (Exception ignored) { - } - } - - seed = options.getSeed().orElse(originalServerWorld.getSeed()); - chunkStati.forEach((s, c) -> super.chunkStatuses.put(new ChunkStatusWrap(s), c)); - - return true; - } - - @Override - @SuppressWarnings("unchecked") - protected boolean initNewWorld() throws Exception { - //world folder - tempDir = java.nio.file.Files.createTempDirectory("FastAsyncWorldEditWorldGen"); - - //prepare for world init (see upstream implementation for reference) - org.bukkit.World.Environment environment = originalBukkitWorld.getEnvironment(); - org.bukkit.generator.ChunkGenerator generator = originalBukkitWorld.getGenerator(); - LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(tempDir); - ResourceKey levelStemResourceKey = getWorldDimKey(environment); - session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey); - PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData; - - MinecraftServer server = originalServerWorld.getCraftServer().getServer(); - WorldOptions originalOpts = originalWorldData.worldGenOptions(); - WorldOptions newOpts = options.getSeed().isPresent() - ? originalOpts.withSeed(OptionalLong.of(seed)) - : originalOpts; - LevelSettings newWorldSettings = new LevelSettings( - "faweregentempworld", - originalWorldData.settings.gameType(), - originalWorldData.settings.hardcore(), - originalWorldData.settings.difficulty(), - originalWorldData.settings.allowCommands(), - originalWorldData.settings.gameRules(), - originalWorldData.settings.getDataConfiguration() - ); - - PrimaryLevelData.SpecialWorldProperty specialWorldProperty = - originalWorldData.isFlatWorld() - ? PrimaryLevelData.SpecialWorldProperty.FLAT - : originalWorldData.isDebugWorld() - ? PrimaryLevelData.SpecialWorldProperty.DEBUG - : PrimaryLevelData.SpecialWorldProperty.NONE; - PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, specialWorldProperty, Lifecycle.stable()); - - BiomeProvider biomeProvider = getBiomeProvider(); - - - //init world - freshWorld = Fawe.instance().getQueueHandler().sync((Supplier) () -> new ServerLevel( - server, - server.executor, - session, - newWorldData, - originalServerWorld.dimension(), - DedicatedServer.getServer().registryAccess().registry(Registries.LEVEL_STEM).orElseThrow() - .getOrThrow(levelStemResourceKey), - new RegenNoOpWorldLoadListener(), - originalServerWorld.isDebug(), - seed, - ImmutableList.of(), - false, - environment, - generator, - biomeProvider - ) { - - private final Holder singleBiome = options.hasBiomeType() ? DedicatedServer.getServer().registryAccess() - .registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow( - WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) - ) : null; - - @Override - public void tick(BooleanSupplier shouldKeepTicking) { //no ticking - } - - @Override - public Holder getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) { - if (options.hasBiomeType()) { - return singleBiome; - } - return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome( - biomeX, biomeY, biomeZ, getChunkSource().randomState().sampler() - ); - } - }).get(); - freshWorld.noSave = true; - removeWorldFromWorldsMap(); - newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name - if (paperConfigField != null) { - paperConfigField.set(freshWorld, originalServerWorld.paperConfig()); - } - - ChunkGenerator originalGenerator = originalChunkProvider.getGenerator(); - if (originalGenerator instanceof FlatLevelSource flatLevelSource) { - FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings(); - chunkGenerator = new FlatLevelSource(generatorSettingFlat); - } else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) { - Holder generatorSettingBaseSupplier = (Holder) generatorSettingBaseSupplierField.get( - originalGenerator); - BiomeSource biomeSource; - if (options.hasBiomeType()) { - - biomeSource = new FixedBiomeSource( - DedicatedServer.getServer().registryAccess() - .registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow( - WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) - ) - ); - } else { - biomeSource = originalGenerator.getBiomeSource(); - } - chunkGenerator = new NoiseBasedChunkGenerator( - biomeSource, - generatorSettingBaseSupplier - ); - } else if (originalGenerator instanceof CustomChunkGenerator customChunkGenerator) { - chunkGenerator = customChunkGenerator.getDelegate(); - } else { - LOGGER.error("Unsupported generator type {}", originalGenerator.getClass().getName()); - return false; - } - if (generator != null) { - chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator); - generateConcurrent = generator.isParallelCapable(); - } -// chunkGenerator.conf = freshWorld.spigotConfig; - Does not exist anymore, may need to be re-addressed - - freshChunkProvider = new ServerChunkCache( - freshWorld, - session, - server.getFixerUpper(), - server.getStructureManager(), - server.executor, - chunkGenerator, - freshWorld.spigotConfig.viewDistance, - freshWorld.spigotConfig.simulationDistance, - server.forceSynchronousWrites(), - new RegenNoOpWorldLoadListener(), - (chunkCoordIntPair, state) -> { - }, - () -> server.overworld().getDataStorage() - ) { - // redirect to LevelChunks created in #createChunks - @Override - public ChunkAccess getChunk(int x, int z, ChunkStatus chunkstatus, boolean create) { - ChunkAccess chunkAccess = getChunkAt(x, z); - if (chunkAccess == null && create) { - chunkAccess = createChunk(getProtoChunkAt(x, z)); - } - return chunkAccess; - } - }; - - if (seed == originalOpts.seed() && !options.hasBiomeType()) { - // Optimisation for needless ring position calculation when the seed and biome is the same. - ChunkGeneratorStructureState state = (ChunkGeneratorStructureState) generatorStructureStateField.get(originalChunkProvider.chunkMap); - boolean hasGeneratedPositions = hasGeneratedPositionsField.getBoolean(state); - if (hasGeneratedPositions) { - Map>> origPositions = - (Map>>) ringPositionsField.get(state); - Map>> copy = new Object2ObjectArrayMap<>( - origPositions); - ChunkGeneratorStructureState newState = (ChunkGeneratorStructureState) generatorStructureStateField.get(freshChunkProvider.chunkMap); - ringPositionsField.set(newState, copy); - hasGeneratedPositionsField.setBoolean(newState, true); - } - } - - - chunkSourceField.set(freshWorld, freshChunkProvider); - //let's start then - structureTemplateManager = server.getStructureManager(); - threadedLevelLightEngine = new NoOpLightEngine(freshChunkProvider); - - return true; - } - - @Override - protected void cleanup() { - try { - session.close(); - } catch (Exception ignored) { - } - - //shutdown chunk provider - try { - Fawe.instance().getQueueHandler().sync(() -> { - try { - freshChunkProvider.close(false); - } catch (Exception e) { - throw new RuntimeException(e); - } - }); - } catch (Exception ignored) { - } - - //remove world from server - try { - Fawe.instance().getQueueHandler().sync(this::removeWorldFromWorldsMap); - } catch (Exception ignored) { - } - - //delete directory - try { - SafeFiles.tryHardToDeleteDir(tempDir); - } catch (Exception ignored) { - } - } - - @Override - protected ProtoChunk createProtoChunk(int x, int z) { - return new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld, - this.freshWorld.registryAccess().registryOrThrow(BIOME), null - ); - } - - @Override - protected LevelChunk createChunk(ProtoChunk protoChunk) { - return new LevelChunk( - freshWorld, - protoChunk, - null // we don't want to add entities - ); - } - - @Override - protected ChunkStatusWrap getFullChunkStatus() { - return new ChunkStatusWrap(ChunkStatus.FULL); - } - - @Override - protected List getBlockPopulators() { - return originalServerWorld.getWorld().getPopulators(); - } - - @Override - protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) { - // BlockPopulator#populate has to be called synchronously for TileEntity access - TaskManager.taskManager().task(() -> { - final CraftWorld world = freshWorld.getWorld(); - final Chunk chunk = world.getChunkAt(levelChunk.locX, levelChunk.locZ); - blockPopulator.populate(world, random, chunk); - }); - } - - @Override - protected IChunkCache initSourceQueueCache() { - return (chunkX, chunkZ) -> new PaperweightGetBlocks(freshWorld, chunkX, chunkZ) { - @Override - public LevelChunk ensureLoaded(ServerLevel nmsWorld, int x, int z) { - return getChunkAt(x, z); - } - }; - } - - //util - @SuppressWarnings("unchecked") - private void removeWorldFromWorldsMap() { - Fawe.instance().getQueueHandler().sync(() -> { - try { - Map map = (Map) serverWorldsField.get(Bukkit.getServer()); - map.remove("faweregentempworld"); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - }); - } - - private ResourceKey getWorldDimKey(org.bukkit.World.Environment env) { - return switch (env) { - case NETHER -> LevelStem.NETHER; - case THE_END -> LevelStem.END; - default -> LevelStem.OVERWORLD; - }; - } - - private static class RegenNoOpWorldLoadListener implements ChunkProgressListener { - - private RegenNoOpWorldLoadListener() { - } - - @Override - public void updateSpawnPos(ChunkPos spawnPos) { - } - - @Override - public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) { - } - - @Override - public void start() { - - } - - @Override - public void stop() { - } - - // TODO Paper only(?) @Override - public void setChunkRadius(int radius) { - } - - } - - private class FastProtoChunk extends ProtoChunk { - - public FastProtoChunk( - final ChunkPos pos, - final UpgradeData upgradeData, - final LevelHeightAccessor world, - final Registry biomeRegistry, - @Nullable final BlendingData blendingData - ) { - super(pos, upgradeData, world, biomeRegistry, blendingData); - } - - // avoid warning on paper - - // compatibility with spigot - - public boolean generateFlatBedrock() { - return generateFlatBedrock; - } - - // no one will ever see the entities! - @Override - public List getEntities() { - return Collections.emptyList(); - } - - } - - protected class ChunkStatusWrap extends ChunkStatusWrapper { - - private final ChunkStatus chunkStatus; - - public ChunkStatusWrap(ChunkStatus chunkStatus) { - this.chunkStatus = chunkStatus; - } - - @Override - public int requiredNeighborChunkRadius() { - return chunkStatus.getRange(); - } - - @Override - public String name() { - return chunkStatus.getName(); - } - - @Override - public CompletableFuture processChunk(List accessibleChunks) { - return chunkStatus.generate( - Runnable::run, // TODO revisit, we might profit from this somehow? - freshWorld, - chunkGenerator, - structureTemplateManager, - threadedLevelLightEngine, - c -> CompletableFuture.completedFuture(Either.left(c)), - accessibleChunks, - true - ); - } - - } - - /** - * A light engine that does nothing. As light is calculated after pasting anyway, we can avoid - * work this way. - */ - static class NoOpLightEngine extends ThreadedLevelLightEngine { - - private static final ProcessorMailbox MAILBOX = ProcessorMailbox.create(task -> { - }, "fawe-no-op"); - private static final ProcessorHandle> HANDLE = ProcessorHandle.of("fawe-no-op", m -> { - }); - - public NoOpLightEngine(final ServerChunkCache chunkProvider) { - super(chunkProvider, chunkProvider.chunkMap, false, MAILBOX, HANDLE); - } - - @Override - public CompletableFuture retainData(final ChunkAccess chunk) { - return CompletableFuture.completedFuture(chunk); - } - - @Override - public CompletableFuture lightChunk(final ChunkAccess chunk, final boolean excludeBlocks) { - return CompletableFuture.completedFuture(chunk); - } - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts deleted file mode 100644 index 51438592a..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension - -plugins { - java -} - -applyPaperweightAdapterConfiguration() - -repositories { - gradlePluginPortal() -} - -dependencies { - // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.1-R0.1-SNAPSHOT - the().paperDevBundle("1.20.1-R0.1-20230921.165944-178") - compileOnly(libs.paperlib) -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java deleted file mode 100644 index 0cecbb45b..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java +++ /dev/null @@ -1,1131 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R1; - -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Sets; -import com.google.common.util.concurrent.Futures; -import com.mojang.datafixers.util.Either; -import com.mojang.serialization.Lifecycle; -import com.sk89q.jnbt.NBTConstants; -import com.sk89q.worldedit.WorldEditException; -import com.sk89q.worldedit.blocks.BaseItem; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.PaperweightPlatformAdapter; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.extension.platform.Watchdog; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.math.BlockVector2; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.registry.state.BooleanProperty; -import com.sk89q.worldedit.registry.state.DirectionalProperty; -import com.sk89q.worldedit.registry.state.EnumProperty; -import com.sk89q.worldedit.registry.state.IntegerProperty; -import com.sk89q.worldedit.registry.state.Property; -import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.concurrency.LazyReference; -import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; -import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.world.DataFixer; -import com.sk89q.worldedit.world.RegenOptions; -import com.sk89q.worldedit.world.biome.BiomeCategory; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockStateHolder; -import com.sk89q.worldedit.world.block.BlockType; -import com.sk89q.worldedit.world.block.BlockTypes; -import com.sk89q.worldedit.world.item.ItemType; -import net.minecraft.Util; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.HolderSet; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; -import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.util.StringRepresentable; -import net.minecraft.util.thread.BlockableEventLoop; -import net.minecraft.world.Clearable; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.context.UseOnContext; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.LevelSettings; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.StructureBlockEntity; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.dimension.LevelStem; -import net.minecraft.world.level.levelgen.WorldOptions; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraft.world.level.storage.PrimaryLevelData; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.Vec3; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World.Environment; -import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.v1_20_R1.CraftServer; -import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_20_R1.util.CraftMagicNumbers; -import org.bukkit.entity.Player; -import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; -import org.bukkit.generator.ChunkGenerator; -import org.enginehub.linbus.common.LinTagId; -import org.enginehub.linbus.tree.LinByteArrayTag; -import org.enginehub.linbus.tree.LinByteTag; -import org.enginehub.linbus.tree.LinCompoundTag; -import org.enginehub.linbus.tree.LinDoubleTag; -import org.enginehub.linbus.tree.LinEndTag; -import org.enginehub.linbus.tree.LinFloatTag; -import org.enginehub.linbus.tree.LinIntArrayTag; -import org.enginehub.linbus.tree.LinIntTag; -import org.enginehub.linbus.tree.LinListTag; -import org.enginehub.linbus.tree.LinLongArrayTag; -import org.enginehub.linbus.tree.LinLongTag; -import org.enginehub.linbus.tree.LinShortTag; -import org.enginehub.linbus.tree.LinStringTag; -import org.enginehub.linbus.tree.LinTag; -import org.enginehub.linbus.tree.LinTagType; -import org.spigotmc.SpigotConfig; -import org.spigotmc.WatchdogThread; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.OptionalInt; -import java.util.OptionalLong; -import java.util.Set; -import java.util.TreeMap; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -public final class PaperweightAdapter implements BukkitImplAdapter { - - private final Logger logger = Logger.getLogger(getClass().getCanonicalName()); - - private final Field serverWorldsField; - private final Method getChunkFutureMethod; - private final Field chunkProviderExecutorField; - private final Watchdog watchdog; - - // ------------------------------------------------------------------------ - // Code that may break between versions of Minecraft - // ------------------------------------------------------------------------ - - public PaperweightAdapter() throws NoSuchFieldException, NoSuchMethodException { - // A simple test - CraftServer.class.cast(Bukkit.getServer()); - - int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion(); - if (dataVersion != 3463 && dataVersion != 3465) { - throw new UnsupportedClassVersionError("Not 1.20(.1)!"); - } - - serverWorldsField = CraftServer.class.getDeclaredField("worlds"); - serverWorldsField.setAccessible(true); - - getChunkFutureMethod = ServerChunkCache.class.getDeclaredMethod( - Refraction.pickName("getChunkFutureMainThread", "c"), - int.class, int.class, ChunkStatus.class, boolean.class - ); - getChunkFutureMethod.setAccessible(true); - - chunkProviderExecutorField = ServerChunkCache.class.getDeclaredField( - Refraction.pickName("mainThreadProcessor", "g") - ); - chunkProviderExecutorField.setAccessible(true); - - new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this).buildUnoptimized(); - - Watchdog watchdog; - try { - Class.forName("org.spigotmc.WatchdogThread"); - watchdog = new SpigotWatchdog(); - } catch (ClassNotFoundException | NoSuchFieldException e) { - try { - watchdog = new MojangWatchdog(((CraftServer) Bukkit.getServer()).getServer()); - } catch (NoSuchFieldException ex) { - watchdog = null; - } - } - this.watchdog = watchdog; - - try { - Class.forName("org.spigotmc.SpigotConfig"); - SpigotConfig.config.set("world-settings.faweregentempworld.verbose", false); - } catch (ClassNotFoundException ignored) { - } - } - - @Override - public DataFixer getDataFixer() { - return PaperweightDataConverters.INSTANCE; - } - - /** - * Read the given NBT data into the given tile entity. - * - * @param tileEntity the tile entity - * @param tag the tag - */ - static void readTagIntoTileEntity(net.minecraft.nbt.CompoundTag tag, BlockEntity tileEntity) { - tileEntity.load(tag); - tileEntity.setChanged(); - } - - /** - * Get the ID string of the given entity. - * - * @param entity the entity - * @return the entity ID - */ - private static String getEntityId(Entity entity) { - return EntityType.getKey(entity.getType()).toString(); - } - - /** - * Create an entity using the given entity ID. - * - * @param id the entity ID - * @param world the world - * @return an entity or null - */ - @Nullable - private static Entity createEntityFromId(String id, net.minecraft.world.level.Level world) { - return EntityType.byString(id).map(t -> t.create(world)).orElse(null); - } - - /** - * Write the given NBT data into the given entity. - * - * @param entity the entity - * @param tag the tag - */ - private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) { - entity.load(tag); - } - - /** - * Write the entity's NBT data to the given tag. - * - * @param entity the entity - * @param tag the tag - */ - private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag tag) { - //FAWE start - avoid villager async catcher - PaperweightPlatformAdapter.readEntityIntoTag(entity, tag); - //FAWE end - } - - private static Block getBlockFromType(BlockType blockType) { - - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK).get(ResourceLocation.tryParse(blockType.id())); - } - - private static Item getItemFromType(ItemType itemType) { - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(itemType.id())); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockData data) { - net.minecraft.world.level.block.state.BlockState state = ((CraftBlockData) data).getState(); - int combinedId = Block.getId(state); - return combinedId == 0 && state.getBlock() != Blocks.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockState state) { - Block mcBlock = getBlockFromType(state.getBlockType()); - net.minecraft.world.level.block.state.BlockState newState = mcBlock.defaultBlockState(); - Map, Object> states = state.getStates(); - newState = applyProperties(mcBlock.getStateDefinition(), newState, states); - final int combinedId = Block.getId(newState); - return combinedId == 0 && state.getBlockType() != BlockTypes.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId); - } - - public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - int internalId = Block.getId(blockState); - BlockState state = BlockStateIdAccess.getBlockStateById(internalId); - if (state == null) { - state = BukkitAdapter.adapt(CraftBlockData.createData(blockState)); - } - - return state; - } - - public BiomeType adapt(Biome biome) { - var mcBiome = ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getKey(biome); - if (mcBiome == null) { - return null; - } - return BiomeType.REGISTRY.get(mcBiome.toString()); - } - - public net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) { - int internalId = BlockStateIdAccess.getBlockStateId(blockState); - return Block.stateById(internalId); - } - - @Override - public BlockState getBlock(Location location) { - checkNotNull(location); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - int internalId = Block.getId(blockData); - BlockState state = BlockStateIdAccess.getBlockStateById(internalId); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - - return state; - } - - @Override - public BaseBlock getFullBlock(Location location) { - BlockState state = getBlock(location); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - - // Read the NBT data - BlockEntity te = chunk.getBlockEntity(blockPos); - if (te != null) { - net.minecraft.nbt.CompoundTag tag = te.saveWithId(); - return state.toBaseBlock((LinCompoundTag) toNativeLin(tag)); - } - - return state.toBaseBlock(); - } -/* - @Override - public boolean hasCustomBiomeSupport() { - return true; - } -*/ - private static final HashMap> biomeTypeToNMSCache = new HashMap<>(); - private static final HashMap, BiomeType> biomeTypeFromNMSCache = new HashMap<>(); - - /* @Override - public BiomeType getBiome(Location location) { - checkNotNull(location); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - - return biomeTypeFromNMSCache.computeIfAbsent(chunk.getNoiseBiome(x >> 2, y >> 2, z >> 2), b -> BiomeType.REGISTRY.get(b.unwrapKey().get().location().toString())); - } - - @Override - public void setBiome(Location location, BiomeType biome) { - checkNotNull(location); - checkNotNull(biome); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = craftWorld.getHandle(); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - chunk.setBiome(x >> 2, y >> 2, z >> 2, biomeTypeToNMSCache.computeIfAbsent(biome, b -> ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getHolderOrThrow(ResourceKey.create(Registries.BIOME, new ResourceLocation(b.getId()))))); - chunk.setUnsaved(true); - }*/ - - @Override - public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { - return new com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R1.PaperweightWorldNativeAccess(this, - new WeakReference<>(((CraftWorld) world).getHandle())); - } - - private static net.minecraft.core.Direction adapt(Direction face) { - switch (face) { - case NORTH: - return net.minecraft.core.Direction.NORTH; - case SOUTH: - return net.minecraft.core.Direction.SOUTH; - case WEST: - return net.minecraft.core.Direction.WEST; - case EAST: - return net.minecraft.core.Direction.EAST; - case DOWN: - return net.minecraft.core.Direction.DOWN; - case UP: - default: - return net.minecraft.core.Direction.UP; - } - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - private net.minecraft.world.level.block.state.BlockState applyProperties( - StateDefinition stateContainer, - net.minecraft.world.level.block.state.BlockState newState, - Map, Object> states - ) { - for (Map.Entry, Object> state : states.entrySet()) { - net.minecraft.world.level.block.state.properties.Property property = - stateContainer.getProperty(state.getKey().getName()); - Comparable value = (Comparable) state.getValue(); - // we may need to adapt this value, depending on the source prop - if (property instanceof DirectionProperty) { - Direction dir = (Direction) value; - value = adapt(dir); - } else if (property instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - String enumName = (String) value; - value = ((net.minecraft.world.level.block.state.properties.EnumProperty) property) - .getValue(enumName).orElseThrow(() -> - new IllegalStateException( - "Enum property " + property.getName() + " does not contain " + enumName - ) - ); - } - - newState = newState.setValue( - (net.minecraft.world.level.block.state.properties.Property) property, - (Comparable) value - ); - } - return newState; - } - - @Override - public BaseEntity getEntity(org.bukkit.entity.Entity entity) { - checkNotNull(entity); - - CraftEntity craftEntity = ((CraftEntity) entity); - Entity mcEntity = craftEntity.getHandle(); - - // Do not allow creating of passenger entity snapshots, passengers are included in the vehicle entity - if (mcEntity.isPassenger()) { - return null; - } - - String id = getEntityId(mcEntity); - - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - readEntityIntoTag(mcEntity, tag); - return new BaseEntity( - com.sk89q.worldedit.world.entity.EntityTypes.get(id), - LazyReference.from(() -> (LinCompoundTag) toNativeLin(tag)) - ); - } - - @Nullable - @Override - public org.bukkit.entity.Entity createEntity(Location location, BaseEntity state) { - checkNotNull(location); - checkNotNull(state); - - CraftWorld craftWorld = ((CraftWorld) location.getWorld()); - ServerLevel worldServer = craftWorld.getHandle(); - - Entity createdEntity = createEntityFromId(state.getType().id(), craftWorld.getHandle()); - - if (createdEntity != null) { - LinCompoundTag nativeTag = state.getNbt(); - if (nativeTag != null) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeLin(nativeTag); - for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - readTagIntoEntity(tag, createdEntity); - } - - createdEntity.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - - worldServer.addFreshEntity(createdEntity, SpawnReason.CUSTOM); - return createdEntity.getBukkitEntity(); - } else { - return null; - } - } - - // This removes all unwanted tags from the main entity and all its passengers - private void removeUnwantedEntityTagsRecursively(net.minecraft.nbt.CompoundTag tag) { - for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - - // Adapted from net.minecraft.world.entity.EntityType#loadEntityRecursive - if (tag.contains("Passengers", NBTConstants.TYPE_LIST)) { - net.minecraft.nbt.ListTag nbttaglist = tag.getList("Passengers", NBTConstants.TYPE_COMPOUND); - - for (int i = 0; i < nbttaglist.size(); ++i) { - removeUnwantedEntityTagsRecursively(nbttaglist.getCompound(i)); - } - } - } - - @Override - public Component getRichBlockName(BlockType blockType) { - return TranslatableComponent.of(getBlockFromType(blockType).getDescriptionId()); - } - - @Override - public Component getRichItemName(ItemType itemType) { - return TranslatableComponent.of(getItemFromType(itemType).getDescriptionId()); - } - - @Override - public Component getRichItemName(BaseItemStack itemStack) { - return TranslatableComponent.of(CraftItemStack.asNMSCopy(BukkitAdapter.adapt(itemStack)).getDescriptionId()); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private static final LoadingCache> PROPERTY_CACHE = CacheBuilder - .newBuilder() - .build(new CacheLoader<>() { - @Override - public Property load(net.minecraft.world.level.block.state.properties.Property state) { - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else if (state instanceof DirectionProperty) { - return new DirectionalProperty( - state.getName(), - new ArrayList<>((List) state - .getPossibleValues() - .stream() - .map(e -> Direction.valueOf(((StringRepresentable) e) - .getSerializedName() - .toUpperCase(Locale.ROOT))) - .toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - return new EnumProperty( - state.getName(), - new ArrayList<>((List) state - .getPossibleValues() - .stream() - .map(e -> ((StringRepresentable) e).getSerializedName()) - .toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); - } else { - throw new IllegalArgumentException("WorldEdit needs an update to support " + state - .getClass() - .getSimpleName()); - } - } - }); - - @SuppressWarnings({ "rawtypes" }) - @Override - public Map> getProperties(BlockType blockType) { - Map> properties = new TreeMap<>(); - Block block = getBlockFromType(blockType); - StateDefinition blockStateList = - block.getStateDefinition(); - for (net.minecraft.world.level.block.state.properties.Property state : blockStateList.getProperties()) { - Property property = PROPERTY_CACHE.getUnchecked(state); - properties.put(property.getName(), property); - } - return properties; - } - - @Override - public void sendFakeNBT(Player player, BlockVector3 pos, LinCompoundTag nbtData) { - ((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create( - new StructureBlockEntity( - new BlockPos(pos.x(), pos.y(), pos.z()), - Blocks.STRUCTURE_BLOCK.defaultBlockState() - ), - __ -> (net.minecraft.nbt.CompoundTag) fromNativeLin(nbtData) - )); - } - - @Override - public void sendFakeOP(Player player) { - ((CraftPlayer) player).getHandle().connection.send(new ClientboundEntityEventPacket( - ((CraftPlayer) player).getHandle(), (byte) 28 - )); - } - - @Override - public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) { - ItemStack stack = new ItemStack( - DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(item.getType().id())), - item.getAmount() - ); - stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData()))); - return CraftItemStack.asCraftMirror(stack); - } - - @Override - public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { - final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); - weStack.setNbt(((LinCompoundTag) toNativeLin(nmsStack.getTag()))); - return weStack; - } - - private final LoadingCache fakePlayers - = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new)); - - @Override - public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) { - CraftWorld craftWorld = (CraftWorld) world; - ServerLevel worldServer = craftWorld.getHandle(); - ItemStack stack = CraftItemStack.asNMSCopy(BukkitAdapter.adapt(item instanceof BaseItemStack - ? ((BaseItemStack) item) : new BaseItemStack(item.getType(), item.getNbtData(), 1))); - stack.setTag((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData())); - - PaperweightFakePlayer fakePlayer; - try { - fakePlayer = fakePlayers.get(worldServer); - } catch (ExecutionException ignored) { - return false; - } - fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack); - fakePlayer.absMoveTo(position.x(), position.y(), position.z(), - (float) face.toVector().toYaw(), (float) face.toVector().toPitch()); - - final BlockPos blockPos = new BlockPos(position.x(), position.y(), position.z()); - final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos); - final net.minecraft.core.Direction enumFacing = adapt(face); - BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false); - UseOnContext context = new UseOnContext(fakePlayer, InteractionHand.MAIN_HAND, rayTrace); - InteractionResult result = stack.useOn(context); - if (result != InteractionResult.SUCCESS) { - if (worldServer.getBlockState(blockPos).use(worldServer, fakePlayer, InteractionHand.MAIN_HAND, rayTrace).consumesAction()) { - result = InteractionResult.SUCCESS; - } else { - result = stack.getItem().use(worldServer, fakePlayer, InteractionHand.MAIN_HAND).getResult(); - } - } - - return result == InteractionResult.SUCCESS; - } - - @Override - public boolean canPlaceAt(org.bukkit.World world, BlockVector3 position, BlockState blockState) { - int internalId = BlockStateIdAccess.getBlockStateId(blockState); - net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId); - return blockData.canSurvive(((CraftWorld) world).getHandle(), new BlockPos(position.x(), position.y(), position.z())); - } - - @Override - public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent extent, RegenOptions options) { - try { - doRegen(bukkitWorld, region, extent, options); - } catch (Exception e) { - throw new IllegalStateException("Regen failed.", e); - } - - return true; - } - - private void doRegen(org.bukkit.World bukkitWorld, Region region, Extent extent, RegenOptions options) throws Exception { - Environment env = bukkitWorld.getEnvironment(); - ChunkGenerator gen = bukkitWorld.getGenerator(); - - Path tempDir = Files.createTempDirectory("WorldEditWorldGen"); - LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir); - ResourceKey worldDimKey = getWorldDimKey(env); - try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("faweregentempworld", worldDimKey)) { - ServerLevel originalWorld = ((CraftWorld) bukkitWorld).getHandle(); - PrimaryLevelData levelProperties = (PrimaryLevelData) originalWorld.getServer() - .getWorldData().overworldData(); - WorldOptions originalOpts = levelProperties.worldGenOptions(); - - long seed = options.getSeed().orElse(originalWorld.getSeed()); - WorldOptions newOpts = options.getSeed().isPresent() - ? originalOpts.withSeed(OptionalLong.of(seed)) - : originalOpts; - - LevelSettings newWorldSettings = new LevelSettings( - "faweregentempworld", - levelProperties.settings.gameType(), - levelProperties.settings.hardcore(), - levelProperties.settings.difficulty(), - levelProperties.settings.allowCommands(), - levelProperties.settings.gameRules(), - levelProperties.settings.getDataConfiguration() - ); - - PrimaryLevelData.SpecialWorldProperty specialWorldProperty = - levelProperties.isFlatWorld() - ? PrimaryLevelData.SpecialWorldProperty.FLAT - : levelProperties.isDebugWorld() - ? PrimaryLevelData.SpecialWorldProperty.DEBUG - : PrimaryLevelData.SpecialWorldProperty.NONE; - - PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, specialWorldProperty, Lifecycle.stable()); - - ServerLevel freshWorld = new ServerLevel( - originalWorld.getServer(), - originalWorld.getServer().executor, - session, newWorldData, - originalWorld.dimension(), - new LevelStem( - originalWorld.dimensionTypeRegistration(), - originalWorld.getChunkSource().getGenerator() - ), - new NoOpWorldLoadListener(), - originalWorld.isDebug(), - seed, - ImmutableList.of(), - false, - originalWorld.getRandomSequences(), - env, - gen, - bukkitWorld.getBiomeProvider() - ); - try { - regenForWorld(region, extent, freshWorld, options); - } finally { - freshWorld.getChunkSource().close(false); - } - } finally { - try { - @SuppressWarnings("unchecked") - Map map = (Map) serverWorldsField.get(Bukkit.getServer()); - map.remove("faweregentempworld"); - } catch (IllegalAccessException ignored) { - } - SafeFiles.tryHardToDeleteDir(tempDir); - } - } - - private BiomeType adapt(ServerLevel serverWorld, Biome origBiome) { - ResourceLocation key = serverWorld.registryAccess().registryOrThrow(Registries.BIOME).getKey(origBiome); - if (key == null) { - return null; - } - return BiomeTypes.get(key.toString()); - } - - @SuppressWarnings("unchecked") - private void regenForWorld(Region region, Extent extent, ServerLevel serverWorld, RegenOptions options) throws WorldEditException { - List> chunkLoadings = submitChunkLoadTasks(region, serverWorld); - BlockableEventLoop executor; - try { - executor = (BlockableEventLoop) chunkProviderExecutorField.get(serverWorld.getChunkSource()); - } catch (IllegalAccessException e) { - throw new IllegalStateException("Couldn't get executor for chunk loading.", e); - } - executor.managedBlock(() -> { - // bail out early if a future fails - if (chunkLoadings.stream().anyMatch(ftr -> - ftr.isDone() && Futures.getUnchecked(ftr) == null - )) { - return false; - } - return chunkLoadings.stream().allMatch(CompletableFuture::isDone); - }); - Map chunks = new HashMap<>(); - for (CompletableFuture future : chunkLoadings) { - @Nullable - ChunkAccess chunk = future.getNow(null); - checkState(chunk != null, "Failed to generate a chunk, regen failed."); - chunks.put(chunk.getPos(), chunk); - } - - for (BlockVector3 vec : region) { - BlockPos pos = new BlockPos(vec.x(), vec.y(), vec.z()); - ChunkAccess chunk = chunks.get(new ChunkPos(pos)); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos); - int internalId = Block.getId(blockData); - BlockStateHolder state = BlockStateIdAccess.getBlockStateById(internalId); - Objects.requireNonNull(state); - BlockEntity blockEntity = chunk.getBlockEntity(pos); - if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); - state = state.toBaseBlock(((LinCompoundTag) toNativeLin(tag))); - } - extent.setBlock(vec, state.toBaseBlock()); - if (options.shouldRegenBiomes()) { - Biome origBiome = chunk.getNoiseBiome(vec.x(), vec.y(), vec.z()).value(); - BiomeType adaptedBiome = adapt(serverWorld, origBiome); - if (adaptedBiome != null) { - extent.setBiome(vec, adaptedBiome); - } - } - } - } - - @SuppressWarnings("unchecked") - private List> submitChunkLoadTasks(Region region, ServerLevel serverWorld) { - ServerChunkCache chunkManager = serverWorld.getChunkSource(); - List> chunkLoadings = new ArrayList<>(); - // Pre-gen all the chunks - for (BlockVector2 chunk : region.getChunks()) { - try { - //noinspection unchecked - chunkLoadings.add( - ((CompletableFuture>) - getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true)) - .thenApply(either -> either.left().orElse(null)) - ); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new IllegalStateException("Couldn't load chunk for regen.", e); - } - } - return chunkLoadings; - } - - private ResourceKey getWorldDimKey(Environment env) { - switch (env) { - case NETHER: - return LevelStem.NETHER; - case THE_END: - return LevelStem.END; - case NORMAL: - default: - return LevelStem.OVERWORLD; - } - } - - private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( - SideEffect.NEIGHBORS, - SideEffect.LIGHTING, - SideEffect.VALIDATION, - SideEffect.ENTITY_AI, - SideEffect.EVENTS, - SideEffect.UPDATE - ); - - @Override - public Set getSupportedSideEffects() { - return SUPPORTED_SIDE_EFFECTS; - } - - @Override - public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) { - ServerLevel originalWorld = ((CraftWorld) world).getHandle(); - - BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.x(), pt.y(), pt.z())); - if (entity instanceof Clearable) { - ((Clearable) entity).clearContent(); - return true; - } - return false; - } - - @Override - public void initializeRegistries() { - DedicatedServer server = ((CraftServer) Bukkit.getServer()).getServer(); - // Biomes - for (ResourceLocation name : server.registryAccess().registryOrThrow(Registries.BIOME).keySet()) { - if (BiomeType.REGISTRY.get(name.toString()) == null) { - BiomeType.REGISTRY.register(name.toString(), new BiomeType(name.toString())); - } - } - - // BiomeCategories - Registry biomeRegistry = server.registryAccess().registryOrThrow(Registries.BIOME); - biomeRegistry.getTagNames().forEach(tagKey -> { - String key = tagKey.location().toString(); - if (BiomeCategory.REGISTRY.get(key) == null) { - BiomeCategory.REGISTRY.register(key, new BiomeCategory( - key, - () -> biomeRegistry.getTag(tagKey) - .stream() - .flatMap(HolderSet.Named::stream) - .map(Holder::value) - .map(this::adapt) - .collect(Collectors.toSet())) - ); - } - }); - } - // ------------------------------------------------------------------------ - // Code that is less likely to break - // ------------------------------------------------------------------------ - - /** - * Converts from a non-native NMS NBT structure to a native WorldEdit NBT - * structure. - * - * @param foreign non-native NMS NBT structure - * @return native WorldEdit NBT structure - */ - @Override - public LinTag toNativeLin(net.minecraft.nbt.Tag foreign) { - if (foreign == null) { - return null; - } - if (foreign instanceof net.minecraft.nbt.CompoundTag) { - Map> values = new HashMap<>(); - Set foreignKeys = ((net.minecraft.nbt.CompoundTag) foreign).getAllKeys(); - - for (String str : foreignKeys) { - net.minecraft.nbt.Tag base = ((net.minecraft.nbt.CompoundTag) foreign).get(str); - values.put(str, toNativeLin(base)); - } - return LinCompoundTag.of(values); - } else if (foreign instanceof net.minecraft.nbt.ByteTag) { - return LinByteTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); - } else if (foreign instanceof net.minecraft.nbt.ByteArrayTag) { - return LinByteArrayTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); - } else if (foreign instanceof net.minecraft.nbt.DoubleTag) { - return LinDoubleTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); - } else if (foreign instanceof net.minecraft.nbt.FloatTag) { - return LinFloatTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); - } else if (foreign instanceof net.minecraft.nbt.IntTag) { - return LinIntTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); - } else if (foreign instanceof net.minecraft.nbt.IntArrayTag) { - return LinIntArrayTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); - } else if (foreign instanceof net.minecraft.nbt.LongArrayTag) { - return LinLongArrayTag.of(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); - } else if (foreign instanceof net.minecraft.nbt.ListTag) { - try { - return toNativeLinList((net.minecraft.nbt.ListTag) foreign); - } catch (Throwable e) { - logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); - } - } else if (foreign instanceof net.minecraft.nbt.LongTag) { - return LinLongTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); - } else if (foreign instanceof net.minecraft.nbt.ShortTag) { - return LinShortTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); - } else if (foreign instanceof net.minecraft.nbt.StringTag) { - return LinStringTag.of(foreign.getAsString()); - } else if (foreign instanceof net.minecraft.nbt.EndTag) { - return LinEndTag.instance(); - } - throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); - } - - /** - * Convert a foreign NBT list tag into a native WorldEdit one. - * - * @param foreign the foreign tag - * @return the converted tag - * @throws SecurityException on error - * @throws IllegalArgumentException on error - */ - private LinListTag toNativeLinList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException { - LinListTag.Builder> builder = LinListTag.builder( - LinTagType.fromId(LinTagId.fromId(foreign.getElementType())) - ); - - for (net.minecraft.nbt.Tag tag : foreign) { - builder.add(toNativeLin(tag)); - } - - return builder.build(); - } - - /** - * Converts a WorldEdit-native NBT structure to a NMS structure. - * - * @param foreign structure to convert - * @return non-native structure - */ - @Override - public net.minecraft.nbt.Tag fromNativeLin(LinTag foreign) { - if (foreign == null) { - return null; - } - if (foreign instanceof LinCompoundTag compoundTag) { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - for (var entry : compoundTag.value().entrySet()) { - tag.put(entry.getKey(), fromNativeLin(entry.getValue())); - } - return tag; - } else if (foreign instanceof LinByteTag byteTag) { - return net.minecraft.nbt.ByteTag.valueOf(byteTag.valueAsByte()); - } else if (foreign instanceof LinByteArrayTag byteArrayTag) { - return new net.minecraft.nbt.ByteArrayTag(byteArrayTag.value()); - } else if (foreign instanceof LinDoubleTag doubleTag) { - return net.minecraft.nbt.DoubleTag.valueOf(doubleTag.valueAsDouble()); - } else if (foreign instanceof LinFloatTag floatTag) { - return net.minecraft.nbt.FloatTag.valueOf(floatTag.valueAsFloat()); - } else if (foreign instanceof LinIntTag intTag) { - return net.minecraft.nbt.IntTag.valueOf(intTag.valueAsInt()); - } else if (foreign instanceof LinIntArrayTag intArrayTag) { - return new net.minecraft.nbt.IntArrayTag(intArrayTag.value()); - } else if (foreign instanceof LinLongArrayTag longArrayTag) { - return new net.minecraft.nbt.LongArrayTag(longArrayTag.value()); - } else if (foreign instanceof LinListTag listTag) { - net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); - for (var t : listTag.value()) { - tag.add(fromNativeLin(t)); - } - return tag; - } else if (foreign instanceof LinLongTag longTag) { - return net.minecraft.nbt.LongTag.valueOf(longTag.valueAsLong()); - } else if (foreign instanceof LinShortTag shortTag) { - return net.minecraft.nbt.ShortTag.valueOf(shortTag.valueAsShort()); - } else if (foreign instanceof LinStringTag stringTag) { - return net.minecraft.nbt.StringTag.valueOf(stringTag.value()); - } else if (foreign instanceof LinEndTag) { - return net.minecraft.nbt.EndTag.INSTANCE; - } else { - throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName()); - } - } - - @Override - public boolean supportsWatchdog() { - return watchdog != null; - } - - @Override - public void tickWatchdog() { - watchdog.tick(); - } - - private class SpigotWatchdog implements Watchdog { - private final Field instanceField; - private final Field lastTickField; - - SpigotWatchdog() throws NoSuchFieldException { - Field instanceField = WatchdogThread.class.getDeclaredField("instance"); - instanceField.setAccessible(true); - this.instanceField = instanceField; - - Field lastTickField = WatchdogThread.class.getDeclaredField("lastTick"); - lastTickField.setAccessible(true); - this.lastTickField = lastTickField; - } - - @Override - public void tick() { - try { - WatchdogThread instance = (WatchdogThread) this.instanceField.get(null); - if ((long) lastTickField.get(instance) != 0) { - WatchdogThread.tick(); - } - } catch (IllegalAccessException e) { - logger.log(Level.WARNING, "Failed to tick watchdog", e); - } - } - } - - private static class MojangWatchdog implements Watchdog { - private final DedicatedServer server; - private final Field tickField; - - MojangWatchdog(DedicatedServer server) throws NoSuchFieldException { - this.server = server; - Field tickField = MinecraftServer.class.getDeclaredField( - Refraction.pickName("nextTickTime", "ah") - ); - if (tickField.getType() != long.class) { - throw new IllegalStateException("nextTickTime is not a long field, mapping is likely incorrect"); - } - tickField.setAccessible(true); - this.tickField = tickField; - } - - @Override - public void tick() { - try { - tickField.set(server, Util.getMillis()); - } catch (IllegalAccessException ignored) { - } - } - } - - private static class NoOpWorldLoadListener implements ChunkProgressListener { - @Override - public void updateSpawnPos(ChunkPos spawnPos) { - } - - @Override - public void onStatusChange(ChunkPos pos, @org.jetbrains.annotations.Nullable ChunkStatus status) { - } - - @Override - public void start() { - } - - @Override - public void stop() { - } - - @Override - public void setChunkRadius(int radius) { - } - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightDataConverters.java deleted file mode 100644 index ebe674ca5..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightDataConverters.java +++ /dev/null @@ -1,2798 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R1; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonParseException; -import com.mojang.datafixers.DSL; -import com.mojang.datafixers.DSL.TypeReference; -import com.mojang.datafixers.DataFixer; -import com.mojang.datafixers.DataFixerBuilder; -import com.mojang.datafixers.schemas.Schema; -import com.mojang.serialization.Dynamic; -import net.minecraft.core.Direction; -import net.minecraft.nbt.NbtOps; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.GsonHelper; -import net.minecraft.util.StringUtil; -import net.minecraft.util.datafix.DataFixers; -import net.minecraft.util.datafix.fixes.References; -import net.minecraft.world.item.DyeColor; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.enginehub.linbus.tree.LinCompoundTag; - -import javax.annotation.Nullable; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; - -/** - * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2) - * - * We register a DFU Fixer per Legacy Data Version and apply the fixes using legacy strategy - * which is safer, faster and cleaner code. - * - * The pre DFU code did not fail when the Source version was unknown. - * - * This class also provides util methods for converting compounds to wrap the update call to - * receive the source version in the compound - */ -@SuppressWarnings({ "rawtypes", "unchecked" }) -class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.worldedit.world.DataFixer { - - @SuppressWarnings("unchecked") - @Override - public T fixUp(FixType type, T original, int srcVer) { - if (type == FixTypes.CHUNK) { - return (T) fixChunk((LinCompoundTag) original, srcVer); - } else if (type == FixTypes.BLOCK_ENTITY) { - return (T) fixBlockEntity((LinCompoundTag) original, srcVer); - } else if (type == FixTypes.ENTITY) { - return (T) fixEntity((LinCompoundTag) original, srcVer); - } else if (type == FixTypes.BLOCK_STATE) { - return (T) fixBlockState((String) original, srcVer); - } else if (type == FixTypes.ITEM_TYPE) { - return (T) fixItemType((String) original, srcVer); - } else if (type == FixTypes.BIOME) { - return (T) fixBiome((String) original, srcVer); - } - return original; - } - - private LinCompoundTag fixChunk(LinCompoundTag originalChunk, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(originalChunk); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.CHUNK, tag, srcVer); - return (LinCompoundTag) adapter.toNativeLin(fixed); - } - - private LinCompoundTag fixBlockEntity(LinCompoundTag origTileEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origTileEnt); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.BLOCK_ENTITY, tag, srcVer); - return (LinCompoundTag) adapter.toNativeLin(fixed); - } - - private LinCompoundTag fixEntity(LinCompoundTag origEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNativeLin(origEnt); - net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.ENTITY, tag, srcVer); - return (LinCompoundTag) adapter.toNativeLin(fixed); - } - - private String fixBlockState(String blockState, int srcVer) { - net.minecraft.nbt.CompoundTag stateNBT = stateToNBT(blockState); - Dynamic dynamic = new Dynamic<>(OPS_NBT, stateNBT); - net.minecraft.nbt.CompoundTag fixed = (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update(References.BLOCK_STATE, dynamic, srcVer, DATA_VERSION).getValue(); - return nbtToState(fixed); - } - - private String nbtToState(net.minecraft.nbt.CompoundTag tagCompound) { - StringBuilder sb = new StringBuilder(); - sb.append(tagCompound.getString("Name")); - if (tagCompound.contains("Properties", 10)) { - sb.append('['); - net.minecraft.nbt.CompoundTag props = tagCompound.getCompound("Properties"); - sb.append(props.getAllKeys().stream().map(k -> k + "=" + props.getString(k).replace("\"", "")).collect(Collectors.joining(","))); - sb.append(']'); - } - return sb.toString(); - } - - private static net.minecraft.nbt.CompoundTag stateToNBT(String blockState) { - int propIdx = blockState.indexOf('['); - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - if (propIdx < 0) { - tag.putString("Name", blockState); - } else { - tag.putString("Name", blockState.substring(0, propIdx)); - net.minecraft.nbt.CompoundTag propTag = new net.minecraft.nbt.CompoundTag(); - String props = blockState.substring(propIdx + 1, blockState.length() - 1); - String[] propArr = props.split(","); - for (String pair : propArr) { - final String[] split = pair.split("="); - propTag.putString(split[0], split[1]); - } - tag.put("Properties", propTag); - } - return tag; - } - - private String fixBiome(String key, int srcVer) { - return fixName(key, srcVer, References.BIOME); - } - - private String fixItemType(String key, int srcVer) { - return fixName(key, srcVer, References.ITEM_NAME); - } - - private static String fixName(String key, int srcVer, TypeReference type) { - return INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, net.minecraft.nbt.StringTag.valueOf(key)), srcVer, DATA_VERSION) - .getValue().getAsString(); - } - - private final PaperweightAdapter adapter; - - private static final NbtOps OPS_NBT = NbtOps.INSTANCE; - private static final int LEGACY_VERSION = 1343; - private static int DATA_VERSION; - static PaperweightDataConverters INSTANCE; - - private final Map> converters = new EnumMap<>(LegacyType.class); - private final Map> inspectors = new EnumMap<>(LegacyType.class); - - // Set on build - private DataFixer fixer; - private static final Map DFU_TO_LEGACY = new HashMap<>(); - - public enum LegacyType { - LEVEL(References.LEVEL), - PLAYER(References.PLAYER), - CHUNK(References.CHUNK), - BLOCK_ENTITY(References.BLOCK_ENTITY), - ENTITY(References.ENTITY), - ITEM_INSTANCE(References.ITEM_STACK), - OPTIONS(References.OPTIONS), - STRUCTURE(References.STRUCTURE); - - private final TypeReference type; - - LegacyType(TypeReference type) { - this.type = type; - DFU_TO_LEGACY.put(type.typeName(), this); - } - - public TypeReference getDFUType() { - return type; - } - } - - PaperweightDataConverters(int dataVersion, PaperweightAdapter adapter) { - super(dataVersion); - DATA_VERSION = dataVersion; - INSTANCE = this; - this.adapter = adapter; - registerConverters(); - registerInspectors(); - } - - - // Called after fixers are built and ready for FIXING - @Override - public DataFixer buildUnoptimized() { - return this.fixer = new WrappedDataFixer(DataFixers.getDataFixer()); - } - - @Override - public DataFixer buildOptimized(final Set requiredTypes, Executor executor) { - return buildUnoptimized(); - } - - @SuppressWarnings("unchecked") - private class WrappedDataFixer implements DataFixer { - private final DataFixer realFixer; - - WrappedDataFixer(DataFixer realFixer) { - this.realFixer = realFixer; - } - - @Override - public Dynamic update(TypeReference type, Dynamic dynamic, int sourceVer, int targetVer) { - LegacyType legacyType = DFU_TO_LEGACY.get(type.typeName()); - if (sourceVer < LEGACY_VERSION && legacyType != null) { - net.minecraft.nbt.CompoundTag cmp = (net.minecraft.nbt.CompoundTag) dynamic.getValue(); - int desiredVersion = Math.min(targetVer, LEGACY_VERSION); - - cmp = convert(legacyType, cmp, sourceVer, desiredVersion); - sourceVer = desiredVersion; - dynamic = new Dynamic(OPS_NBT, cmp); - } - return realFixer.update(type, dynamic, sourceVer, targetVer); - } - - private net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int desiredVersion) { - List converters = PaperweightDataConverters.this.converters.get(type); - if (converters != null && !converters.isEmpty()) { - for (DataConverter converter : converters) { - int dataVersion = converter.getDataVersion(); - if (dataVersion > sourceVer && dataVersion <= desiredVersion) { - cmp = converter.convert(cmp); - } - } - } - - List inspectors = PaperweightDataConverters.this.inspectors.get(type); - if (inspectors != null && !inspectors.isEmpty()) { - for (DataInspector inspector : inspectors) { - cmp = inspector.inspect(cmp, sourceVer, desiredVersion); - } - } - - return cmp; - } - - @Override - public Schema getSchema(int i) { - return realFixer.getSchema(i); - } - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp) { - return convert(type.getDFUType(), cmp); - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { - return convert(type.getDFUType(), cmp, sourceVer); - } - - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - return convert(type.getDFUType(), cmp, sourceVer, targetVer); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp) { - int i = cmp.contains("DataVersion", 99) ? cmp.getInt("DataVersion") : -1; - return convert(type, cmp, i); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) { - return convert(type, cmp, sourceVer, DATA_VERSION); - } - - public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (sourceVer >= targetVer) { - return cmp; - } - return (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, cmp), sourceVer, targetVer).getValue(); - } - - - public interface DataInspector { - net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer); - } - - public interface DataConverter { - - int getDataVersion(); - - net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp); - } - - - private void registerInspector(LegacyType type, DataInspector inspector) { - this.inspectors.computeIfAbsent(type, k -> new ArrayList<>()).add(inspector); - } - - private void registerConverter(LegacyType type, DataConverter converter) { - int version = converter.getDataVersion(); - - List list = this.converters.computeIfAbsent(type, k -> new ArrayList<>()); - if (!list.isEmpty() && list.get(list.size() - 1).getDataVersion() > version) { - for (int j = 0; j < list.size(); ++j) { - if (list.get(j).getDataVersion() > version) { - list.add(j, converter); - break; - } - } - } else { - list.add(converter); - } - } - - private void registerInspectors() { - registerEntityItemList("EntityHorseDonkey", "SaddleItem", "Items"); - registerEntityItemList("EntityHorseMule", "Items"); - registerEntityItemList("EntityMinecartChest", "Items"); - registerEntityItemList("EntityMinecartHopper", "Items"); - registerEntityItemList("EntityVillager", "Inventory"); - registerEntityItemListEquipment("EntityArmorStand"); - registerEntityItemListEquipment("EntityBat"); - registerEntityItemListEquipment("EntityBlaze"); - registerEntityItemListEquipment("EntityCaveSpider"); - registerEntityItemListEquipment("EntityChicken"); - registerEntityItemListEquipment("EntityCow"); - registerEntityItemListEquipment("EntityCreeper"); - registerEntityItemListEquipment("EntityEnderDragon"); - registerEntityItemListEquipment("EntityEnderman"); - registerEntityItemListEquipment("EntityEndermite"); - registerEntityItemListEquipment("EntityEvoker"); - registerEntityItemListEquipment("EntityGhast"); - registerEntityItemListEquipment("EntityGiantZombie"); - registerEntityItemListEquipment("EntityGuardian"); - registerEntityItemListEquipment("EntityGuardianElder"); - registerEntityItemListEquipment("EntityHorse"); - registerEntityItemListEquipment("EntityHorseDonkey"); - registerEntityItemListEquipment("EntityHorseMule"); - registerEntityItemListEquipment("EntityHorseSkeleton"); - registerEntityItemListEquipment("EntityHorseZombie"); - registerEntityItemListEquipment("EntityIronGolem"); - registerEntityItemListEquipment("EntityMagmaCube"); - registerEntityItemListEquipment("EntityMushroomCow"); - registerEntityItemListEquipment("EntityOcelot"); - registerEntityItemListEquipment("EntityPig"); - registerEntityItemListEquipment("EntityPigZombie"); - registerEntityItemListEquipment("EntityRabbit"); - registerEntityItemListEquipment("EntitySheep"); - registerEntityItemListEquipment("EntityShulker"); - registerEntityItemListEquipment("EntitySilverfish"); - registerEntityItemListEquipment("EntitySkeleton"); - registerEntityItemListEquipment("EntitySkeletonStray"); - registerEntityItemListEquipment("EntitySkeletonWither"); - registerEntityItemListEquipment("EntitySlime"); - registerEntityItemListEquipment("EntitySnowman"); - registerEntityItemListEquipment("EntitySpider"); - registerEntityItemListEquipment("EntitySquid"); - registerEntityItemListEquipment("EntityVex"); - registerEntityItemListEquipment("EntityVillager"); - registerEntityItemListEquipment("EntityVindicator"); - registerEntityItemListEquipment("EntityWitch"); - registerEntityItemListEquipment("EntityWither"); - registerEntityItemListEquipment("EntityWolf"); - registerEntityItemListEquipment("EntityZombie"); - registerEntityItemListEquipment("EntityZombieHusk"); - registerEntityItemListEquipment("EntityZombieVillager"); - registerEntityItemSingle("EntityFireworks", "FireworksItem"); - registerEntityItemSingle("EntityHorse", "ArmorItem"); - registerEntityItemSingle("EntityHorse", "SaddleItem"); - registerEntityItemSingle("EntityHorseMule", "SaddleItem"); - registerEntityItemSingle("EntityHorseSkeleton", "SaddleItem"); - registerEntityItemSingle("EntityHorseZombie", "SaddleItem"); - registerEntityItemSingle("EntityItem", "Item"); - registerEntityItemSingle("EntityItemFrame", "Item"); - registerEntityItemSingle("EntityPotion", "Potion"); - - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItem("TileEntityRecordPlayer", "RecordItem")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityBrewingStand", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityChest", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDispenser", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDropper", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityFurnace", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityHopper", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityShulkerBox", "Items")); - registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorMobSpawnerMobs()); - registerInspector(LegacyType.CHUNK, new DataInspectorChunks()); - registerInspector(LegacyType.ENTITY, new DataInspectorCommandBlock()); - registerInspector(LegacyType.ENTITY, new DataInspectorEntityPassengers()); - registerInspector(LegacyType.ENTITY, new DataInspectorMobSpawnerMinecart()); - registerInspector(LegacyType.ENTITY, new DataInspectorVillagers()); - registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorBlockEntity()); - registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorEntity()); - registerInspector(LegacyType.LEVEL, new DataInspectorLevelPlayer()); - registerInspector(LegacyType.PLAYER, new DataInspectorPlayer()); - registerInspector(LegacyType.PLAYER, new DataInspectorPlayerVehicle()); - registerInspector(LegacyType.STRUCTURE, new DataInspectorStructure()); - } - - private void registerConverters() { - registerConverter(LegacyType.ENTITY, new DataConverterEquipment()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterSignText()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterMaterialId()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionId()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterSpawnEgg()); - registerConverter(LegacyType.ENTITY, new DataConverterMinecart()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterMobSpawner()); - registerConverter(LegacyType.ENTITY, new DataConverterUUID()); - registerConverter(LegacyType.ENTITY, new DataConverterHealth()); - registerConverter(LegacyType.ENTITY, new DataConverterSaddle()); - registerConverter(LegacyType.ENTITY, new DataConverterHanging()); - registerConverter(LegacyType.ENTITY, new DataConverterDropChances()); - registerConverter(LegacyType.ENTITY, new DataConverterRiding()); - registerConverter(LegacyType.ENTITY, new DataConverterArmorStand()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBook()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterCookedFish()); - registerConverter(LegacyType.ENTITY, new DataConverterZombie()); - registerConverter(LegacyType.OPTIONS, new DataConverterVBO()); - registerConverter(LegacyType.ENTITY, new DataConverterGuardian()); - registerConverter(LegacyType.ENTITY, new DataConverterSkeleton()); - registerConverter(LegacyType.ENTITY, new DataConverterZombieType()); - registerConverter(LegacyType.ENTITY, new DataConverterHorse()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterTileEntity()); - registerConverter(LegacyType.ENTITY, new DataConverterEntity()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBanner()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionWater()); - registerConverter(LegacyType.ENTITY, new DataConverterShulker()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterShulkerBoxItem()); - registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterShulkerBoxBlock()); - registerConverter(LegacyType.OPTIONS, new DataConverterLang()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterTotem()); - registerConverter(LegacyType.CHUNK, new DataConverterBedBlock()); - registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBedItem()); - } - - private void registerEntityItemList(String type, String... keys) { - registerInspector(LegacyType.ENTITY, new DataInspectorItemList(type, keys)); - } - - private void registerEntityItemSingle(String type, String key) { - registerInspector(LegacyType.ENTITY, new DataInspectorItem(type, key)); - } - - private void registerEntityItemListEquipment(String type) { - registerEntityItemList(type, "ArmorItems", "HandItems"); - } - - private static final Map OLD_ID_TO_KEY_MAP = new HashMap<>(); - - static { - final Map map = OLD_ID_TO_KEY_MAP; - map.put("EntityItem", new ResourceLocation("item")); - map.put("EntityExperienceOrb", new ResourceLocation("xp_orb")); - map.put("EntityAreaEffectCloud", new ResourceLocation("area_effect_cloud")); - map.put("EntityGuardianElder", new ResourceLocation("elder_guardian")); - map.put("EntitySkeletonWither", new ResourceLocation("wither_skeleton")); - map.put("EntitySkeletonStray", new ResourceLocation("stray")); - map.put("EntityEgg", new ResourceLocation("egg")); - map.put("EntityLeash", new ResourceLocation("leash_knot")); - map.put("EntityPainting", new ResourceLocation("painting")); - map.put("EntityTippedArrow", new ResourceLocation("arrow")); - map.put("EntitySnowball", new ResourceLocation("snowball")); - map.put("EntityLargeFireball", new ResourceLocation("fireball")); - map.put("EntitySmallFireball", new ResourceLocation("small_fireball")); - map.put("EntityEnderPearl", new ResourceLocation("ender_pearl")); - map.put("EntityEnderSignal", new ResourceLocation("eye_of_ender_signal")); - map.put("EntityPotion", new ResourceLocation("potion")); - map.put("EntityThrownExpBottle", new ResourceLocation("xp_bottle")); - map.put("EntityItemFrame", new ResourceLocation("item_frame")); - map.put("EntityWitherSkull", new ResourceLocation("wither_skull")); - map.put("EntityTNTPrimed", new ResourceLocation("tnt")); - map.put("EntityFallingBlock", new ResourceLocation("falling_block")); - map.put("EntityFireworks", new ResourceLocation("fireworks_rocket")); - map.put("EntityZombieHusk", new ResourceLocation("husk")); - map.put("EntitySpectralArrow", new ResourceLocation("spectral_arrow")); - map.put("EntityShulkerBullet", new ResourceLocation("shulker_bullet")); - map.put("EntityDragonFireball", new ResourceLocation("dragon_fireball")); - map.put("EntityZombieVillager", new ResourceLocation("zombie_villager")); - map.put("EntityHorseSkeleton", new ResourceLocation("skeleton_horse")); - map.put("EntityHorseZombie", new ResourceLocation("zombie_horse")); - map.put("EntityArmorStand", new ResourceLocation("armor_stand")); - map.put("EntityHorseDonkey", new ResourceLocation("donkey")); - map.put("EntityHorseMule", new ResourceLocation("mule")); - map.put("EntityEvokerFangs", new ResourceLocation("evocation_fangs")); - map.put("EntityEvoker", new ResourceLocation("evocation_illager")); - map.put("EntityVex", new ResourceLocation("vex")); - map.put("EntityVindicator", new ResourceLocation("vindication_illager")); - map.put("EntityIllagerIllusioner", new ResourceLocation("illusion_illager")); - map.put("EntityMinecartCommandBlock", new ResourceLocation("commandblock_minecart")); - map.put("EntityBoat", new ResourceLocation("boat")); - map.put("EntityMinecartRideable", new ResourceLocation("minecart")); - map.put("EntityMinecartChest", new ResourceLocation("chest_minecart")); - map.put("EntityMinecartFurnace", new ResourceLocation("furnace_minecart")); - map.put("EntityMinecartTNT", new ResourceLocation("tnt_minecart")); - map.put("EntityMinecartHopper", new ResourceLocation("hopper_minecart")); - map.put("EntityMinecartMobSpawner", new ResourceLocation("spawner_minecart")); - map.put("EntityCreeper", new ResourceLocation("creeper")); - map.put("EntitySkeleton", new ResourceLocation("skeleton")); - map.put("EntitySpider", new ResourceLocation("spider")); - map.put("EntityGiantZombie", new ResourceLocation("giant")); - map.put("EntityZombie", new ResourceLocation("zombie")); - map.put("EntitySlime", new ResourceLocation("slime")); - map.put("EntityGhast", new ResourceLocation("ghast")); - map.put("EntityPigZombie", new ResourceLocation("zombie_pigman")); - map.put("EntityEnderman", new ResourceLocation("enderman")); - map.put("EntityCaveSpider", new ResourceLocation("cave_spider")); - map.put("EntitySilverfish", new ResourceLocation("silverfish")); - map.put("EntityBlaze", new ResourceLocation("blaze")); - map.put("EntityMagmaCube", new ResourceLocation("magma_cube")); - map.put("EntityEnderDragon", new ResourceLocation("ender_dragon")); - map.put("EntityWither", new ResourceLocation("wither")); - map.put("EntityBat", new ResourceLocation("bat")); - map.put("EntityWitch", new ResourceLocation("witch")); - map.put("EntityEndermite", new ResourceLocation("endermite")); - map.put("EntityGuardian", new ResourceLocation("guardian")); - map.put("EntityShulker", new ResourceLocation("shulker")); - map.put("EntityPig", new ResourceLocation("pig")); - map.put("EntitySheep", new ResourceLocation("sheep")); - map.put("EntityCow", new ResourceLocation("cow")); - map.put("EntityChicken", new ResourceLocation("chicken")); - map.put("EntitySquid", new ResourceLocation("squid")); - map.put("EntityWolf", new ResourceLocation("wolf")); - map.put("EntityMushroomCow", new ResourceLocation("mooshroom")); - map.put("EntitySnowman", new ResourceLocation("snowman")); - map.put("EntityOcelot", new ResourceLocation("ocelot")); - map.put("EntityIronGolem", new ResourceLocation("villager_golem")); - map.put("EntityHorse", new ResourceLocation("horse")); - map.put("EntityRabbit", new ResourceLocation("rabbit")); - map.put("EntityPolarBear", new ResourceLocation("polar_bear")); - map.put("EntityLlama", new ResourceLocation("llama")); - map.put("EntityLlamaSpit", new ResourceLocation("llama_spit")); - map.put("EntityParrot", new ResourceLocation("parrot")); - map.put("EntityVillager", new ResourceLocation("villager")); - map.put("EntityEnderCrystal", new ResourceLocation("ender_crystal")); - map.put("TileEntityFurnace", new ResourceLocation("furnace")); - map.put("TileEntityChest", new ResourceLocation("chest")); - map.put("TileEntityEnderChest", new ResourceLocation("ender_chest")); - map.put("TileEntityRecordPlayer", new ResourceLocation("jukebox")); - map.put("TileEntityDispenser", new ResourceLocation("dispenser")); - map.put("TileEntityDropper", new ResourceLocation("dropper")); - map.put("TileEntitySign", new ResourceLocation("sign")); - map.put("TileEntityMobSpawner", new ResourceLocation("mob_spawner")); - map.put("TileEntityNote", new ResourceLocation("noteblock")); - map.put("TileEntityPiston", new ResourceLocation("piston")); - map.put("TileEntityBrewingStand", new ResourceLocation("brewing_stand")); - map.put("TileEntityEnchantTable", new ResourceLocation("enchanting_table")); - map.put("TileEntityEnderPortal", new ResourceLocation("end_portal")); - map.put("TileEntityBeacon", new ResourceLocation("beacon")); - map.put("TileEntitySkull", new ResourceLocation("skull")); - map.put("TileEntityLightDetector", new ResourceLocation("daylight_detector")); - map.put("TileEntityHopper", new ResourceLocation("hopper")); - map.put("TileEntityComparator", new ResourceLocation("comparator")); - map.put("TileEntityFlowerPot", new ResourceLocation("flower_pot")); - map.put("TileEntityBanner", new ResourceLocation("banner")); - map.put("TileEntityStructure", new ResourceLocation("structure_block")); - map.put("TileEntityEndGateway", new ResourceLocation("end_gateway")); - map.put("TileEntityCommand", new ResourceLocation("command_block")); - map.put("TileEntityShulkerBox", new ResourceLocation("shulker_box")); - map.put("TileEntityBed", new ResourceLocation("bed")); - } - - private static ResourceLocation getKey(String type) { - final ResourceLocation key = OLD_ID_TO_KEY_MAP.get(type); - if (key == null) { - throw new IllegalArgumentException("Unknown mapping for " + type); - } - return key; - } - - private static void convertCompound(LegacyType type, net.minecraft.nbt.CompoundTag cmp, String key, int sourceVer, int targetVer) { - cmp.put(key, convert(type, cmp.getCompound(key), sourceVer, targetVer)); - } - - private static void convertItem(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { - if (nbttagcompound.contains(key, 10)) { - convertCompound(LegacyType.ITEM_INSTANCE, nbttagcompound, key, sourceVer, targetVer); - } - } - - private static void convertItems(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) { - if (nbttagcompound.contains(key, 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound.getList(key, 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ITEM_INSTANCE, nbttaglist.getCompound(j), sourceVer, targetVer)); - } - } - - } - - private static class DataConverterEquipment implements DataConverter { - - DataConverterEquipment() { - } - - public int getDataVersion() { - return 100; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("Equipment", 10); - net.minecraft.nbt.ListTag nbttaglist1; - - if (!nbttaglist.isEmpty() && !cmp.contains("HandItems", 10)) { - nbttaglist1 = new net.minecraft.nbt.ListTag(); - nbttaglist1.add(nbttaglist.get(0)); - nbttaglist1.add(new net.minecraft.nbt.CompoundTag()); - cmp.put("HandItems", nbttaglist1); - } - - if (nbttaglist.size() > 1 && !cmp.contains("ArmorItem", 10)) { - nbttaglist1 = new net.minecraft.nbt.ListTag(); - nbttaglist1.add(nbttaglist.get(1)); - nbttaglist1.add(nbttaglist.get(2)); - nbttaglist1.add(nbttaglist.get(3)); - nbttaglist1.add(nbttaglist.get(4)); - cmp.put("ArmorItems", nbttaglist1); - } - - cmp.remove("Equipment"); - if (cmp.contains("DropChances", 9)) { - nbttaglist1 = cmp.getList("DropChances", 5); - net.minecraft.nbt.ListTag nbttaglist2; - - if (!cmp.contains("HandDropChances", 10)) { - nbttaglist2 = new net.minecraft.nbt.ListTag(); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(0))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(0.0F)); - cmp.put("HandDropChances", nbttaglist2); - } - - if (!cmp.contains("ArmorDropChances", 10)) { - nbttaglist2 = new net.minecraft.nbt.ListTag(); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(1))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(2))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(3))); - nbttaglist2.add(net.minecraft.nbt.FloatTag.valueOf(nbttaglist1.getFloat(4))); - cmp.put("ArmorDropChances", nbttaglist2); - } - - cmp.remove("DropChances"); - } - - return cmp; - } - } - - private static class DataInspectorBlockEntity implements DataInspector { - - private static final Map b = Maps.newHashMap(); - private static final Map c = Maps.newHashMap(); - - DataInspectorBlockEntity() { - } - - @Nullable - private static String convertEntityId(int i, String s) { - String key = new ResourceLocation(s).toString(); - if (i < 515 && DataInspectorBlockEntity.b.containsKey(key)) { - return DataInspectorBlockEntity.b.get(key); - } else { - return DataInspectorBlockEntity.c.get(key); - } - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (!cmp.contains("tag", 10)) { - return cmp; - } else { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - String s = cmp.getString("id"); - String s1 = convertEntityId(sourceVer, s); - boolean flag; - - if (s1 == null) { - // CraftBukkit - Remove unnecessary warning (occurs when deserializing a Shulker Box item) - // DataInspectorBlockEntity.a.warn("Unable to resolve BlockEntity for ItemInstance: {}", s); - flag = false; - } else { - flag = !nbttagcompound2.contains("id"); - nbttagcompound2.putString("id", s1); - } - - convert(LegacyType.BLOCK_ENTITY, nbttagcompound2, sourceVer, targetVer); - if (flag) { - nbttagcompound2.remove("id"); - } - } - - return cmp; - } - } - - static { - Map map = DataInspectorBlockEntity.b; - - map.put("minecraft:furnace", "Furnace"); - map.put("minecraft:lit_furnace", "Furnace"); - map.put("minecraft:chest", "Chest"); - map.put("minecraft:trapped_chest", "Chest"); - map.put("minecraft:ender_chest", "EnderChest"); - map.put("minecraft:jukebox", "RecordPlayer"); - map.put("minecraft:dispenser", "Trap"); - map.put("minecraft:dropper", "Dropper"); - map.put("minecraft:sign", "Sign"); - map.put("minecraft:mob_spawner", "MobSpawner"); - map.put("minecraft:noteblock", "Music"); - map.put("minecraft:brewing_stand", "Cauldron"); - map.put("minecraft:enhanting_table", "EnchantTable"); - map.put("minecraft:command_block", "CommandBlock"); - map.put("minecraft:beacon", "Beacon"); - map.put("minecraft:skull", "Skull"); - map.put("minecraft:daylight_detector", "DLDetector"); - map.put("minecraft:hopper", "Hopper"); - map.put("minecraft:banner", "Banner"); - map.put("minecraft:flower_pot", "FlowerPot"); - map.put("minecraft:repeating_command_block", "CommandBlock"); - map.put("minecraft:chain_command_block", "CommandBlock"); - map.put("minecraft:standing_sign", "Sign"); - map.put("minecraft:wall_sign", "Sign"); - map.put("minecraft:piston_head", "Piston"); - map.put("minecraft:daylight_detector_inverted", "DLDetector"); - map.put("minecraft:unpowered_comparator", "Comparator"); - map.put("minecraft:powered_comparator", "Comparator"); - map.put("minecraft:wall_banner", "Banner"); - map.put("minecraft:standing_banner", "Banner"); - map.put("minecraft:structure_block", "Structure"); - map.put("minecraft:end_portal", "Airportal"); - map.put("minecraft:end_gateway", "EndGateway"); - map.put("minecraft:shield", "Shield"); - map = DataInspectorBlockEntity.c; - map.put("minecraft:furnace", "minecraft:furnace"); - map.put("minecraft:lit_furnace", "minecraft:furnace"); - map.put("minecraft:chest", "minecraft:chest"); - map.put("minecraft:trapped_chest", "minecraft:chest"); - map.put("minecraft:ender_chest", "minecraft:enderchest"); - map.put("minecraft:jukebox", "minecraft:jukebox"); - map.put("minecraft:dispenser", "minecraft:dispenser"); - map.put("minecraft:dropper", "minecraft:dropper"); - map.put("minecraft:sign", "minecraft:sign"); - map.put("minecraft:mob_spawner", "minecraft:mob_spawner"); - map.put("minecraft:noteblock", "minecraft:noteblock"); - map.put("minecraft:brewing_stand", "minecraft:brewing_stand"); - map.put("minecraft:enhanting_table", "minecraft:enchanting_table"); - map.put("minecraft:command_block", "minecraft:command_block"); - map.put("minecraft:beacon", "minecraft:beacon"); - map.put("minecraft:skull", "minecraft:skull"); - map.put("minecraft:daylight_detector", "minecraft:daylight_detector"); - map.put("minecraft:hopper", "minecraft:hopper"); - map.put("minecraft:banner", "minecraft:banner"); - map.put("minecraft:flower_pot", "minecraft:flower_pot"); - map.put("minecraft:repeating_command_block", "minecraft:command_block"); - map.put("minecraft:chain_command_block", "minecraft:command_block"); - map.put("minecraft:shulker_box", "minecraft:shulker_box"); - map.put("minecraft:white_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:orange_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:magenta_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:light_blue_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:yellow_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:lime_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:pink_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:gray_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:silver_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:cyan_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:purple_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:blue_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:brown_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:green_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:red_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:black_shulker_box", "minecraft:shulker_box"); - map.put("minecraft:bed", "minecraft:bed"); - map.put("minecraft:standing_sign", "minecraft:sign"); - map.put("minecraft:wall_sign", "minecraft:sign"); - map.put("minecraft:piston_head", "minecraft:piston"); - map.put("minecraft:daylight_detector_inverted", "minecraft:daylight_detector"); - map.put("minecraft:unpowered_comparator", "minecraft:comparator"); - map.put("minecraft:powered_comparator", "minecraft:comparator"); - map.put("minecraft:wall_banner", "minecraft:banner"); - map.put("minecraft:standing_banner", "minecraft:banner"); - map.put("minecraft:structure_block", "minecraft:structure_block"); - map.put("minecraft:end_portal", "minecraft:end_portal"); - map.put("minecraft:end_gateway", "minecraft:end_gateway"); - map.put("minecraft:shield", "minecraft:shield"); - } - } - - private static class DataInspectorEntity implements DataInspector { - - DataInspectorEntity() { - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("EntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); - String s = cmp.getString("id"); - String s1; - - if ("minecraft:armor_stand".equals(s)) { - s1 = sourceVer < 515 ? "ArmorStand" : "minecraft:armor_stand"; - } else { - if (!"minecraft:spawn_egg".equals(s)) { - return cmp; - } - - s1 = nbttagcompound2.getString("id"); - } - - boolean flag; - - flag = !nbttagcompound2.contains("id", 8); - nbttagcompound2.putString("id", s1); - - convert(LegacyType.ENTITY, nbttagcompound2, sourceVer, targetVer); - if (flag) { - nbttagcompound2.remove("id"); - } - } - - return cmp; - } - } - - - private abstract static class DataInspectorTagged implements DataInspector { - - private final ResourceLocation key; - - DataInspectorTagged(String type) { - this.key = getKey(type); - } - - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (this.key.equals(new ResourceLocation(cmp.getString("id")))) { - cmp = this.inspectChecked(cmp, sourceVer, targetVer); - } - - return cmp; - } - - abstract net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer); - } - - private static class DataInspectorItemList extends DataInspectorTagged { - - private final String[] keys; - - DataInspectorItemList(String oclass, String... astring) { - super(oclass); - this.keys = astring; - } - - net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer) { - for (String s : this.keys) { - PaperweightDataConverters.convertItems(nbttagcompound, s, sourceVer, targetVer); - } - - return nbttagcompound; - } - } - - private static class DataInspectorItem extends DataInspectorTagged { - - private final String[] keys; - - DataInspectorItem(String oclass, String... astring) { - super(oclass); - this.keys = astring; - } - - net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer) { - for (String key : this.keys) { - PaperweightDataConverters.convertItem(nbttagcompound, key, sourceVer, targetVer); - } - - return nbttagcompound; - } - } - - private static class DataConverterMaterialId implements DataConverter { - - private static final String[] materials = new String[2268]; - - DataConverterMaterialId() { - } - - public int getDataVersion() { - return 102; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("id", 99)) { - short short0 = cmp.getShort("id"); - - if (short0 > 0 && short0 < materials.length && materials[short0] != null) { - cmp.putString("id", materials[short0]); - } - } - - return cmp; - } - - static { - materials[1] = "minecraft:stone"; - materials[2] = "minecraft:grass"; - materials[3] = "minecraft:dirt"; - materials[4] = "minecraft:cobblestone"; - materials[5] = "minecraft:planks"; - materials[6] = "minecraft:sapling"; - materials[7] = "minecraft:bedrock"; - materials[8] = "minecraft:flowing_water"; - materials[9] = "minecraft:water"; - materials[10] = "minecraft:flowing_lava"; - materials[11] = "minecraft:lava"; - materials[12] = "minecraft:sand"; - materials[13] = "minecraft:gravel"; - materials[14] = "minecraft:gold_ore"; - materials[15] = "minecraft:iron_ore"; - materials[16] = "minecraft:coal_ore"; - materials[17] = "minecraft:log"; - materials[18] = "minecraft:leaves"; - materials[19] = "minecraft:sponge"; - materials[20] = "minecraft:glass"; - materials[21] = "minecraft:lapis_ore"; - materials[22] = "minecraft:lapis_block"; - materials[23] = "minecraft:dispenser"; - materials[24] = "minecraft:sandstone"; - materials[25] = "minecraft:noteblock"; - materials[27] = "minecraft:golden_rail"; - materials[28] = "minecraft:detector_rail"; - materials[29] = "minecraft:sticky_piston"; - materials[30] = "minecraft:web"; - materials[31] = "minecraft:tallgrass"; - materials[32] = "minecraft:deadbush"; - materials[33] = "minecraft:piston"; - materials[35] = "minecraft:wool"; - materials[37] = "minecraft:yellow_flower"; - materials[38] = "minecraft:red_flower"; - materials[39] = "minecraft:brown_mushroom"; - materials[40] = "minecraft:red_mushroom"; - materials[41] = "minecraft:gold_block"; - materials[42] = "minecraft:iron_block"; - materials[43] = "minecraft:double_stone_slab"; - materials[44] = "minecraft:stone_slab"; - materials[45] = "minecraft:brick_block"; - materials[46] = "minecraft:tnt"; - materials[47] = "minecraft:bookshelf"; - materials[48] = "minecraft:mossy_cobblestone"; - materials[49] = "minecraft:obsidian"; - materials[50] = "minecraft:torch"; - materials[51] = "minecraft:fire"; - materials[52] = "minecraft:mob_spawner"; - materials[53] = "minecraft:oak_stairs"; - materials[54] = "minecraft:chest"; - materials[56] = "minecraft:diamond_ore"; - materials[57] = "minecraft:diamond_block"; - materials[58] = "minecraft:crafting_table"; - materials[60] = "minecraft:farmland"; - materials[61] = "minecraft:furnace"; - materials[62] = "minecraft:lit_furnace"; - materials[65] = "minecraft:ladder"; - materials[66] = "minecraft:rail"; - materials[67] = "minecraft:stone_stairs"; - materials[69] = "minecraft:lever"; - materials[70] = "minecraft:stone_pressure_plate"; - materials[72] = "minecraft:wooden_pressure_plate"; - materials[73] = "minecraft:redstone_ore"; - materials[76] = "minecraft:redstone_torch"; - materials[77] = "minecraft:stone_button"; - materials[78] = "minecraft:snow_layer"; - materials[79] = "minecraft:ice"; - materials[80] = "minecraft:snow"; - materials[81] = "minecraft:cactus"; - materials[82] = "minecraft:clay"; - materials[84] = "minecraft:jukebox"; - materials[85] = "minecraft:fence"; - materials[86] = "minecraft:pumpkin"; - materials[87] = "minecraft:netherrack"; - materials[88] = "minecraft:soul_sand"; - materials[89] = "minecraft:glowstone"; - materials[90] = "minecraft:portal"; - materials[91] = "minecraft:lit_pumpkin"; - materials[95] = "minecraft:stained_glass"; - materials[96] = "minecraft:trapdoor"; - materials[97] = "minecraft:monster_egg"; - materials[98] = "minecraft:stonebrick"; - materials[99] = "minecraft:brown_mushroom_block"; - materials[100] = "minecraft:red_mushroom_block"; - materials[101] = "minecraft:iron_bars"; - materials[102] = "minecraft:glass_pane"; - materials[103] = "minecraft:melon_block"; - materials[106] = "minecraft:vine"; - materials[107] = "minecraft:fence_gate"; - materials[108] = "minecraft:brick_stairs"; - materials[109] = "minecraft:stone_brick_stairs"; - materials[110] = "minecraft:mycelium"; - materials[111] = "minecraft:waterlily"; - materials[112] = "minecraft:nether_brick"; - materials[113] = "minecraft:nether_brick_fence"; - materials[114] = "minecraft:nether_brick_stairs"; - materials[116] = "minecraft:enchanting_table"; - materials[119] = "minecraft:end_portal"; - materials[120] = "minecraft:end_portal_frame"; - materials[121] = "minecraft:end_stone"; - materials[122] = "minecraft:dragon_egg"; - materials[123] = "minecraft:redstone_lamp"; - materials[125] = "minecraft:double_wooden_slab"; - materials[126] = "minecraft:wooden_slab"; - materials[127] = "minecraft:cocoa"; - materials[128] = "minecraft:sandstone_stairs"; - materials[129] = "minecraft:emerald_ore"; - materials[130] = "minecraft:ender_chest"; - materials[131] = "minecraft:tripwire_hook"; - materials[133] = "minecraft:emerald_block"; - materials[134] = "minecraft:spruce_stairs"; - materials[135] = "minecraft:birch_stairs"; - materials[136] = "minecraft:jungle_stairs"; - materials[137] = "minecraft:command_block"; - materials[138] = "minecraft:beacon"; - materials[139] = "minecraft:cobblestone_wall"; - materials[141] = "minecraft:carrots"; - materials[142] = "minecraft:potatoes"; - materials[143] = "minecraft:wooden_button"; - materials[145] = "minecraft:anvil"; - materials[146] = "minecraft:trapped_chest"; - materials[147] = "minecraft:light_weighted_pressure_plate"; - materials[148] = "minecraft:heavy_weighted_pressure_plate"; - materials[151] = "minecraft:daylight_detector"; - materials[152] = "minecraft:redstone_block"; - materials[153] = "minecraft:quartz_ore"; - materials[154] = "minecraft:hopper"; - materials[155] = "minecraft:quartz_block"; - materials[156] = "minecraft:quartz_stairs"; - materials[157] = "minecraft:activator_rail"; - materials[158] = "minecraft:dropper"; - materials[159] = "minecraft:stained_hardened_clay"; - materials[160] = "minecraft:stained_glass_pane"; - materials[161] = "minecraft:leaves2"; - materials[162] = "minecraft:log2"; - materials[163] = "minecraft:acacia_stairs"; - materials[164] = "minecraft:dark_oak_stairs"; - materials[170] = "minecraft:hay_block"; - materials[171] = "minecraft:carpet"; - materials[172] = "minecraft:hardened_clay"; - materials[173] = "minecraft:coal_block"; - materials[174] = "minecraft:packed_ice"; - materials[175] = "minecraft:double_plant"; - materials[256] = "minecraft:iron_shovel"; - materials[257] = "minecraft:iron_pickaxe"; - materials[258] = "minecraft:iron_axe"; - materials[259] = "minecraft:flint_and_steel"; - materials[260] = "minecraft:apple"; - materials[261] = "minecraft:bow"; - materials[262] = "minecraft:arrow"; - materials[263] = "minecraft:coal"; - materials[264] = "minecraft:diamond"; - materials[265] = "minecraft:iron_ingot"; - materials[266] = "minecraft:gold_ingot"; - materials[267] = "minecraft:iron_sword"; - materials[268] = "minecraft:wooden_sword"; - materials[269] = "minecraft:wooden_shovel"; - materials[270] = "minecraft:wooden_pickaxe"; - materials[271] = "minecraft:wooden_axe"; - materials[272] = "minecraft:stone_sword"; - materials[273] = "minecraft:stone_shovel"; - materials[274] = "minecraft:stone_pickaxe"; - materials[275] = "minecraft:stone_axe"; - materials[276] = "minecraft:diamond_sword"; - materials[277] = "minecraft:diamond_shovel"; - materials[278] = "minecraft:diamond_pickaxe"; - materials[279] = "minecraft:diamond_axe"; - materials[280] = "minecraft:stick"; - materials[281] = "minecraft:bowl"; - materials[282] = "minecraft:mushroom_stew"; - materials[283] = "minecraft:golden_sword"; - materials[284] = "minecraft:golden_shovel"; - materials[285] = "minecraft:golden_pickaxe"; - materials[286] = "minecraft:golden_axe"; - materials[287] = "minecraft:string"; - materials[288] = "minecraft:feather"; - materials[289] = "minecraft:gunpowder"; - materials[290] = "minecraft:wooden_hoe"; - materials[291] = "minecraft:stone_hoe"; - materials[292] = "minecraft:iron_hoe"; - materials[293] = "minecraft:diamond_hoe"; - materials[294] = "minecraft:golden_hoe"; - materials[295] = "minecraft:wheat_seeds"; - materials[296] = "minecraft:wheat"; - materials[297] = "minecraft:bread"; - materials[298] = "minecraft:leather_helmet"; - materials[299] = "minecraft:leather_chestplate"; - materials[300] = "minecraft:leather_leggings"; - materials[301] = "minecraft:leather_boots"; - materials[302] = "minecraft:chainmail_helmet"; - materials[303] = "minecraft:chainmail_chestplate"; - materials[304] = "minecraft:chainmail_leggings"; - materials[305] = "minecraft:chainmail_boots"; - materials[306] = "minecraft:iron_helmet"; - materials[307] = "minecraft:iron_chestplate"; - materials[308] = "minecraft:iron_leggings"; - materials[309] = "minecraft:iron_boots"; - materials[310] = "minecraft:diamond_helmet"; - materials[311] = "minecraft:diamond_chestplate"; - materials[312] = "minecraft:diamond_leggings"; - materials[313] = "minecraft:diamond_boots"; - materials[314] = "minecraft:golden_helmet"; - materials[315] = "minecraft:golden_chestplate"; - materials[316] = "minecraft:golden_leggings"; - materials[317] = "minecraft:golden_boots"; - materials[318] = "minecraft:flint"; - materials[319] = "minecraft:porkchop"; - materials[320] = "minecraft:cooked_porkchop"; - materials[321] = "minecraft:painting"; - materials[322] = "minecraft:golden_apple"; - materials[323] = "minecraft:sign"; - materials[324] = "minecraft:wooden_door"; - materials[325] = "minecraft:bucket"; - materials[326] = "minecraft:water_bucket"; - materials[327] = "minecraft:lava_bucket"; - materials[328] = "minecraft:minecart"; - materials[329] = "minecraft:saddle"; - materials[330] = "minecraft:iron_door"; - materials[331] = "minecraft:redstone"; - materials[332] = "minecraft:snowball"; - materials[333] = "minecraft:boat"; - materials[334] = "minecraft:leather"; - materials[335] = "minecraft:milk_bucket"; - materials[336] = "minecraft:brick"; - materials[337] = "minecraft:clay_ball"; - materials[338] = "minecraft:reeds"; - materials[339] = "minecraft:paper"; - materials[340] = "minecraft:book"; - materials[341] = "minecraft:slime_ball"; - materials[342] = "minecraft:chest_minecart"; - materials[343] = "minecraft:furnace_minecart"; - materials[344] = "minecraft:egg"; - materials[345] = "minecraft:compass"; - materials[346] = "minecraft:fishing_rod"; - materials[347] = "minecraft:clock"; - materials[348] = "minecraft:glowstone_dust"; - materials[349] = "minecraft:fish"; - materials[350] = "minecraft:cooked_fish"; // Paper - cooked_fished -> cooked_fish - materials[351] = "minecraft:dye"; - materials[352] = "minecraft:bone"; - materials[353] = "minecraft:sugar"; - materials[354] = "minecraft:cake"; - materials[355] = "minecraft:bed"; - materials[356] = "minecraft:repeater"; - materials[357] = "minecraft:cookie"; - materials[358] = "minecraft:filled_map"; - materials[359] = "minecraft:shears"; - materials[360] = "minecraft:melon"; - materials[361] = "minecraft:pumpkin_seeds"; - materials[362] = "minecraft:melon_seeds"; - materials[363] = "minecraft:beef"; - materials[364] = "minecraft:cooked_beef"; - materials[365] = "minecraft:chicken"; - materials[366] = "minecraft:cooked_chicken"; - materials[367] = "minecraft:rotten_flesh"; - materials[368] = "minecraft:ender_pearl"; - materials[369] = "minecraft:blaze_rod"; - materials[370] = "minecraft:ghast_tear"; - materials[371] = "minecraft:gold_nugget"; - materials[372] = "minecraft:nether_wart"; - materials[373] = "minecraft:potion"; - materials[374] = "minecraft:glass_bottle"; - materials[375] = "minecraft:spider_eye"; - materials[376] = "minecraft:fermented_spider_eye"; - materials[377] = "minecraft:blaze_powder"; - materials[378] = "minecraft:magma_cream"; - materials[379] = "minecraft:brewing_stand"; - materials[380] = "minecraft:cauldron"; - materials[381] = "minecraft:ender_eye"; - materials[382] = "minecraft:speckled_melon"; - materials[383] = "minecraft:spawn_egg"; - materials[384] = "minecraft:experience_bottle"; - materials[385] = "minecraft:fire_charge"; - materials[386] = "minecraft:writable_book"; - materials[387] = "minecraft:written_book"; - materials[388] = "minecraft:emerald"; - materials[389] = "minecraft:item_frame"; - materials[390] = "minecraft:flower_pot"; - materials[391] = "minecraft:carrot"; - materials[392] = "minecraft:potato"; - materials[393] = "minecraft:baked_potato"; - materials[394] = "minecraft:poisonous_potato"; - materials[395] = "minecraft:map"; - materials[396] = "minecraft:golden_carrot"; - materials[397] = "minecraft:skull"; - materials[398] = "minecraft:carrot_on_a_stick"; - materials[399] = "minecraft:nether_star"; - materials[400] = "minecraft:pumpkin_pie"; - materials[401] = "minecraft:fireworks"; - materials[402] = "minecraft:firework_charge"; - materials[403] = "minecraft:enchanted_book"; - materials[404] = "minecraft:comparator"; - materials[405] = "minecraft:netherbrick"; - materials[406] = "minecraft:quartz"; - materials[407] = "minecraft:tnt_minecart"; - materials[408] = "minecraft:hopper_minecart"; - materials[417] = "minecraft:iron_horse_armor"; - materials[418] = "minecraft:golden_horse_armor"; - materials[419] = "minecraft:diamond_horse_armor"; - materials[420] = "minecraft:lead"; - materials[421] = "minecraft:name_tag"; - materials[422] = "minecraft:command_block_minecart"; - materials[2256] = "minecraft:record_13"; - materials[2257] = "minecraft:record_cat"; - materials[2258] = "minecraft:record_blocks"; - materials[2259] = "minecraft:record_chirp"; - materials[2260] = "minecraft:record_far"; - materials[2261] = "minecraft:record_mall"; - materials[2262] = "minecraft:record_mellohi"; - materials[2263] = "minecraft:record_stal"; - materials[2264] = "minecraft:record_strad"; - materials[2265] = "minecraft:record_ward"; - materials[2266] = "minecraft:record_11"; - materials[2267] = "minecraft:record_wait"; - // Paper start - materials[409] = "minecraft:prismarine_shard"; - materials[410] = "minecraft:prismarine_crystals"; - materials[411] = "minecraft:rabbit"; - materials[412] = "minecraft:cooked_rabbit"; - materials[413] = "minecraft:rabbit_stew"; - materials[414] = "minecraft:rabbit_foot"; - materials[415] = "minecraft:rabbit_hide"; - materials[416] = "minecraft:armor_stand"; - materials[423] = "minecraft:mutton"; - materials[424] = "minecraft:cooked_mutton"; - materials[425] = "minecraft:banner"; - materials[426] = "minecraft:end_crystal"; - materials[427] = "minecraft:spruce_door"; - materials[428] = "minecraft:birch_door"; - materials[429] = "minecraft:jungle_door"; - materials[430] = "minecraft:acacia_door"; - materials[431] = "minecraft:dark_oak_door"; - materials[432] = "minecraft:chorus_fruit"; - materials[433] = "minecraft:chorus_fruit_popped"; - materials[434] = "minecraft:beetroot"; - materials[435] = "minecraft:beetroot_seeds"; - materials[436] = "minecraft:beetroot_soup"; - materials[437] = "minecraft:dragon_breath"; - materials[438] = "minecraft:splash_potion"; - materials[439] = "minecraft:spectral_arrow"; - materials[440] = "minecraft:tipped_arrow"; - materials[441] = "minecraft:lingering_potion"; - materials[442] = "minecraft:shield"; - materials[443] = "minecraft:elytra"; - materials[444] = "minecraft:spruce_boat"; - materials[445] = "minecraft:birch_boat"; - materials[446] = "minecraft:jungle_boat"; - materials[447] = "minecraft:acacia_boat"; - materials[448] = "minecraft:dark_oak_boat"; - materials[449] = "minecraft:totem_of_undying"; - materials[450] = "minecraft:shulker_shell"; - materials[452] = "minecraft:iron_nugget"; - materials[453] = "minecraft:knowledge_book"; - // Paper end - } - } - - private static class DataConverterArmorStand implements DataConverter { - - DataConverterArmorStand() { - } - - public int getDataVersion() { - return 147; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("ArmorStand".equals(cmp.getString("id")) && cmp.getBoolean("Silent") && !cmp.getBoolean("Marker")) { - cmp.remove("Silent"); - } - - return cmp; - } - } - - private static class DataConverterBanner implements DataConverter { - - DataConverterBanner() { - } - - public int getDataVersion() { - return 804; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:banner".equals(cmp.getString("id")) && cmp.contains("tag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - - if (nbttagcompound2.contains("Base", 99)) { - cmp.putShort("Damage", (short) (nbttagcompound2.getShort("Base") & 15)); - if (nbttagcompound1.contains("display", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound3 = nbttagcompound1.getCompound("display"); - - if (nbttagcompound3.contains("Lore", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound3.getList("Lore", 8); - - if (nbttaglist.size() == 1 && "(+NBT)".equals(nbttaglist.getString(0))) { - return cmp; - } - } - } - - nbttagcompound2.remove("Base"); - if (nbttagcompound2.isEmpty()) { - nbttagcompound1.remove("BlockEntityTag"); - } - - if (nbttagcompound1.isEmpty()) { - cmp.remove("tag"); - } - } - } - } - - return cmp; - } - } - - private static class DataConverterPotionId implements DataConverter { - - private static final String[] potions = new String[128]; - - DataConverterPotionId() { - } - - public int getDataVersion() { - return 102; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:potion".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - short short0 = cmp.getShort("Damage"); - - if (!nbttagcompound1.contains("Potion", 8)) { - String s = DataConverterPotionId.potions[short0 & 127]; - - nbttagcompound1.putString("Potion", s == null ? "minecraft:water" : s); - cmp.put("tag", nbttagcompound1); - if ((short0 & 16384) == 16384) { - cmp.putString("id", "minecraft:splash_potion"); - } - } - - if (short0 != 0) { - cmp.putShort("Damage", (short) 0); - } - } - - return cmp; - } - - static { - DataConverterPotionId.potions[0] = "minecraft:water"; - DataConverterPotionId.potions[1] = "minecraft:regeneration"; - DataConverterPotionId.potions[2] = "minecraft:swiftness"; - DataConverterPotionId.potions[3] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[4] = "minecraft:poison"; - DataConverterPotionId.potions[5] = "minecraft:healing"; - DataConverterPotionId.potions[6] = "minecraft:night_vision"; - DataConverterPotionId.potions[7] = null; - DataConverterPotionId.potions[8] = "minecraft:weakness"; - DataConverterPotionId.potions[9] = "minecraft:strength"; - DataConverterPotionId.potions[10] = "minecraft:slowness"; - DataConverterPotionId.potions[11] = "minecraft:leaping"; - DataConverterPotionId.potions[12] = "minecraft:harming"; - DataConverterPotionId.potions[13] = "minecraft:water_breathing"; - DataConverterPotionId.potions[14] = "minecraft:invisibility"; - DataConverterPotionId.potions[15] = null; - DataConverterPotionId.potions[16] = "minecraft:awkward"; - DataConverterPotionId.potions[17] = "minecraft:regeneration"; - DataConverterPotionId.potions[18] = "minecraft:swiftness"; - DataConverterPotionId.potions[19] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[20] = "minecraft:poison"; - DataConverterPotionId.potions[21] = "minecraft:healing"; - DataConverterPotionId.potions[22] = "minecraft:night_vision"; - DataConverterPotionId.potions[23] = null; - DataConverterPotionId.potions[24] = "minecraft:weakness"; - DataConverterPotionId.potions[25] = "minecraft:strength"; - DataConverterPotionId.potions[26] = "minecraft:slowness"; - DataConverterPotionId.potions[27] = "minecraft:leaping"; - DataConverterPotionId.potions[28] = "minecraft:harming"; - DataConverterPotionId.potions[29] = "minecraft:water_breathing"; - DataConverterPotionId.potions[30] = "minecraft:invisibility"; - DataConverterPotionId.potions[31] = null; - DataConverterPotionId.potions[32] = "minecraft:thick"; - DataConverterPotionId.potions[33] = "minecraft:strong_regeneration"; - DataConverterPotionId.potions[34] = "minecraft:strong_swiftness"; - DataConverterPotionId.potions[35] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[36] = "minecraft:strong_poison"; - DataConverterPotionId.potions[37] = "minecraft:strong_healing"; - DataConverterPotionId.potions[38] = "minecraft:night_vision"; - DataConverterPotionId.potions[39] = null; - DataConverterPotionId.potions[40] = "minecraft:weakness"; - DataConverterPotionId.potions[41] = "minecraft:strong_strength"; - DataConverterPotionId.potions[42] = "minecraft:slowness"; - DataConverterPotionId.potions[43] = "minecraft:strong_leaping"; - DataConverterPotionId.potions[44] = "minecraft:strong_harming"; - DataConverterPotionId.potions[45] = "minecraft:water_breathing"; - DataConverterPotionId.potions[46] = "minecraft:invisibility"; - DataConverterPotionId.potions[47] = null; - DataConverterPotionId.potions[48] = null; - DataConverterPotionId.potions[49] = "minecraft:strong_regeneration"; - DataConverterPotionId.potions[50] = "minecraft:strong_swiftness"; - DataConverterPotionId.potions[51] = "minecraft:fire_resistance"; - DataConverterPotionId.potions[52] = "minecraft:strong_poison"; - DataConverterPotionId.potions[53] = "minecraft:strong_healing"; - DataConverterPotionId.potions[54] = "minecraft:night_vision"; - DataConverterPotionId.potions[55] = null; - DataConverterPotionId.potions[56] = "minecraft:weakness"; - DataConverterPotionId.potions[57] = "minecraft:strong_strength"; - DataConverterPotionId.potions[58] = "minecraft:slowness"; - DataConverterPotionId.potions[59] = "minecraft:strong_leaping"; - DataConverterPotionId.potions[60] = "minecraft:strong_harming"; - DataConverterPotionId.potions[61] = "minecraft:water_breathing"; - DataConverterPotionId.potions[62] = "minecraft:invisibility"; - DataConverterPotionId.potions[63] = null; - DataConverterPotionId.potions[64] = "minecraft:mundane"; - DataConverterPotionId.potions[65] = "minecraft:long_regeneration"; - DataConverterPotionId.potions[66] = "minecraft:long_swiftness"; - DataConverterPotionId.potions[67] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[68] = "minecraft:long_poison"; - DataConverterPotionId.potions[69] = "minecraft:healing"; - DataConverterPotionId.potions[70] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[71] = null; - DataConverterPotionId.potions[72] = "minecraft:long_weakness"; - DataConverterPotionId.potions[73] = "minecraft:long_strength"; - DataConverterPotionId.potions[74] = "minecraft:long_slowness"; - DataConverterPotionId.potions[75] = "minecraft:long_leaping"; - DataConverterPotionId.potions[76] = "minecraft:harming"; - DataConverterPotionId.potions[77] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[78] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[79] = null; - DataConverterPotionId.potions[80] = "minecraft:awkward"; - DataConverterPotionId.potions[81] = "minecraft:long_regeneration"; - DataConverterPotionId.potions[82] = "minecraft:long_swiftness"; - DataConverterPotionId.potions[83] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[84] = "minecraft:long_poison"; - DataConverterPotionId.potions[85] = "minecraft:healing"; - DataConverterPotionId.potions[86] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[87] = null; - DataConverterPotionId.potions[88] = "minecraft:long_weakness"; - DataConverterPotionId.potions[89] = "minecraft:long_strength"; - DataConverterPotionId.potions[90] = "minecraft:long_slowness"; - DataConverterPotionId.potions[91] = "minecraft:long_leaping"; - DataConverterPotionId.potions[92] = "minecraft:harming"; - DataConverterPotionId.potions[93] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[94] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[95] = null; - DataConverterPotionId.potions[96] = "minecraft:thick"; - DataConverterPotionId.potions[97] = "minecraft:regeneration"; - DataConverterPotionId.potions[98] = "minecraft:swiftness"; - DataConverterPotionId.potions[99] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[100] = "minecraft:poison"; - DataConverterPotionId.potions[101] = "minecraft:strong_healing"; - DataConverterPotionId.potions[102] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[103] = null; - DataConverterPotionId.potions[104] = "minecraft:long_weakness"; - DataConverterPotionId.potions[105] = "minecraft:strength"; - DataConverterPotionId.potions[106] = "minecraft:long_slowness"; - DataConverterPotionId.potions[107] = "minecraft:leaping"; - DataConverterPotionId.potions[108] = "minecraft:strong_harming"; - DataConverterPotionId.potions[109] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[110] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[111] = null; - DataConverterPotionId.potions[112] = null; - DataConverterPotionId.potions[113] = "minecraft:regeneration"; - DataConverterPotionId.potions[114] = "minecraft:swiftness"; - DataConverterPotionId.potions[115] = "minecraft:long_fire_resistance"; - DataConverterPotionId.potions[116] = "minecraft:poison"; - DataConverterPotionId.potions[117] = "minecraft:strong_healing"; - DataConverterPotionId.potions[118] = "minecraft:long_night_vision"; - DataConverterPotionId.potions[119] = null; - DataConverterPotionId.potions[120] = "minecraft:long_weakness"; - DataConverterPotionId.potions[121] = "minecraft:strength"; - DataConverterPotionId.potions[122] = "minecraft:long_slowness"; - DataConverterPotionId.potions[123] = "minecraft:leaping"; - DataConverterPotionId.potions[124] = "minecraft:strong_harming"; - DataConverterPotionId.potions[125] = "minecraft:long_water_breathing"; - DataConverterPotionId.potions[126] = "minecraft:long_invisibility"; - DataConverterPotionId.potions[127] = null; - } - } - - private static class DataConverterSpawnEgg implements DataConverter { - - private static final String[] eggs = new String[256]; - - DataConverterSpawnEgg() { - } - - public int getDataVersion() { - return 105; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:spawn_egg".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("EntityTag"); - short short0 = cmp.getShort("Damage"); - - if (!nbttagcompound2.contains("id", 8)) { - String s = DataConverterSpawnEgg.eggs[short0 & 255]; - - if (s != null) { - nbttagcompound2.putString("id", s); - nbttagcompound1.put("EntityTag", nbttagcompound2); - cmp.put("tag", nbttagcompound1); - } - } - - if (short0 != 0) { - cmp.putShort("Damage", (short) 0); - } - } - - return cmp; - } - - static { - - DataConverterSpawnEgg.eggs[1] = "Item"; - DataConverterSpawnEgg.eggs[2] = "XPOrb"; - DataConverterSpawnEgg.eggs[7] = "ThrownEgg"; - DataConverterSpawnEgg.eggs[8] = "LeashKnot"; - DataConverterSpawnEgg.eggs[9] = "Painting"; - DataConverterSpawnEgg.eggs[10] = "Arrow"; - DataConverterSpawnEgg.eggs[11] = "Snowball"; - DataConverterSpawnEgg.eggs[12] = "Fireball"; - DataConverterSpawnEgg.eggs[13] = "SmallFireball"; - DataConverterSpawnEgg.eggs[14] = "ThrownEnderpearl"; - DataConverterSpawnEgg.eggs[15] = "EyeOfEnderSignal"; - DataConverterSpawnEgg.eggs[16] = "ThrownPotion"; - DataConverterSpawnEgg.eggs[17] = "ThrownExpBottle"; - DataConverterSpawnEgg.eggs[18] = "ItemFrame"; - DataConverterSpawnEgg.eggs[19] = "WitherSkull"; - DataConverterSpawnEgg.eggs[20] = "PrimedTnt"; - DataConverterSpawnEgg.eggs[21] = "FallingSand"; - DataConverterSpawnEgg.eggs[22] = "FireworksRocketEntity"; - DataConverterSpawnEgg.eggs[23] = "TippedArrow"; - DataConverterSpawnEgg.eggs[24] = "SpectralArrow"; - DataConverterSpawnEgg.eggs[25] = "ShulkerBullet"; - DataConverterSpawnEgg.eggs[26] = "DragonFireball"; - DataConverterSpawnEgg.eggs[30] = "ArmorStand"; - DataConverterSpawnEgg.eggs[41] = "Boat"; - DataConverterSpawnEgg.eggs[42] = "MinecartRideable"; - DataConverterSpawnEgg.eggs[43] = "MinecartChest"; - DataConverterSpawnEgg.eggs[44] = "MinecartFurnace"; - DataConverterSpawnEgg.eggs[45] = "MinecartTNT"; - DataConverterSpawnEgg.eggs[46] = "MinecartHopper"; - DataConverterSpawnEgg.eggs[47] = "MinecartSpawner"; - DataConverterSpawnEgg.eggs[40] = "MinecartCommandBlock"; - DataConverterSpawnEgg.eggs[48] = "Mob"; - DataConverterSpawnEgg.eggs[49] = "Monster"; - DataConverterSpawnEgg.eggs[50] = "Creeper"; - DataConverterSpawnEgg.eggs[51] = "Skeleton"; - DataConverterSpawnEgg.eggs[52] = "Spider"; - DataConverterSpawnEgg.eggs[53] = "Giant"; - DataConverterSpawnEgg.eggs[54] = "Zombie"; - DataConverterSpawnEgg.eggs[55] = "Slime"; - DataConverterSpawnEgg.eggs[56] = "Ghast"; - DataConverterSpawnEgg.eggs[57] = "PigZombie"; - DataConverterSpawnEgg.eggs[58] = "Enderman"; - DataConverterSpawnEgg.eggs[59] = "CaveSpider"; - DataConverterSpawnEgg.eggs[60] = "Silverfish"; - DataConverterSpawnEgg.eggs[61] = "Blaze"; - DataConverterSpawnEgg.eggs[62] = "LavaSlime"; - DataConverterSpawnEgg.eggs[63] = "EnderDragon"; - DataConverterSpawnEgg.eggs[64] = "WitherBoss"; - DataConverterSpawnEgg.eggs[65] = "Bat"; - DataConverterSpawnEgg.eggs[66] = "Witch"; - DataConverterSpawnEgg.eggs[67] = "Endermite"; - DataConverterSpawnEgg.eggs[68] = "Guardian"; - DataConverterSpawnEgg.eggs[69] = "Shulker"; - DataConverterSpawnEgg.eggs[90] = "Pig"; - DataConverterSpawnEgg.eggs[91] = "Sheep"; - DataConverterSpawnEgg.eggs[92] = "Cow"; - DataConverterSpawnEgg.eggs[93] = "Chicken"; - DataConverterSpawnEgg.eggs[94] = "Squid"; - DataConverterSpawnEgg.eggs[95] = "Wolf"; - DataConverterSpawnEgg.eggs[96] = "MushroomCow"; - DataConverterSpawnEgg.eggs[97] = "SnowMan"; - DataConverterSpawnEgg.eggs[98] = "Ozelot"; - DataConverterSpawnEgg.eggs[99] = "VillagerGolem"; - DataConverterSpawnEgg.eggs[100] = "EntityHorse"; - DataConverterSpawnEgg.eggs[101] = "Rabbit"; - DataConverterSpawnEgg.eggs[120] = "Villager"; - DataConverterSpawnEgg.eggs[200] = "EnderCrystal"; - } - } - - private static class DataConverterMinecart implements DataConverter { - - private static final List a = Lists.newArrayList("MinecartRideable", "MinecartChest", "MinecartFurnace", "MinecartTNT", "MinecartSpawner", "MinecartHopper", "MinecartCommandBlock"); - - DataConverterMinecart() { - } - - public int getDataVersion() { - return 106; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Minecart".equals(cmp.getString("id"))) { - String s = "MinecartRideable"; - int i = cmp.getInt("Type"); - - if (i > 0 && i < DataConverterMinecart.a.size()) { - s = DataConverterMinecart.a.get(i); - } - - cmp.putString("id", s); - cmp.remove("Type"); - } - - return cmp; - } - } - - private static class DataConverterMobSpawner implements DataConverter { - - DataConverterMobSpawner() { - } - - public int getDataVersion() { - return 107; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (!"MobSpawner".equals(cmp.getString("id"))) { - return cmp; - } else { - if (cmp.contains("EntityId", 8)) { - String s = cmp.getString("EntityId"); - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("SpawnData"); - - nbttagcompound1.putString("id", s.isEmpty() ? "Pig" : s); - cmp.put("SpawnData", nbttagcompound1); - cmp.remove("EntityId"); - } - - if (cmp.contains("SpawnPotentials", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("SpawnPotentials", 10); - - for (int i = 0; i < nbttaglist.size(); ++i) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompound(i); - - if (nbttagcompound2.contains("Type", 8)) { - net.minecraft.nbt.CompoundTag nbttagcompound3 = nbttagcompound2.getCompound("Properties"); - - nbttagcompound3.putString("id", nbttagcompound2.getString("Type")); - nbttagcompound2.put("Entity", nbttagcompound3); - nbttagcompound2.remove("Type"); - nbttagcompound2.remove("Properties"); - } - } - } - - return cmp; - } - } - } - - private static class DataConverterUUID implements DataConverter { - - DataConverterUUID() { - } - - public int getDataVersion() { - return 108; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("UUID", 8)) { - cmp.putUUID("UUID", UUID.fromString(cmp.getString("UUID"))); - } - - return cmp; - } - } - - private static class DataConverterHealth implements DataConverter { - - private static final Set a = Sets.newHashSet("ArmorStand", "Bat", "Blaze", "CaveSpider", "Chicken", "Cow", "Creeper", "EnderDragon", "Enderman", "Endermite", "EntityHorse", "Ghast", "Giant", "Guardian", "LavaSlime", "MushroomCow", "Ozelot", "Pig", "PigZombie", "Rabbit", "Sheep", "Shulker", "Silverfish", "Skeleton", "Slime", "SnowMan", "Spider", "Squid", "Villager", "VillagerGolem", "Witch", "WitherBoss", "Wolf", "Zombie"); - - DataConverterHealth() { - } - - public int getDataVersion() { - return 109; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (DataConverterHealth.a.contains(cmp.getString("id"))) { - float f; - - if (cmp.contains("HealF", 99)) { - f = cmp.getFloat("HealF"); - cmp.remove("HealF"); - } else { - if (!cmp.contains("Health", 99)) { - return cmp; - } - - f = cmp.getFloat("Health"); - } - - cmp.putFloat("Health", f); - } - - return cmp; - } - } - - private static class DataConverterSaddle implements DataConverter { - - DataConverterSaddle() { - } - - public int getDataVersion() { - return 110; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("EntityHorse".equals(cmp.getString("id")) && !cmp.contains("SaddleItem", 10) && cmp.getBoolean("Saddle")) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = new net.minecraft.nbt.CompoundTag(); - - nbttagcompound1.putString("id", "minecraft:saddle"); - nbttagcompound1.putByte("Count", (byte) 1); - nbttagcompound1.putShort("Damage", (short) 0); - cmp.put("SaddleItem", nbttagcompound1); - cmp.remove("Saddle"); - } - - return cmp; - } - } - - private static class DataConverterHanging implements DataConverter { - - DataConverterHanging() { - } - - public int getDataVersion() { - return 111; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - boolean flag = "Painting".equals(s); - boolean flag1 = "ItemFrame".equals(s); - - if ((flag || flag1) && !cmp.contains("Facing", 99)) { - Direction enumdirection; - - if (cmp.contains("Direction", 99)) { - enumdirection = Direction.from2DDataValue(cmp.getByte("Direction")); - cmp.putInt("TileX", cmp.getInt("TileX") + enumdirection.getStepX()); - cmp.putInt("TileY", cmp.getInt("TileY") + enumdirection.getStepY()); - cmp.putInt("TileZ", cmp.getInt("TileZ") + enumdirection.getStepZ()); - cmp.remove("Direction"); - if (flag1 && cmp.contains("ItemRotation", 99)) { - cmp.putByte("ItemRotation", (byte) (cmp.getByte("ItemRotation") * 2)); - } - } else { - enumdirection = Direction.from2DDataValue(cmp.getByte("Dir")); - cmp.remove("Dir"); - } - - cmp.putByte("Facing", (byte) enumdirection.get2DDataValue()); - } - - return cmp; - } - } - - private static class DataConverterDropChances implements DataConverter { - - DataConverterDropChances() { - } - - public int getDataVersion() { - return 113; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - net.minecraft.nbt.ListTag nbttaglist; - - if (cmp.contains("HandDropChances", 9)) { - nbttaglist = cmp.getList("HandDropChances", 5); - if (nbttaglist.size() == 2 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F) { - cmp.remove("HandDropChances"); - } - } - - if (cmp.contains("ArmorDropChances", 9)) { - nbttaglist = cmp.getList("ArmorDropChances", 5); - if (nbttaglist.size() == 4 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F && nbttaglist.getFloat(2) == 0.0F && nbttaglist.getFloat(3) == 0.0F) { - cmp.remove("ArmorDropChances"); - } - } - - return cmp; - } - } - - private static class DataConverterRiding implements DataConverter { - - DataConverterRiding() { - } - - public int getDataVersion() { - return 135; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - while (cmp.contains("Riding", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = this.b(cmp); - - this.convert(cmp, nbttagcompound1); - cmp = nbttagcompound1; - } - - return cmp; - } - - protected void convert(net.minecraft.nbt.CompoundTag nbttagcompound, net.minecraft.nbt.CompoundTag nbttagcompound1) { - net.minecraft.nbt.ListTag nbttaglist = new net.minecraft.nbt.ListTag(); - - nbttaglist.add(nbttagcompound); - nbttagcompound1.put("Passengers", nbttaglist); - } - - protected net.minecraft.nbt.CompoundTag b(net.minecraft.nbt.CompoundTag nbttagcompound) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttagcompound.getCompound("Riding"); - - nbttagcompound.remove("Riding"); - return nbttagcompound1; - } - } - - private static class DataConverterBook implements DataConverter { - - DataConverterBook() { - } - - public int getDataVersion() { - return 165; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:written_book".equals(cmp.getString("id"))) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("pages", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("pages", 8); - - for (int i = 0; i < nbttaglist.size(); ++i) { - String s = nbttaglist.getString(i); - Component object = null; - - if (!"null".equals(s) && !StringUtil.isNullOrEmpty(s)) { - if ((s.charAt(0) != 34 || s.charAt(s.length() - 1) != 34) && (s.charAt(0) != 123 || s.charAt(s.length() - 1) != 125)) { - object = Component.literal(s); - } else { - try { - object = GsonHelper.fromJson(DataConverterSignText.a, s, Component.class, true); - if (object == null) { - object = Component.literal(""); - } - } catch (JsonParseException jsonparseexception) { - ; - } - - if (object == null) { - try { - object = Component.Serializer.fromJson(s); - } catch (JsonParseException jsonparseexception1) { - ; - } - } - - if (object == null) { - try { - object = Component.Serializer.fromJsonLenient(s); - } catch (JsonParseException jsonparseexception2) { - ; - } - } - - if (object == null) { - object = Component.literal(s); - } - } - } else { - object = Component.literal(""); - } - - nbttaglist.set(i, net.minecraft.nbt.StringTag.valueOf(Component.Serializer.toJson(object))); - } - - nbttagcompound1.put("pages", nbttaglist); - } - } - - return cmp; - } - } - - private static class DataConverterCookedFish implements DataConverter { - - private static final ResourceLocation a = new ResourceLocation("cooked_fished"); - - DataConverterCookedFish() { - } - - public int getDataVersion() { - return 502; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("id", 8) && DataConverterCookedFish.a.equals(new ResourceLocation(cmp.getString("id")))) { - cmp.putString("id", "minecraft:cooked_fish"); - } - - return cmp; - } - } - - private static class DataConverterZombie implements DataConverter { - - private static final Random a = new Random(); - - DataConverterZombie() { - } - - public int getDataVersion() { - return 502; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Zombie".equals(cmp.getString("id")) && cmp.getBoolean("IsVillager")) { - if (!cmp.contains("ZombieType", 99)) { - int i = -1; - - if (cmp.contains("VillagerProfession", 99)) { - try { - i = this.convert(cmp.getInt("VillagerProfession")); - } catch (RuntimeException runtimeexception) { - ; - } - } - - if (i == -1) { - i = this.convert(DataConverterZombie.a.nextInt(6)); - } - - cmp.putInt("ZombieType", i); - } - - cmp.remove("IsVillager"); - } - - return cmp; - } - - private int convert(int i) { - return i >= 0 && i < 6 ? i : -1; - } - } - - private static class DataConverterVBO implements DataConverter { - - DataConverterVBO() { - } - - public int getDataVersion() { - return 505; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - cmp.putString("useVbo", "true"); - return cmp; - } - } - - private static class DataConverterGuardian implements DataConverter { - - DataConverterGuardian() { - } - - public int getDataVersion() { - return 700; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Guardian".equals(cmp.getString("id"))) { - if (cmp.getBoolean("Elder")) { - cmp.putString("id", "ElderGuardian"); - } - - cmp.remove("Elder"); - } - - return cmp; - } - } - - private static class DataConverterSkeleton implements DataConverter { - - DataConverterSkeleton() { - } - - public int getDataVersion() { - return 701; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - - if ("Skeleton".equals(s)) { - int i = cmp.getInt("SkeletonType"); - - if (i == 1) { - cmp.putString("id", "WitherSkeleton"); - } else if (i == 2) { - cmp.putString("id", "Stray"); - } - - cmp.remove("SkeletonType"); - } - - return cmp; - } - } - - private static class DataConverterZombieType implements DataConverter { - - DataConverterZombieType() { - } - - public int getDataVersion() { - return 702; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Zombie".equals(cmp.getString("id"))) { - int i = cmp.getInt("ZombieType"); - - switch (i) { - case 0: - default: - break; - - case 1: - case 2: - case 3: - case 4: - case 5: - cmp.putString("id", "ZombieVillager"); - cmp.putInt("Profession", i - 1); - break; - - case 6: - cmp.putString("id", "Husk"); - } - - cmp.remove("ZombieType"); - } - - return cmp; - } - } - - private static class DataConverterHorse implements DataConverter { - - DataConverterHorse() { - } - - public int getDataVersion() { - return 703; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("EntityHorse".equals(cmp.getString("id"))) { - int i = cmp.getInt("Type"); - - switch (i) { - case 0: - default: - cmp.putString("id", "Horse"); - break; - - case 1: - cmp.putString("id", "Donkey"); - break; - - case 2: - cmp.putString("id", "Mule"); - break; - - case 3: - cmp.putString("id", "ZombieHorse"); - break; - - case 4: - cmp.putString("id", "SkeletonHorse"); - } - - cmp.remove("Type"); - } - - return cmp; - } - } - - private static class DataConverterTileEntity implements DataConverter { - - private static final Map a = Maps.newHashMap(); - - DataConverterTileEntity() { - } - - public int getDataVersion() { - return 704; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = DataConverterTileEntity.a.get(cmp.getString("id")); - - if (s != null) { - cmp.putString("id", s); - } - - return cmp; - } - - static { - DataConverterTileEntity.a.put("Airportal", "minecraft:end_portal"); - DataConverterTileEntity.a.put("Banner", "minecraft:banner"); - DataConverterTileEntity.a.put("Beacon", "minecraft:beacon"); - DataConverterTileEntity.a.put("Cauldron", "minecraft:brewing_stand"); - DataConverterTileEntity.a.put("Chest", "minecraft:chest"); - DataConverterTileEntity.a.put("Comparator", "minecraft:comparator"); - DataConverterTileEntity.a.put("Control", "minecraft:command_block"); - DataConverterTileEntity.a.put("DLDetector", "minecraft:daylight_detector"); - DataConverterTileEntity.a.put("Dropper", "minecraft:dropper"); - DataConverterTileEntity.a.put("EnchantTable", "minecraft:enchanting_table"); - DataConverterTileEntity.a.put("EndGateway", "minecraft:end_gateway"); - DataConverterTileEntity.a.put("EnderChest", "minecraft:ender_chest"); - DataConverterTileEntity.a.put("FlowerPot", "minecraft:flower_pot"); - DataConverterTileEntity.a.put("Furnace", "minecraft:furnace"); - DataConverterTileEntity.a.put("Hopper", "minecraft:hopper"); - DataConverterTileEntity.a.put("MobSpawner", "minecraft:mob_spawner"); - DataConverterTileEntity.a.put("Music", "minecraft:noteblock"); - DataConverterTileEntity.a.put("Piston", "minecraft:piston"); - DataConverterTileEntity.a.put("RecordPlayer", "minecraft:jukebox"); - DataConverterTileEntity.a.put("Sign", "minecraft:sign"); - DataConverterTileEntity.a.put("Skull", "minecraft:skull"); - DataConverterTileEntity.a.put("Structure", "minecraft:structure_block"); - DataConverterTileEntity.a.put("Trap", "minecraft:dispenser"); - } - } - - private static class DataConverterEntity implements DataConverter { - - private static final Map a = Maps.newHashMap(); - - DataConverterEntity() { - } - - public int getDataVersion() { - return 704; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = DataConverterEntity.a.get(cmp.getString("id")); - - if (s != null) { - cmp.putString("id", s); - } - - return cmp; - } - - static { - DataConverterEntity.a.put("AreaEffectCloud", "minecraft:area_effect_cloud"); - DataConverterEntity.a.put("ArmorStand", "minecraft:armor_stand"); - DataConverterEntity.a.put("Arrow", "minecraft:arrow"); - DataConverterEntity.a.put("Bat", "minecraft:bat"); - DataConverterEntity.a.put("Blaze", "minecraft:blaze"); - DataConverterEntity.a.put("Boat", "minecraft:boat"); - DataConverterEntity.a.put("CaveSpider", "minecraft:cave_spider"); - DataConverterEntity.a.put("Chicken", "minecraft:chicken"); - DataConverterEntity.a.put("Cow", "minecraft:cow"); - DataConverterEntity.a.put("Creeper", "minecraft:creeper"); - DataConverterEntity.a.put("Donkey", "minecraft:donkey"); - DataConverterEntity.a.put("DragonFireball", "minecraft:dragon_fireball"); - DataConverterEntity.a.put("ElderGuardian", "minecraft:elder_guardian"); - DataConverterEntity.a.put("EnderCrystal", "minecraft:ender_crystal"); - DataConverterEntity.a.put("EnderDragon", "minecraft:ender_dragon"); - DataConverterEntity.a.put("Enderman", "minecraft:enderman"); - DataConverterEntity.a.put("Endermite", "minecraft:endermite"); - DataConverterEntity.a.put("EyeOfEnderSignal", "minecraft:eye_of_ender_signal"); - DataConverterEntity.a.put("FallingSand", "minecraft:falling_block"); - DataConverterEntity.a.put("Fireball", "minecraft:fireball"); - DataConverterEntity.a.put("FireworksRocketEntity", "minecraft:fireworks_rocket"); - DataConverterEntity.a.put("Ghast", "minecraft:ghast"); - DataConverterEntity.a.put("Giant", "minecraft:giant"); - DataConverterEntity.a.put("Guardian", "minecraft:guardian"); - DataConverterEntity.a.put("Horse", "minecraft:horse"); - DataConverterEntity.a.put("Husk", "minecraft:husk"); - DataConverterEntity.a.put("Item", "minecraft:item"); - DataConverterEntity.a.put("ItemFrame", "minecraft:item_frame"); - DataConverterEntity.a.put("LavaSlime", "minecraft:magma_cube"); - DataConverterEntity.a.put("LeashKnot", "minecraft:leash_knot"); - DataConverterEntity.a.put("MinecartChest", "minecraft:chest_minecart"); - DataConverterEntity.a.put("MinecartCommandBlock", "minecraft:commandblock_minecart"); - DataConverterEntity.a.put("MinecartFurnace", "minecraft:furnace_minecart"); - DataConverterEntity.a.put("MinecartHopper", "minecraft:hopper_minecart"); - DataConverterEntity.a.put("MinecartRideable", "minecraft:minecart"); - DataConverterEntity.a.put("MinecartSpawner", "minecraft:spawner_minecart"); - DataConverterEntity.a.put("MinecartTNT", "minecraft:tnt_minecart"); - DataConverterEntity.a.put("Mule", "minecraft:mule"); - DataConverterEntity.a.put("MushroomCow", "minecraft:mooshroom"); - DataConverterEntity.a.put("Ozelot", "minecraft:ocelot"); - DataConverterEntity.a.put("Painting", "minecraft:painting"); - DataConverterEntity.a.put("Pig", "minecraft:pig"); - DataConverterEntity.a.put("PigZombie", "minecraft:zombie_pigman"); - DataConverterEntity.a.put("PolarBear", "minecraft:polar_bear"); - DataConverterEntity.a.put("PrimedTnt", "minecraft:tnt"); - DataConverterEntity.a.put("Rabbit", "minecraft:rabbit"); - DataConverterEntity.a.put("Sheep", "minecraft:sheep"); - DataConverterEntity.a.put("Shulker", "minecraft:shulker"); - DataConverterEntity.a.put("ShulkerBullet", "minecraft:shulker_bullet"); - DataConverterEntity.a.put("Silverfish", "minecraft:silverfish"); - DataConverterEntity.a.put("Skeleton", "minecraft:skeleton"); - DataConverterEntity.a.put("SkeletonHorse", "minecraft:skeleton_horse"); - DataConverterEntity.a.put("Slime", "minecraft:slime"); - DataConverterEntity.a.put("SmallFireball", "minecraft:small_fireball"); - DataConverterEntity.a.put("SnowMan", "minecraft:snowman"); - DataConverterEntity.a.put("Snowball", "minecraft:snowball"); - DataConverterEntity.a.put("SpectralArrow", "minecraft:spectral_arrow"); - DataConverterEntity.a.put("Spider", "minecraft:spider"); - DataConverterEntity.a.put("Squid", "minecraft:squid"); - DataConverterEntity.a.put("Stray", "minecraft:stray"); - DataConverterEntity.a.put("ThrownEgg", "minecraft:egg"); - DataConverterEntity.a.put("ThrownEnderpearl", "minecraft:ender_pearl"); - DataConverterEntity.a.put("ThrownExpBottle", "minecraft:xp_bottle"); - DataConverterEntity.a.put("ThrownPotion", "minecraft:potion"); - DataConverterEntity.a.put("Villager", "minecraft:villager"); - DataConverterEntity.a.put("VillagerGolem", "minecraft:villager_golem"); - DataConverterEntity.a.put("Witch", "minecraft:witch"); - DataConverterEntity.a.put("WitherBoss", "minecraft:wither"); - DataConverterEntity.a.put("WitherSkeleton", "minecraft:wither_skeleton"); - DataConverterEntity.a.put("WitherSkull", "minecraft:wither_skull"); - DataConverterEntity.a.put("Wolf", "minecraft:wolf"); - DataConverterEntity.a.put("XPOrb", "minecraft:xp_orb"); - DataConverterEntity.a.put("Zombie", "minecraft:zombie"); - DataConverterEntity.a.put("ZombieHorse", "minecraft:zombie_horse"); - DataConverterEntity.a.put("ZombieVillager", "minecraft:zombie_villager"); - } - } - - private static class DataConverterPotionWater implements DataConverter { - - DataConverterPotionWater() { - } - - public int getDataVersion() { - return 806; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - String s = cmp.getString("id"); - - if ("minecraft:potion".equals(s) || "minecraft:splash_potion".equals(s) || "minecraft:lingering_potion".equals(s) || "minecraft:tipped_arrow".equals(s)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (!nbttagcompound1.contains("Potion", 8)) { - nbttagcompound1.putString("Potion", "minecraft:water"); - } - - if (!cmp.contains("tag", 10)) { - cmp.put("tag", nbttagcompound1); - } - } - - return cmp; - } - } - - private static class DataConverterShulker implements DataConverter { - - DataConverterShulker() { - } - - public int getDataVersion() { - return 808; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker".equals(cmp.getString("id")) && !cmp.contains("Color", 99)) { - cmp.putByte("Color", (byte) 10); - } - - return cmp; - } - } - - private static class DataConverterShulkerBoxItem implements DataConverter { - - public static final String[] a = new String[] { "minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box" }; - - DataConverterShulkerBoxItem() { - } - - public int getDataVersion() { - return 813; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker_box".equals(cmp.getString("id")) && cmp.contains("tag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); - - if (nbttagcompound1.contains("BlockEntityTag", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompound("BlockEntityTag"); - - if (nbttagcompound2.getList("Items", 10).isEmpty()) { - nbttagcompound2.remove("Items"); - } - - int i = nbttagcompound2.getInt("Color"); - - nbttagcompound2.remove("Color"); - if (nbttagcompound2.isEmpty()) { - nbttagcompound1.remove("BlockEntityTag"); - } - - if (nbttagcompound1.isEmpty()) { - cmp.remove("tag"); - } - - cmp.putString("id", DataConverterShulkerBoxItem.a[i % 16]); - } - } - - return cmp; - } - } - - private static class DataConverterShulkerBoxBlock implements DataConverter { - - DataConverterShulkerBoxBlock() { - } - - public int getDataVersion() { - return 813; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:shulker".equals(cmp.getString("id"))) { - cmp.remove("Color"); - } - - return cmp; - } - } - - private static class DataConverterLang implements DataConverter { - - DataConverterLang() { - } - - public int getDataVersion() { - return 816; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if (cmp.contains("lang", 8)) { - cmp.putString("lang", cmp.getString("lang").toLowerCase(Locale.ROOT)); - } - - return cmp; - } - } - - private static class DataConverterTotem implements DataConverter { - - DataConverterTotem() { - } - - public int getDataVersion() { - return 820; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:totem".equals(cmp.getString("id"))) { - cmp.putString("id", "minecraft:totem_of_undying"); - } - - return cmp; - } - } - - private static class DataConverterBedBlock implements DataConverter { - - private static final Logger a = LogManager.getLogger(PaperweightDataConverters.class); - - DataConverterBedBlock() { - } - - public int getDataVersion() { - return 1125; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - try { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Level"); - int i = nbttagcompound1.getInt("xPos"); - int j = nbttagcompound1.getInt("zPos"); - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("TileEntities", 10); - net.minecraft.nbt.ListTag nbttaglist1 = nbttagcompound1.getList("Sections", 10); - - for (int k = 0; k < nbttaglist1.size(); ++k) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist1.getCompound(k); - byte b0 = nbttagcompound2.getByte("Y"); - byte[] abyte = nbttagcompound2.getByteArray("Blocks"); - - for (int l = 0; l < abyte.length; ++l) { - if (416 == (abyte[l] & 255) << 4) { - int i1 = l & 15; - int j1 = l >> 8 & 15; - int k1 = l >> 4 & 15; - net.minecraft.nbt.CompoundTag nbttagcompound3 = new net.minecraft.nbt.CompoundTag(); - - nbttagcompound3.putString("id", "bed"); - nbttagcompound3.putInt("x", i1 + (i << 4)); - nbttagcompound3.putInt("y", j1 + (b0 << 4)); - nbttagcompound3.putInt("z", k1 + (j << 4)); - nbttaglist.add(nbttagcompound3); - } - } - } - } catch (Exception exception) { - DataConverterBedBlock.a.warn("Unable to datafix Bed blocks, level format may be missing tags."); - } - - return cmp; - } - } - - private static class DataConverterBedItem implements DataConverter { - - DataConverterBedItem() { - } - - public int getDataVersion() { - return 1125; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("minecraft:bed".equals(cmp.getString("id")) && cmp.getShort("Damage") == 0) { - cmp.putShort("Damage", (short) DyeColor.RED.getId()); - } - - return cmp; - } - } - - private static class DataConverterSignText implements DataConverter { - - public static final Gson a = new GsonBuilder().registerTypeAdapter(Component.class, new JsonDeserializer() { - MutableComponent a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { - if (jsonelement.isJsonPrimitive()) { - return Component.literal(jsonelement.getAsString()); - } else if (jsonelement.isJsonArray()) { - JsonArray jsonarray = jsonelement.getAsJsonArray(); - MutableComponent ichatbasecomponent = null; - Iterator iterator = jsonarray.iterator(); - - while (iterator.hasNext()) { - JsonElement jsonelement1 = (JsonElement) iterator.next(); - MutableComponent ichatbasecomponent1 = this.a(jsonelement1, jsonelement1.getClass(), jsondeserializationcontext); - - if (ichatbasecomponent == null) { - ichatbasecomponent = ichatbasecomponent1; - } else { - ichatbasecomponent.append(ichatbasecomponent1); - } - } - - return ichatbasecomponent; - } else { - throw new JsonParseException("Don't know how to turn " + jsonelement + " into a Component"); - } - } - - public Object deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { - return this.a(jsonelement, type, jsondeserializationcontext); - } - }).create(); - - DataConverterSignText() { - } - - public int getDataVersion() { - return 101; - } - - public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { - if ("Sign".equals(cmp.getString("id"))) { - this.convert(cmp, "Text1"); - this.convert(cmp, "Text2"); - this.convert(cmp, "Text3"); - this.convert(cmp, "Text4"); - } - - return cmp; - } - - private void convert(net.minecraft.nbt.CompoundTag nbttagcompound, String s) { - String s1 = nbttagcompound.getString(s); - Component object = null; - - if (!"null".equals(s1) && !StringUtil.isNullOrEmpty(s1)) { - if ((s1.charAt(0) != 34 || s1.charAt(s1.length() - 1) != 34) && (s1.charAt(0) != 123 || s1.charAt(s1.length() - 1) != 125)) { - object = Component.literal(s1); - } else { - try { - object = GsonHelper.fromJson(DataConverterSignText.a, s1, Component.class, true); - if (object == null) { - object = Component.literal(""); - } - } catch (JsonParseException jsonparseexception) { - ; - } - - if (object == null) { - try { - object = Component.Serializer.fromJson(s1); - } catch (JsonParseException jsonparseexception1) { - ; - } - } - - if (object == null) { - try { - object = Component.Serializer.fromJsonLenient(s1); - } catch (JsonParseException jsonparseexception2) { - ; - } - } - - if (object == null) { - object = Component.literal(s1); - } - } - } else { - object = Component.literal(""); - } - - nbttagcompound.putString(s, Component.Serializer.toJson(object)); - } - } - - private static class DataInspectorPlayerVehicle implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("RootVehicle", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("RootVehicle"); - - if (nbttagcompound1.contains("Entity", 10)) { - convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer); - } - } - - return cmp; - } - } - - private static class DataInspectorLevelPlayer implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Player", 10)) { - convertCompound(LegacyType.PLAYER, cmp, "Player", sourceVer, targetVer); - } - - return cmp; - } - } - - private static class DataInspectorStructure implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - net.minecraft.nbt.ListTag nbttaglist; - int j; - net.minecraft.nbt.CompoundTag nbttagcompound1; - - if (cmp.contains("entities", 9)) { - nbttaglist = cmp.getList("entities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j); - if (nbttagcompound1.contains("nbt", 10)) { - convertCompound(LegacyType.ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer); - } - } - } - - if (cmp.contains("blocks", 9)) { - nbttaglist = cmp.getList("blocks", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j); - if (nbttagcompound1.contains("nbt", 10)) { - convertCompound(LegacyType.BLOCK_ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer); - } - } - } - - return cmp; - } - } - - private static class DataInspectorChunks implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Level", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Level"); - net.minecraft.nbt.ListTag nbttaglist; - int j; - - if (nbttagcompound1.contains("Entities", 9)) { - nbttaglist = nbttagcompound1.getList("Entities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); - } - } - - if (nbttagcompound1.contains("TileEntities", 9)) { - nbttaglist = nbttagcompound1.getList("TileEntities", 10); - - for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.BLOCK_ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); - } - } - } - - return cmp; - } - } - - private static class DataInspectorEntityPassengers implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (cmp.contains("Passengers", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("Passengers", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ENTITY, nbttaglist.getCompound(j), sourceVer, targetVer)); - } - } - - return cmp; - } - } - - private static class DataInspectorPlayer implements DataInspector { - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - convertItems(cmp, "Inventory", sourceVer, targetVer); - convertItems(cmp, "EnderItems", sourceVer, targetVer); - if (cmp.contains("ShoulderEntityLeft", 10)) { - convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityLeft", sourceVer, targetVer); - } - - if (cmp.contains("ShoulderEntityRight", 10)) { - convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityRight", sourceVer, targetVer); - } - - return cmp; - } - } - - private static class DataInspectorVillagers implements DataInspector { - ResourceLocation entityVillager = getKey("EntityVillager"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (entityVillager.equals(new ResourceLocation(cmp.getString("id"))) && cmp.contains("Offers", 10)) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("Offers"); - - if (nbttagcompound1.contains("Recipes", 9)) { - net.minecraft.nbt.ListTag nbttaglist = nbttagcompound1.getList("Recipes", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist.getCompound(j); - - convertItem(nbttagcompound2, "buy", sourceVer, targetVer); - convertItem(nbttagcompound2, "buyB", sourceVer, targetVer); - convertItem(nbttagcompound2, "sell", sourceVer, targetVer); - nbttaglist.set(j, nbttagcompound2); - } - } - } - - return cmp; - } - } - - private static class DataInspectorMobSpawnerMinecart implements DataInspector { - ResourceLocation entityMinecartMobSpawner = getKey("EntityMinecartMobSpawner"); - ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - String s = cmp.getString("id"); - if (entityMinecartMobSpawner.equals(new ResourceLocation(s))) { - cmp.putString("id", tileEntityMobSpawner.toString()); - convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer); - cmp.putString("id", s); - } - - return cmp; - } - } - - private static class DataInspectorMobSpawnerMobs implements DataInspector { - ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (tileEntityMobSpawner.equals(new ResourceLocation(cmp.getString("id")))) { - if (cmp.contains("SpawnPotentials", 9)) { - net.minecraft.nbt.ListTag nbttaglist = cmp.getList("SpawnPotentials", 10); - - for (int j = 0; j < nbttaglist.size(); ++j) { - net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttaglist.getCompound(j); - - convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer); - } - } - - convertCompound(LegacyType.ENTITY, cmp, "SpawnData", sourceVer, targetVer); - } - - return cmp; - } - } - - private static class DataInspectorCommandBlock implements DataInspector { - ResourceLocation tileEntityCommand = getKey("TileEntityCommand"); - - @Override - public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { - if (tileEntityCommand.equals(new ResourceLocation(cmp.getString("id")))) { - cmp.putString("id", "Control"); - convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer); - cmp.putString("id", "MinecartCommandBlock"); - } - - return cmp; - } - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightFakePlayer.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightFakePlayer.java deleted file mode 100644 index 87dca94f2..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightFakePlayer.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R1; - -import com.mojang.authlib.GameProfile; -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.game.ServerboundClientInformationPacket; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.stats.Stat; -import net.minecraft.world.MenuProvider; -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.block.entity.SignBlockEntity; -import net.minecraft.world.phys.Vec3; -import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; - -import java.util.OptionalInt; -import java.util.UUID; - -class PaperweightFakePlayer extends ServerPlayer { - private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]"); - private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D); - - PaperweightFakePlayer(ServerLevel world) { - super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE); - } - - @Override - public Vec3 position() { - return ORIGIN; - } - - @Override - public void tick() { - } - - @Override - public void die(DamageSource damagesource) { - } - - @Override - public Entity changeDimension(ServerLevel worldserver, TeleportCause cause) { - return this; - } - - @Override - public OptionalInt openMenu(MenuProvider factory) { - return OptionalInt.empty(); - } - - @Override - public void updateOptions(ServerboundClientInformationPacket packet) { - } - - @Override - public void displayClientMessage(Component message, boolean actionBar) { - } - - @Override - public void awardStat(Stat stat, int amount) { - } - - @Override - public void awardStat(Stat stat) { - } - - @Override - public boolean isInvulnerableTo(DamageSource damageSource) { - return true; - } - - @Override - public void openTextEdit(SignBlockEntity sign, boolean front) { - } -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java deleted file mode 100644 index ffca9e50d..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightWorldNativeAccess.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R1; - -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.world.block.BlockState; -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.Tag; -import net.minecraft.server.level.FullChunkStatus; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.enginehub.linbus.tree.LinCompoundTag; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.util.Objects; - -public class PaperweightWorldNativeAccess implements WorldNativeAccess { - private static final int UPDATE = 1; - private static final int NOTIFY = 2; - - private final PaperweightAdapter adapter; - private final WeakReference world; - private SideEffectSet sideEffectSet; - - public PaperweightWorldNativeAccess(PaperweightAdapter adapter, WeakReference world) { - this.adapter = adapter; - this.world = world; - } - - private ServerLevel getWorld() { - return Objects.requireNonNull(world.get(), "The reference to the world was lost"); - } - - @Override - public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) { - this.sideEffectSet = sideEffectSet; - } - - @Override - public LevelChunk getChunk(int x, int z) { - return getWorld().getChunk(x, z); - } - - @Override - public net.minecraft.world.level.block.state.BlockState toNative(BlockState state) { - int stateId = BlockStateIdAccess.getBlockStateId(state); - return BlockStateIdAccess.isValidInternalId(stateId) - ? Block.stateById(stateId) - : ((CraftBlockData) BukkitAdapter.adapt(state)).getState(); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk chunk, BlockPos position) { - return chunk.getBlockState(position); - } - - @Nullable - @Override - public net.minecraft.world.level.block.state.BlockState setBlockState(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState state) { - return chunk.setBlockState(position, state, false, this.sideEffectSet.shouldApply(SideEffect.UPDATE)); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition(net.minecraft.world.level.block.state.BlockState block, BlockPos position) { - return Block.updateFromNeighbourShapes(block, getWorld(), position); - } - - @Override - public BlockPos getPosition(int x, int y, int z) { - return new BlockPos(x, y, z); - } - - @Override - public void updateLightingForBlock(BlockPos position) { - getWorld().getChunkSource().getLightEngine().checkBlock(position); - } - - @Override - public boolean updateTileEntity(BlockPos position, LinCompoundTag tag) { - // We will assume that the tile entity was created for us - BlockEntity tileEntity = getWorld().getBlockEntity(position); - if (tileEntity == null) { - return false; - } - Tag nativeTag = adapter.fromNative(new CompoundTag(tag)); - PaperweightAdapter.readTagIntoTileEntity((net.minecraft.nbt.CompoundTag) nativeTag, tileEntity); - return true; - } - - @Override - public void notifyBlockUpdate(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { - getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY); - } - } - - @Override - public boolean isChunkTicking(LevelChunk chunk) { - return chunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING); - } - - @Override - public void markBlockChanged(LevelChunk chunk, BlockPos position) { - if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { - getWorld().getChunkSource().blockChanged(position); - } - } - - @Override - public void notifyNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - ServerLevel world = getWorld(); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - world.updateNeighborsAt(pos, oldState.getBlock()); - } else { - // When we don't want events, manually run the physics without them. - Block block = oldState.getBlock(); - fireNeighborChanged(pos, world, block, pos.west()); - fireNeighborChanged(pos, world, block, pos.east()); - fireNeighborChanged(pos, world, block, pos.below()); - fireNeighborChanged(pos, world, block, pos.above()); - fireNeighborChanged(pos, world, block, pos.north()); - fireNeighborChanged(pos, world, block, pos.south()); - } - if (newState.hasAnalogOutputSignal()) { - world.updateNeighbourForOutputSignal(pos, newState.getBlock()); - } - } - - @Override - public void updateBlock(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - ServerLevel world = getWorld(); - newState.onPlace(world, pos, oldState, false); - } - - // Not sure why neighborChanged is deprecated - @SuppressWarnings("deprecation") - private void fireNeighborChanged(BlockPos pos, ServerLevel world, Block block, BlockPos neighborPos) { - world.getBlockState(neighborPos).neighborChanged(world, neighborPos, block, pos, false); - } - - @Override - public void updateNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState, int recursionLimit) { - ServerLevel world = getWorld(); - // a == updateNeighbors - // b == updateDiagonalNeighbors - oldState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - CraftWorld craftWorld = world.getWorld(); - BlockPhysicsEvent event = new BlockPhysicsEvent(craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), CraftBlockData.fromData(newState)); - world.getCraftServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - } - newState.updateNeighbourShapes(world, pos, NOTIFY, recursionLimit); - newState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); - } - - @Override - public void onBlockStateChange(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - getWorld().onBlockStateChange(pos, oldState, newState); - } - - @Override - public void flush() { - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightBlockMaterial.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightBlockMaterial.java deleted file mode 100644 index 826874f57..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightBlockMaterial.java +++ /dev/null @@ -1,185 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.util.ReflectionUtil; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.world.registry.BlockMaterial; -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.EmptyBlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.LiquidBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.PushReaction; -import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData; - -public class PaperweightBlockMaterial implements BlockMaterial { - - private final Block block; - private final BlockState blockState; - private final boolean isTranslucent; - private final CraftBlockData craftBlockData; - private final org.bukkit.Material craftMaterial; - private final int opacity; - private final CompoundTag tile; - - public PaperweightBlockMaterial(Block block) { - this(block, block.defaultBlockState()); - } - - public PaperweightBlockMaterial(Block block, BlockState blockState) { - this.block = block; - this.blockState = blockState; - this.craftBlockData = CraftBlockData.fromData(blockState); - this.craftMaterial = craftBlockData.getMaterial(); - BlockBehaviour.Properties blockInfo = ReflectionUtil.getField(BlockBehaviour.class, block, - Refraction.pickName("properties", "aN")); - this.isTranslucent = !(boolean) ReflectionUtil.getField(BlockBehaviour.Properties.class, blockInfo, - Refraction.pickName("canOcclude", "m") - ); - opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); - BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity( - BlockPos.ZERO, - blockState - ); - tile = tileEntity == null - ? null - : new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); - } - - public Block getBlock() { - return block; - } - - public BlockState getState() { - return blockState; - } - - public CraftBlockData getCraftBlockData() { - return craftBlockData; - } - - @Override - public boolean isAir() { - return blockState.isAir(); - } - - @Override - public boolean isFullCube() { - return craftMaterial.isOccluding(); - } - - @Override - public boolean isOpaque() { - return blockState.isOpaque(); - } - - @Override - public boolean isPowerSource() { - return blockState.isSignalSource(); - } - - @Override - public boolean isLiquid() { - // TODO: Better check ? - return block instanceof LiquidBlock; - } - - @Override - public boolean isSolid() { - // TODO: Replace - return blockState.isSolid(); - } - - @Override - public float getHardness() { - return craftBlockData.getState().destroySpeed; - } - - @Override - public float getResistance() { - return block.getExplosionResistance(); - } - - @Override - public float getSlipperiness() { - return block.getFriction(); - } - - @Override - public int getLightValue() { - return blockState.getLightEmission(); - } - - @Override - public int getLightOpacity() { - return opacity; - } - - @Override - public boolean isFragileWhenPushed() { - return blockState.getPistonPushReaction() == PushReaction.DESTROY; - } - - @Override - public boolean isUnpushable() { - return blockState.getPistonPushReaction() == PushReaction.BLOCK; - } - - @Override - public boolean isTicksRandomly() { - return block.isRandomlyTicking(blockState); - } - - @Override - public boolean isMovementBlocker() { - return craftMaterial.isSolid(); - } - - @Override - public boolean isBurnable() { - return craftMaterial.isBurnable(); - } - - @Override - public boolean isToolRequired() { - // Removed in 1.16.1, this is not present in higher versions - return false; - } - - @Override - public boolean isReplacedDuringPlacement() { - return blockState.canBeReplaced(); - } - - @Override - public boolean isTranslucent() { - return isTranslucent; - } - - @Override - public boolean hasContainer() { - return block instanceof EntityBlock; - } - - @Override - public boolean isTile() { - return block instanceof EntityBlock; - } - - @Override - public CompoundTag getDefaultTile() { - return tile; - } - - @Override - public int getMapColor() { - // rgb field - return block.defaultMapColor().col; - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java deleted file mode 100644 index 7fd24c7d9..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweAdapter.java +++ /dev/null @@ -1,614 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.bukkit.adapter.FaweAdapter; -import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.entity.LazyBaseEntity; -import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; -import com.fastasyncworldedit.core.queue.IBatchProcessor; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket; -import com.fastasyncworldedit.core.util.NbtUtils; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R1.PaperweightAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.regen.PaperweightRegen; -import com.sk89q.worldedit.entity.BaseEntity; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.registry.state.BooleanProperty; -import com.sk89q.worldedit.registry.state.DirectionalProperty; -import com.sk89q.worldedit.registry.state.EnumProperty; -import com.sk89q.worldedit.registry.state.IntegerProperty; -import com.sk89q.worldedit.registry.state.Property; -import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.util.formatting.text.Component; -import com.sk89q.worldedit.world.RegenOptions; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockStateHolder; -import com.sk89q.worldedit.world.block.BlockType; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import com.sk89q.worldedit.world.entity.EntityType; -import com.sk89q.worldedit.world.item.ItemType; -import com.sk89q.worldedit.world.registry.BlockMaterial; -import io.papermc.lib.PaperLib; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Registry; -import net.minecraft.core.WritableRegistry; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.util.StringRepresentable; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.chunk.LevelChunk; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.NamespacedKey; -import org.bukkit.World; -import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.v1_20_R1.CraftServer; -import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_20_R1.util.CraftNamespacedKey; -import org.bukkit.entity.Player; -import org.enginehub.linbus.tree.LinCompoundTag; -import org.enginehub.linbus.tree.LinStringTag; -import org.enginehub.linbus.tree.LinTag; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.OptionalInt; -import java.util.Set; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static net.minecraft.core.registries.Registries.BIOME; - -public final class PaperweightFaweAdapter extends FaweAdapter { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - private static Method CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE; - - static { - try { - CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE = ChunkHolder.class.getDeclaredMethod("wasAccessibleSinceLastSave"); - } catch (NoSuchMethodException ignored) { // may not be present in newer paper versions - } - } - - private final PaperweightAdapter parent; - // ------------------------------------------------------------------------ - // Code that may break between versions of Minecraft - // ------------------------------------------------------------------------ - private final PaperweightMapChunkUtil mapUtil = new PaperweightMapChunkUtil(); - private char[] ibdToStateOrdinal = null; - private int[] ordinalToIbdID = null; - private boolean initialised = false; - private Map>> allBlockProperties = null; - - public PaperweightFaweAdapter() throws NoSuchFieldException, NoSuchMethodException { - this.parent = new PaperweightAdapter(); - } - - @Nullable - private static String getEntityId(Entity entity) { - ResourceLocation resourceLocation = net.minecraft.world.entity.EntityType.getKey(entity.getType()); - return resourceLocation == null ? null : resourceLocation.toString(); - } - - @Override - public BukkitImplAdapter getParent() { - return parent; - } - - private synchronized boolean init() { - if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) { - return false; - } - ibdToStateOrdinal = new char[BlockTypesCache.states.length]; // size - ordinalToIbdID = new int[ibdToStateOrdinal.length]; // size - for (int i = 0; i < ibdToStateOrdinal.length; i++) { - BlockState blockState = BlockTypesCache.states[i]; - PaperweightBlockMaterial material = (PaperweightBlockMaterial) blockState.getMaterial(); - int id = Block.BLOCK_STATE_REGISTRY.getId(material.getState()); - char ordinal = blockState.getOrdinalChar(); - ibdToStateOrdinal[id] = ordinal; - ordinalToIbdID[ordinal] = id; - } - Map>> properties = new HashMap<>(); - try { - for (Field field : BlockStateProperties.class.getDeclaredFields()) { - Object obj = field.get(null); - if (!(obj instanceof net.minecraft.world.level.block.state.properties.Property state)) { - continue; - } - Property property; - if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { - property = new BooleanProperty( - state.getName(), - (List) ImmutableList.copyOf(state.getPossibleValues()) - ); - } else if (state instanceof DirectionProperty) { - property = new DirectionalProperty( - state.getName(), - state - .getPossibleValues() - .stream() - .map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase())) - .collect(Collectors.toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) { - property = new EnumProperty( - state.getName(), - state - .getPossibleValues() - .stream() - .map(e -> ((StringRepresentable) e).getSerializedName()) - .collect(Collectors.toList()) - ); - } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { - property = new IntegerProperty( - state.getName(), - (List) ImmutableList.copyOf(state.getPossibleValues()) - ); - } else { - throw new IllegalArgumentException("FastAsyncWorldEdit needs an update to support " + state - .getClass() - .getSimpleName()); - } - properties.compute(property.getName().toLowerCase(Locale.ROOT), (k, v) -> { - if (v == null) { - v = new ArrayList<>(Collections.singletonList(property)); - } else { - v.add(property); - } - return v; - }); - } - } catch (IllegalAccessException e) { - e.printStackTrace(); - } finally { - allBlockProperties = ImmutableMap.copyOf(properties); - } - initialised = true; - return true; - } - - @Override - public BlockMaterial getMaterial(BlockType blockType) { - Block block = getBlock(blockType); - return new PaperweightBlockMaterial(block); - } - - @Override - public synchronized BlockMaterial getMaterial(BlockState state) { - net.minecraft.world.level.block.state.BlockState blockState = ((CraftBlockData) Bukkit.createBlockData(state.getAsString())).getState(); - return new PaperweightBlockMaterial(blockState.getBlock(), blockState); - } - - public Block getBlock(BlockType blockType) { - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK) - .get(new ResourceLocation(blockType.getNamespace(), blockType.getResource())); - } - - @Deprecated - @Override - public BlockState getBlock(Location location) { - Preconditions.checkNotNull(location); - - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - final ServerLevel handle = getServerLevel(location.getWorld()); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - BlockState state = adapt(blockData); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - return state; - } - - @Override - public BaseBlock getFullBlock(final Location location) { - Preconditions.checkNotNull(location); - - int x = location.getBlockX(); - int y = location.getBlockY(); - int z = location.getBlockZ(); - - final ServerLevel handle = getServerLevel(location.getWorld()); - LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); - final BlockPos blockPos = new BlockPos(x, y, z); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - BlockState state = adapt(blockData); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } - if (state.getBlockType().getMaterial().hasContainer()) { - - // Read the NBT data - BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK); - if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); - return state.toBaseBlock((LinCompoundTag) toNativeLin(tag)); - } - } - - return state.toBaseBlock(); - } - - @Override - public Set getSupportedSideEffects() { - return SideEffectSet.defaults().getSideEffectsToApply(); - } - - @Override - public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { - return new PaperweightFaweWorldNativeAccess(this, new WeakReference<>(getServerLevel(world))); - } - - @Override - public BaseEntity getEntity(org.bukkit.entity.Entity entity) { - Preconditions.checkNotNull(entity); - - CraftEntity craftEntity = ((CraftEntity) entity); - Entity mcEntity = craftEntity.getHandle(); - - String id = getEntityId(mcEntity); - - if (id != null) { - EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id); - Supplier saveTag = () -> { - final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag); - //add Id for AbstractChangeSet to work - final LinCompoundTag tag = (LinCompoundTag) toNativeLin(minecraftTag); - final Map> tags = NbtUtils.getLinCompoundTagValues(tag); - tags.put("Id", LinStringTag.of(id)); - return LinCompoundTag.of(tags); - }; - return new LazyBaseEntity(type, saveTag); - } else { - return null; - } - } - - @Override - public Component getRichBlockName(BlockType blockType) { - return parent.getRichBlockName(blockType); - } - - @Override - public Component getRichItemName(ItemType itemType) { - return parent.getRichItemName(itemType); - } - - @Override - public Component getRichItemName(BaseItemStack itemStack) { - return parent.getRichItemName(itemStack); - } - - @Override - public OptionalInt getInternalBlockStateId(BlockState state) { - PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial(); - net.minecraft.world.level.block.state.BlockState mcState = material.getCraftBlockData().getState(); - return OptionalInt.of(Block.BLOCK_STATE_REGISTRY.getId(mcState)); - } - - @Override - public BlockState adapt(BlockData blockData) { - CraftBlockData cbd = ((CraftBlockData) blockData); - net.minecraft.world.level.block.state.BlockState ibd = cbd.getState(); - return adapt(ibd); - } - - public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; - } - - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { - int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); - if (initialised) { - return ibdToStateOrdinal[id]; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - try { - init(); - return ibdToStateOrdinal[id]; - } catch (ArrayIndexOutOfBoundsException e1) { - LOGGER.error("Attempted to convert {} with ID {} to char. ibdToStateOrdinal length: {}. Defaulting to air!", - blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToStateOrdinal.length, e1 - ); - return BlockTypesCache.ReservedIDs.AIR; - } - } - } - - public char ibdIDToOrdinal(int id) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal[id]; - } - init(); - return ibdToStateOrdinal[id]; - } - } - - @Override - public char[] getIbdToStateOrdinal() { - if (initialised) { - return ibdToStateOrdinal; - } - synchronized (this) { - if (initialised) { - return ibdToStateOrdinal; - } - init(); - return ibdToStateOrdinal; - } - } - - public int ordinalToIbdID(char ordinal) { - if (initialised) { - return ordinalToIbdID[ordinal]; - } - synchronized (this) { - if (initialised) { - return ordinalToIbdID[ordinal]; - } - init(); - return ordinalToIbdID[ordinal]; - } - } - - @Override - public int[] getOrdinalToIbdID() { - if (initialised) { - return ordinalToIbdID; - } - synchronized (this) { - if (initialised) { - return ordinalToIbdID; - } - init(); - return ordinalToIbdID; - } - } - - @Override - public > BlockData adapt(B state) { - PaperweightBlockMaterial material = (PaperweightBlockMaterial) state.getMaterial(); - return material.getCraftBlockData(); - } - - @Override - public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) { - ServerLevel nmsWorld = getServerLevel(world); - ChunkHolder map = PaperweightPlatformAdapter.getPlayerChunk(nmsWorld, chunkPacket.getChunkX(), chunkPacket.getChunkZ()); - if (map != null && wasAccessibleSinceLastSave(map)) { - boolean flag = false; - // PlayerChunk.d players = map.players; - Stream stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag) - */ Stream.empty(); - - ServerPlayer checkPlayer = player == null ? null : ((CraftPlayer) player).getHandle(); - stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer) - .forEach(entityPlayer -> { - synchronized (chunkPacket) { - ClientboundLevelChunkWithLightPacket nmsPacket = (ClientboundLevelChunkWithLightPacket) chunkPacket.getNativePacket(); - if (nmsPacket == null) { - nmsPacket = mapUtil.create(this, chunkPacket); - chunkPacket.setNativePacket(nmsPacket); - } - try { - FaweCache.INSTANCE.CHUNK_FLAG.get().set(true); - entityPlayer.connection.send(nmsPacket); - } finally { - FaweCache.INSTANCE.CHUNK_FLAG.get().set(false); - } - } - }); - } - } - - @Override - public Map> getProperties(BlockType blockType) { - return getParent().getProperties(blockType); - } - - @Override - public boolean canPlaceAt(org.bukkit.World world, BlockVector3 blockVector3, BlockState blockState) { - int internalId = BlockStateIdAccess.getBlockStateId(blockState); - net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId); - return blockState1.hasPostProcess( - getServerLevel(world), - new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z()) - ); - } - - @Override - public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) { - ItemStack stack = new ItemStack( - DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM) - .get(ResourceLocation.tryParse(baseItemStack.getType().id())), - baseItemStack.getAmount() - ); - stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(baseItemStack.getNbtData()))); - return CraftItemStack.asCraftMirror(stack); - } - - @Override - protected void preCaptureStates(final ServerLevel serverLevel) { - serverLevel.captureTreeGeneration = true; - serverLevel.captureBlockStates = true; - } - - @Override - protected List getCapturedBlockStatesCopy(final ServerLevel serverLevel) { - return new ArrayList<>(serverLevel.capturedBlockStates.values()); - } - - @Override - protected void postCaptureBlockStates(final ServerLevel serverLevel) { - serverLevel.captureBlockStates = false; - serverLevel.captureTreeGeneration = false; - serverLevel.capturedBlockStates.clear(); - } - - @Override - protected ServerLevel getServerLevel(final World world) { - return ((CraftWorld) world).getHandle(); - } - - @Override - public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { - final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); - final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); - weStack.setNbt(((LinCompoundTag) toNativeLin(nmsStack.getTag()))); - return weStack; - } - - @Override - public Tag toNative(net.minecraft.nbt.Tag foreign) { - return parent.toNative(foreign); - } - - @Override - public net.minecraft.nbt.Tag fromNative(Tag foreign) { - if (foreign instanceof PaperweightLazyCompoundTag) { - return ((PaperweightLazyCompoundTag) foreign).get(); - } - return parent.fromNative(foreign); - } - - @Override - public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent target, RegenOptions options) throws Exception { - return new PaperweightRegen(bukkitWorld, region, target, options).regenerate(); - } - - @Override - public IChunkGet get(org.bukkit.World world, int chunkX, int chunkZ) { - return new PaperweightGetBlocks(world, chunkX, chunkZ); - } - - @Override - public int getInternalBiomeId(BiomeType biomeType) { - final Registry registry = MinecraftServer - .getServer() - .registryAccess() - .registryOrThrow(BIOME); - ResourceLocation resourceLocation = ResourceLocation.tryParse(biomeType.id()); - Biome biome = registry.get(resourceLocation); - return registry.getId(biome); - } - - @Override - public Iterable getRegisteredBiomes() { - WritableRegistry biomeRegistry = (WritableRegistry) ((CraftServer) Bukkit.getServer()) - .getServer() - .registryAccess() - .registryOrThrow(BIOME); - List keys = biomeRegistry.stream() - .map(biomeRegistry::getKey).filter(Objects::nonNull).toList(); - List namespacedKeys = new ArrayList<>(); - for (ResourceLocation key : keys) { - try { - namespacedKeys.add(CraftNamespacedKey.fromMinecraft(key)); - } catch (IllegalArgumentException e) { - LOGGER.error("Error converting biome key {}", key.toString(), e); - } - } - return namespacedKeys; - } - - @Override - public RelighterFactory getRelighterFactory() { - if (PaperLib.isPaper()) { - return new PaperweightStarlightRelighterFactory(); - } else { - return new NMSRelighterFactory(); - } - } - - @Override - public Map>> getAllProperties() { - if (initialised) { - return allBlockProperties; - } - synchronized (this) { - if (initialised) { - return allBlockProperties; - } - init(); - return allBlockProperties; - } - } - - @Override - public IBatchProcessor getTickingPostProcessor() { - return new PaperweightPostProcessor(); - } - - private boolean wasAccessibleSinceLastSave(ChunkHolder holder) { - if (!PaperLib.isPaper() || !PaperweightPlatformAdapter.POST_CHUNK_REWRITE) { - try { - return (boolean) CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE.invoke(holder); - } catch (IllegalAccessException | InvocationTargetException ignored) { - // fall-through - } - } - // Papers new chunk system has no related replacement - therefor we assume true. - return true; - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweWorldNativeAccess.java deleted file mode 100644 index b06d962a0..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightFaweWorldNativeAccess.java +++ /dev/null @@ -1,292 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.math.IntPair; -import com.fastasyncworldedit.core.util.TaskManager; -import com.fastasyncworldedit.core.util.task.RunnableVal; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.internal.block.BlockStateIdAccess; -import com.sk89q.worldedit.internal.wna.WorldNativeAccess; -import com.sk89q.worldedit.util.SideEffect; -import com.sk89q.worldedit.util.SideEffectSet; -import com.sk89q.worldedit.world.block.BlockState; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.FullChunkStatus; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData; -import org.bukkit.event.block.BlockPhysicsEvent; -import org.enginehub.linbus.tree.LinCompoundTag; - -import javax.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.util.Collections; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; - -public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess { - - private static final int UPDATE = 1; - private static final int NOTIFY = 2; - private static final Direction[] NEIGHBOUR_ORDER = { - Direction.EAST, - Direction.WEST, - Direction.DOWN, - Direction.UP, - Direction.NORTH, - Direction.SOUTH - }; - private final PaperweightFaweAdapter paperweightFaweAdapter; - private final WeakReference level; - private final AtomicInteger lastTick; - private final Set cachedChanges = new HashSet<>(); - private final Set cachedChunksToSend = new HashSet<>(); - private SideEffectSet sideEffectSet; - - public PaperweightFaweWorldNativeAccess(PaperweightFaweAdapter paperweightFaweAdapter, WeakReference level) { - this.paperweightFaweAdapter = paperweightFaweAdapter; - this.level = level; - // Use the actual tick as minecraft-defined so we don't try to force blocks into the world when the server's already lagging. - // - With the caveat that we don't want to have too many cached changed (1024) so we'd flush those at 1024 anyway. - this.lastTick = new AtomicInteger(MinecraftServer.currentTick); - } - - private Level getLevel() { - return Objects.requireNonNull(level.get(), "The reference to the world was lost"); - } - - @Override - public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) { - this.sideEffectSet = sideEffectSet; - } - - @Override - public LevelChunk getChunk(int x, int z) { - return getLevel().getChunk(x, z); - } - - @Override - public net.minecraft.world.level.block.state.BlockState toNative(BlockState blockState) { - int stateId = paperweightFaweAdapter.ordinalToIbdID(blockState.getOrdinalChar()); - return BlockStateIdAccess.isValidInternalId(stateId) - ? Block.stateById(stateId) - : ((CraftBlockData) BukkitAdapter.adapt(blockState)).getState(); - } - - @Override - public net.minecraft.world.level.block.state.BlockState getBlockState(LevelChunk levelChunk, BlockPos blockPos) { - return levelChunk.getBlockState(blockPos); - } - - @Nullable - @Override - public synchronized net.minecraft.world.level.block.state.BlockState setBlockState( - LevelChunk levelChunk, BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState blockState - ) { - int currentTick = MinecraftServer.currentTick; - if (Fawe.isMainThread()) { - return levelChunk.setBlockState(blockPos, blockState, - this.sideEffectSet != null && this.sideEffectSet.shouldApply(SideEffect.UPDATE) - ); - } - // Since FAWE is.. Async we need to do it on the main thread (wooooo.. :( ) - cachedChanges.add(new CachedChange(levelChunk, blockPos, blockState)); - cachedChunksToSend.add(new IntPair(levelChunk.locX, levelChunk.locZ)); - boolean nextTick = lastTick.get() > currentTick; - if (nextTick || cachedChanges.size() >= 1024) { - if (nextTick) { - lastTick.set(currentTick); - } - flushAsync(nextTick); - } - return blockState; - } - - @Override - public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition( - net.minecraft.world.level.block.state.BlockState blockState, - BlockPos blockPos - ) { - return Block.updateFromNeighbourShapes(blockState, getLevel(), blockPos); - } - - @Override - public BlockPos getPosition(int x, int y, int z) { - return new BlockPos(x, y, z); - } - - @Override - public void updateLightingForBlock(BlockPos blockPos) { - getLevel().getChunkSource().getLightEngine().checkBlock(blockPos); - } - - @Override - public boolean updateTileEntity(BlockPos blockPos, LinCompoundTag tag) { - // We will assume that the tile entity was created for us, - // though we do not do this on the other versions - BlockEntity blockEntity = getLevel().getBlockEntity(blockPos); - if (blockEntity == null) { - return false; - } - net.minecraft.nbt.Tag nativeTag = paperweightFaweAdapter.fromNativeLin(tag); - blockEntity.load((CompoundTag) nativeTag); - return true; - } - - @Override - public void notifyBlockUpdate( - LevelChunk levelChunk, BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) { - getLevel().sendBlockUpdated(blockPos, oldState, newState, UPDATE | NOTIFY); - } - } - - @Override - public boolean isChunkTicking(LevelChunk levelChunk) { - return levelChunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING); - } - - @Override - public void markBlockChanged(LevelChunk levelChunk, BlockPos blockPos) { - if (levelChunk.getSections()[level.get().getSectionIndex(blockPos.getY())] != null) { - ((ServerChunkCache) getLevel().getChunkSource()).blockChanged(blockPos); - } - } - - @Override - public void notifyNeighbors( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - Level level = getLevel(); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - level.blockUpdated(blockPos, oldState.getBlock()); - } else { - // When we don't want events, manually run the physics without them. - // Un-nest neighbour updating - for (Direction direction : NEIGHBOUR_ORDER) { - BlockPos shifted = blockPos.relative(direction); - level.getBlockState(shifted).neighborChanged(level, shifted, oldState.getBlock(), blockPos, false); - } - } - if (newState.hasAnalogOutputSignal()) { - level.updateNeighbourForOutputSignal(blockPos, newState.getBlock()); - } - } - - @Override - public void updateNeighbors( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState, - int recursionLimit - ) { - Level level = getLevel(); - // a == updateNeighbors - // b == updateDiagonalNeighbors - oldState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit); - if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { - CraftWorld craftWorld = level.getWorld(); - if (craftWorld != null) { - BlockPhysicsEvent event = new BlockPhysicsEvent( - craftWorld.getBlockAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()), - CraftBlockData.fromData(newState) - ); - level.getCraftServer().getPluginManager().callEvent(event); - if (event.isCancelled()) { - return; - } - } - } - newState.triggerEvent(level, blockPos, NOTIFY, recursionLimit); - newState.updateIndirectNeighbourShapes(level, blockPos, NOTIFY, recursionLimit); - } - - @Override - public void updateBlock(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) { - Level world = getLevel(); - newState.onPlace(world, pos, oldState, false); - } - - @Override - public void onBlockStateChange( - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState oldState, - net.minecraft.world.level.block.state.BlockState newState - ) { - getLevel().onBlockStateChange(blockPos, oldState, newState); - } - - private synchronized void flushAsync(final boolean sendChunks) { - final Set changes = Set.copyOf(cachedChanges); - cachedChanges.clear(); - final Set toSend; - if (sendChunks) { - toSend = Set.copyOf(cachedChunksToSend); - cachedChunksToSend.clear(); - } else { - toSend = Collections.emptySet(); - } - RunnableVal runnableVal = new RunnableVal<>() { - @Override - public void run(Object value) { - changes.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState, - sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE) - )); - if (!sendChunks) { - return; - } - for (IntPair chunk : toSend) { - PaperweightPlatformAdapter.sendChunk(chunk, getLevel().getWorld().getHandle(), chunk.x(), chunk.z()); - } - } - }; - TaskManager.taskManager().async(() -> TaskManager.taskManager().sync(runnableVal)); - } - - @Override - public synchronized void flush() { - RunnableVal runnableVal = new RunnableVal<>() { - @Override - public void run(Object value) { - cachedChanges.forEach(cc -> cc.levelChunk.setBlockState(cc.blockPos, cc.blockState, - sideEffectSet != null && sideEffectSet.shouldApply(SideEffect.UPDATE) - )); - for (IntPair chunk : cachedChunksToSend) { - PaperweightPlatformAdapter.sendChunk(chunk, getLevel().getWorld().getHandle(), chunk.x(), chunk.z()); - } - } - }; - if (Fawe.isMainThread()) { - runnableVal.run(); - } else { - TaskManager.taskManager().sync(runnableVal); - } - cachedChanges.clear(); - cachedChunksToSend.clear(); - } - - private record CachedChange( - LevelChunk levelChunk, - BlockPos blockPos, - net.minecraft.world.level.block.state.BlockState blockState - ) { - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java deleted file mode 100644 index 91bcf0e92..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java +++ /dev/null @@ -1,1184 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.bukkit.adapter.BukkitGetBlocks; -import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; -import com.fastasyncworldedit.core.math.BitArrayUnstretched; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.fastasyncworldedit.core.queue.implementation.QueueHandler; -import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks; -import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.util.collection.AdaptedMap; -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import io.papermc.lib.PaperLib; -import io.papermc.paper.event.block.BeaconDeactivatedEvent; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.IdMap; -import net.minecraft.core.Registry; -import net.minecraft.core.SectionPos; -import net.minecraft.nbt.IntTag; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.util.BitStorage; -import net.minecraft.util.ZeroBitStorage; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.LightLayer; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.entity.BeaconBlockEntity; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.DataLayer; -import net.minecraft.world.level.chunk.HashMapPalette; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import net.minecraft.world.level.chunk.LinearPalette; -import net.minecraft.world.level.chunk.Palette; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.chunk.PalettedContainerRO; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.lighting.LevelLightEngine; -import org.apache.logging.log4j.Logger; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R1.block.CraftBlock; -import org.bukkit.event.entity.CreatureSpawnEvent; - -import javax.annotation.Nonnull; -import java.util.AbstractSet; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Future; -import java.util.concurrent.Semaphore; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.function.Function; -import java.util.stream.Collectors; - -import static net.minecraft.core.registries.Registries.BIOME; - -public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private static final Function posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ()); - private static final Function nmsTile2We = - tileEntity -> new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); - private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin - .getInstance() - .getBukkitImplAdapter()); - private final ReadWriteLock sectionLock = new ReentrantReadWriteLock(); - private final ReentrantLock callLock = new ReentrantLock(); - private final ServerLevel serverLevel; - private final int chunkX; - private final int chunkZ; - private final int minHeight; - private final int maxHeight; - private final int minSectionPosition; - private final int maxSectionPosition; - private final Registry biomeRegistry; - private final IdMap> biomeHolderIdMap; - private final ConcurrentHashMap copies = new ConcurrentHashMap<>(); - private final Object sendLock = new Object(); - private LevelChunkSection[] sections; - private LevelChunk levelChunk; - private DataLayer[] blockLight; - private DataLayer[] skyLight; - private boolean createCopy = false; - private boolean forceLoadSections = true; - private boolean lightUpdate = false; - private int copyKey = 0; - - public PaperweightGetBlocks(World world, int chunkX, int chunkZ) { - this(((CraftWorld) world).getHandle(), chunkX, chunkZ); - } - - public PaperweightGetBlocks(ServerLevel serverLevel, int chunkX, int chunkZ) { - super(serverLevel.getMinBuildHeight() >> 4, (serverLevel.getMaxBuildHeight() - 1) >> 4); - this.serverLevel = serverLevel; - this.chunkX = chunkX; - this.chunkZ = chunkZ; - this.minHeight = serverLevel.getMinBuildHeight(); - this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.minSectionPosition = minHeight >> 4; - this.maxSectionPosition = maxHeight >> 4; - this.skyLight = new DataLayer[getSectionCount()]; - this.blockLight = new DataLayer[getSectionCount()]; - this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(BIOME); - this.biomeHolderIdMap = biomeRegistry.asHolderIdMap(); - } - - public int getChunkX() { - return chunkX; - } - - public int getChunkZ() { - return chunkZ; - } - - @Override - public boolean isCreateCopy() { - return createCopy; - } - - @Override - public int setCreateCopy(boolean createCopy) { - if (!callLock.isHeldByCurrentThread()) { - throw new IllegalStateException("Attempting to set if chunk GET should create copy, but it is not call-locked."); - } - this.createCopy = createCopy; - // Increment regardless of whether copy will be created or not to return null from getCopy() - return ++this.copyKey; - } - - @Override - public IChunkGet getCopy(final int key) { - return copies.remove(key); - } - - @Override - public void lockCall() { - this.callLock.lock(); - } - - @Override - public void unlockCall() { - this.callLock.unlock(); - } - - @Override - public void setLightingToGet(char[][] light, int minSectionPosition, int maxSectionPosition) { - if (light != null) { - lightUpdate = true; - try { - fillLightNibble(light, LightLayer.BLOCK, minSectionPosition, maxSectionPosition); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - @Override - public void setSkyLightingToGet(char[][] light, int minSectionPosition, int maxSectionPosition) { - if (light != null) { - lightUpdate = true; - try { - fillLightNibble(light, LightLayer.SKY, minSectionPosition, maxSectionPosition); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - @Override - public void setHeightmapToGet(HeightMapType type, int[] data) { - // height + 1 to match server internal - BitArrayUnstretched bitArray = new BitArrayUnstretched(MathMan.log2nlz(getChunk().getHeight() + 1), 256); - bitArray.fromRaw(data); - Heightmap.Types nativeType = Heightmap.Types.valueOf(type.name()); - Heightmap heightMap = getChunk().heightmaps.get(nativeType); - heightMap.setRawData(getChunk(), nativeType, bitArray.getData()); - } - - @Override - public int getMaxY() { - return maxHeight; - } - - @Override - public int getMinY() { - return minHeight; - } - - @Override - public BiomeType getBiomeType(int x, int y, int z) { - LevelChunkSection section = getSections(false)[(y >> 4) - getMinSectionPosition()]; - Holder biomes = section.getNoiseBiome(x >> 2, (y & 15) >> 2, z >> 2); - return PaperweightPlatformAdapter.adapt(biomes, serverLevel); - } - - @Override - public void removeSectionLighting(int layer, boolean sky) { - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = serverLevel.getChunkSource().getLightEngine().getLayerListener(LightLayer.BLOCK).getDataLayerData( - sectionPos); - if (dataLayer != null) { - lightUpdate = true; - synchronized (dataLayer) { - byte[] bytes = dataLayer.getData(); - Arrays.fill(bytes, (byte) 0); - } - } - if (sky) { - SectionPos sectionPos1 = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer1 = serverLevel - .getChunkSource() - .getLightEngine() - .getLayerListener(LightLayer.SKY) - .getDataLayerData(sectionPos1); - if (dataLayer1 != null) { - lightUpdate = true; - synchronized (dataLayer1) { - byte[] bytes = dataLayer1.getData(); - Arrays.fill(bytes, (byte) 0); - } - } - } - } - - @Override - public CompoundTag getTile(int x, int y, int z) { - BlockEntity blockEntity = getChunk().getBlockEntity(new BlockPos((x & 15) + ( - chunkX << 4), y, (z & 15) + ( - chunkZ << 4))); - if (blockEntity == null) { - return null; - } - return new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)); - } - - @Override - public Map getTiles() { - Map nmsTiles = getChunk().getBlockEntities(); - if (nmsTiles.isEmpty()) { - return Collections.emptyMap(); - } - return AdaptedMap.immutable(nmsTiles, posNms2We, nmsTile2We); - } - - @Override - public int getSkyLight(int x, int y, int z) { - int layer = y >> 4; - int alayer = layer - getMinSectionPosition(); - if (skyLight[alayer] == null) { - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = - serverLevel.getChunkSource().getLightEngine().getLayerListener(LightLayer.SKY).getDataLayerData(sectionPos); - // If the server hasn't generated the section's NibbleArray yet, it will be null - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. - Arrays.fill(LAYER_COUNT, (byte) 15); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( - LightLayer.BLOCK, - sectionPos, - dataLayer - ); - } - skyLight[alayer] = dataLayer; - } - return skyLight[alayer].get(x & 15, y & 15, z & 15); - } - - @Override - public int getEmittedLight(int x, int y, int z) { - int layer = y >> 4; - int alayer = layer - getMinSectionPosition(); - if (blockLight[alayer] == null) { - serverLevel.getRawBrightness(new BlockPos(1, 1, 1), 5); - SectionPos sectionPos = SectionPos.of(getChunk().getPos(), layer); - DataLayer dataLayer = serverLevel - .getChunkSource() - .getLightEngine() - .getLayerListener(LightLayer.BLOCK) - .getDataLayerData(sectionPos); - // If the server hasn't generated the section's DataLayer yet, it will be null - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - // Safe enough to assume if it's not created, it's under the sky. Unlikely to be created before lighting is fixed anyway. - Arrays.fill(LAYER_COUNT, (byte) 15); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(LightLayer.BLOCK, sectionPos, - dataLayer - ); - } - blockLight[alayer] = dataLayer; - } - return blockLight[alayer].get(x & 15, y & 15, z & 15); - } - - @Override - public int[] getHeightMap(HeightMapType type) { - long[] longArray = getChunk().heightmaps.get(Heightmap.Types.valueOf(type.name())).getRawData(); - BitArrayUnstretched bitArray = new BitArrayUnstretched(9, 256, longArray); - return bitArray.toRaw(new int[256]); - } - - @Override - public CompoundTag getEntity(UUID uuid) { - Entity entity = serverLevel.getEntity(uuid); - if (entity != null) { - org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity(); - return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); - } - for (CompoundTag tag : getEntities()) { - if (uuid.equals(tag.getUUID())) { - return tag; - } - } - return null; - } - - @Override - public Set getEntities() { - ensureLoaded(serverLevel, chunkX, chunkZ); - List entities = PaperweightPlatformAdapter.getEntities(getChunk()); - if (entities.isEmpty()) { - return Collections.emptySet(); - } - int size = entities.size(); - return new AbstractSet<>() { - @Override - public int size() { - return size; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public boolean contains(Object get) { - if (!(get instanceof CompoundTag getTag)) { - return false; - } - UUID getUUID = getTag.getUUID(); - for (Entity entity : entities) { - UUID uuid = entity.getUUID(); - if (uuid.equals(getUUID)) { - return true; - } - } - return false; - } - - @Nonnull - @Override - public Iterator iterator() { - Iterable result = entities.stream().map(input -> { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(input, tag); - return (CompoundTag) adapter.toNative(tag); - }).collect(Collectors.toList()); - return result.iterator(); - } - }; - } - - private void removeEntity(Entity entity) { - entity.discard(); - } - - public LevelChunk ensureLoaded(ServerLevel nmsWorld, int chunkX, int chunkZ) { - return PaperweightPlatformAdapter.ensureLoaded(nmsWorld, chunkX, chunkZ); - } - - @Override - @SuppressWarnings("rawtypes") - public synchronized > T call(IChunkSet set, Runnable finalizer) { - if (!callLock.isHeldByCurrentThread()) { - throw new IllegalStateException("Attempted to call chunk GET but chunk was not call-locked."); - } - forceLoadSections = false; - PaperweightGetBlocks_Copy copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null; - if (createCopy) { - if (copies.containsKey(copyKey)) { - throw new IllegalStateException("Copy key already used."); - } - copies.put(copyKey, copy); - } - try { - ServerLevel nmsWorld = serverLevel; - LevelChunk nmsChunk = ensureLoaded(nmsWorld, chunkX, chunkZ); - - // Remove existing tiles. Create a copy so that we can remove blocks - Map chunkTiles = new HashMap<>(nmsChunk.getBlockEntities()); - List beacons = null; - if (!chunkTiles.isEmpty()) { - for (Map.Entry entry : chunkTiles.entrySet()) { - final BlockPos pos = entry.getKey(); - final int lx = pos.getX() & 15; - final int ly = pos.getY(); - final int lz = pos.getZ() & 15; - final int layer = ly >> 4; - if (!set.hasSection(layer)) { - continue; - } - - int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { - BlockEntity tile = entry.getValue(); - if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { - if (beacons == null) { - beacons = new ArrayList<>(); - } - beacons.add(tile); - PaperweightPlatformAdapter.removeBeacon(tile, nmsChunk); - continue; - } - nmsChunk.removeBlockEntity(tile.getBlockPos()); - if (createCopy) { - copy.storeTile(tile); - } - } - } - } - final BiomeType[][] biomes = set.getBiomes(); - - int bitMask = 0; - synchronized (nmsChunk) { - LevelChunkSection[] levelChunkSections = nmsChunk.getSections(); - - for (int layerNo = getMinSectionPosition(); layerNo <= getMaxSectionPosition(); layerNo++) { - - int getSectionIndex = layerNo - getMinSectionPosition(); - int setSectionIndex = layerNo - set.getMinSectionPosition(); - - if (!set.hasSection(layerNo)) { - // No blocks, but might be biomes present. Handle this lazily. - if (biomes == null) { - continue; - } - if (layerNo < set.getMinSectionPosition() || layerNo > set.getMaxSectionPosition()) { - continue; - } - if (biomes[setSectionIndex] != null) { - synchronized (super.sectionLocks[getSectionIndex]) { - LevelChunkSection existingSection = levelChunkSections[getSectionIndex]; - if (createCopy && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); - } - - if (existingSection == null) { - PalettedContainer> biomeData = PaperweightPlatformAdapter.getBiomePalettedContainer( - biomes[setSectionIndex], - biomeHolderIdMap - ); - LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( - layerNo, - new char[4096], - adapter, - biomeRegistry, - biomeData - ); - if (PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - null, - newSection, - getSectionIndex - )) { - updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); - continue; - } else { - existingSection = levelChunkSections[getSectionIndex]; - if (existingSection == null) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - getSectionIndex - ); - continue; - } - } - } else { - PalettedContainer> paletteBiomes = setBiomesToPalettedContainer( - biomes, - setSectionIndex, - existingSection.getBiomes() - ); - if (paletteBiomes != null) { - PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); - } - } - } - } - continue; - } - - bitMask |= 1 << getSectionIndex; - - // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to - // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); - - // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was - // submitted to keep loaded internal chunks to queue target size. - synchronized (super.sectionLocks[getSectionIndex]) { - - LevelChunkSection newSection; - LevelChunkSection existingSection = levelChunkSections[getSectionIndex]; - // Don't attempt to tick section whilst we're editing - if (existingSection != null) { - PaperweightPlatformAdapter.clearCounts(existingSection); - if (PaperLib.isPaper()) { - existingSection.tickingList.clear(); - } - } - - if (createCopy) { - char[] tmpLoad = loadPrivately(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); - copy.storeSection(getSectionIndex, copyArr); - if (biomes != null && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); - } - } - - if (existingSection == null) { - PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( - biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES - ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); - newSection = PaperweightPlatformAdapter.newChunkSection( - layerNo, - setArr, - adapter, - biomeRegistry, - biomeData - ); - if (PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - null, - newSection, - getSectionIndex - )) { - updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex); - continue; - } else { - existingSection = levelChunkSections[getSectionIndex]; - if (existingSection == null) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - getSectionIndex - ); - continue; - } - } - } - - //ensure that the server doesn't try to tick the chunksection while we're editing it. (Again) - PaperweightPlatformAdapter.clearCounts(existingSection); - if (PaperLib.isPaper()) { - existingSection.tickingList.clear(); - } - DelegateSemaphore lock = PaperweightPlatformAdapter.applyLock(existingSection); - - // Synchronize to prevent further acquisitions - synchronized (lock) { - lock.acquire(); // Wait until we have the lock - lock.release(); - try { - sectionLock.writeLock().lock(); - if (this.getChunk() != nmsChunk) { - this.levelChunk = nmsChunk; - this.sections = null; - this.reset(); - } else if (existingSection != getSections(false)[getSectionIndex]) { - this.sections[getSectionIndex] = existingSection; - this.reset(); - } else if (!Arrays.equals( - update(getSectionIndex, new char[4096], true), - loadPrivately(layerNo) - )) { - this.reset(layerNo); - /*} else if (lock.isModified()) { - this.reset(layerNo);*/ - } - } finally { - sectionLock.writeLock().unlock(); - } - - PalettedContainer> biomeData = setBiomesToPalettedContainer( - biomes, - setSectionIndex, - existingSection.getBiomes() - ); - - newSection = PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() - ); - if (!PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - existingSection, - newSection, - getSectionIndex - )) { - LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - getSectionIndex - ); - } else { - updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex); - } - } - } - } - - Map heightMaps = set.getHeightMaps(); - for (Map.Entry entry : heightMaps.entrySet()) { - PaperweightGetBlocks.this.setHeightmapToGet(entry.getKey(), entry.getValue()); - } - PaperweightGetBlocks.this.setLightingToGet( - set.getLight(), - set.getMinSectionPosition(), - set.getMaxSectionPosition() - ); - PaperweightGetBlocks.this.setSkyLightingToGet( - set.getSkyLight(), - set.getMinSectionPosition(), - set.getMaxSectionPosition() - ); - - Runnable[] syncTasks = null; - - int bx = chunkX << 4; - int bz = chunkZ << 4; - - // Call beacon deactivate events here synchronously - // list will be null on spigot, so this is an implicit isPaper check - if (beacons != null && !beacons.isEmpty()) { - final List finalBeacons = beacons; - - syncTasks = new Runnable[4]; - - syncTasks[3] = () -> { - for (BlockEntity beacon : finalBeacons) { - BeaconBlockEntity.playSound(beacon.getLevel(), beacon.getBlockPos(), SoundEvents.BEACON_DEACTIVATE); - new BeaconDeactivatedEvent(CraftBlock.at(beacon.getLevel(), beacon.getBlockPos())).callEvent(); - } - }; - } - - Set entityRemoves = set.getEntityRemoves(); - if (entityRemoves != null && !entityRemoves.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[3]; - } - - syncTasks[2] = () -> { - Set entitiesRemoved = new HashSet<>(); - final List entities = PaperweightPlatformAdapter.getEntities(nmsChunk); - - for (Entity entity : entities) { - UUID uuid = entity.getUUID(); - if (entityRemoves.contains(uuid)) { - if (createCopy) { - copy.storeEntity(entity); - } - removeEntity(entity); - entitiesRemoved.add(uuid); - entityRemoves.remove(uuid); - } - } - if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) { - for (UUID uuid : entityRemoves) { - Entity entity = nmsWorld.getEntities().get(uuid); - if (entity != null) { - removeEntity(entity); - } - } - } - // Only save entities that were actually removed to history - set.getEntityRemoves().clear(); - set.getEntityRemoves().addAll(entitiesRemoved); - }; - } - - Set entities = set.getEntities(); - if (entities != null && !entities.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[2]; - } - - syncTasks[1] = () -> { - Iterator iterator = entities.iterator(); - while (iterator.hasNext()) { - final CompoundTag nativeTag = iterator.next(); - final Map> entityTagMap = nativeTag.getValue(); - final StringTag idTag = (StringTag) entityTagMap.get("Id"); - final ListTag posTag = (ListTag) entityTagMap.get("Pos"); - final ListTag rotTag = (ListTag) entityTagMap.get("Rotation"); - if (idTag == null || posTag == null || rotTag == null) { - LOGGER.error("Unknown entity tag: {}", nativeTag); - continue; - } - final double x = posTag.getDouble(0); - final double y = posTag.getDouble(1); - final double z = posTag.getDouble(2); - final float yaw = rotTag.getFloat(0); - final float pitch = rotTag.getFloat(1); - final String id = idTag.getValue(); - - EntityType type = EntityType.byString(id).orElse(null); - if (type != null) { - Entity entity = type.create(nmsWorld); - if (entity != null) { - final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative( - nativeTag); - for (final String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.remove(name); - } - entity.load(tag); - entity.absMoveTo(x, y, z, yaw, pitch); - entity.setUUID(nativeTag.getUUID()); - if (!nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM)) { - LOGGER.warn( - "Error creating entity of type `{}` in world `{}` at location `{},{},{}`", - id, - nmsWorld.getWorld().getName(), - x, - y, - z - ); - // Unsuccessful create should not be saved to history - iterator.remove(); - } - } - } - } - }; - } - - // set tiles - Map tiles = set.getTiles(); - if (tiles != null && !tiles.isEmpty()) { - if (syncTasks == null) { - syncTasks = new Runnable[1]; - } - - syncTasks[0] = () -> { - for (final Map.Entry entry : tiles.entrySet()) { - final CompoundTag nativeTag = entry.getValue(); - final BlockVector3 blockHash = entry.getKey(); - final int x = blockHash.x() + bx; - final int y = blockHash.y(); - final int z = blockHash.z() + bz; - final BlockPos pos = new BlockPos(x, y, z); - - synchronized (nmsWorld) { - BlockEntity tileEntity = nmsWorld.getBlockEntity(pos); - if (tileEntity == null || tileEntity.isRemoved()) { - nmsWorld.removeBlockEntity(pos); - tileEntity = nmsWorld.getBlockEntity(pos); - } - if (tileEntity != null) { - final net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative( - nativeTag); - tag.put("x", IntTag.valueOf(x)); - tag.put("y", IntTag.valueOf(y)); - tag.put("z", IntTag.valueOf(z)); - tileEntity.load(tag); - } - } - } - }; - } - - Runnable callback; - if (bitMask == 0 && biomes == null && !lightUpdate) { - callback = null; - } else { - int finalMask = bitMask != 0 ? bitMask : lightUpdate ? set.getBitMask() : 0; - boolean finalLightUpdate = lightUpdate; - callback = () -> { - // Set Modified - nmsChunk.setLightCorrect(true); // Set Modified - nmsChunk.mustNotSave = false; - nmsChunk.setUnsaved(true); - // send to player - if (Settings.settings().LIGHTING.MODE == 0 || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalMask == 0 && biomes != null) { - this.send(); - } - if (finalizer != null) { - finalizer.run(); - } - }; - } - if (syncTasks != null) { - QueueHandler queueHandler = Fawe.instance().getQueueHandler(); - Runnable[] finalSyncTasks = syncTasks; - - // Chain the sync tasks and the callback - Callable chain = () -> { - try { - // Run the sync tasks - for (Runnable task : finalSyncTasks) { - if (task != null) { - task.run(); - } - } - if (callback == null) { - if (finalizer != null) { - queueHandler.async(finalizer, null); - } - return null; - } else { - return queueHandler.async(callback, null); - } - } catch (Throwable e) { - e.printStackTrace(); - throw e; - } - }; - //noinspection unchecked - required at compile time - return (T) (Future) queueHandler.sync(chain); - } else { - if (callback == null) { - if (finalizer != null) { - finalizer.run(); - } - } else { - callback.run(); - } - } - } - return null; - } catch (Throwable e) { - e.printStackTrace(); - return null; - } finally { - forceLoadSections = true; - } - } - - private void updateGet( - LevelChunk nmsChunk, - LevelChunkSection[] chunkSections, - LevelChunkSection section, - char[] arr, - int layer - ) { - try { - sectionLock.writeLock().lock(); - if (this.getChunk() != nmsChunk) { - this.levelChunk = nmsChunk; - this.sections = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, this.sections, 0, chunkSections.length); - this.reset(); - } - if (this.sections == null) { - this.sections = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, this.sections, 0, chunkSections.length); - } - if (this.sections[layer] != section) { - // Not sure why it's funky, but it's what I did in commit fda7d00747abe97d7891b80ed8bb88d97e1c70d1 and I don't want to touch it >dords - this.sections[layer] = new LevelChunkSection[]{section}.clone()[0]; - } - } finally { - sectionLock.writeLock().unlock(); - } - this.blocks[layer] = arr; - } - - private char[] loadPrivately(int layer) { - layer -= getMinSectionPosition(); - if (super.sections[layer] != null) { - synchronized (super.sectionLocks[layer]) { - if (super.sections[layer].isFull() && super.blocks[layer] != null) { - return super.blocks[layer]; - } - } - } - return PaperweightGetBlocks.this.update(layer, null, true); - } - - @Override - public void send() { - synchronized (sendLock) { - PaperweightPlatformAdapter.sendChunk(this, serverLevel, chunkX, chunkZ); - } - } - - /** - * Update a given (nullable) data array to the current data stored in the server's chunk, associated with this - * {@link PaperweightPlatformAdapter} instance. Not synchronised to the {@link PaperweightPlatformAdapter} instance as synchronisation - * is handled where necessary in the method, and should otherwise be handled correctly by this method's caller. - * - * @param layer layer index (0 may denote a negative layer in the world, e.g. at y=-32) - * @param data array to be updated/filled with data or null - * @param aggressive if the cached section array should be re-acquired. - * @return the given array to be filled with data, or a new array if null is given. - */ - @Override - @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { - LevelChunkSection section = getSections(aggressive)[layer]; - // Section is null, return empty array - if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; - } - if (data != null && data.length != 4096) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - } - Semaphore lock = PaperweightPlatformAdapter.applyLock(section); - synchronized (lock) { - // Efficiently convert ChunkSection to raw data - try { - lock.acquire(); - - final PalettedContainer blocks = section.getStates(); - final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocks); - final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); - - if (bits instanceof ZeroBitStorage) { - Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper - return data; - } - - final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get(dataObject); - - final int bitsPerEntry = bits.getBits(); - final long[] blockStates = bits.getRaw(); - - new BitArrayUnstretched(bitsPerEntry, 4096, blockStates).toRaw(data); - - int num_palette; - if (palette instanceof LinearPalette || palette instanceof HashMapPalette) { - num_palette = palette.getSize(); - } else { - // The section's palette is the global block palette. - for (int i = 0; i < 4096; i++) { - char paletteVal = data[i]; - char ordinal = adapter.ibdIDToOrdinal(paletteVal); - data[i] = ordinal; - } - return data; - } - - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); - try { - if (num_palette != 1) { - for (int i = 0; i < num_palette; i++) { - char ordinal = ordinal(palette.valueFor(i), adapter); - paletteToOrdinal[i] = ordinal; - } - for (int i = 0; i < 4096; i++) { - char paletteVal = data[i]; - char val = paletteToOrdinal[paletteVal]; - if (val == Character.MAX_VALUE) { - val = ordinal(palette.valueFor(i), adapter); - paletteToOrdinal[i] = val; - } - data[i] = val; - } - } else { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); - } - } finally { - for (int i = 0; i < num_palette; i++) { - paletteToOrdinal[i] = Character.MAX_VALUE; - } - } - return data; - } catch (IllegalAccessException | InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } finally { - lock.release(); - } - } - } - - private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { - if (ibd == null) { - return BlockTypesCache.ReservedIDs.AIR; - } else { - return adapter.adaptToChar(ibd); - } - } - - public LevelChunkSection[] getSections(boolean force) { - force &= forceLoadSections; - LevelChunkSection[] tmp = sections; - if (tmp == null || force) { - try { - sectionLock.writeLock().lock(); - tmp = sections; - if (tmp == null || force) { - LevelChunkSection[] chunkSections = getChunk().getSections(); - tmp = new LevelChunkSection[chunkSections.length]; - System.arraycopy(chunkSections, 0, tmp, 0, chunkSections.length); - sections = tmp; - } - } finally { - sectionLock.writeLock().unlock(); - } - } - return tmp; - } - - public LevelChunk getChunk() { - LevelChunk levelChunk = this.levelChunk; - if (levelChunk == null) { - synchronized (this) { - levelChunk = this.levelChunk; - if (levelChunk == null) { - this.levelChunk = levelChunk = ensureLoaded(this.serverLevel, chunkX, chunkZ); - } - } - } - return levelChunk; - } - - private void fillLightNibble(char[][] light, LightLayer lightLayer, int minSectionPosition, int maxSectionPosition) { - for (int Y = 0; Y <= maxSectionPosition - minSectionPosition; Y++) { - if (light[Y] == null) { - continue; - } - SectionPos sectionPos = SectionPos.of(levelChunk.getPos(), Y + minSectionPosition); - DataLayer dataLayer = serverLevel.getChunkSource().getLightEngine().getLayerListener(lightLayer).getDataLayerData( - sectionPos); - if (dataLayer == null) { - byte[] LAYER_COUNT = new byte[2048]; - Arrays.fill(LAYER_COUNT, lightLayer == LightLayer.SKY ? (byte) 15 : (byte) 0); - dataLayer = new DataLayer(LAYER_COUNT); - ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( - lightLayer, - sectionPos, - dataLayer - ); - } - synchronized (dataLayer) { - for (int x = 0; x < 16; x++) { - for (int y = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - int i = y << 8 | z << 4 | x; - if (light[Y][i] < 16) { - dataLayer.set(x, y, z, light[Y][i]); - } - } - } - } - } - } - } - - private PalettedContainer> setBiomesToPalettedContainer( - final BiomeType[][] biomes, - final int sectionIndex, - final PalettedContainerRO> data - ) { - BiomeType[] sectionBiomes; - if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return null; - } - PalettedContainer> biomeData = data.recreate(); - for (int y = 0, index = 0; y < 4; y++) { - for (int z = 0; z < 4; z++) { - for (int x = 0; x < 4; x++, index++) { - BiomeType biomeType = sectionBiomes[index]; - if (biomeType == null) { - biomeData.set(x, y, z, data.get(x, y, z)); - } else { - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) - ); - } - } - } - } - return biomeData; - } - - @Override - public boolean hasSection(int layer) { - layer -= getMinSectionPosition(); - return getSections(false)[layer] != null; - } - - @Override - @SuppressWarnings("unchecked") - public synchronized boolean trim(boolean aggressive) { - skyLight = new DataLayer[getSectionCount()]; - blockLight = new DataLayer[getSectionCount()]; - if (aggressive) { - sectionLock.writeLock().lock(); - sections = null; - levelChunk = null; - sectionLock.writeLock().unlock(); - return super.trim(true); - } else if (sections == null) { - // don't bother trimming if there are no sections stored. - return true; - } else { - for (int i = getMinSectionPosition(); i <= getMaxSectionPosition(); i++) { - int layer = i - getMinSectionPosition(); - if (!hasSection(i) || !super.sections[layer].isFull()) { - continue; - } - LevelChunkSection existing = getSections(true)[layer]; - try { - final PalettedContainer blocksExisting = existing.getStates(); - - final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocksExisting); - final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get( - dataObject); - int paletteSize; - - if (palette instanceof LinearPalette || palette instanceof HashMapPalette) { - paletteSize = palette.getSize(); - } else { - super.trim(false, i); - continue; - } - if (paletteSize == 1) { - //If the cached palette size is 1 then no blocks can have been changed i.e. do not need to update these chunks. - continue; - } - super.trim(false, i); - } catch (IllegalAccessException ignored) { - super.trim(false, i); - } - } - return true; - } - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java deleted file mode 100644 index d2412b98f..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; -import com.fastasyncworldedit.core.queue.IBlocks; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.google.common.base.Suppliers; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import net.minecraft.core.Holder; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.chunk.PalettedContainerRO; -import org.apache.logging.log4j.Logger; - -import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Future; - -public class PaperweightGetBlocks_Copy implements IChunkGet { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private final Map tiles = new HashMap<>(); - private final Set entities = new HashSet<>(); - private final char[][] blocks; - private final int minHeight; - private final int maxHeight; - final ServerLevel serverLevel; - final LevelChunk levelChunk; - private Holder[][] biomes = null; - - protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { - this.levelChunk = levelChunk; - this.serverLevel = levelChunk.level; - this.minHeight = serverLevel.getMinBuildHeight(); - this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; - } - - protected void storeTile(BlockEntity blockEntity) { - tiles.put( - BlockVector3.at( - blockEntity.getBlockPos().getX(), - blockEntity.getBlockPos().getY(), - blockEntity.getBlockPos().getZ() - ), - new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)) - ); - } - - @Override - public Map getTiles() { - return tiles; - } - - @Override - @Nullable - public CompoundTag getTile(int x, int y, int z) { - return tiles.get(BlockVector3.at(x, y, z)); - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - protected void storeEntity(Entity entity) { - BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); - net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag(); - PaperweightPlatformAdapter.readEntityIntoTag(entity, compoundTag); - entities.add((CompoundTag) adapter.toNative(compoundTag)); - } - - @Override - public Set getEntities() { - return this.entities; - } - - @Override - public CompoundTag getEntity(UUID uuid) { - for (CompoundTag tag : entities) { - if (uuid.equals(tag.getUUID())) { - return tag; - } - } - return null; - } - - @Override - public boolean isCreateCopy() { - return false; - } - - @Override - public int setCreateCopy(boolean createCopy) { - return -1; - } - - @Override - public void setLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) { - } - - @Override - public void setSkyLightingToGet(char[][] lighting, int minSectionPosition, int maxSectionPosition) { - } - - @Override - public void setHeightmapToGet(HeightMapType type, int[] data) { - } - - @Override - public int getMaxY() { - return maxHeight; - } - - @Override - public int getMinY() { - return minHeight; - } - - @Override - public int getMaxSectionPosition() { - return maxHeight >> 4; - } - - @Override - public int getMinSectionPosition() { - return minHeight >> 4; - } - - @Override - public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; - return PaperweightPlatformAdapter.adapt(biome, serverLevel); - } - - @Override - public void removeSectionLighting(int layer, boolean sky) { - } - - @Override - public boolean trim(boolean aggressive, int layer) { - return false; - } - - @Override - public IBlocks reset() { - return null; - } - - @Override - public int getSectionCount() { - return serverLevel.getSectionsCount(); - } - - protected void storeSection(int layer, char[] data) { - blocks[layer] = data; - } - - protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { - if (biomes == null) { - biomes = new Holder[getSectionCount()][]; - } - if (biomes[layer] == null) { - biomes[layer] = new Holder[64]; - } - if (biomeData instanceof PalettedContainer> palettedContainer) { - for (int i = 0; i < 64; i++) { - biomes[layer][i] = palettedContainer.get(i); - } - } else { - LOGGER.error( - "Cannot correctly save biomes to history. Expected class type {} but got {}", - PalettedContainer.class.getSimpleName(), - biomeData.getClass().getSimpleName() - ); - } - } - - @Override - public BaseBlock getFullBlock(int x, int y, int z) { - BlockState state = BlockTypesCache.states[get(x, y, z)]; - return state.toBaseBlock(this, x, y, z); - } - - @Override - public boolean hasSection(int layer) { - layer -= getMinSectionPosition(); - return blocks[layer] != null; - } - - @Override - public char[] load(int layer) { - layer -= getMinSectionPosition(); - if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); - } - return blocks[layer]; - } - - @Override - public char[] loadIfPresent(int layer) { - layer -= getMinSectionPosition(); - return blocks[layer]; - } - - @Override - public BlockState getBlock(int x, int y, int z) { - return BlockTypesCache.states[get(x, y, z)]; - } - - @Override - public int getSkyLight(int x, int y, int z) { - return 0; - } - - @Override - public int getEmittedLight(int x, int y, int z) { - return 0; - } - - @Override - public int[] getHeightMap(HeightMapType type) { - return new int[0]; - } - - @Override - public > T call(IChunkSet set, Runnable finalize) { - return null; - } - - public char get(int x, int y, int z) { - final int layer = (y >> 4) - getMinSectionPosition(); - final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; - } - - - @Override - public boolean trim(boolean aggressive) { - return false; - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightMapChunkUtil.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightMapChunkUtil.java deleted file mode 100644 index 62f5d4e03..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightMapChunkUtil.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData; -import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; - -//TODO un-very-break-this -public class PaperweightMapChunkUtil extends MapChunkUtil { - - public PaperweightMapChunkUtil() throws NoSuchFieldException { - fieldX = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("TWO_MEGABYTES", "a")); - fieldZ = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("x", "a")); - fieldBitMask = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("z", "b")); - fieldHeightMap = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("heightmaps", "b")); - fieldChunkData = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("chunkData", "c")); - fieldBlockEntities = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("buffer", "c")); - fieldFull = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("blockEntitiesData", "d")); - fieldX.setAccessible(true); - fieldZ.setAccessible(true); - fieldBitMask.setAccessible(true); - fieldHeightMap.setAccessible(true); - fieldChunkData.setAccessible(true); - fieldBlockEntities.setAccessible(true); - fieldFull.setAccessible(true); - } - - @Override - public ClientboundLevelChunkWithLightPacket createPacket() { - // TODO ??? return new ClientboundLevelChunkPacket(); - throw new UnsupportedOperationException(); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java deleted file mode 100644 index 05c0b58f9..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java +++ /dev/null @@ -1,764 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.destroystokyo.paper.util.maplist.EntityList; -import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter; -import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; -import com.fastasyncworldedit.bukkit.adapter.NMSAdapter; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.math.BitArrayUnstretched; -import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.util.ReflectionUtils; -import com.fastasyncworldedit.core.util.TaskManager; -import com.mojang.datafixers.util.Either; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import io.papermc.lib.PaperLib; -import io.papermc.paper.world.ChunkEntitySlices; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.IdMap; -import net.minecraft.core.Registry; -import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ChunkHolder; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.level.TicketType; -import net.minecraft.util.BitStorage; -import net.minecraft.util.ExceptionCollector; -import net.minecraft.util.SimpleBitStorage; -import net.minecraft.util.ThreadingDetector; -import net.minecraft.util.Unit; -import net.minecraft.util.ZeroBitStorage; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.npc.AbstractVillager; -import net.minecraft.world.entity.npc.Villager; -import net.minecraft.world.item.trading.MerchantOffers; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.GlobalPalette; -import net.minecraft.world.level.chunk.HashMapPalette; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.LevelChunkSection; -import net.minecraft.world.level.chunk.LinearPalette; -import net.minecraft.world.level.chunk.Palette; -import net.minecraft.world.level.chunk.PalettedContainer; -import net.minecraft.world.level.chunk.SingleValuePalette; -import net.minecraft.world.level.entity.PersistentEntitySectionManager; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_20_R1.CraftChunk; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.function.Function; - -import static java.lang.invoke.MethodType.methodType; -import static net.minecraft.core.registries.Registries.BIOME; - -public final class PaperweightPlatformAdapter extends NMSAdapter { - - public static final Field fieldData; - - public static final Constructor dataConstructor; - - public static final Field fieldStorage; - public static final Field fieldPalette; - - private static final Field fieldTickingFluidCount; - private static final Field fieldTickingBlockCount; - - private static final MethodHandle methodGetVisibleChunk; - - private static final Field fieldThreadingDetector; - private static final Field fieldLock; - - private static final MethodHandle methodRemoveGameEventListener; - private static final MethodHandle methodremoveTickingBlockEntity; - private static final Field fieldBiomes; - - private static final Field fieldOffers; - private static final MerchantOffers OFFERS = new MerchantOffers(); - - /* - * This is a workaround for the changes from https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/1fddefce1cdce44010927b888432bf70c0e88cde#src/main/java/org/bukkit/craftbukkit/CraftChunk.java - * and is only needed to support 1.19.4 versions before *and* after this change. - */ - private static final MethodHandle CRAFT_CHUNK_GET_HANDLE; - - private static final Field fieldRemove; - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - static final boolean POST_CHUNK_REWRITE; - private static Method PAPER_CHUNK_GEN_ALL_ENTITIES; - private static Field LEVEL_CHUNK_ENTITIES; - private static Field SERVER_LEVEL_ENTITY_MANAGER; - - static { - final MethodHandles.Lookup lookup = MethodHandles.lookup(); - try { - fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d")); - fieldData.setAccessible(true); - - Class dataClazz = fieldData.getType(); - dataConstructor = dataClazz.getDeclaredConstructors()[0]; - dataConstructor.setAccessible(true); - - fieldStorage = dataClazz.getDeclaredField(Refraction.pickName("storage", "b")); - fieldStorage.setAccessible(true); - fieldPalette = dataClazz.getDeclaredField(Refraction.pickName("palette", "c")); - fieldPalette.setAccessible(true); - - fieldTickingFluidCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "g")); - fieldTickingFluidCount.setAccessible(true); - fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); - fieldTickingBlockCount.setAccessible(true); - Field tmpFieldBiomes; - try { - // It seems to actually be biomes, but is apparently obfuscated to "i" - tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); - } catch (NoSuchFieldException ignored) { - tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("i"); - } - fieldBiomes = tmpFieldBiomes; - fieldBiomes.setAccessible(true); - - Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( - "getVisibleChunkIfPresent", - "b" - ), long.class); - getVisibleChunkIfPresent.setAccessible(true); - methodGetVisibleChunk = lookup.unreflect(getVisibleChunkIfPresent); - - if (!PaperLib.isPaper()) { - fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f")); - fieldThreadingDetector.setAccessible(true); - fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c")); - fieldLock.setAccessible(true); - } else { - // in paper, the used methods are synchronized properly - fieldThreadingDetector = null; - fieldLock = null; - } - - Method removeGameEventListener = LevelChunk.class.getDeclaredMethod( - Refraction.pickName("removeGameEventListener", "a"), - BlockEntity.class, - ServerLevel.class - ); - removeGameEventListener.setAccessible(true); - methodRemoveGameEventListener = lookup.unreflect(removeGameEventListener); - - Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod( - Refraction.pickName( - "removeBlockEntityTicker", - "l" - ), BlockPos.class - ); - removeBlockEntityTicker.setAccessible(true); - methodremoveTickingBlockEntity = lookup.unreflect(removeBlockEntityTicker); - - fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "q")); - fieldRemove.setAccessible(true); - - boolean chunkRewrite; - try { - ServerLevel.class.getDeclaredMethod("getEntityLookup"); - chunkRewrite = true; - PAPER_CHUNK_GEN_ALL_ENTITIES = ChunkEntitySlices.class.getDeclaredMethod("getAllEntities"); - PAPER_CHUNK_GEN_ALL_ENTITIES.setAccessible(true); - } catch (NoSuchMethodException ignored) { - chunkRewrite = false; - } - try { - // Paper - Pre-Chunk-Update - LEVEL_CHUNK_ENTITIES = LevelChunk.class.getDeclaredField("entities"); - LEVEL_CHUNK_ENTITIES.setAccessible(true); - } catch (NoSuchFieldException ignored) { - } - try { - // Non-Paper - SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField(Refraction.pickName("entityManager", "M")); - SERVER_LEVEL_ENTITY_MANAGER.setAccessible(true); - } catch (NoSuchFieldException ignored) { - } - POST_CHUNK_REWRITE = chunkRewrite; - - fieldOffers = AbstractVillager.class.getDeclaredField(Refraction.pickName("offers", "bU")); - fieldOffers.setAccessible(true); - } catch (RuntimeException | Error e) { - throw e; - } catch (Exception e) { - throw new RuntimeException(e); - } - MethodHandle craftChunkGetHandle; - final MethodType type = methodType(LevelChunk.class); - try { - craftChunkGetHandle = lookup.findVirtual(CraftChunk.class, "getHandle", type); - } catch (NoSuchMethodException | IllegalAccessException e) { - try { - final MethodType newType = methodType(ChunkAccess.class, ChunkStatus.class); - craftChunkGetHandle = lookup.findVirtual(CraftChunk.class, "getHandle", newType); - craftChunkGetHandle = MethodHandles.insertArguments(craftChunkGetHandle, 1, ChunkStatus.FULL); - } catch (NoSuchMethodException | IllegalAccessException ex) { - throw new RuntimeException(ex); - } - } - CRAFT_CHUNK_GET_HANDLE = craftChunkGetHandle; - } - - static boolean setSectionAtomic( - LevelChunkSection[] sections, - LevelChunkSection expected, - LevelChunkSection value, - int layer - ) { - if (layer >= 0 && layer < sections.length) { - return ReflectionUtils.compareAndSet(sections, expected, value, layer); - } - return false; - } - - // There is no point in having a functional semaphore for paper servers. - private static final ThreadLocal SEMAPHORE_THREAD_LOCAL = - ThreadLocal.withInitial(() -> new DelegateSemaphore(1, null)); - - static DelegateSemaphore applyLock(LevelChunkSection section) { - if (PaperLib.isPaper()) { - return SEMAPHORE_THREAD_LOCAL.get(); - } - try { - synchronized (section) { - PalettedContainer blocks = section.getStates(); - ThreadingDetector currentThreadingDetector = (ThreadingDetector) fieldThreadingDetector.get(blocks); - synchronized (currentThreadingDetector) { - Semaphore currentLock = (Semaphore) fieldLock.get(currentThreadingDetector); - if (currentLock instanceof DelegateSemaphore delegateSemaphore) { - return delegateSemaphore; - } - DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); - fieldLock.set(currentThreadingDetector, newLock); - return newLock; - } - } - } catch (Throwable e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } - - public static LevelChunk ensureLoaded(ServerLevel serverLevel, int chunkX, int chunkZ) { - if (!PaperLib.isPaper()) { - LevelChunk nmsChunk = serverLevel.getChunkSource().getChunk(chunkX, chunkZ, false); - if (nmsChunk != null) { - return nmsChunk; - } - if (Fawe.isMainThread()) { - return serverLevel.getChunk(chunkX, chunkZ); - } - } else { - LevelChunk nmsChunk = serverLevel.getChunkSource().getChunkAtIfCachedImmediately(chunkX, chunkZ); - if (nmsChunk != null) { - addTicket(serverLevel, chunkX, chunkZ); - return nmsChunk; - } - nmsChunk = serverLevel.getChunkSource().getChunkAtIfLoadedImmediately(chunkX, chunkZ); - if (nmsChunk != null) { - addTicket(serverLevel, chunkX, chunkZ); - return nmsChunk; - } - // Avoid "async" methods from the main thread. - if (Fawe.isMainThread()) { - return serverLevel.getChunk(chunkX, chunkZ); - } - CompletableFuture future = serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true); - try { - CraftChunk chunk; - try { - chunk = (CraftChunk) future.get(10, TimeUnit.SECONDS); - } catch (TimeoutException e) { - String world = serverLevel.getWorld().getName(); - // We've already taken 10 seconds we can afford to wait a little here. - boolean loaded = TaskManager.taskManager().sync(() -> Bukkit.getWorld(world) != null); - if (loaded) { - LOGGER.warn("Chunk {},{} failed to load in 10 seconds in world {}. Retrying...", chunkX, chunkZ, world); - // Retry chunk load - chunk = (CraftChunk) serverLevel.getWorld().getChunkAtAsync(chunkX, chunkZ, true, true).get(); - } else { - throw new UnsupportedOperationException("Cannot load chunk from unloaded world " + world + "!"); - } - } - addTicket(serverLevel, chunkX, chunkZ); - return (LevelChunk) CRAFT_CHUNK_GET_HANDLE.invoke(chunk); - } catch (Throwable e) { - e.printStackTrace(); - } - } - return TaskManager.taskManager().sync(() -> serverLevel.getChunk(chunkX, chunkZ)); - } - - private static void addTicket(ServerLevel serverLevel, int chunkX, int chunkZ) { - // Ensure chunk is definitely loaded before applying a ticket - io.papermc.paper.util.MCUtil.MAIN_EXECUTOR.execute(() -> serverLevel - .getChunkSource() - .addRegionTicket(TicketType.UNLOAD_COOLDOWN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE)); - } - - public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) { - ChunkMap chunkMap = nmsWorld.getChunkSource().chunkMap; - try { - return (ChunkHolder) methodGetVisibleChunk.invoke(chunkMap, ChunkPos.asLong(chunkX, chunkZ)); - } catch (Throwable thr) { - throw new RuntimeException(thr); - } - } - - @SuppressWarnings("deprecation") - public static void sendChunk(Object chunk, ServerLevel nmsWorld, int chunkX, int chunkZ) { - ChunkHolder chunkHolder = getPlayerChunk(nmsWorld, chunkX, chunkZ); - if (chunkHolder == null) { - return; - } - ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ); - LevelChunk levelChunk; - if (PaperLib.isPaper()) { - // getChunkAtIfLoadedImmediately is paper only - levelChunk = nmsWorld - .getChunkSource() - .getChunkAtIfLoadedImmediately(chunkX, chunkZ); - } else { - levelChunk = ((Optional) ((Either) chunkHolder - .getTickingChunkFuture() // method is not present with new paper chunk system - .getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left()) - .orElse(null); - } - if (levelChunk == null) { - return; - } - MinecraftServer.getServer().execute(() -> { - ClientboundLevelChunkWithLightPacket packet; - if (PaperLib.isPaper()) { - synchronized (chunk) { - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null, - false // last false is to not bother with x-ray - ); - } - } else { - synchronized (chunk) { - // deprecated on paper - deprecation suppressed - packet = new ClientboundLevelChunkWithLightPacket( - levelChunk, - nmsWorld.getChunkSource().getLightEngine(), - null, - null - ); - } - } - nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); - }); - } - - private static List nearbyPlayers(ServerLevel serverLevel, ChunkPos coordIntPair) { - return serverLevel.getChunkSource().chunkMap.getPlayers(coordIntPair, false); - } - - /* - NMS conversion - */ - public static LevelChunkSection newChunkSection( - final int layer, - final char[] blocks, - CachedBukkitAdapter adapter, - Registry biomeRegistry, - @Nullable PalettedContainer> biomes - ) { - return newChunkSection(layer, null, blocks, adapter, biomeRegistry, biomes); - } - - public static LevelChunkSection newChunkSection( - final int layer, - final Function get, - char[] set, - CachedBukkitAdapter adapter, - Registry biomeRegistry, - @Nullable PalettedContainer> biomes - ) { - if (set == null) { - return newChunkSection(biomeRegistry, biomes); - } - final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); - final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); - final long[] blockStates = FaweCache.INSTANCE.BLOCK_STATES.get(); - final int[] blocksCopy = FaweCache.INSTANCE.SECTION_BLOCKS.get(); - try { - int num_palette; - if (get == null) { - num_palette = createPalette(blockToPalette, paletteToBlock, blocksCopy, set, adapter, null); - } else { - num_palette = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, get, set, adapter, null); - } - - int bitsPerEntry = MathMan.log2nlz(num_palette - 1); - if (bitsPerEntry > 0 && bitsPerEntry < 5) { - bitsPerEntry = 4; - } else if (bitsPerEntry > 8) { - bitsPerEntry = MathMan.log2nlz(Block.BLOCK_STATE_REGISTRY.size() - 1); - } - - int bitsPerEntryNonZero = Math.max(bitsPerEntry, 1); // We do want to use zero sometimes - final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntryNonZero); - final int blockBitArrayEnd = MathMan.ceilZero((float) 4096 / blocksPerLong); - - if (num_palette == 1) { - for (int i = 0; i < blockBitArrayEnd; i++) { - blockStates[i] = 0; - } - } else { - final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntryNonZero, 4096, blockStates); - bitArray.fromRaw(blocksCopy); - } - - final long[] bits = Arrays.copyOfRange(blockStates, 0, blockBitArrayEnd); - final BitStorage nmsBits; - if (bitsPerEntry == 0) { - nmsBits = new ZeroBitStorage(4096); - } else { - nmsBits = new SimpleBitStorage(bitsPerEntry, 4096, bits); - } - List palette; - if (bitsPerEntry < 9) { - palette = new ArrayList<>(); - for (int i = 0; i < num_palette; i++) { - int ordinal = paletteToBlock[i]; - blockToPalette[ordinal] = Integer.MAX_VALUE; - final BlockState state = BlockTypesCache.states[ordinal]; - palette.add(((PaperweightBlockMaterial) state.getMaterial()).getState()); - } - } else { - palette = List.of(); - } - - // Create palette with data - @SuppressWarnings("deprecation") // constructor is deprecated on paper, but needed to keep compatibility with spigot - final PalettedContainer blockStatePalettedContainer = - new PalettedContainer<>( - Block.BLOCK_STATE_REGISTRY, - PalettedContainer.Strategy.SECTION_STATES, - PalettedContainer.Strategy.SECTION_STATES.getConfiguration(Block.BLOCK_STATE_REGISTRY, bitsPerEntry), - nmsBits, - palette - ); - if (biomes == null) { - IdMap> biomeHolderIdMap = biomeRegistry.asHolderIdMap(); - biomes = new PalettedContainer<>( - biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES - ); - } - - return new LevelChunkSection(blockStatePalettedContainer, biomes); - } catch (final Throwable e) { - throw e; - } finally { - Arrays.fill(blockToPalette, Integer.MAX_VALUE); - Arrays.fill(paletteToBlock, Integer.MAX_VALUE); - Arrays.fill(blockStates, 0); - Arrays.fill(blocksCopy, 0); - } - } - - @SuppressWarnings("deprecation") // Only deprecated in paper - private static LevelChunkSection newChunkSection( - Registry biomeRegistry, - @Nullable PalettedContainer> biomes - ) { - if (biomes == null) { - return new LevelChunkSection(biomeRegistry); - } - PalettedContainer dataPaletteBlocks = new PalettedContainer<>( - Block.BLOCK_STATE_REGISTRY, - Blocks.AIR.defaultBlockState(), - PalettedContainer.Strategy.SECTION_STATES - ); - return new LevelChunkSection(dataPaletteBlocks, biomes); - } - - public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { - try { - fieldBiomes.set(section, biomes); - } catch (IllegalAccessException e) { - LOGGER.error("Could not set biomes to chunk section", e); - } - } - - /** - * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. - */ - public static PalettedContainer> getBiomePalettedContainer( - BiomeType[] biomes, - IdMap> biomeRegistry - ) { - if (biomes == null) { - return null; - } - BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); - // Don't stream this as typically will see 1-4 biomes; stream overhead is large for the small length - Map> palette = new HashMap<>(); - for (BiomeType biomeType : new LinkedList<>(Arrays.asList(biomes))) { - Holder biome; - if (biomeType == null) { - biome = biomeRegistry.byId(adapter.getInternalBiomeId(BiomeTypes.PLAINS)); - } else { - biome = biomeRegistry.byId(adapter.getInternalBiomeId(biomeType)); - } - palette.put(biomeType, biome); - } - int biomeCount = palette.size(); - int bitsPerEntry = MathMan.log2nlz(biomeCount - 1); - Object configuration = PalettedContainer.Strategy.SECTION_STATES.getConfiguration( - new FakeIdMapBiome(biomeCount), - bitsPerEntry - ); - if (bitsPerEntry > 3) { - bitsPerEntry = MathMan.log2nlz(biomeRegistry.size() - 1); - } - PalettedContainer> biomePalettedContainer = new PalettedContainer<>( - biomeRegistry, - biomeRegistry.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), - PalettedContainer.Strategy.SECTION_BIOMES - ); - - final Palette> biomePalette; - if (bitsPerEntry == 0) { - biomePalette = new SingleValuePalette<>( - biomePalettedContainer.registry, - biomePalettedContainer, - new ArrayList<>(palette.values()) // Must be modifiable - ); - } else if (bitsPerEntry == 4) { - biomePalette = LinearPalette.create( - 4, - biomePalettedContainer.registry, - biomePalettedContainer, - new ArrayList<>(palette.values()) // Must be modifiable - ); - } else if (bitsPerEntry < 9) { - biomePalette = HashMapPalette.create( - bitsPerEntry, - biomePalettedContainer.registry, - biomePalettedContainer, - new ArrayList<>(palette.values()) // Must be modifiable - ); - } else { - biomePalette = GlobalPalette.create( - bitsPerEntry, - biomePalettedContainer.registry, - biomePalettedContainer, - null // unused - ); - } - - int bitsPerEntryNonZero = Math.max(bitsPerEntry, 1); // We do want to use zero sometimes - final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntryNonZero); - final int arrayLength = MathMan.ceilZero(64f / blocksPerLong); - - - BitStorage bitStorage = bitsPerEntry == 0 ? new ZeroBitStorage(64) : new SimpleBitStorage( - bitsPerEntry, - 64, - new long[arrayLength] - ); - - try { - Object data = dataConstructor.newInstance(configuration, bitStorage, biomePalette); - fieldData.set(biomePalettedContainer, data); - int index = 0; - for (int y = 0; y < 4; y++) { - for (int z = 0; z < 4; z++) { - for (int x = 0; x < 4; x++, index++) { - BiomeType biomeType = biomes[index]; - if (biomeType == null) { - continue; - } - Holder biome = biomeRegistry.byId(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)); - if (biome == null) { - continue; - } - biomePalettedContainer.set(x, y, z, biome); - } - } - } - } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - return biomePalettedContainer; - } - - public static void clearCounts(final LevelChunkSection section) throws IllegalAccessException { - fieldTickingFluidCount.setShort(section, (short) 0); - fieldTickingBlockCount.setShort(section, (short) 0); - } - - public static BiomeType adapt(Holder biome, LevelAccessor levelAccessor) { - final Registry biomeRegistry = levelAccessor.registryAccess().registryOrThrow(BIOME); - if (biomeRegistry.getKey(biome.value()) == null) { - return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN - : null; - } - return BiomeTypes.get(biome.unwrapKey().orElseThrow().location().toString()); - } - - static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { - try { - if (levelChunk.loaded || levelChunk.level.isClientSide()) { - BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos()); - if (blockEntity != null) { - if (!levelChunk.level.isClientSide) { - methodRemoveGameEventListener.invoke(levelChunk, beacon, levelChunk.level); - } - fieldRemove.set(beacon, true); - } - } - methodremoveTickingBlockEntity.invoke(levelChunk, beacon.getBlockPos()); - } catch (Throwable throwable) { - throwable.printStackTrace(); - } - } - - static List getEntities(LevelChunk chunk) { - ExceptionCollector collector = new ExceptionCollector<>(); - if (PaperLib.isPaper()) { - if (POST_CHUNK_REWRITE) { - try { - //noinspection unchecked - return (List) PAPER_CHUNK_GEN_ALL_ENTITIES.invoke(chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ)); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=true]", e); - } - } - try { - EntityList entityList = (EntityList) LEVEL_CHUNK_ENTITIES.get(chunk); - return List.of(entityList.getRawData()); - } catch (IllegalAccessException e) { - collector.add(new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=false]", e)); - // fall through - } - } - try { - //noinspection unchecked - return ((PersistentEntitySectionManager) (SERVER_LEVEL_ENTITY_MANAGER.get(chunk.level))).getEntities(chunk.getPos()); - } catch (IllegalAccessException e) { - collector.add(new RuntimeException("Failed to lookup entities [PAPER=false]", e)); - } - collector.throwIfPresent(); - return List.of(); - } - - public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) { - boolean unset = false; - if (entity instanceof Villager villager && !Fawe.isMainThread()) { - try { - if (fieldOffers.get(entity) == null) { - villager.setOffers(OFFERS); - unset = true; - } - } catch (IllegalAccessException e) { - throw new RuntimeException("Failed to set offers field to villager to avoid async catcher.", e); - } - } - entity.save(compoundTag); - if (unset) { - ((Villager) entity).setOffers(null); - } - } - - record FakeIdMapBlock(int size) implements IdMap { - - @Override - public int getId(final net.minecraft.world.level.block.state.BlockState entry) { - return 0; - } - - @Nullable - @Override - public net.minecraft.world.level.block.state.BlockState byId(final int index) { - return null; - } - - @Nonnull - @Override - public Iterator iterator() { - return Collections.emptyIterator(); - } - - } - - record FakeIdMapBiome(int size) implements IdMap { - - @Override - public int getId(final Biome entry) { - return 0; - } - - @Nullable - @Override - public Biome byId(final int index) { - return null; - } - - @Nonnull - @Override - public Iterator iterator() { - return Collections.emptyIterator(); - } - - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPostProcessor.java deleted file mode 100644 index 0c4bcff85..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPostProcessor.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.ProcessorScope; -import com.fastasyncworldedit.core.queue.IBatchProcessor; -import com.fastasyncworldedit.core.queue.IChunk; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.queue.IChunkSet; -import com.fastasyncworldedit.core.registry.state.PropertyKey; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.world.block.BlockState; -import com.sk89q.worldedit.world.block.BlockTypes; -import com.sk89q.worldedit.world.block.BlockTypesCache; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.Fluids; - -import javax.annotation.Nullable; - -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } - - @SuppressWarnings("deprecation") - @Override - public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final IChunkSet iChunkSet) { - boolean tickFluid = Settings.settings().EXPERIMENTAL.ALLOW_TICK_FLUIDS; - // The PostProcessor shouldn't be added, but just in case - if (!tickFluid) { - return; - } - PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; - layer: - for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); - if (set == null) { - // No edit means no need to process - continue; - } - char[] get = null; - for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; - boolean fromGet = false; // Used for liquids - if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { - if (get == null) { - get = getBlocks.load(layer); - } - // If this is null, then it's because we're loading a layer in the range of 0->15, but blocks aren't - // actually being set - if (get == null) { - continue layer; - } - fromGet = true; - ordinal = replacedOrdinal = get[i]; - } - if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { - continue; - } else if (!fromGet) { // if fromGet, don't do the same again - if (get == null) { - get = getBlocks.load(layer); - } - replacedOrdinal = get[i]; - } - boolean ticking = BlockTypesCache.ticking[ordinal]; - boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; - boolean replacedWasLiquid = false; - BlockState replacedState = null; - if (!ticking) { - // If the block being replaced was not ticking, it cannot be a liquid - if (!replacedWasTicking) { - continue; - } - // If the block being replaced is not fluid, we do not need to worry - if (!(replacedWasLiquid = - (replacedState = BlockState.getFromOrdinal(replacedOrdinal)).getMaterial().isLiquid())) { - continue; - } - } - BlockState state = BlockState.getFromOrdinal(ordinal); - boolean liquid = state.getMaterial().isLiquid(); - int x = i & 15; - int y = (i >> 8) & 15; - int z = (i >> 4) & 15; - BlockPos position = new BlockPos((chunk.getX() << 4) + x, (layer << 4) + y, (chunk.getZ() << 4) + z); - if (liquid || replacedWasLiquid) { - if (liquid) { - addFluid(getBlocks.serverLevel, state, position); - continue; - } - // If the replaced fluid (is?) adjacent to water. Do not bother to check adjacent chunks(sections) as this - // may be time consuming. Chances are any fluid blocks in adjacent chunks are being replaced or will end up - // being ticked anyway. We only need it to be "hit" once. - if (!wasAdjacentToWater(get, set, i, x, y, z)) { - continue; - } - addFluid(getBlocks.serverLevel, replacedState, position); - } - } - } - } - - @Nullable - @Override - public Extent construct(final Extent child) { - throw new UnsupportedOperationException("Processing only"); - } - - @Override - public ProcessorScope getScope() { - return ProcessorScope.READING_SET_BLOCKS; - } - - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - - @SuppressWarnings("deprecation") - private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { - Fluid type; - if (replacedState.getBlockType() == BlockTypes.LAVA) { - type = (int) replacedState.getState(PropertyKey.LEVEL) == 0 ? Fluids.LAVA : Fluids.FLOWING_LAVA; - } else { - type = (int) replacedState.getState(PropertyKey.LEVEL) == 0 ? Fluids.WATER : Fluids.FLOWING_WATER; - } - serverLevel.scheduleTick( - position, - type, - type.getTickDelay(serverLevel) - ); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighter.java deleted file mode 100644 index 7de83af21..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighter.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter; -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.TicketType; -import net.minecraft.util.Unit; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.chunk.ChunkStatus; - -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; -import java.util.function.IntConsumer; - -public class PaperweightStarlightRelighter extends StarlightRelighter { - - private static final TicketType FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0); - private static final int LIGHT_LEVEL = ChunkMap.MAX_VIEW_DISTANCE + ChunkStatus.getDistance(ChunkStatus.LIGHT); - - public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent queue) { - super(serverLevel, queue); - } - - @Override - protected ChunkPos createChunkPos(final long chunkKey) { - return new ChunkPos(chunkKey); - } - - @Override - protected long asLong(final int chunkX, final int chunkZ) { - return ChunkPos.asLong(chunkX, chunkZ); - } - - @Override - protected CompletableFuture chunkLoadFuture(final ChunkPos chunkPos) { - return serverLevel.getWorld().getChunkAtAsync(chunkPos.x, chunkPos.z) - .thenAccept(c -> serverLevel.getChunkSource().addTicketAtLevel( - FAWE_TICKET, - chunkPos, - LIGHT_LEVEL, - Unit.INSTANCE - )); - } - - protected void invokeRelight( - Set coords, - Consumer chunkCallback, - IntConsumer processCallback - ) { - try { - serverLevel.getChunkSource().getLightEngine().relight(coords, chunkCallback, processCallback); - } catch (Exception e) { - LOGGER.error("Error occurred on relighting", e); - } - } - - /* - * Allow the server to unload the chunks again. - * Also, if chunk packets are sent delayed, we need to do that here - */ - protected void postProcessChunks(Set coords) { - boolean delay = Settings.settings().LIGHTING.DELAY_PACKET_SENDING; - for (ChunkPos pos : coords) { - int x = pos.x; - int z = pos.z; - if (delay) { // we still need to send the block changes of that chunk - PaperweightPlatformAdapter.sendChunk(pos, serverLevel, x, z); - } - serverLevel.getChunkSource().removeTicketAtLevel(FAWE_TICKET, pos, LIGHT_LEVEL, Unit.INSTANCE); - } - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighterFactory.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighterFactory.java deleted file mode 100644 index 83509a2bb..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightStarlightRelighterFactory.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1; - -import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter; -import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode; -import com.fastasyncworldedit.core.extent.processor.lighting.Relighter; -import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import com.sk89q.worldedit.world.World; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; - -import javax.annotation.Nonnull; - -public class PaperweightStarlightRelighterFactory implements RelighterFactory { - - @Override - public @Nonnull Relighter createRelighter(RelightMode relightMode, World world, IQueueExtent queue) { - org.bukkit.World w = Bukkit.getWorld(world.getName()); - if (w == null) { - return NullRelighter.INSTANCE; - } - return new PaperweightStarlightRelighter(((CraftWorld) w).getHandle(), queue); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/nbt/PaperweightLazyCompoundTag.java deleted file mode 100644 index f2a694a2f..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/nbt/PaperweightLazyCompoundTag.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.nbt; - -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.LazyCompoundTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import net.minecraft.nbt.NumericTag; -import org.enginehub.linbus.tree.LinCompoundTag; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; - -public class PaperweightLazyCompoundTag extends LazyCompoundTag { - - private final Supplier compoundTagSupplier; - private CompoundTag compoundTag; - - public PaperweightLazyCompoundTag(Supplier compoundTagSupplier) { - super(new HashMap<>()); - this.compoundTagSupplier = compoundTagSupplier; - } - - public PaperweightLazyCompoundTag(net.minecraft.nbt.CompoundTag compoundTag) { - this(() -> compoundTag); - } - - public net.minecraft.nbt.CompoundTag get() { - return compoundTagSupplier.get(); - } - - @Override - @SuppressWarnings("unchecked") - public Map> getValue() { - if (compoundTag == null) { - compoundTag = (CompoundTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(compoundTagSupplier.get()); - } - return compoundTag.getValue(); - } - - @Override - public LinCompoundTag toLinTag() { - getValue(); - return compoundTag.toLinTag(); - } - - public boolean containsKey(String key) { - return compoundTagSupplier.get().contains(key); - } - - public byte[] getByteArray(String key) { - return compoundTagSupplier.get().getByteArray(key); - } - - public byte getByte(String key) { - return compoundTagSupplier.get().getByte(key); - } - - public double getDouble(String key) { - return compoundTagSupplier.get().getDouble(key); - } - - public double asDouble(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsDouble(); - } - return 0; - } - - public float getFloat(String key) { - return compoundTagSupplier.get().getFloat(key); - } - - public int[] getIntArray(String key) { - return compoundTagSupplier.get().getIntArray(key); - } - - public int getInt(String key) { - return compoundTagSupplier.get().getInt(key); - } - - public int asInt(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsInt(); - } - return 0; - } - - @SuppressWarnings("unchecked") - public List> getList(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof net.minecraft.nbt.ListTag nbtList) { - ArrayList> list = new ArrayList<>(); - for (net.minecraft.nbt.Tag elem : nbtList) { - if (elem instanceof net.minecraft.nbt.CompoundTag compoundTag) { - list.add(new PaperweightLazyCompoundTag(compoundTag)); - } else { - list.add(WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(elem)); - } - } - return list; - } - return Collections.emptyList(); - } - - @SuppressWarnings("unchecked") - public ListTag getListTag(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof net.minecraft.nbt.ListTag) { - return (ListTag) WorldEditPlugin.getInstance().getBukkitImplAdapter().toNative(tag); - } - return new ListTag(StringTag.class, Collections.emptyList()); - } - - @SuppressWarnings("unchecked") - public > List getList(String key, Class listType) { - ListTag listTag = getListTag(key); - if (listTag.getType().equals(listType)) { - return (List) listTag.getValue(); - } else { - return Collections.emptyList(); - } - } - - public long[] getLongArray(String key) { - return compoundTagSupplier.get().getLongArray(key); - } - - public long getLong(String key) { - return compoundTagSupplier.get().getLong(key); - } - - public long asLong(String key) { - net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof NumericTag numTag) { - return numTag.getAsLong(); - } - return 0; - } - - public short getShort(String key) { - return compoundTagSupplier.get().getShort(key); - } - - public String getString(String key) { - return compoundTagSupplier.get().getString(key); - } - - @Override - public String toString() { - return compoundTagSupplier.get().toString(); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/regen/PaperweightRegen.java deleted file mode 100644 index 99e001837..000000000 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/regen/PaperweightRegen.java +++ /dev/null @@ -1,591 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.regen; - -import com.fastasyncworldedit.bukkit.adapter.Regenerator; -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.queue.IChunkCache; -import com.fastasyncworldedit.core.queue.IChunkGet; -import com.fastasyncworldedit.core.util.ReflectionUtils; -import com.fastasyncworldedit.core.util.TaskManager; -import com.google.common.collect.ImmutableList; -import com.mojang.datafixers.util.Either; -import com.mojang.serialization.Lifecycle; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R1.PaperweightGetBlocks; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.world.RegenOptions; -import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.Registries; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.server.level.ChunkMap; -import net.minecraft.server.level.ChunkTaskPriorityQueueSorter.Message; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ThreadedLevelLightEngine; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.util.thread.ProcessorHandle; -import net.minecraft.util.thread.ProcessorMailbox; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.LevelSettings; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.FixedBiomeSource; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.chunk.ChunkGeneratorStructureState; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.ProtoChunk; -import net.minecraft.world.level.chunk.UpgradeData; -import net.minecraft.world.level.dimension.LevelStem; -import net.minecraft.world.level.levelgen.FlatLevelSource; -import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; -import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; -import net.minecraft.world.level.levelgen.WorldOptions; -import net.minecraft.world.level.levelgen.blending.BlendingData; -import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; -import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraft.world.level.storage.PrimaryLevelData; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.craftbukkit.v1_20_R1.CraftServer; -import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R1.generator.CustomChunkGenerator; -import org.bukkit.generator.BiomeProvider; -import org.bukkit.generator.BlockPopulator; - -import javax.annotation.Nullable; -import java.lang.reflect.Field; -import java.nio.file.Path; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.OptionalLong; -import java.util.Random; -import java.util.concurrent.CompletableFuture; -import java.util.function.BooleanSupplier; -import java.util.function.Supplier; - -import static net.minecraft.core.registries.Registries.BIOME; - -public class PaperweightRegen extends Regenerator { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private static final Field serverWorldsField; - private static final Field paperConfigField; - private static final Field flatBedrockField; - private static final Field generatorSettingFlatField; - private static final Field generatorSettingBaseSupplierField; - private static final Field delegateField; - private static final Field chunkSourceField; - private static final Field generatorStructureStateField; - private static final Field ringPositionsField; - private static final Field hasGeneratedPositionsField; - - //list of chunk stati in correct order without FULL - private static final Map chunkStati = new LinkedHashMap<>(); - - static { - chunkStati.put(ChunkStatus.EMPTY, Concurrency.FULL); // empty: radius -1, does nothing - chunkStati.put(ChunkStatus.STRUCTURE_STARTS, Concurrency.NONE); // structure starts: uses unsynchronized maps - chunkStati.put( - ChunkStatus.STRUCTURE_REFERENCES, - Concurrency.FULL - ); // structure refs: radius 8, but only writes to current chunk - chunkStati.put(ChunkStatus.BIOMES, Concurrency.FULL); // biomes: radius 0 - chunkStati.put(ChunkStatus.NOISE, Concurrency.RADIUS); // noise: radius 8 - chunkStati.put(ChunkStatus.SURFACE, Concurrency.NONE); // surface: radius 0, requires NONE - chunkStati.put(ChunkStatus.CARVERS, Concurrency.NONE); // carvers: radius 0, but RADIUS and FULL change results - /*chunkStati.put( - ChunkStatus.LIQUID_CARVERS, - Concurrency.NONE - ); // liquid carvers: radius 0, but RADIUS and FULL change results*/ - chunkStati.put(ChunkStatus.FEATURES, Concurrency.NONE); // features: uses unsynchronized maps - chunkStati.put( - ChunkStatus.LIGHT, - Concurrency.FULL - ); // light: radius 1, but no writes to other chunks, only current chunk - chunkStati.put(ChunkStatus.SPAWN, Concurrency.FULL); // spawn: radius 0 - // chunkStati.put(ChunkStatus.HEIGHTMAPS, Concurrency.FULL); // heightmaps: radius 0 - - try { - serverWorldsField = CraftServer.class.getDeclaredField("worlds"); - serverWorldsField.setAccessible(true); - - Field tmpPaperConfigField; - Field tmpFlatBedrockField; - try { //only present on paper - tmpPaperConfigField = Level.class.getDeclaredField("paperConfig"); - tmpPaperConfigField.setAccessible(true); - - tmpFlatBedrockField = tmpPaperConfigField.getType().getDeclaredField("generateFlatBedrock"); - tmpFlatBedrockField.setAccessible(true); - } catch (Exception e) { - tmpPaperConfigField = null; - tmpFlatBedrockField = null; - } - paperConfigField = tmpPaperConfigField; - flatBedrockField = tmpFlatBedrockField; - - generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName( - "settings", "e")); - generatorSettingBaseSupplierField.setAccessible(true); - - generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "d")); - generatorSettingFlatField.setAccessible(true); - - delegateField = CustomChunkGenerator.class.getDeclaredField("delegate"); - delegateField.setAccessible(true); - - chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "I")); - chunkSourceField.setAccessible(true); - - generatorStructureStateField = ChunkMap.class.getDeclaredField(Refraction.pickName("chunkGeneratorState", "v")); - generatorStructureStateField.setAccessible(true); - - ringPositionsField = ChunkGeneratorStructureState.class.getDeclaredField(Refraction.pickName("ringPositions", "g")); - ringPositionsField.setAccessible(true); - - hasGeneratedPositionsField = ChunkGeneratorStructureState.class.getDeclaredField( - Refraction.pickName("hasGeneratedPositions", "h") - ); - hasGeneratedPositionsField.setAccessible(true); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - //runtime - private ServerLevel originalServerWorld; - private ServerChunkCache originalChunkProvider; - private ServerLevel freshWorld; - private ServerChunkCache freshChunkProvider; - private LevelStorageSource.LevelStorageAccess session; - private StructureTemplateManager structureTemplateManager; - private ThreadedLevelLightEngine threadedLevelLightEngine; - private ChunkGenerator chunkGenerator; - - private Path tempDir; - - private boolean generateFlatBedrock = false; - - public PaperweightRegen(org.bukkit.World originalBukkitWorld, Region region, Extent target, RegenOptions options) { - super(originalBukkitWorld, region, target, options); - } - - @Override - protected boolean prepare() { - this.originalServerWorld = ((CraftWorld) originalBukkitWorld).getHandle(); - originalChunkProvider = originalServerWorld.getChunkSource(); - - //flat bedrock? (only on paper) - if (paperConfigField != null) { - try { - generateFlatBedrock = flatBedrockField.getBoolean(paperConfigField.get(originalServerWorld)); - } catch (Exception ignored) { - } - } - - seed = options.getSeed().orElse(originalServerWorld.getSeed()); - chunkStati.forEach((s, c) -> super.chunkStatuses.put(new ChunkStatusWrap(s), c)); - - return true; - } - - @Override - @SuppressWarnings("unchecked") - protected boolean initNewWorld() throws Exception { - //world folder - tempDir = java.nio.file.Files.createTempDirectory("FastAsyncWorldEditWorldGen"); - - //prepare for world init (see upstream implementation for reference) - org.bukkit.World.Environment environment = originalBukkitWorld.getEnvironment(); - org.bukkit.generator.ChunkGenerator generator = originalBukkitWorld.getGenerator(); - LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(tempDir); - ResourceKey levelStemResourceKey = getWorldDimKey(environment); - session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey); - PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData; - - MinecraftServer server = originalServerWorld.getCraftServer().getServer(); - WorldOptions originalOpts = originalWorldData.worldGenOptions(); - WorldOptions newOpts = options.getSeed().isPresent() - ? originalOpts.withSeed(OptionalLong.of(seed)) - : originalOpts; - LevelSettings newWorldSettings = new LevelSettings( - "faweregentempworld", - originalWorldData.settings.gameType(), - originalWorldData.settings.hardcore(), - originalWorldData.settings.difficulty(), - originalWorldData.settings.allowCommands(), - originalWorldData.settings.gameRules(), - originalWorldData.settings.getDataConfiguration() - ); - - PrimaryLevelData.SpecialWorldProperty specialWorldProperty = - originalWorldData.isFlatWorld() - ? PrimaryLevelData.SpecialWorldProperty.FLAT - : originalWorldData.isDebugWorld() - ? PrimaryLevelData.SpecialWorldProperty.DEBUG - : PrimaryLevelData.SpecialWorldProperty.NONE; - PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, specialWorldProperty, Lifecycle.stable()); - - BiomeProvider biomeProvider = getBiomeProvider(); - - - //init world - freshWorld = Fawe.instance().getQueueHandler().sync((Supplier) () -> new ServerLevel( - server, - server.executor, - session, - newWorldData, - originalServerWorld.dimension(), - DedicatedServer.getServer().registryAccess().registry(Registries.LEVEL_STEM).orElseThrow() - .getOrThrow(levelStemResourceKey), - new RegenNoOpWorldLoadListener(), - originalServerWorld.isDebug(), - seed, - ImmutableList.of(), - false, - originalServerWorld.getRandomSequences(), - environment, - generator, - biomeProvider - ) { - - private final Holder singleBiome = options.hasBiomeType() ? DedicatedServer.getServer().registryAccess() - .registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow( - WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) - ) : null; - - @Override - public void tick(BooleanSupplier shouldKeepTicking) { //no ticking - } - - @Override - public Holder getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) { - if (options.hasBiomeType()) { - return singleBiome; - } - return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome( - biomeX, biomeY, biomeZ, getChunkSource().randomState().sampler() - ); - } - }).get(); - freshWorld.noSave = true; - removeWorldFromWorldsMap(); - newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name - if (paperConfigField != null) { - paperConfigField.set(freshWorld, originalServerWorld.paperConfig()); - } - - ChunkGenerator originalGenerator = originalChunkProvider.getGenerator(); - if (originalGenerator instanceof FlatLevelSource flatLevelSource) { - FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings(); - chunkGenerator = new FlatLevelSource(generatorSettingFlat); - } else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) { - Holder generatorSettingBaseSupplier = (Holder) generatorSettingBaseSupplierField.get( - originalGenerator); - BiomeSource biomeSource; - if (options.hasBiomeType()) { - - biomeSource = new FixedBiomeSource( - DedicatedServer.getServer().registryAccess() - .registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow( - WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) - ) - ); - } else { - biomeSource = originalGenerator.getBiomeSource(); - } - chunkGenerator = new NoiseBasedChunkGenerator( - biomeSource, - generatorSettingBaseSupplier - ); - } else if (originalGenerator instanceof CustomChunkGenerator customChunkGenerator) { - chunkGenerator = customChunkGenerator.getDelegate(); - } else { - LOGGER.error("Unsupported generator type {}", originalGenerator.getClass().getName()); - return false; - } - if (generator != null) { - chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator); - generateConcurrent = generator.isParallelCapable(); - } -// chunkGenerator.conf = freshWorld.spigotConfig; - Does not exist anymore, may need to be re-addressed - - freshChunkProvider = new ServerChunkCache( - freshWorld, - session, - server.getFixerUpper(), - server.getStructureManager(), - server.executor, - chunkGenerator, - freshWorld.spigotConfig.viewDistance, - freshWorld.spigotConfig.simulationDistance, - server.forceSynchronousWrites(), - new RegenNoOpWorldLoadListener(), - (chunkCoordIntPair, state) -> { - }, - () -> server.overworld().getDataStorage() - ) { - // redirect to LevelChunks created in #createChunks - @Override - public ChunkAccess getChunk(int x, int z, ChunkStatus chunkstatus, boolean create) { - ChunkAccess chunkAccess = getChunkAt(x, z); - if (chunkAccess == null && create) { - chunkAccess = createChunk(getProtoChunkAt(x, z)); - } - return chunkAccess; - } - }; - - if (seed == originalOpts.seed() && !options.hasBiomeType()) { - // Optimisation for needless ring position calculation when the seed and biome is the same. - ChunkGeneratorStructureState state = (ChunkGeneratorStructureState) generatorStructureStateField.get(originalChunkProvider.chunkMap); - boolean hasGeneratedPositions = hasGeneratedPositionsField.getBoolean(state); - if (hasGeneratedPositions) { - Map>> origPositions = - (Map>>) ringPositionsField.get(state); - Map>> copy = new Object2ObjectArrayMap<>( - origPositions); - ChunkGeneratorStructureState newState = (ChunkGeneratorStructureState) generatorStructureStateField.get(freshChunkProvider.chunkMap); - ringPositionsField.set(newState, copy); - hasGeneratedPositionsField.setBoolean(newState, true); - } - } - - - chunkSourceField.set(freshWorld, freshChunkProvider); - //let's start then - structureTemplateManager = server.getStructureManager(); - threadedLevelLightEngine = new NoOpLightEngine(freshChunkProvider); - - return true; - } - - @Override - protected void cleanup() { - try { - session.close(); - } catch (Exception ignored) { - } - - //shutdown chunk provider - try { - Fawe.instance().getQueueHandler().sync(() -> { - try { - freshChunkProvider.close(false); - } catch (Exception e) { - throw new RuntimeException(e); - } - }); - } catch (Exception ignored) { - } - - //remove world from server - try { - Fawe.instance().getQueueHandler().sync(this::removeWorldFromWorldsMap); - } catch (Exception ignored) { - } - - //delete directory - try { - SafeFiles.tryHardToDeleteDir(tempDir); - } catch (Exception ignored) { - } - } - - @Override - protected ProtoChunk createProtoChunk(int x, int z) { - return new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld, - this.freshWorld.registryAccess().registryOrThrow(BIOME), null - ); - } - - @Override - protected LevelChunk createChunk(ProtoChunk protoChunk) { - return new LevelChunk( - freshWorld, - protoChunk, - null // we don't want to add entities - ); - } - - @Override - protected ChunkStatusWrap getFullChunkStatus() { - return new ChunkStatusWrap(ChunkStatus.FULL); - } - - @Override - protected List getBlockPopulators() { - return originalServerWorld.getWorld().getPopulators(); - } - - @Override - protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) { - // BlockPopulator#populate has to be called synchronously for TileEntity access - TaskManager.taskManager().task(() -> { - final CraftWorld world = freshWorld.getWorld(); - final Chunk chunk = world.getChunkAt(levelChunk.locX, levelChunk.locZ); - blockPopulator.populate(world, random, chunk); - }); - } - - @Override - protected IChunkCache initSourceQueueCache() { - return (chunkX, chunkZ) -> new PaperweightGetBlocks(freshWorld, chunkX, chunkZ) { - @Override - public LevelChunk ensureLoaded(ServerLevel nmsWorld, int x, int z) { - return getChunkAt(x, z); - } - }; - } - - //util - @SuppressWarnings("unchecked") - private void removeWorldFromWorldsMap() { - Fawe.instance().getQueueHandler().sync(() -> { - try { - Map map = (Map) serverWorldsField.get(Bukkit.getServer()); - map.remove("faweregentempworld"); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - }); - } - - private ResourceKey getWorldDimKey(org.bukkit.World.Environment env) { - return switch (env) { - case NETHER -> LevelStem.NETHER; - case THE_END -> LevelStem.END; - default -> LevelStem.OVERWORLD; - }; - } - - private static class RegenNoOpWorldLoadListener implements ChunkProgressListener { - - private RegenNoOpWorldLoadListener() { - } - - @Override - public void updateSpawnPos(ChunkPos spawnPos) { - } - - @Override - public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) { - } - - @Override - public void start() { - - } - - @Override - public void stop() { - } - - // TODO Paper only(?) @Override - public void setChunkRadius(int radius) { - } - - } - - private class FastProtoChunk extends ProtoChunk { - - public FastProtoChunk( - final ChunkPos pos, - final UpgradeData upgradeData, - final LevelHeightAccessor world, - final Registry biomeRegistry, - @Nullable final BlendingData blendingData - ) { - super(pos, upgradeData, world, biomeRegistry, blendingData); - } - - // avoid warning on paper - - // compatibility with spigot - - public boolean generateFlatBedrock() { - return generateFlatBedrock; - } - - // no one will ever see the entities! - @Override - public List getEntities() { - return Collections.emptyList(); - } - - } - - protected class ChunkStatusWrap extends ChunkStatusWrapper { - - private final ChunkStatus chunkStatus; - - public ChunkStatusWrap(ChunkStatus chunkStatus) { - this.chunkStatus = chunkStatus; - } - - @Override - public int requiredNeighborChunkRadius() { - return chunkStatus.getRange(); - } - - @Override - public String name() { - return chunkStatus.toString(); - } - - @Override - public CompletableFuture processChunk(List accessibleChunks) { - return chunkStatus.generate( - Runnable::run, // TODO revisit, we might profit from this somehow? - freshWorld, - chunkGenerator, - structureTemplateManager, - threadedLevelLightEngine, - c -> CompletableFuture.completedFuture(Either.left(c)), - accessibleChunks - ); - } - - } - - /** - * A light engine that does nothing. As light is calculated after pasting anyway, we can avoid - * work this way. - */ - static class NoOpLightEngine extends ThreadedLevelLightEngine { - - private static final ProcessorMailbox MAILBOX = ProcessorMailbox.create(task -> { - }, "fawe-no-op"); - private static final ProcessorHandle> HANDLE = ProcessorHandle.of("fawe-no-op", m -> { - }); - - public NoOpLightEngine(final ServerChunkCache chunkProvider) { - super(chunkProvider, chunkProvider.chunkMap, false, MAILBOX, HANDLE); - } - - @Override - public CompletableFuture lightChunk(final ChunkAccess chunk, final boolean excludeBlocks) { - return CompletableFuture.completedFuture(chunk); - } - - } - -} From d2033d49ca00e52c90dce9b13e8e27a01303ce2f Mon Sep 17 00:00:00 2001 From: Zeranny Date: Sun, 21 Jul 2024 08:48:57 +0100 Subject: [PATCH 211/220] Fix parseFromInput Method for Masks and Patterns When Called via API (#2839) Explicitly Mask or Pattern in parseFromInput --- .../sk89q/worldedit/extension/factory/MaskFactory.java | 6 ++++++ .../worldedit/extension/factory/PatternFactory.java | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java index 3440b009c..dce3e1c4f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java @@ -53,6 +53,7 @@ import com.sk89q.worldedit.extension.factory.parser.mask.NoiseMaskParser; import com.sk89q.worldedit.extension.factory.parser.mask.OffsetMaskParser; import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser; import com.sk89q.worldedit.extension.factory.parser.mask.SolidMaskParser; +import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.NoMatchException; import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.function.mask.Mask; @@ -132,6 +133,11 @@ public final class MaskFactory extends AbstractFactory { //FAWE start - rich mask parsing + @Override + public Mask parseFromInput(String input, ParserContext context) throws InputParseException { + return super.parseFromInput(input, context); + } + @Override protected Mask getParsed(final String input, final List masks) { return switch (masks.size()) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java index 25955adee..242d1d7bc 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java @@ -60,7 +60,9 @@ import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.RandomStatePatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.SingleBlockPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.TypeOrStateApplyingPatternParser; +import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.NoMatchException; +import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.RandomPattern; import com.sk89q.worldedit.internal.registry.AbstractFactory; @@ -130,6 +132,13 @@ public final class PatternFactory extends AbstractFactory { register(new VoronoiPatternParser(worldEdit)); } + //FAWE start - rich pattern parsing + + @Override + public Pattern parseFromInput(String input, ParserContext context) throws InputParseException { + return super.parseFromInput(input, context); + } + @Override protected Pattern getParsed(final String input, final List patterns) { switch (patterns.size()) { From 01273e0ed7d77b61315e0e438452b07d9b27c162 Mon Sep 17 00:00:00 2001 From: Jordan Date: Sun, 21 Jul 2024 14:59:12 +0200 Subject: [PATCH 212/220] fix: use new index calculations for BlockVectorSet remove (#2842) - fixes #2841 --- .../com/fastasyncworldedit/core/math/BlockVectorSet.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BlockVectorSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BlockVectorSet.java index b181f9506..8911099af 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BlockVectorSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BlockVectorSet.java @@ -192,12 +192,13 @@ public class BlockVectorSet extends AbstractCollection implements } public boolean remove(int x, int y, int z) { - int pair = MathMan.pair((short) (x >> 11), (short) (z >> 11)); - LocalBlockVectorSet localMap = localSets.get(pair); + int indexedY = (y + 128) >> 9; + long triple = MathMan.tripleWorldCoord((x >> 11), indexedY, (z >> 11)); + LocalBlockVectorSet localMap = localSets.get(triple); if (localMap != null) { - if (localMap.remove(x & 2047, y, z & 2047)) { + if (localMap.remove(x & 2047, ((y + 128) & 511) - 128, z & 2047)) { if (localMap.isEmpty()) { - localSets.remove(pair); + localSets.remove(triple); } return true; } From f65801c5a41e54a7875f5e41e37ce4ea1d1f265f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 00:42:51 +0000 Subject: [PATCH 213/220] Update dependency org.checkerframework:checker-qual to v3.45.0 (#2847) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 79d9258b8..2c6294307 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,7 +23,7 @@ sparsebitset = "1.3" parallelgzip = "1.0.5" adventure = "4.17.0" adventure-bukkit = "4.3.3" -checkerqual = "3.44.0" +checkerqual = "3.45.0" truezip = "6.8.4" auto-value = "1.11.0" findbugs = "3.0.2" From b5ff3282185f22ba50b5cceef15f1a0dec05bcc5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 00:43:03 +0000 Subject: [PATCH 214/220] Update dependency com.palmergames.bukkit.towny:towny to v0.100.3.9 (#2846) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2c6294307..4f8f18a17 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.3.7" +towny = "0.100.3.9" plotsquared = "7.3.8" # Third party From ddacb976e4bc0e1140a3ce6061f5fd95c5f8e3f5 Mon Sep 17 00:00:00 2001 From: Jordan Date: Tue, 23 Jul 2024 19:53:12 +0200 Subject: [PATCH 215/220] fix: improve SchemGen, allow null mask (reordered command args) (#2817) - fixes #2815 --- .../command/tool/brush/PopulateSchem.java | 3 +- .../core/function/generator/SchemGen.java | 53 +++++++++++++++---- .../java/com/sk89q/worldedit/EditSession.java | 2 +- .../worldedit/command/BrushCommands.java | 4 +- .../com/sk89q/worldedit/extent/Extent.java | 25 ++++++--- 5 files changed, 67 insertions(+), 20 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/PopulateSchem.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/PopulateSchem.java index b28d7536b..59fc2add2 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/PopulateSchem.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/PopulateSchem.java @@ -24,7 +24,8 @@ public record PopulateSchem(Mask mask, List clipboards, int rar CuboidRegion cuboid = new CuboidRegion( editSession.getWorld(), position.subtract(size1, size1, size1), - position.add(size1, size1, size1) + position.add(size1, size1, size1), + true ); try { editSession.addSchems(cuboid, mask, clipboards, rarity, randomRotate); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/SchemGen.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/SchemGen.java index 250914c05..83207f50b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/SchemGen.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/SchemGen.java @@ -7,6 +7,7 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.math.transform.Transform; +import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.session.ClipboardHolder; import java.util.List; @@ -19,29 +20,60 @@ public class SchemGen implements Resource { private final List clipboards; private final boolean randomRotate; private final Mask mask; + private final Region region; private final MutableBlockVector3 mutable = new MutableBlockVector3(); + /** + * @deprecated Use {@link SchemGen#SchemGen(Mask, Extent, List, boolean, Region)} + */ + @Deprecated(forRemoval = true, since = "TODO") public SchemGen(Mask mask, Extent extent, List clipboards, boolean randomRotate) { this.mask = mask; this.extent = extent; this.clipboards = clipboards; this.randomRotate = randomRotate; + this.region = null; + } + + /** + * New instance. Places a schematic on terrain at a given x,z when appropriate + * + * @since TODO + */ + public SchemGen(Mask mask, Extent extent, List clipboards, boolean randomRotate, Region region) { + this.mask = mask; + this.extent = extent; + this.clipboards = clipboards; + this.randomRotate = randomRotate; + this.region = region; + } + + private int getY(int x, int z) { + if (region == null) { + return extent.getNearestSurfaceTerrainBlock( + x, + z, + mutable.y(), + this.extent.getMinY(), + this.extent.getMaxY(), + Integer.MIN_VALUE, + Integer.MAX_VALUE + ); + } else { + int y = extent.getHighestTerrainBlock(x, z, region.getMinimumY(), region.getMaximumY(), mask); + if (y == region.getMinimumY() && !extent.getBlock(x, y, z).getMaterial().isMovementBlocker()) { + return Integer.MIN_VALUE; + } + return y; + } } @Override public boolean spawn(Random random, int x, int z) throws WorldEditException { mutable.mutX(x); mutable.mutZ(z); - int y = extent.getNearestSurfaceTerrainBlock( - x, - z, - mutable.y(), - this.extent.getMinY(), - this.extent.getMaxY(), - Integer.MIN_VALUE, - Integer.MAX_VALUE - ); + int y = getY(x, z); if (y == Integer.MIN_VALUE || y == Integer.MAX_VALUE) { return false; } @@ -54,7 +86,8 @@ public class SchemGen implements Resource { if (randomRotate) { holder.setTransform(new AffineTransform().rotateY(ThreadLocalRandom.current().nextInt(4) * 90)); } - Clipboard clipboard = holder.getClipboard(); + Clipboard clipboard = holder.getClipboards().size() == 1 ? holder.getClipboard() : + holder.getClipboards().get(ThreadLocalRandom.current().nextInt(clipboards.size())); Transform transform = holder.getTransform(); if (transform.isIdentity()) { clipboard.paste(extent, mutable, false); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index 1469ffb96..926265bfb 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -3881,7 +3881,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { @Override public void addSchems(Region region, Mask mask, List clipboards, int rarity, boolean rotate) throws WorldEditException { - spawnResource(region, new SchemGen(mask, this, clipboards, rotate), rarity, 1); + spawnResource(region, new SchemGen(mask, this, clipboards, rotate, region), rarity, 1); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index 7160be750..664e656c4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -645,10 +645,10 @@ public class BrushCommands { @CommandPermissions("worldedit.brush.populateschematic") public void scatterSchemBrush( Player player, InjectedValueAccess context, - @Arg(desc = "Mask") - Mask mask, @Arg(name = "clipboard", desc = "Clipboard uri") String clipboardStr, + @Arg(desc = "Mask of block to place on. Defaults to solid blocks.", def = "") + Mask mask, @Arg(desc = "Expression", def = "30") Expression radius, @Arg(desc = "double", def = "50") diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java index 6117c6850..1b4420d27 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/Extent.java @@ -216,7 +216,7 @@ public interface Extent extends InputExtent, OutputExtent { */ /** - * Returns the highest solid 'terrain' block. + * Returns the highest solid 'terrain' (movement-blocking) block. * * @param x the X coordinate * @param z the Z coordinate @@ -225,6 +225,9 @@ public interface Extent extends InputExtent, OutputExtent { * @return height of highest block found or 'minY' */ default int getHighestTerrainBlock(final int x, final int z, int minY, int maxY) { + maxY = Math.min(maxY, getMaxY()); + minY = Math.max(getMinY(), minY); + for (int y = maxY; y >= minY; --y) { BlockState block = getBlock(x, y, z); if (block.getBlockType().getMaterial().isMovementBlocker()) { @@ -235,7 +238,7 @@ public interface Extent extends InputExtent, OutputExtent { } /** - * Returns the highest solid 'terrain' block. + * Returns the highest block matching the given mask. * * @param x the X coordinate * @param z the Z coordinate @@ -245,6 +248,9 @@ public interface Extent extends InputExtent, OutputExtent { * @return height of highest block found or 'minY' */ default int getHighestTerrainBlock(final int x, final int z, int minY, int maxY, Mask filter) { + if (filter == null) { + return getHighestTerrainBlock(x, z, minY, maxY); + } maxY = Math.min(maxY, getMaxY()); minY = Math.max(getMinY(), minY); @@ -259,9 +265,7 @@ public interface Extent extends InputExtent, OutputExtent { } /** - * Returns the nearest surface layer (up/down from start) - *

    - * TODO: Someone understand this..? + * Returns the nearest surface layer (up/down from start), where a layer is 1/16th of a block to allow for snow, liquid, etc. * * @param x x to search from * @param z y to search from @@ -271,6 +275,9 @@ public interface Extent extends InputExtent, OutputExtent { * @return nearest surface layer */ default int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) { + maxY = Math.min(maxY, getMaxY()); + minY = Math.max(getMinY(), minY); + int clearanceAbove = maxY - y; int clearanceBelow = y - minY; int clearance = Math.min(clearanceAbove, clearanceBelow); @@ -331,6 +338,9 @@ public interface Extent extends InputExtent, OutputExtent { * @return The y value of the nearest terrain block */ default int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, Mask mask) { + maxY = Math.min(maxY, getMaxY()); + minY = Math.max(getMinY(), minY); + y = Math.max(minY, Math.min(maxY, y)); int clearanceAbove = maxY - y; int clearanceBelow = y - minY; @@ -438,6 +448,9 @@ public interface Extent extends InputExtent, OutputExtent { int failedMax, boolean ignoreAir ) { + maxY = Math.min(maxY, getMaxY()); + minY = Math.max(getMinY(), minY); + y = Math.max(minY, Math.min(maxY, y)); int clearanceAbove = maxY - y; int clearanceBelow = y - minY; @@ -494,7 +507,7 @@ public interface Extent extends InputExtent, OutputExtent { default void addSchems(Region region, Mask mask, List clipboards, int rarity, boolean rotate) throws WorldEditException { - spawnResource(region, new SchemGen(mask, this, clipboards, rotate), rarity, 1); + spawnResource(region, new SchemGen(mask, this, clipboards, rotate, region), rarity, 1); } default void spawnResource(Region region, Resource gen, int rarity, int frequency) throws WorldEditException { From 8c3df594132650ffbed1c2c1f86439629df9bf6a Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 25 Jul 2024 21:05:16 +0200 Subject: [PATCH 216/220] fix: improve schematic format selection (#2838) - no longer allow selecting a format specifically because of the generic extension `.schem` --- .../worldedit/command/SchematicCommands.java | 12 ++--- .../clipboard/io/BuiltInClipboardFormat.java | 45 +++++++++++++++++++ .../extent/clipboard/io/ClipboardFormat.java | 7 +++ .../extent/clipboard/io/ClipboardFormats.java | 43 +++++++++++++++++- .../src/main/resources/lang/strings.json | 1 + 5 files changed, 101 insertions(+), 7 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java index 8a7751bd4..e6a369502 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java @@ -376,11 +376,13 @@ public class SchematicCommands { actor.print(Caption.of("fawe.error.no-perm", "worldedit.schematic.load.other")); return; } - if (noExplicitFormat && filename.matches(".*\\.[\\w].*")) { - format = ClipboardFormats - .findByExtension(filename.substring(filename.lastIndexOf('.') + 1)); - } else { + if (!noExplicitFormat) { format = ClipboardFormats.findByAlias(formatName); + } else if (filename.matches(".*\\.[\\w].*")) { + format = ClipboardFormats + .findByExplicitExtension(filename.substring(filename.lastIndexOf('.') + 1)); + } else { + format = null; } file = MainUtil.resolve(dir, filename, format, false); } @@ -396,7 +398,7 @@ public class SchematicCommands { .isInSubDirectory(saveDir, file)) + ")")); return; } - if (format == null || noExplicitFormat) { + if (format == null) { format = ClipboardFormats.findByFile(file); if (format == null) { actor.print(Caption.of("worldedit.schematic.unknown-format", TextComponent.of(formatName))); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java index bfd6b2029..a26e7c99a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/BuiltInClipboardFormat.java @@ -50,6 +50,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.Collections; import java.util.Locale; import java.util.Set; import java.util.zip.GZIPInputStream; @@ -125,6 +126,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { public String getPrimaryFileExtension() { return "schem"; } + + @Override + public Set getExplicitFileExtensions() { + return Set.of("schem3", "sponge3", "fast3"); + } }, FAST_V2("fast.2", "fawe.2", "schem.2") { @Override @@ -168,6 +174,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { } return super.isFormat(file); } + + @Override + public Set getExplicitFileExtensions() { + return Set.of("schem2", "sponge2", "fast2"); + } }, //FAWE end @@ -217,6 +228,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { } return rootEntry.value().value().containsKey("Materials"); } + + @Override + public Set getExplicitFileExtensions() { + return Set.of("mcedit", "schem1", "sponge1", "fast1"); + } }, SPONGE_V1_SCHEMATIC("sponge.1") { @Override @@ -243,6 +259,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { public boolean isFormat(File file) { return MCEDIT_SCHEMATIC.isFormat(file); } + + @Override + public Set getExplicitFileExtensions() { + return Collections.emptySet(); + } }, /** @@ -277,6 +298,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { public boolean isFormat(File file) { return FAST_V2.isFormat(file); } + + @Override + public Set getExplicitFileExtensions() { + return Collections.emptySet(); + } }, SPONGE_V3_SCHEMATIC("sponge.3", "slow", "safe") { // FAWE - edit aliases for fast @@ -301,6 +327,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { return FAST_V3.isFormat(file); //FAWE end } + + @Override + public Set getExplicitFileExtensions() { + return Collections.emptySet(); + } }, //FAWE start - recover schematics with bad entity data & register other clipboard formats BROKENENTITY("brokenentity", "legacyentity", "le", "be", "brokenentities", "legacyentities") { @@ -341,6 +372,10 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { return false; } + @Override + public Set getExplicitFileExtensions() { + return Collections.emptySet(); + } }, /** @@ -401,6 +436,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { public boolean isFormat(final File file) { return file.getName().toLowerCase(Locale.ROOT).endsWith(".nbt") && super.isFormat(file); } + + @Override + public Set getExplicitFileExtensions() { + return Set.of("nbt"); + } }, /** @@ -427,6 +467,11 @@ public enum BuiltInClipboardFormat implements ClipboardFormat { public String getPrimaryFileExtension() { return "png"; } + + @Override + public Set getExplicitFileExtensions() { + return Set.of("png"); + } }; //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java index 7b4b1bf3b..cb1b97e2a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormat.java @@ -124,6 +124,13 @@ public interface ClipboardFormat { //FAWE start + /** + * Get the explicit file extensions (e.g. .schem2) this format is commonly known to use. + * + * @return The explicit file extensions this format might be known by + */ + Set getExplicitFileExtensions(); + /** * Sets the actor's clipboard. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java index b69a7a0cc..786af54fa 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/ClipboardFormats.java @@ -66,6 +66,7 @@ public class ClipboardFormats { private static final Map aliasMap = new HashMap<>(); // FAWE start - keep order of ClipboardFormat entries -> prefer FAST over SPONGE_SCHEMATIC private static final Multimap fileExtensionMap = Multimaps.newMultimap(new HashMap<>(), LinkedHashSet::new); + private static final Multimap explicitFileExtensionMap = Multimaps.newMultimap(new HashMap<>(), LinkedHashSet::new); // FAWE end private static final List registeredFormats = new ArrayList<>(); @@ -86,6 +87,10 @@ public class ClipboardFormats { String lowExt = ext.toLowerCase(Locale.ROOT); fileExtensionMap.put(lowExt, format); } + for (String ext : format.getExplicitFileExtensions()) { + String lowExt = ext.toLowerCase(Locale.ROOT); + explicitFileExtensionMap.put(lowExt, format); + } registeredFormats.add(format); } @@ -147,6 +152,18 @@ public class ClipboardFormats { return fileExtensionMap.keySet().toArray(new String[fileExtensionMap.keySet().size()]); } + //FAWE start + + /** + * A mapping from explicit extensions (e.g. .schem2) to formats. + * + * @return a multimap from a file extension to the potential matching formats. + */ + public static Multimap getExplicitFileExtensionMap() { + return Multimaps.unmodifiableMultimap(explicitFileExtensionMap); + } + //FAWE end + private ClipboardFormats() { } @@ -157,8 +174,10 @@ public class ClipboardFormats { * * @param extension the extension * @return the format, otherwise null if one cannot be detected + * @deprecated DO NOT USE. Sponge formats 2 and 3 both use .schem by default. */ @Nullable + @Deprecated(forRemoval = true, since = "TODO") public static ClipboardFormat findByExtension(String extension) { checkNotNull(extension); @@ -172,6 +191,26 @@ public class ClipboardFormats { } + /** + * Detect the format given an explicit extension, e.g. ".schem2" + * + * @param extension the extension + * @return the format, otherwise null if one cannot be detected + */ + @Nullable + public static ClipboardFormat findByExplicitExtension(String extension) { + checkNotNull(extension); + + Collection> entries = getExplicitFileExtensionMap().entries(); + for (Map.Entry entry : entries) { + if (entry.getKey().equalsIgnoreCase(extension)) { + return entry.getValue(); + } + } + return null; + + } + public static MultiClipboardHolder loadAllFromInput( Actor player, String input, @@ -231,7 +270,7 @@ public class ClipboardFormats { } if (format == null && input.matches(".*\\.[\\w].*")) { String extension = input.substring(input.lastIndexOf('.') + 1); - format = findByExtension(extension); + format = findByExplicitExtension(extension); } f = MainUtil.resolve(dir, input, format, true); } @@ -302,7 +341,7 @@ public class ClipboardFormats { byte[] buffer = new byte[8192]; while ((entry = zip.getNextEntry()) != null) { String filename = entry.getName(); - ClipboardFormat format = findByExtension(filename); + ClipboardFormat format = findByExtension(filename); // FIXME if (format != null) { FastByteArrayOutputStream out = new FastByteArrayOutputStream(); int len; diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index 16e10a00d..7d49114b5 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -68,6 +68,7 @@ "fawe.worldedit.schematic.schematic.loaded": "{0} loaded. Paste it with //paste", "fawe.worldedit.schematic.schematic.saved": "{0} saved.", "fawe.worldedit.schematic.schematic.none": "No files found.", + "fawe.worldedit.schematic.schematic.load-failure": "File could not be read or it does not exist: {0}. If you are specifying a format, you may not be specifying the correct one. Sponge schematic v2 and v3 both use the .schem file extension. To allow FAWE to select the format, do not specify one.", "fawe.worldedit.clipboard.clipboard.uri.not.found": "You do not have {0} loaded", "fawe.worldedit.clipboard.clipboard.cleared": "Clipboard cleared", "fawe.worldedit.clipboard.clipboard.invalid.format": "Unknown clipboard format: {0}", From dac7cdbe4b7bc77b9c4c0d9e677cdb83ae17ebb2 Mon Sep 17 00:00:00 2001 From: Jordan Date: Sat, 27 Jul 2024 10:34:10 +0200 Subject: [PATCH 217/220] chore: deprecate FaweApi#load for clipboards as it does not allow closing (#2852) --- .../src/main/java/com/fastasyncworldedit/core/FaweAPI.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweAPI.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweAPI.java index acc0d8bf3..0bf621bc6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweAPI.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweAPI.java @@ -116,7 +116,10 @@ public class FaweAPI { * @param file the file to load * @return a clipboard containing the schematic * @see ClipboardFormat + * @deprecated Opens streams that are not then closed. Use {@link ClipboardFormats#findByFile(File)} and its relevant + * methods to allow closing created streams/closing the reader (which will close the stream(s)) */ + @Deprecated(forRemoval = true, since = "TODO") public static Clipboard load(File file) throws IOException { return ClipboardFormats.findByFile(file).load(file); } From 6fb0102e85621e0ff88fecee7352205c101cacd5 Mon Sep 17 00:00:00 2001 From: Jordan Date: Sat, 27 Jul 2024 10:34:25 +0200 Subject: [PATCH 218/220] feat: add litematica error when failing to load schematic (#2850) * feat: add litematica error when failing to load schematic * Adjust --- .../core/extent/clipboard/io/FastSchematicReaderV2.java | 2 +- .../java/com/sk89q/worldedit/command/SchematicCommands.java | 3 +++ worldedit-core/src/main/resources/lang/strings.json | 4 ++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV2.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV2.java index 97fdd1f27..4c71a9f66 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV2.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV2.java @@ -247,7 +247,7 @@ public class FastSchematicReaderV2 extends NBTSchematicReader { throw new IOException("This schematic version is not supported; Version: " + version + ", DataVersion: " + dataVersion + ". It's very likely your schematic has an invalid file extension," + " if the schematic has been created on a version lower than 1.13.2, the extension MUST be `.schematic`," + - " elsewise the schematic can't be read properly."); + " elsewise the schematic can't be read properly. If you are using a litematica schematic, it is not supported!"); } if (blocks != null) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java index e6a369502..2d75b65b8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SchematicCommands.java @@ -421,6 +421,9 @@ public class SchematicCommands { } catch (URISyntaxException | IOException e) { actor.print(Caption.of("worldedit.schematic.file-not-exist", TextComponent.of(Objects.toString(e.getMessage())))); LOGGER.warn("Failed to load a saved clipboard", e); + } catch (Exception e) { + actor.print(Caption.of("fawe.worldedit.schematic.schematic.load-failure", TextComponent.of(e.getMessage()))); + LOGGER.error("Error loading a schematic", e); } finally { if (in != null) { try { diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index 7d49114b5..a56d98695 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -68,7 +68,7 @@ "fawe.worldedit.schematic.schematic.loaded": "{0} loaded. Paste it with //paste", "fawe.worldedit.schematic.schematic.saved": "{0} saved.", "fawe.worldedit.schematic.schematic.none": "No files found.", - "fawe.worldedit.schematic.schematic.load-failure": "File could not be read or it does not exist: {0}. If you are specifying a format, you may not be specifying the correct one. Sponge schematic v2 and v3 both use the .schem file extension. To allow FAWE to select the format, do not specify one.", + "fawe.worldedit.schematic.schematic.load-failure": "File could not be read or it does not exist: {0}. If you are specifying a format, you may not be specifying the correct one. Sponge schematic v2 and v3 both use the .schem file extension. To allow FAWE to select the format, do not specify one. If you are using a litematica schematic, it is not supported!", "fawe.worldedit.clipboard.clipboard.uri.not.found": "You do not have {0} loaded", "fawe.worldedit.clipboard.clipboard.cleared": "Clipboard cleared", "fawe.worldedit.clipboard.clipboard.invalid.format": "Unknown clipboard format: {0}", @@ -360,7 +360,7 @@ "worldedit.schematic.unknown-format": "Unknown schematic format: {0}.", "worldedit.schematic.load.does-not-exist": "Schematic {0} does not exist!", "worldedit.schematic.load.loading": "(Please wait... loading schematic.)", - "worldedit.schematic.load.unsupported-version": "This schematic is not supported. Version: {0}.", + "worldedit.schematic.load.unsupported-version": "This schematic is not supported. Version: {0}. If you are using a litematica schematic, it is not supported!", "worldedit.schematic.save.already-exists": "That schematic already exists. Use the -f flag to overwrite it.", "worldedit.schematic.save.failed-directory": "Could not create folder for schematics!", "worldedit.schematic.save.saving": "(Please wait... saving schematic.)", From 6052fc3128410ec5dc9c2703b497082b8647d22c Mon Sep 17 00:00:00 2001 From: Jordan Date: Sun, 28 Jul 2024 09:53:20 +0200 Subject: [PATCH 219/220] feat: improve fawe limits (#2773) - add FaweLimit implementations for increasing concurrency levels - allow FaweLimit to perform processing (and forcefully disable as required) to capture [tile] entities - Use `BlockVector3#set(Extent orDefault)` where appropriate to reduce block checks - fixes #2679 - fixes #1874 --- .../fastasyncworldedit/core/FaweCache.java | 11 +- .../platform/binding/EditSessionHolder.java | 7 + .../platform/binding/ProvideBindings.java | 34 ++- .../core/extent/LimitExtent.java | 208 ++++++++++-------- .../extent/filter/block/CharFilterBlock.java | 5 +- .../core/function/mask/ABlockMask.java | 2 +- .../core/function/mask/DataMask.java | 4 +- .../core/function/mask/IdMask.java | 4 +- .../function/mask/SingleBlockStateMask.java | 2 +- .../core/function/mask/SplatterBrushMask.java | 2 +- .../core/limit/ConcurrentFaweLimit.java | 201 +++++++++++++++++ .../core/limit/FaweLimit.java | 65 ++++-- .../core/limit/ProcessorFaweLimit.java | 135 ++++++++++++ .../core/queue/IBatchProcessor.java | 2 +- .../java/com/sk89q/worldedit/EditSession.java | 11 +- .../sk89q/worldedit/EditSessionBuilder.java | 16 +- .../com/sk89q/worldedit/LocalSession.java | 17 +- .../worldedit/command/BiomeCommands.java | 2 + .../worldedit/command/BrushCommands.java | 6 +- .../worldedit/command/ClipboardCommands.java | 3 + .../worldedit/command/GenerationCommands.java | 19 +- .../worldedit/command/HistoryCommands.java | 3 + .../worldedit/command/RegionCommands.java | 18 ++ .../command/SnapshotUtilCommands.java | 2 + .../worldedit/command/UtilityCommands.java | 62 ++---- .../worldedit/command/tool/AreaPickaxe.java | 2 +- .../command/tool/BlockDataCyler.java | 2 +- .../worldedit/command/tool/BlockReplacer.java | 2 +- .../worldedit/command/tool/BrushTool.java | 2 +- .../command/tool/FloatingTreeRemover.java | 2 +- .../worldedit/command/tool/FloodFillTool.java | 2 +- .../command/tool/LongRangeBuildTool.java | 4 +- .../command/tool/RecursivePickaxe.java | 2 +- .../worldedit/command/tool/SinglePickaxe.java | 2 +- .../worldedit/command/tool/StackTool.java | 2 +- .../worldedit/command/tool/TreePlanter.java | 2 +- .../worldedit/command/tool/brush/Brush.java | 11 + .../util/annotation/ConfirmHandler.java | 2 +- .../util/annotation/PreloadHandler.java | 2 +- .../SynchronousSettingExpected.java | 22 ++ .../command/util/annotation/package-info.java | 1 + .../platform/PlatformCommandManager.java | 23 +- .../worldedit/function/mask/BiomeMask.java | 2 +- .../function/mask/BlockCategoryMask.java | 2 +- .../worldedit/function/mask/BlockMask.java | 2 +- .../function/mask/BlockStateMask.java | 2 +- .../function/mask/BlockTypeMask.java | 2 +- .../function/mask/ExistingBlockMask.java | 2 +- .../mask/InverseSingleBlockStateMask.java | 2 +- .../src/main/resources/lang/strings.json | 2 + 50 files changed, 706 insertions(+), 236 deletions(-) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/platform/binding/EditSessionHolder.java create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/ConcurrentFaweLimit.java create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/ProcessorFaweLimit.java create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/SynchronousSettingExpected.java diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java index 526570296..3ed494298 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java @@ -192,17 +192,22 @@ public enum FaweCache implements Trimable { Type.OUTSIDE_REGION ); public static final FaweException MAX_CHECKS = new FaweException( - Caption.of("fawe.cancel.reason.max" + ".checks"), + Caption.of("fawe.cancel.reason.max.checks"), + Type.MAX_CHECKS, + true + ); + public static final FaweException MAX_FAILS = new FaweException( + Caption.of("fawe.cancel.reason.max.fails"), Type.MAX_CHECKS, true ); public static final FaweException MAX_CHANGES = new FaweException( - Caption.of("fawe.cancel.reason.max" + ".changes"), + Caption.of("fawe.cancel.reason.max.changes"), Type.MAX_CHANGES, false ); public static final FaweException LOW_MEMORY = new FaweException( - Caption.of("fawe.cancel.reason.low" + ".memory"), + Caption.of("fawe.cancel.reason.low.memory"), Type.LOW_MEMORY, false ); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/platform/binding/EditSessionHolder.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/platform/binding/EditSessionHolder.java new file mode 100644 index 000000000..1fd588ec4 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/platform/binding/EditSessionHolder.java @@ -0,0 +1,7 @@ +package com.fastasyncworldedit.core.extension.platform.binding; + +import com.sk89q.worldedit.EditSession; + +public record EditSessionHolder(EditSession session) { + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/platform/binding/ProvideBindings.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/platform/binding/ProvideBindings.java index bc1e2bfbf..3e38b1724 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/platform/binding/ProvideBindings.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/platform/binding/ProvideBindings.java @@ -3,7 +3,11 @@ package com.fastasyncworldedit.core.extension.platform.binding; import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.database.DBHandler; import com.fastasyncworldedit.core.database.RollbackDatabase; +import com.fastasyncworldedit.core.extent.LimitExtent; +import com.fastasyncworldedit.core.extent.processor.ExtentBatchProcessorHolder; +import com.fastasyncworldedit.core.internal.exception.FaweException; import com.fastasyncworldedit.core.regions.FaweMaskManager; +import com.fastasyncworldedit.core.util.ExtentTraverser; import com.fastasyncworldedit.core.util.TextureUtil; import com.fastasyncworldedit.core.util.image.ImageUtil; import com.sk89q.worldedit.EditSession; @@ -11,6 +15,7 @@ import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.command.argument.Arguments; import com.sk89q.worldedit.command.util.annotation.AllowedRegion; +import com.sk89q.worldedit.command.util.annotation.SynchronousSettingExpected; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.platform.Actor; @@ -25,6 +30,7 @@ import org.enginehub.piston.inject.Key; import org.enginehub.piston.util.ValueProvider; import java.awt.image.BufferedImage; +import java.lang.reflect.Method; import java.net.URI; import java.util.Optional; @@ -52,11 +58,33 @@ public class ProvideBindings extends Bindings { @Binding public EditSession editSession(LocalSession localSession, Actor actor, InjectedValueAccess context) { + Method commandMethod = + context.injectedValue(Key.of(InjectedValueStore.class)).get().injectedValue(Key.of(Method.class)).get(); + Arguments arguments = context.injectedValue(Key.of(Arguments.class)).orElse(null); String command = arguments == null ? null : arguments.get(); - EditSession editSession = localSession.createEditSession(actor, command); - editSession.enableStandardMode(); - Request.request().setEditSession(editSession); + boolean synchronousSetting = commandMethod.getAnnotation(SynchronousSettingExpected.class) != null; + EditSessionHolder holder = context.injectedValue(Key.of(EditSessionHolder.class)).orElse(null); + EditSession editSession = holder != null ? holder.session() : null; + if (editSession == null) { + editSession = localSession.createEditSession(actor, command, synchronousSetting); + editSession.enableStandardMode(); + } else { + LimitExtent limitExtent = new ExtentTraverser<>(editSession).findAndGet(LimitExtent.class); + if (limitExtent != null) { + limitExtent.setProcessing(!synchronousSetting); + if (!synchronousSetting) { + ExtentBatchProcessorHolder processorHolder = new ExtentTraverser<>(editSession).findAndGet( + ExtentBatchProcessorHolder.class); + if (processorHolder != null) { + processorHolder.addProcessor(limitExtent); + } else { + throw new FaweException(Caption.of("fawe.error.no-process-non-synchronous-edit")); + } + } + } + Request.request().setEditSession(editSession); + } return editSession; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/LimitExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/LimitExtent.java index d02ff9320..33f19bfaa 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/LimitExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/LimitExtent.java @@ -1,11 +1,17 @@ package com.fastasyncworldedit.core.extent; import com.fastasyncworldedit.core.extent.filter.block.ExtentFilterBlock; -import com.fastasyncworldedit.core.function.generator.GenBase; -import com.fastasyncworldedit.core.function.generator.Resource; +import com.fastasyncworldedit.core.extent.processor.ProcessorScope; import com.fastasyncworldedit.core.internal.exception.FaweException; +import com.fastasyncworldedit.core.limit.ConcurrentFaweLimit; import com.fastasyncworldedit.core.limit.FaweLimit; +import com.fastasyncworldedit.core.limit.ProcessorFaweLimit; import com.fastasyncworldedit.core.queue.Filter; +import com.fastasyncworldedit.core.queue.IBatchProcessor; +import com.fastasyncworldedit.core.queue.IChunk; +import com.fastasyncworldedit.core.queue.IChunkGet; +import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.util.ExtentTraverser; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.WorldEditException; @@ -17,7 +23,6 @@ import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.util.Countable; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.formatting.text.Component; @@ -37,18 +42,22 @@ import java.util.Set; import java.util.UUID; import java.util.function.Consumer; -public class LimitExtent extends AbstractDelegateExtent { +public class LimitExtent extends AbstractDelegateExtent implements IBatchProcessor { private final FaweLimit limit; private final boolean[] faweExceptionReasonsUsed = new boolean[FaweException.Type.values().length]; private final Consumer onErrorMessage; + private final int chunk_size; + private boolean processing; /** * Create a new instance. * * @param extent the extent * @param limit the limit + * @deprecated Use {@link LimitExtent#LimitExtent(Extent, FaweLimit, Consumer, boolean, boolean)} */ + @Deprecated(forRemoval = true, since = "TODO") public LimitExtent(Extent extent, FaweLimit limit) { this(extent, limit, c -> { }); @@ -60,11 +69,41 @@ public class LimitExtent extends AbstractDelegateExtent { * @param extent the extent * @param limit the limit * @param onErrorMessage consumer to handle a component generated by exceptions + * @deprecated Use {@link LimitExtent#LimitExtent(Extent, FaweLimit, Consumer, boolean, boolean)} */ + @Deprecated(forRemoval = true, since = "TODO") public LimitExtent(Extent extent, FaweLimit limit, Consumer onErrorMessage) { + this(extent, limit, onErrorMessage, false, false); + } + + /** + * Create a new instance. + * + * @param extent the extent + * @param limit the limit + * @param onErrorMessage consumer to handle a component generated by exceptions + * @param processing if this limit extent is expected to be processing + * @param expectSynchronousSetting if synchronous block setting is expected + * @since TODO + */ + public LimitExtent( + Extent extent, + FaweLimit limit, + Consumer onErrorMessage, + boolean processing, + boolean expectSynchronousSetting + ) { super(extent); - this.limit = limit; + if (!expectSynchronousSetting) { + this.limit = new ConcurrentFaweLimit(limit); + } else if (processing) { + this.limit = new ProcessorFaweLimit(limit); + } else { + this.limit = limit; + } this.onErrorMessage = onErrorMessage; + this.chunk_size = 16 * 16 * (extent.getMaxY() - extent.getMinY()); + this.processing = !expectSynchronousSetting; } private void handleException(FaweException e) { @@ -81,7 +120,7 @@ public class LimitExtent extends AbstractDelegateExtent { public List getEntities(Region region) { limit.THROW_MAX_CHECKS(region.getVolume()); try { - return super.getEntities(region); + return extent.getEntities(region); } catch (FaweException e) { handleException(e); return Collections.emptyList(); @@ -92,7 +131,7 @@ public class LimitExtent extends AbstractDelegateExtent { public List getEntities() { limit.THROW_MAX_CHECKS(); try { - return super.getEntities(); + return extent.getEntities(); } catch (FaweException e) { handleException(e); return Collections.emptyList(); @@ -105,7 +144,7 @@ public class LimitExtent extends AbstractDelegateExtent { limit.THROW_MAX_CHANGES(); limit.THROW_MAX_ENTITIES(); try { - return super.createEntity(location, entity); + return extent.createEntity(location, entity); } catch (FaweException e) { handleException(e); return null; @@ -118,7 +157,7 @@ public class LimitExtent extends AbstractDelegateExtent { limit.THROW_MAX_CHANGES(); limit.THROW_MAX_ENTITIES(); try { - return super.createEntity(location, entity, uuid); + return extent.createEntity(location, entity, uuid); } catch (FaweException e) { handleException(e); return null; @@ -130,7 +169,7 @@ public class LimitExtent extends AbstractDelegateExtent { limit.THROW_MAX_CHANGES(); limit.THROW_MAX_ENTITIES(); try { - super.removeEntity(x, y, z, uuid); + extent.removeEntity(x, y, z, uuid); } catch (FaweException e) { handleException(e); } @@ -138,9 +177,9 @@ public class LimitExtent extends AbstractDelegateExtent { @Override public boolean regenerateChunk(int x, int z, @Nullable BiomeType type, @Nullable Long seed) { - limit.THROW_MAX_CHANGES(Character.MAX_VALUE); + limit.THROW_MAX_CHANGES(chunk_size); try { - return super.regenerateChunk(x, z, type, seed); + return extent.regenerateChunk(x, z, type, seed); } catch (FaweException e) { handleException(e); return false; @@ -151,7 +190,7 @@ public class LimitExtent extends AbstractDelegateExtent { public int getHighestTerrainBlock(int x, int z, int minY, int maxY) { limit.THROW_MAX_CHECKS(maxY - minY + 1); try { - return super.getHighestTerrainBlock(x, z, minY, maxY); + return extent.getHighestTerrainBlock(x, z, minY, maxY); } catch (FaweException e) { handleException(e); return minY; @@ -162,7 +201,7 @@ public class LimitExtent extends AbstractDelegateExtent { public int getHighestTerrainBlock(int x, int z, int minY, int maxY, Mask filter) { limit.THROW_MAX_CHECKS(maxY - minY + 1); try { - return super.getHighestTerrainBlock(x, z, minY, maxY, filter); + return extent.getHighestTerrainBlock(x, z, minY, maxY, filter); } catch (FaweException e) { handleException(e); return minY; @@ -173,7 +212,7 @@ public class LimitExtent extends AbstractDelegateExtent { public int getNearestSurfaceLayer(int x, int z, int y, int minY, int maxY) { limit.THROW_MAX_CHECKS(maxY - minY + 1); try { - return super.getNearestSurfaceLayer(x, z, y, minY, maxY); + return extent.getNearestSurfaceLayer(x, z, y, minY, maxY); } catch (FaweException e) { handleException(e); return minY; @@ -184,7 +223,7 @@ public class LimitExtent extends AbstractDelegateExtent { public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, boolean ignoreAir) { limit.THROW_MAX_CHECKS(maxY - minY + 1); try { - return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, ignoreAir); + return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, ignoreAir); } catch (FaweException e) { handleException(e); return minY; @@ -195,7 +234,7 @@ public class LimitExtent extends AbstractDelegateExtent { public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY) { limit.THROW_MAX_CHECKS(maxY - minY + 1); try { - return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY); + return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY); } catch (FaweException e) { handleException(e); return minY; @@ -206,7 +245,7 @@ public class LimitExtent extends AbstractDelegateExtent { public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax) { limit.THROW_MAX_CHECKS(maxY - minY + 1); try { - return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax); + return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax); } catch (FaweException e) { handleException(e); return minY; @@ -217,7 +256,7 @@ public class LimitExtent extends AbstractDelegateExtent { public int getNearestSurfaceTerrainBlock(int x, int z, int y, int minY, int maxY, int failedMin, int failedMax, Mask mask) { limit.THROW_MAX_CHECKS(maxY - minY + 1); try { - return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, mask); + return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, mask); } catch (FaweException e) { handleException(e); return minY; @@ -237,91 +276,47 @@ public class LimitExtent extends AbstractDelegateExtent { ) { limit.THROW_MAX_CHECKS(maxY - minY + 1); try { - return super.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, ignoreAir); + return extent.getNearestSurfaceTerrainBlock(x, z, y, minY, maxY, failedMin, failedMax, ignoreAir); } catch (FaweException e) { handleException(e); return minY; } } - @Override - public void addCaves(Region region) throws WorldEditException { - limit.THROW_MAX_CHECKS(region.getVolume()); - limit.THROW_MAX_CHANGES(region.getVolume()); - super.addCaves(region); - } - - @Override - public void generate(Region region, GenBase gen) throws WorldEditException { - limit.THROW_MAX_CHECKS(region.getVolume()); - limit.THROW_MAX_CHANGES(region.getVolume()); - super.generate(region, gen); - } - - @Override - public void addSchems(Region region, Mask mask, List clipboards, int rarity, boolean rotate) throws - WorldEditException { - limit.THROW_MAX_CHECKS(region.getVolume()); - limit.THROW_MAX_CHANGES(region.getVolume()); - super.addSchems(region, mask, clipboards, rarity, rotate); - } - - @Override - public void spawnResource(Region region, Resource gen, int rarity, int frequency) throws WorldEditException { - limit.THROW_MAX_CHECKS(region.getVolume()); - limit.THROW_MAX_CHANGES(region.getVolume()); - super.spawnResource(region, gen, rarity, frequency); - } - - @Override - public void addOre(Region region, Mask mask, Pattern material, int size, int frequency, int rarity, int minY, int maxY) throws - WorldEditException { - limit.THROW_MAX_CHECKS(region.getVolume()); - limit.THROW_MAX_CHANGES(region.getVolume()); - super.addOre(region, mask, material, size, frequency, rarity, minY, maxY); - } - - @Override - public void addOres(Region region, Mask mask) throws WorldEditException { - limit.THROW_MAX_CHECKS(region.getVolume()); - limit.THROW_MAX_CHANGES(region.getVolume()); - super.addOres(region, mask); - } - @Override public List> getBlockDistribution(Region region) { limit.THROW_MAX_CHECKS(region.getVolume()); - return super.getBlockDistribution(region); + return extent.getBlockDistribution(region); } @Override public List> getBlockDistributionWithData(Region region) { limit.THROW_MAX_CHECKS(region.getVolume()); - return super.getBlockDistributionWithData(region); + return extent.getBlockDistributionWithData(region); } @Override public int countBlocks(Region region, Set searchBlocks) { limit.THROW_MAX_CHECKS(region.getVolume()); - return super.countBlocks(region, searchBlocks); + return extent.countBlocks(region, searchBlocks); } @Override public int countBlocks(Region region, Mask searchMask) { limit.THROW_MAX_CHECKS(region.getVolume()); - return super.countBlocks(region, searchMask); + return extent.countBlocks(region, searchMask); } @Override public > int setBlocks(Region region, B block) throws MaxChangedBlocksException { limit.THROW_MAX_CHANGES(region.getVolume()); - return super.setBlocks(region, block); + return extent.setBlocks(region, block); } @Override public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException { limit.THROW_MAX_CHANGES(region.getVolume()); - return super.setBlocks(region, pattern); + return extent.setBlocks(region, pattern); } @Override @@ -329,41 +324,34 @@ public class LimitExtent extends AbstractDelegateExtent { MaxChangedBlocksException { limit.THROW_MAX_CHECKS(region.getVolume()); limit.THROW_MAX_CHANGES(region.getVolume()); - return super.replaceBlocks(region, filter, replacement); + return extent.replaceBlocks(region, filter, replacement); } @Override public int replaceBlocks(Region region, Set filter, Pattern pattern) throws MaxChangedBlocksException { limit.THROW_MAX_CHECKS(region.getVolume()); limit.THROW_MAX_CHANGES(region.getVolume()); - return super.replaceBlocks(region, filter, pattern); + return extent.replaceBlocks(region, filter, pattern); } @Override public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException { limit.THROW_MAX_CHECKS(region.getVolume()); limit.THROW_MAX_CHANGES(region.getVolume()); - return super.replaceBlocks(region, mask, pattern); - } - - @Override - public int center(Region region, Pattern pattern) throws MaxChangedBlocksException { - limit.THROW_MAX_CHECKS(region.getVolume()); - limit.THROW_MAX_CHANGES(region.getVolume()); - return super.center(region, pattern); + return extent.replaceBlocks(region, mask, pattern); } @Override public int setBlocks(Set vset, Pattern pattern) { limit.THROW_MAX_CHANGES(vset.size()); - return super.setBlocks(vset, pattern); + return extent.setBlocks(vset, pattern); } @Override public T apply(Region region, T filter, boolean full) { limit.THROW_MAX_CHECKS(region.getVolume()); limit.THROW_MAX_CHANGES(region.getVolume()); - return super.apply(region, filter, full); + return extent.apply(region, filter, full); } @Override @@ -393,14 +381,14 @@ public class LimitExtent extends AbstractDelegateExtent { } limit.THROW_MAX_CHECKS(size); limit.THROW_MAX_CHANGES(size); - return super.apply(positions, filter); + return extent.apply(positions, filter); } @Override public BlockState getBlock(BlockVector3 position) { limit.THROW_MAX_CHECKS(); try { - return super.getBlock(position); + return extent.getBlock(position); } catch (FaweException e) { handleException(e); return BlockTypes.AIR.getDefaultState(); @@ -411,7 +399,7 @@ public class LimitExtent extends AbstractDelegateExtent { public BlockState getBlock(int x, int y, int z) { limit.THROW_MAX_CHECKS(); try { - return super.getBlock(x, y, z); + return extent.getBlock(x, y, z); } catch (FaweException e) { handleException(e); return BlockTypes.AIR.getDefaultState(); @@ -422,7 +410,7 @@ public class LimitExtent extends AbstractDelegateExtent { public BaseBlock getFullBlock(BlockVector3 position) { limit.THROW_MAX_CHECKS(); try { - return super.getFullBlock(position); + return extent.getFullBlock(position); } catch (FaweException e) { handleException(e); return BlockTypes.AIR.getDefaultState().toBaseBlock(); @@ -433,7 +421,7 @@ public class LimitExtent extends AbstractDelegateExtent { public BaseBlock getFullBlock(int x, int y, int z) { limit.THROW_MAX_CHECKS(); try { - return super.getFullBlock(x, y, z); + return extent.getFullBlock(x, y, z); } catch (FaweException e) { handleException(e); return BlockTypes.AIR.getDefaultState().toBaseBlock(); @@ -444,7 +432,7 @@ public class LimitExtent extends AbstractDelegateExtent { public BiomeType getBiome(BlockVector3 position) { limit.THROW_MAX_CHECKS(); try { - return super.getBiome(position); + return extent.getBiome(position); } catch (FaweException e) { handleException(e); return BiomeTypes.FOREST; @@ -455,7 +443,7 @@ public class LimitExtent extends AbstractDelegateExtent { public BiomeType getBiomeType(int x, int y, int z) { limit.THROW_MAX_CHECKS(); try { - return super.getBiomeType(x, y, z); + return extent.getBiomeType(x, y, z); } catch (FaweException e) { handleException(e); return BiomeTypes.FOREST; @@ -470,7 +458,7 @@ public class LimitExtent extends AbstractDelegateExtent { limit.THROW_MAX_BLOCKSTATES(); } try { - return super.setBlock(position, block); + return extent.setBlock(position, block); } catch (FaweException e) { handleException(e); return false; @@ -484,7 +472,7 @@ public class LimitExtent extends AbstractDelegateExtent { limit.THROW_MAX_BLOCKSTATES(); } try { - return super.setBlock(x, y, z, block); + return extent.setBlock(x, y, z, block); } catch (FaweException e) { handleException(e); return false; @@ -494,9 +482,9 @@ public class LimitExtent extends AbstractDelegateExtent { @Override public boolean setTile(int x, int y, int z, CompoundTag tile) throws WorldEditException { limit.THROW_MAX_CHANGES(); - limit.MAX_BLOCKSTATES(); + limit.THROW_MAX_BLOCKSTATES(); try { - return super.setTile(x, y, z, tile); + return extent.setTile(x, y, z, tile); } catch (FaweException e) { handleException(e); return false; @@ -507,7 +495,7 @@ public class LimitExtent extends AbstractDelegateExtent { public boolean setBiome(BlockVector3 position, BiomeType biome) { limit.THROW_MAX_CHANGES(); try { - return super.setBiome(position, biome); + return extent.setBiome(position, biome); } catch (FaweException e) { handleException(e); return false; @@ -518,11 +506,41 @@ public class LimitExtent extends AbstractDelegateExtent { public boolean setBiome(int x, int y, int z, BiomeType biome) { limit.THROW_MAX_CHANGES(); try { - return super.setBiome(x, y, z, biome); + return extent.setBiome(x, y, z, biome); } catch (FaweException e) { handleException(e); return false; } } + public void setProcessing(boolean processing) { + this.processing = processing; + } + + @Override + public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { + if (!processing) { + return set; + } + int tiles = set.getTiles().size(); + int ents = set.getEntities().size() + set.getEntityRemoves().size(); + limit.THROW_MAX_CHANGES(tiles + ents); + limit.THROW_MAX_BLOCKSTATES(tiles); + limit.THROW_MAX_ENTITIES(ents); + return set; + } + + @Override + public Extent construct(final Extent child) { + if (extent != child) { + new ExtentTraverser(this).setNext(child); + } + return this; + } + + @Override + public ProcessorScope getScope() { + return ProcessorScope.READING_SET_BLOCKS; + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/CharFilterBlock.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/CharFilterBlock.java index 579f04a9a..f569ff0bb 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/CharFilterBlock.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/CharFilterBlock.java @@ -170,10 +170,13 @@ public class CharFilterBlock extends ChunkFilterBlock { @Override public synchronized final void filter(Filter filter) { + initSet(); for (y = 0, index = 0; y < 16; y++) { for (z = 0; z < 16; z++) { for (x = 0; x < 16; x++, index++) { - filter.applyBlock(this); + if (setArr[index] != BlockTypesCache.ReservedIDs.__RESERVED__) { + filter.applyBlock(this); + } } } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java index 7fdebdded..ed5b028dd 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java @@ -26,7 +26,7 @@ public abstract class ABlockMask extends AbstractExtentMask { @Override public boolean test(BlockVector3 vector) { - return test(getExtent().getBlock(vector)); + return test(vector.getBlock(getExtent())); } public abstract boolean test(BlockState state); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/DataMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/DataMask.java index 2b3ad7edb..84b8f77ad 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/DataMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/DataMask.java @@ -16,9 +16,9 @@ public class DataMask extends AbstractExtentMask implements ResettableMask { @Override public boolean test(BlockVector3 vector) { if (data != -1) { - return getExtent().getBlock(vector).getInternalPropertiesId() == data; + return vector.getBlock(getExtent()).getInternalPropertiesId() == data; } else { - data = getExtent().getBlock(vector).getInternalPropertiesId(); + data = vector.getBlock(getExtent()).getInternalPropertiesId(); return true; } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/IdMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/IdMask.java index 49c90183a..b0ba4fb59 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/IdMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/IdMask.java @@ -24,7 +24,9 @@ public class IdMask extends AbstractExtentMask implements ResettableMask { @Override public boolean test(BlockVector3 vector) { - return test(getExtent(), vector); + int blockID = vector.getBlock(getExtent()).getInternalBlockTypeId(); + int testId = id.compareAndExchange(-1, blockID); + return blockID == testId || testId == -1; } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SingleBlockStateMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SingleBlockStateMask.java index 32d853bda..400f32163 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SingleBlockStateMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SingleBlockStateMask.java @@ -30,7 +30,7 @@ public class SingleBlockStateMask extends ABlockMask { @Override public boolean test(BlockVector3 vector) { - int test = getExtent().getBlock(vector).getOrdinal(); + int test = vector.getBlock(getExtent()).getOrdinal(); return ordinal == test || isAir && test == 0; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SplatterBrushMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SplatterBrushMask.java index 250969616..d80399be4 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SplatterBrushMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/SplatterBrushMask.java @@ -40,7 +40,7 @@ public class SplatterBrushMask extends AbstractExtentMask { double dist = vector.distanceSq(position); synchronized (placed) { if (dist < size2 && !placed.contains(vector) && ThreadLocalRandom.current().nextInt(5) < 2 && surface.test(vector)) { - placed.add(vector); + placed.add(vector.toImmutable()); return true; } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/ConcurrentFaweLimit.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/ConcurrentFaweLimit.java new file mode 100644 index 000000000..91ec1621d --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/ConcurrentFaweLimit.java @@ -0,0 +1,201 @@ +package com.fastasyncworldedit.core.limit; + +import com.fastasyncworldedit.core.FaweCache; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +/** + * Allows concurrent limit calculations + * + * @since TODO + */ +public class ConcurrentFaweLimit extends FaweLimit { + + public AtomicLong ATOMIC_MAX_CHANGES = new AtomicLong(); + public AtomicInteger ATOMIC_MAX_FAILS = new AtomicInteger(); + public AtomicLong ATOMIC_MAX_CHECKS = new AtomicLong(); + public AtomicInteger ATOMIC_MAX_ITERATIONS = new AtomicInteger(); + public AtomicInteger ATOMIC_MAX_BLOCKSTATES = new AtomicInteger(); + public AtomicInteger ATOMIC_MAX_ENTITIES = new AtomicInteger(); + + public ConcurrentFaweLimit(FaweLimit other) { + set(other); + } + + @Override + public boolean MAX_CHANGES() { + return ATOMIC_MAX_CHANGES.decrementAndGet() < 0; + } + + @Override + public boolean MAX_FAILS() { + return ATOMIC_MAX_FAILS.decrementAndGet() < 0; + } + + @Override + public boolean MAX_CHECKS() { + return ATOMIC_MAX_CHECKS.decrementAndGet() < 0; + } + + @Override + public boolean MAX_ITERATIONS() { + return ATOMIC_MAX_ITERATIONS.decrementAndGet() < 0; + } + + @Override + public boolean MAX_BLOCKSTATES() { + return ATOMIC_MAX_BLOCKSTATES.decrementAndGet() < 0; + } + + @Override + public boolean MAX_ENTITIES() { + return ATOMIC_MAX_ENTITIES.decrementAndGet() < 0; + } + + @Override + public void THROW_MAX_CHANGES() { + if (ATOMIC_MAX_CHANGES.decrementAndGet() < 0) { + throw FaweCache.MAX_CHANGES; + } + } + + @Override + public void THROW_MAX_FAILS() { + if (ATOMIC_MAX_FAILS.decrementAndGet() < 0) { + throw FaweCache.MAX_FAILS; + } + } + + @Override + public void THROW_MAX_CHECKS() { + if (ATOMIC_MAX_CHECKS.decrementAndGet() < 0) { + throw FaweCache.MAX_CHECKS; + } + } + + @Override + public void THROW_MAX_ITERATIONS() { + if (ATOMIC_MAX_ITERATIONS.decrementAndGet() < 0) { + throw FaweCache.MAX_ITERATIONS; + } + } + + @Override + public void THROW_MAX_BLOCKSTATES() { + if (ATOMIC_MAX_BLOCKSTATES.decrementAndGet() < 0) { + throw FaweCache.MAX_TILES; + } + } + + @Override + public void THROW_MAX_ENTITIES() { + if (ATOMIC_MAX_ENTITIES.decrementAndGet() < 0) { + throw FaweCache.MAX_ENTITIES; + } + } + + @Override + public void THROW_MAX_CHANGES(int amt) { + if (amt == 0) { + return; + } + if (ATOMIC_MAX_CHANGES.addAndGet(-amt) < 0) { + throw FaweCache.MAX_CHANGES; + } + } + + @Override + public void THROW_MAX_CHANGES(long amt) { + if (amt == 0) { + return; + } + if (ATOMIC_MAX_CHANGES.addAndGet(-amt) < 0) { + throw FaweCache.MAX_CHANGES; + } + } + + @Override + public void THROW_MAX_FAILS(int amt) { + if (amt == 0) { + return; + } + if (ATOMIC_MAX_FAILS.addAndGet(-amt) < 0) { + throw FaweCache.MAX_FAILS; + } + } + + @Override + public void THROW_MAX_CHECKS(int amt) { + if (amt == 0) { + return; + } + if (ATOMIC_MAX_CHECKS.addAndGet(-amt) < 0) { + throw FaweCache.MAX_CHECKS; + } + } + + @Override + public void THROW_MAX_CHECKS(long amt) { + if (amt == 0) { + return; + } + if (ATOMIC_MAX_CHECKS.addAndGet(-amt) < 0) { + throw FaweCache.MAX_CHECKS; + } + } + + @Override + public void THROW_MAX_ITERATIONS(int amt) { + if (amt == 0) { + return; + } + if (ATOMIC_MAX_ITERATIONS.addAndGet(-amt) < 0) { + throw FaweCache.MAX_ITERATIONS; + } + } + + @Override + public void THROW_MAX_BLOCKSTATES(int amt) { + if (amt == 0) { + return; + } + if (ATOMIC_MAX_BLOCKSTATES.addAndGet(-amt) < 0) { + throw FaweCache.MAX_TILES; + } + } + + @Override + public void THROW_MAX_ENTITIES(int amt) { + if (amt == 0) { + return; + } + if (ATOMIC_MAX_ENTITIES.addAndGet(-amt) < 0) { + throw FaweCache.MAX_ENTITIES; + } + } + + @Override + public void set(FaweLimit other) { + super.set(other); + ATOMIC_MAX_CHANGES.set(other.MAX_CHANGES); + ATOMIC_MAX_FAILS.set(other.MAX_FAILS); + ATOMIC_MAX_CHECKS.set(other.MAX_CHECKS); + ATOMIC_MAX_ITERATIONS.set(other.MAX_ITERATIONS); + ATOMIC_MAX_BLOCKSTATES.set(other.MAX_BLOCKSTATES); + ATOMIC_MAX_ENTITIES.set(other.MAX_ENTITIES); + } + + @Override + public FaweLimit getLimitUsed(FaweLimit originalLimit) { + FaweLimit newLimit = new FaweLimit(); + newLimit.MAX_CHANGES = originalLimit.MAX_CHANGES - this.ATOMIC_MAX_CHANGES.get(); + newLimit.MAX_FAILS = originalLimit.MAX_FAILS - this.ATOMIC_MAX_FAILS.get(); + newLimit.MAX_CHECKS = originalLimit.MAX_CHECKS - this.ATOMIC_MAX_CHECKS.get(); + newLimit.MAX_ITERATIONS = originalLimit.MAX_ITERATIONS - this.ATOMIC_MAX_ITERATIONS.get(); + newLimit.MAX_BLOCKSTATES = originalLimit.MAX_BLOCKSTATES - this.ATOMIC_MAX_BLOCKSTATES.get(); + newLimit.MAX_ENTITIES = originalLimit.MAX_ENTITIES - this.ATOMIC_MAX_ENTITIES.get(); + return newLimit; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java index d17787f03..f7a99dd35 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java @@ -1,6 +1,7 @@ package com.fastasyncworldedit.core.limit; import com.fastasyncworldedit.core.FaweCache; +import com.fastasyncworldedit.core.internal.exception.FaweException; import com.fastasyncworldedit.core.configuration.Settings; import java.util.Collections; @@ -9,12 +10,12 @@ import java.util.Set; public class FaweLimit { public int MAX_ACTIONS = 0; - public long MAX_CHANGES = 0; - public int MAX_FAILS = 0; - public long MAX_CHECKS = 0; - public int MAX_ITERATIONS = 0; - public int MAX_BLOCKSTATES = 0; - public int MAX_ENTITIES = 0; + public volatile long MAX_CHANGES = 0; + public volatile int MAX_FAILS = 0; + public volatile long MAX_CHECKS = 0; + public volatile int MAX_ITERATIONS = 0; + public volatile int MAX_BLOCKSTATES = 0; + public volatile int MAX_ENTITIES = 0; public int MAX_HISTORY = 0; public int SCHEM_FILE_SIZE_LIMIT = 0; public int SCHEM_FILE_NUM_LIMIT = 0; @@ -161,85 +162,85 @@ public class FaweLimit { return MAX_ENTITIES-- > 0; } - public void THROW_MAX_CHANGES() { + public void THROW_MAX_CHANGES() throws FaweException { if (MAX_CHANGES-- <= 0) { throw FaweCache.MAX_CHANGES; } } - public void THROW_MAX_FAILS() { + public void THROW_MAX_FAILS() throws FaweException { if (MAX_FAILS-- <= 0) { - throw FaweCache.MAX_CHECKS; + throw FaweCache.MAX_FAILS; } } - public void THROW_MAX_CHECKS() { + public void THROW_MAX_CHECKS() throws FaweException { if (MAX_CHECKS-- <= 0) { throw FaweCache.MAX_CHECKS; } } - public void THROW_MAX_ITERATIONS() { + public void THROW_MAX_ITERATIONS() throws FaweException { if (MAX_ITERATIONS-- <= 0) { throw FaweCache.MAX_ITERATIONS; } } - public void THROW_MAX_BLOCKSTATES() { + public void THROW_MAX_BLOCKSTATES() throws FaweException { if (MAX_BLOCKSTATES-- <= 0) { throw FaweCache.MAX_TILES; } } - public void THROW_MAX_ENTITIES() { + public void THROW_MAX_ENTITIES() throws FaweException { if (MAX_ENTITIES-- <= 0) { throw FaweCache.MAX_ENTITIES; } } - public void THROW_MAX_CHANGES(int amt) { + public void THROW_MAX_CHANGES(int amt) throws FaweException { if ((MAX_CHANGES -= amt) <= 0) { throw FaweCache.MAX_CHANGES; } } - public void THROW_MAX_CHANGES(long amt) { + public void THROW_MAX_CHANGES(long amt) throws FaweException { if ((MAX_CHANGES -= amt) <= 0) { throw FaweCache.MAX_CHANGES; } } - public void THROW_MAX_FAILS(int amt) { + public void THROW_MAX_FAILS(int amt) throws FaweException { if ((MAX_FAILS -= amt) <= 0) { - throw FaweCache.MAX_CHECKS; + throw FaweCache.MAX_FAILS; } } - public void THROW_MAX_CHECKS(int amt) { + public void THROW_MAX_CHECKS(int amt) throws FaweException { if ((MAX_CHECKS -= amt) <= 0) { throw FaweCache.MAX_CHECKS; } } - public void THROW_MAX_CHECKS(long amt) { + public void THROW_MAX_CHECKS(long amt) throws FaweException { if ((MAX_CHECKS -= amt) <= 0) { throw FaweCache.MAX_CHECKS; } } - public void THROW_MAX_ITERATIONS(int amt) { + public void THROW_MAX_ITERATIONS(int amt) throws FaweException { if ((MAX_ITERATIONS -= amt) <= 0) { throw FaweCache.MAX_ITERATIONS; } } - public void THROW_MAX_BLOCKSTATES(int amt) { + public void THROW_MAX_BLOCKSTATES(int amt) throws FaweException { if ((MAX_BLOCKSTATES -= amt) <= 0) { throw FaweCache.MAX_TILES; } } - public void THROW_MAX_ENTITIES(int amt) { + public void THROW_MAX_ENTITIES(int amt) throws FaweException { if ((MAX_ENTITIES -= amt) <= 0) { throw FaweCache.MAX_ENTITIES; } @@ -270,6 +271,22 @@ public class FaweLimit { && MAX_BUTCHER_RADIUS == Integer.MAX_VALUE; } + /** + * Get an {@link FaweLimit} representing the amount of a limit used from a given "original" limit + * + * @since TODO + */ + public FaweLimit getLimitUsed(FaweLimit originalLimit) { + FaweLimit newLimit = new FaweLimit(); + newLimit.MAX_CHANGES = originalLimit.MAX_CHANGES - this.MAX_CHANGES; + newLimit.MAX_FAILS = originalLimit.MAX_FAILS - this.MAX_FAILS; + newLimit.MAX_CHECKS = originalLimit.MAX_CHECKS - this.MAX_CHECKS; + newLimit.MAX_ITERATIONS = originalLimit.MAX_ITERATIONS - this.MAX_ITERATIONS; + newLimit.MAX_BLOCKSTATES = originalLimit.MAX_BLOCKSTATES - this.MAX_BLOCKSTATES; + newLimit.MAX_ENTITIES = originalLimit.MAX_ENTITIES - this.MAX_ENTITIES; + return newLimit; + } + public void set(FaweLimit limit) { MAX_ACTIONS = limit.MAX_ACTIONS; MAX_CHANGES = limit.MAX_CHANGES; @@ -331,4 +348,8 @@ public class FaweLimit { return MAX_CHANGES + ""; } + public ProcessorFaweLimit toConcurrent() { + return new ProcessorFaweLimit(this); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/ProcessorFaweLimit.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/ProcessorFaweLimit.java new file mode 100644 index 000000000..47c97a78b --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/ProcessorFaweLimit.java @@ -0,0 +1,135 @@ +package com.fastasyncworldedit.core.limit; + +import com.fastasyncworldedit.core.FaweCache; + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +/** + * Allows concurrent limit calculations for THROW_MAX_XXX(amount) methods. Other methods use the default implementations in + * {@link FaweLimit} + * + * @since TODO + */ +public class ProcessorFaweLimit extends FaweLimit { + + public AtomicLong ATOMIC_MAX_CHANGES = new AtomicLong(); + public AtomicInteger ATOMIC_MAX_FAILS = new AtomicInteger(); + public AtomicLong ATOMIC_MAX_CHECKS = new AtomicLong(); + public AtomicInteger ATOMIC_MAX_ITERATIONS = new AtomicInteger(); + public AtomicInteger ATOMIC_MAX_BLOCKSTATES = new AtomicInteger(); + public AtomicInteger ATOMIC_MAX_ENTITIES = new AtomicInteger(); + + public ProcessorFaweLimit(FaweLimit other) { + set(other); + } + + @Override + public void THROW_MAX_CHANGES(int amt) { + if (amt == 0) { + return; + } + final long changes = MAX_CHANGES; + if (ATOMIC_MAX_CHANGES.updateAndGet(i -> (MAX_CHANGES = Math.min(i, changes) - amt)) < 0) { + throw FaweCache.MAX_CHANGES; + } + } + + @Override + public void THROW_MAX_CHANGES(long amt) { + if (amt == 0) { + return; + } + final long changes = MAX_CHANGES; + if (ATOMIC_MAX_CHANGES.updateAndGet(i -> (MAX_CHANGES = Math.min(i, changes) - amt))< 0) { + throw FaweCache.MAX_CHANGES; + } + } + + @Override + public void THROW_MAX_FAILS(int amt) { + if (amt == 0) { + return; + } + final int fails = MAX_FAILS; + if (ATOMIC_MAX_FAILS.updateAndGet(i -> (MAX_FAILS = Math.min(i, fails) - amt)) < 0) { + throw FaweCache.MAX_FAILS; + } + } + + @Override + public void THROW_MAX_CHECKS(int amt) { + final long checks = MAX_CHECKS; + if (ATOMIC_MAX_CHECKS.updateAndGet(i -> (MAX_CHECKS = Math.min(i, checks) - amt)) < 0) { + throw FaweCache.MAX_CHECKS; + } + } + + @Override + public void THROW_MAX_CHECKS(long amt) { + if (amt == 0) { + return; + } + final long checks = MAX_CHECKS; + if (ATOMIC_MAX_CHECKS.updateAndGet(i -> (MAX_CHECKS = Math.min(i, checks) - amt)) < 0) { + throw FaweCache.MAX_CHECKS; + } + } + + @Override + public void THROW_MAX_ITERATIONS(int amt) { + if (amt == 0) { + return; + } + final int iterations = MAX_ITERATIONS; + if (ATOMIC_MAX_ITERATIONS.updateAndGet(i -> (MAX_ITERATIONS = Math.min(i, iterations) - amt)) < 0) { + throw FaweCache.MAX_ITERATIONS; + } + } + + @Override + public void THROW_MAX_BLOCKSTATES(int amt) { + if (amt == 0) { + return; + } + final int states = MAX_BLOCKSTATES; + if (ATOMIC_MAX_BLOCKSTATES.updateAndGet(i -> (MAX_BLOCKSTATES = Math.min(i, states) - amt)) < 0) { + throw FaweCache.MAX_TILES; + } + } + + @Override + public void THROW_MAX_ENTITIES(int amt) { + if (amt == 0) { + return; + } + final int entities = MAX_ENTITIES; + if (ATOMIC_MAX_ENTITIES.updateAndGet(i -> (MAX_ENTITIES = Math.min(i, entities) - amt)) < 0) { + throw FaweCache.MAX_ENTITIES; + } + } + + @Override + public void set(FaweLimit other) { + super.set(other); + ATOMIC_MAX_CHANGES.set(other.MAX_CHANGES); + ATOMIC_MAX_FAILS.set(other.MAX_FAILS); + ATOMIC_MAX_CHECKS.set(other.MAX_CHECKS); + ATOMIC_MAX_ITERATIONS.set(other.MAX_ITERATIONS); + ATOMIC_MAX_BLOCKSTATES.set(other.MAX_BLOCKSTATES); + ATOMIC_MAX_ENTITIES.set(other.MAX_ENTITIES); + } + + @Override + public FaweLimit getLimitUsed(FaweLimit originalLimit) { + FaweLimit newLimit = new FaweLimit(); + newLimit.MAX_CHANGES = originalLimit.MAX_CHANGES - Math.min(this.ATOMIC_MAX_CHANGES.get(), MAX_CHANGES); + newLimit.MAX_FAILS = originalLimit.MAX_FAILS - Math.min(this.ATOMIC_MAX_FAILS.get(), MAX_FAILS); + newLimit.MAX_CHECKS = originalLimit.MAX_CHECKS - Math.min(this.ATOMIC_MAX_CHECKS.get(), MAX_CHECKS); + newLimit.MAX_ITERATIONS = originalLimit.MAX_ITERATIONS - Math.min(this.ATOMIC_MAX_ITERATIONS.get(), MAX_ITERATIONS); + newLimit.MAX_BLOCKSTATES = originalLimit.MAX_BLOCKSTATES - Math.min(this.ATOMIC_MAX_BLOCKSTATES.get(), MAX_BLOCKSTATES); + newLimit.MAX_ENTITIES = originalLimit.MAX_ENTITIES - Math.min(this.ATOMIC_MAX_ENTITIES.get(), MAX_ENTITIES); + return newLimit; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java index 4ba91a4f3..6a5473979 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java @@ -50,7 +50,7 @@ public interface IBatchProcessor { } /** - * Convert this processor into an Extent based processor instead of a queue batch based on. + * Convert this processor into an Extent based processor instead of a queue batch based one. */ @Nullable Extent construct(Extent child); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index 926265bfb..7bc243134 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -308,16 +308,7 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { * @return Limit remaining */ public FaweLimit getLimitUsed() { - FaweLimit newLimit = new FaweLimit(); - newLimit.MAX_ACTIONS = originalLimit.MAX_ACTIONS - limit.MAX_ACTIONS; - newLimit.MAX_CHANGES = originalLimit.MAX_CHANGES - limit.MAX_CHANGES; - newLimit.MAX_FAILS = originalLimit.MAX_FAILS - limit.MAX_FAILS; - newLimit.MAX_CHECKS = originalLimit.MAX_CHECKS - limit.MAX_CHECKS; - newLimit.MAX_ITERATIONS = originalLimit.MAX_ITERATIONS - limit.MAX_ITERATIONS; - newLimit.MAX_BLOCKSTATES = originalLimit.MAX_BLOCKSTATES - limit.MAX_BLOCKSTATES; - newLimit.MAX_ENTITIES = originalLimit.MAX_ENTITIES - limit.MAX_ENTITIES; - newLimit.MAX_HISTORY = limit.MAX_HISTORY; - return newLimit; + return originalLimit.getLimitUsed(limit); } /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSessionBuilder.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSessionBuilder.java index ca6f3b6a5..5cf0cf745 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSessionBuilder.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSessionBuilder.java @@ -104,6 +104,7 @@ public final class EditSessionBuilder { private Extent extent; private boolean compiled; private boolean wrapped; + private boolean expectSynchronousSetting = false; private @Nullable World world; @@ -415,6 +416,15 @@ public final class EditSessionBuilder { return setDirty(); } + public EditSessionBuilder expectSynchronousSetting(boolean expectSynchronousSetting) { + this.expectSynchronousSetting = expectSynchronousSetting; + return setDirty(); + } + + public boolean isExpectingSynchronousSetting() { + return this.expectSynchronousSetting; + } + /** * Compile the builder to the settings given. Prepares history, limits, lighting, etc. */ @@ -635,7 +645,11 @@ public final class EditSessionBuilder { }; } if (limit != null && !limit.isUnlimited()) { - this.extent = new LimitExtent(this.extent, limit, onErrorMessage); + this.extent = new LimitExtent(this.extent, limit, onErrorMessage, placeChunks && combineStages, expectSynchronousSetting); + // Only process if we're not necessarily going to catch tiles via Extent#setBlock, e.g. because using PQE methods + if (placeChunks && combineStages && !expectSynchronousSetting) { + queue.addProcessor((LimitExtent) this.extent); + } } this.extent = wrapExtent(this.extent, eventBus, event, EditSession.Stage.BEFORE_HISTORY); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index 48e2a8078..aa5f51e57 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -1725,10 +1725,25 @@ public class LocalSession implements TextureHolder { * @return an edit session */ public EditSession createEditSession(Actor actor) { + //FAWE start return createEditSession(actor, null); } public EditSession createEditSession(Actor actor, String command) { + return createEditSession(actor, command, false); + } + + /** + * Construct a new edit session. + * + * @param actor the actor + * @param command the command executed resulting in the creation of the edit session + * @param expectSynchronousSetting if it is expected that blocks will only be set synchronously, i.e. from one thread (at a + * time) + * @return an edit session + * @since TODO + */ + public EditSession createEditSession(Actor actor, String command, boolean expectSynchronousSetting) { checkNotNull(actor); World world = null; @@ -1739,7 +1754,6 @@ public class LocalSession implements TextureHolder { } // Create an edit session - //FAWE start - we don't use the edit session builder yet EditSession editSession; EditSessionBuilder builder = WorldEdit.getInstance().newEditSessionBuilder().world(world); if (actor.isPlayer() && actor instanceof Player) { @@ -1749,6 +1763,7 @@ public class LocalSession implements TextureHolder { } builder.command(command); builder.fastMode(!this.sideEffectSet.doesApplyAny()); + builder.expectSynchronousSetting(expectSynchronousSetting); editSession = builder.build(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java index a60968da1..1f551aefa 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java @@ -30,6 +30,7 @@ import com.sk89q.worldedit.command.util.Logging; import com.sk89q.worldedit.command.util.WorldEditAsyncCommandBuilder; import com.sk89q.worldedit.command.util.annotation.Confirm; import com.sk89q.worldedit.command.util.annotation.Preload; +import com.sk89q.worldedit.command.util.annotation.SynchronousSettingExpected; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Capability; @@ -179,6 +180,7 @@ public class BiomeCommands { ) @Logging(REGION) @Preload(Preload.PreloadCheck.PRELOAD) + @SynchronousSettingExpected // TODO improve using filter/chunk-based-placement @Confirm(Confirm.Processor.REGION) @CommandPermissions("worldedit.biome.set") public void setBiome( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index 664e656c4..8f1733fbb 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -992,15 +992,15 @@ public class BrushCommands { Expression radius, @Arg(desc = "Command to run") List input, - @Switch(name = 'p', desc = "Show any printed output") - boolean print + @Switch(name = 'h', desc = "Hide any printed output") + boolean hide ) throws WorldEditException { worldEdit.checkMaxBrushRadius( radius, context.injectedValue(Key.of(Player.class)).orElseThrow(() -> new IllegalStateException("No player")) ); String cmd = StringMan.join(input, " "); - set(context, new CommandBrush(cmd, print), "worldedit.brush.command").setSize(radius); + set(context, new CommandBrush(cmd, !hide), "worldedit.brush.command").setSize(radius); } @Command( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java index 378449755..a8fa5076e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/ClipboardCommands.java @@ -47,6 +47,7 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator; import com.sk89q.worldedit.command.util.Logging; import com.sk89q.worldedit.command.util.annotation.Confirm; import com.sk89q.worldedit.command.util.annotation.Preload; +import com.sk89q.worldedit.command.util.annotation.SynchronousSettingExpected; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; @@ -438,6 +439,7 @@ public class ClipboardCommands { desc = "Place the clipboard's contents without applying transformations (e.g. rotate)" ) @CommandPermissions("worldedit.clipboard.place") + @SynchronousSettingExpected @Logging(PLACEMENT) public void place( Actor actor, World world, LocalSession session, final EditSession editSession, @@ -502,6 +504,7 @@ public class ClipboardCommands { desc = "Paste the clipboard's contents" ) @CommandPermissions("worldedit.clipboard.paste") + @SynchronousSettingExpected @Logging(PLACEMENT) public void paste( Actor actor, World world, LocalSession session, EditSession editSession, diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java index 4b2f98e0c..f2a3c80ed 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GenerationCommands.java @@ -38,6 +38,7 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator; import com.sk89q.worldedit.command.util.Logging; import com.sk89q.worldedit.command.util.annotation.Confirm; import com.sk89q.worldedit.command.util.annotation.Preload; +import com.sk89q.worldedit.command.util.annotation.SynchronousSettingExpected; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.function.mask.Mask; @@ -104,6 +105,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.cylinder") @Logging(PLACEMENT) + @SynchronousSettingExpected public int hcyl( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The pattern of blocks to generate") @@ -152,6 +154,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.cylinder") @Logging(PLACEMENT) + @SynchronousSettingExpected public int cyl( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The pattern of blocks to generate") @@ -197,6 +200,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.cone") @Logging(PLACEMENT) + @SynchronousSettingExpected public int cone(Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The pattern of blocks to generate") Pattern pattern, @@ -243,6 +247,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.sphere") @Logging(PLACEMENT) + @SynchronousSettingExpected public int hsphere( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The pattern of blocks to generate") @@ -262,6 +267,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.sphere") @Logging(PLACEMENT) + @SynchronousSettingExpected public int sphere( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The pattern of blocks to generate") @@ -313,6 +319,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.forest") @Logging(POSITION) + @SynchronousSettingExpected public int forestGen( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The size of the forest, in blocks", def = "10") @@ -337,6 +344,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.pumpkins") @Logging(POSITION) + @SynchronousSettingExpected public int pumpkins( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The size of the patch", def = "10") @@ -357,6 +365,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.pyramid") @Logging(PLACEMENT) + @SynchronousSettingExpected public int hollowPyramid( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The pattern of blocks to set") @@ -373,6 +382,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.pyramid") @Logging(PLACEMENT) + @SynchronousSettingExpected public int pyramid( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The pattern of blocks to set") @@ -400,6 +410,7 @@ public class GenerationCommands { ) @CommandPermissions("worldedit.generation.shape") @Logging(ALL) + @SynchronousSettingExpected @Confirm(Confirm.Processor.REGION) public int generate( Actor actor, LocalSession session, EditSession editSession, @@ -486,6 +497,7 @@ public class GenerationCommands { @CommandPermissions("worldedit.generation.shape.biome") @Logging(ALL) @Preload(Preload.PreloadCheck.PRELOAD) + @SynchronousSettingExpected @Confirm(Confirm.Processor.REGION) public int generateBiome( Actor actor, LocalSession session, EditSession editSession, @@ -564,6 +576,7 @@ public class GenerationCommands { @CommandPermissions("worldedit.generation.caves") @Logging(PLACEMENT) @Preload(Preload.PreloadCheck.PRELOAD) + @SynchronousSettingExpected @Confirm(Confirm.Processor.REGION) public void caves( Actor actor, LocalSession session, EditSession editSession, @Selection Region region, @@ -602,6 +615,7 @@ public class GenerationCommands { @CommandPermissions("worldedit.generation.ore") @Logging(PLACEMENT) @Preload(Preload.PreloadCheck.PRELOAD) + @SynchronousSettingExpected @Confirm(Confirm.Processor.REGION) public void ores( Actor actor, @@ -621,6 +635,7 @@ public class GenerationCommands { desc = "Generate an image" ) @CommandPermissions("worldedit.generation.image") + @SynchronousSettingExpected @Logging(PLACEMENT) public void image( Actor actor, @@ -685,6 +700,7 @@ public class GenerationCommands { @CommandPermissions("worldedit.generation.ore") @Logging(PLACEMENT) @Preload(Preload.PreloadCheck.PRELOAD) + @SynchronousSettingExpected @Confirm(Confirm.Processor.REGION) public void ore( Actor actor, @@ -719,8 +735,9 @@ public class GenerationCommands { desc = "Creates a distorted sphere" ) @Logging(PLACEMENT) + @SynchronousSettingExpected @CommandPermissions("worldedit.generation.blob") - public int blobBrush( + public int blob( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "Pattern") Pattern pattern, diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java index d1a647587..ba736e45e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistoryCommands.java @@ -27,6 +27,7 @@ import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.command.util.CommandPermissions; import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator; import com.sk89q.worldedit.command.util.annotation.Confirm; +import com.sk89q.worldedit.command.util.annotation.SynchronousSettingExpected; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extent.inventory.BlockBag; @@ -61,6 +62,7 @@ public class HistoryCommands { desc = "Undoes the last action (from history)" ) @CommandPermissions({"worldedit.history.undo", "worldedit.history.undo.self"}) + @SynchronousSettingExpected public void undo( Actor actor, LocalSession session, @Confirm(Confirm.Processor.LIMIT) @Arg(desc = "Number of undoes to perform", def = "1") @@ -108,6 +110,7 @@ public class HistoryCommands { desc = "Redoes the last action (from history)" ) @CommandPermissions({"worldedit.history.redo", "worldedit.history.redo.self"}) + @SynchronousSettingExpected public void redo( Actor actor, LocalSession session, @Confirm(Confirm.Processor.LIMIT) @Arg(desc = "Number of redoes to perform", def = "1") diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java index 6a121aa02..ac3490cca 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/RegionCommands.java @@ -35,6 +35,7 @@ import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator; import com.sk89q.worldedit.command.util.Logging; import com.sk89q.worldedit.command.util.annotation.Confirm; import com.sk89q.worldedit.command.util.annotation.Preload; +import com.sk89q.worldedit.command.util.annotation.SynchronousSettingExpected; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.function.GroundFunction; @@ -225,6 +226,7 @@ public class RegionCommands { ) @CommandPermissions("worldedit.region.line") @Logging(REGION) + @SynchronousSettingExpected public int line( Actor actor, EditSession editSession, @Selection Region region, @@ -257,6 +259,7 @@ public class RegionCommands { @CommandPermissions("worldedit.region.curve") @Logging(REGION) @Confirm(Confirm.Processor.REGION) + @SynchronousSettingExpected public int curve( Actor actor, EditSession editSession, @Selection Region region, @@ -315,6 +318,7 @@ public class RegionCommands { @CommandPermissions("worldedit.region.overlay") @Logging(REGION) @Confirm(Confirm.Processor.REGION) + @SynchronousSettingExpected // TODO improve using filter/chunk-based-placement public int overlay( Actor actor, EditSession editSession, @Selection Region region, @Arg(desc = "The pattern of blocks to overlay") @@ -333,6 +337,7 @@ public class RegionCommands { @Logging(REGION) @Preload(Preload.PreloadCheck.PRELOAD) @Confirm(Confirm.Processor.REGION) + @SynchronousSettingExpected // TODO improve using filter/chunk-based-placement public void lay( Actor actor, EditSession editSession, @@ -369,6 +374,7 @@ public class RegionCommands { ) @Logging(REGION) @CommandPermissions("worldedit.region.center") + @SynchronousSettingExpected public int center( Actor actor, EditSession editSession, @Selection Region region, @Arg(desc = "The pattern of blocks to set") @@ -386,6 +392,8 @@ public class RegionCommands { @CommandPermissions("worldedit.region.naturalize") @Logging(REGION) @Confirm(Confirm.Processor.REGION) + @SynchronousSettingExpected // TODO improve using filter/chunk-based-placement + @Preload(Preload.PreloadCheck.PRELOAD) public int naturalize(Actor actor, EditSession editSession, @Selection Region region) throws WorldEditException { int affected = editSession.naturalizeCuboidBlocks(region); actor.print(Caption.of("worldedit.naturalize.naturalized", TextComponent.of(affected))); @@ -437,6 +445,7 @@ public class RegionCommands { @Logging(REGION) @Preload(Preload.PreloadCheck.PRELOAD) @Confirm(Confirm.Processor.REGION) + @SynchronousSettingExpected public int smooth( Actor actor, EditSession editSession, @Selection Region region, @Arg(desc = "# of iterations to perform", def = "1") @@ -510,6 +519,7 @@ public class RegionCommands { @CommandPermissions("worldedit.region.snowsmooth") @Logging(REGION) @Preload(Preload.PreloadCheck.PRELOAD) + @SynchronousSettingExpected @Confirm(Confirm.Processor.REGION) public int snowSmooth( Actor actor, EditSession editSession, @Selection Region region, @@ -536,6 +546,7 @@ public class RegionCommands { @CommandPermissions("worldedit.region.move") @Logging(ORIENTATION_REGION) @Preload(Preload.PreloadCheck.PRELOAD) + @SynchronousSettingExpected @Confirm(Confirm.Processor.REGION) public int move( Actor actor, World world, EditSession editSession, LocalSession session, @@ -599,6 +610,7 @@ public class RegionCommands { @CommandPermissions("worldedit.region.fall") @Logging(ORIENTATION_REGION) @Preload(Preload.PreloadCheck.PRELOAD) + @SynchronousSettingExpected @Confirm(Confirm.Processor.REGION) public void fall( Actor actor, EditSession editSession, @@ -618,6 +630,7 @@ public class RegionCommands { ) @CommandPermissions("worldedit.region.stack") @Preload(Preload.PreloadCheck.PRELOAD) + @SynchronousSettingExpected @Logging(ORIENTATION_REGION) public int stack( Actor actor, World world, EditSession editSession, LocalSession session, @@ -683,6 +696,7 @@ public class RegionCommands { ) @CommandPermissions("worldedit.regen") @Logging(REGION) + @SynchronousSettingExpected @Confirm(Confirm.Processor.REGION) void regenerate( Actor actor, World world, LocalSession session, EditSession editSession, @@ -737,6 +751,7 @@ public class RegionCommands { @CommandPermissions("worldedit.region.deform") @Logging(ALL) @Preload(Preload.PreloadCheck.PRELOAD) + @SynchronousSettingExpected @Confirm(Confirm.Processor.REGION) public int deform( Actor actor, LocalSession session, EditSession editSession, @@ -814,6 +829,7 @@ public class RegionCommands { @CommandPermissions("worldedit.region.hollow") @Logging(REGION) @Preload(Preload.PreloadCheck.PRELOAD) + @SynchronousSettingExpected @Confirm(Confirm.Processor.REGION) public int hollow( Actor actor, EditSession editSession, @@ -848,6 +864,7 @@ public class RegionCommands { @CommandPermissions("worldedit.region.forest") @Logging(REGION) @Preload(Preload.PreloadCheck.PRELOAD) + @SynchronousSettingExpected @Confirm(Confirm.Processor.REGION) public int forest( Actor actor, EditSession editSession, @Selection Region region, @@ -869,6 +886,7 @@ public class RegionCommands { @CommandPermissions("worldedit.region.flora") @Logging(REGION) @Preload(Preload.PreloadCheck.PRELOAD) + @SynchronousSettingExpected @Confirm(Confirm.Processor.REGION) public int flora( Actor actor, EditSession editSession, @Selection Region region, diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java index b98785631..074711521 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SnapshotUtilCommands.java @@ -28,6 +28,7 @@ import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.command.util.CommandPermissions; import com.sk89q.worldedit.command.util.CommandPermissionsConditionGenerator; import com.sk89q.worldedit.command.util.Logging; +import com.sk89q.worldedit.command.util.annotation.SynchronousSettingExpected; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.formatting.text.TextComponent; @@ -66,6 +67,7 @@ public class SnapshotUtilCommands { ) @Logging(REGION) @CommandPermissions("worldedit.snapshots.restore") + @SynchronousSettingExpected public void restore( Actor actor, World world, LocalSession session, EditSession editSession, @Arg(name = "snapshot", desc = "The snapshot to restore", def = "") diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index c81db21d8..c7c6ab9a1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -44,6 +44,7 @@ import com.sk89q.worldedit.command.util.EntityRemover; import com.sk89q.worldedit.command.util.Logging; import com.sk89q.worldedit.command.util.PrintCommandHelp; import com.sk89q.worldedit.command.util.WorldEditAsyncCommandBuilder; +import com.sk89q.worldedit.command.util.annotation.SynchronousSettingExpected; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; @@ -220,6 +221,7 @@ public class UtilityCommands { ) @CommandPermissions("worldedit.fill") @Logging(PLACEMENT) + @SynchronousSettingExpected public int fill( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The blocks to fill with") @@ -311,6 +313,7 @@ public class UtilityCommands { ) @CommandPermissions("worldedit.fill.recursive") @Logging(PLACEMENT) + @SynchronousSettingExpected public int fillr( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The blocks to fill with") @@ -343,6 +346,7 @@ public class UtilityCommands { ) @CommandPermissions("worldedit.drain") @Logging(PLACEMENT) + @SynchronousSettingExpected public int drain( Actor actor, LocalSession session, EditSession editSession, //FAWE start - we take an expression over a double @@ -373,6 +377,7 @@ public class UtilityCommands { ) @CommandPermissions("worldedit.fixlava") @Logging(PLACEMENT) + @SynchronousSettingExpected public int fixLava( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The radius to fix in") @@ -394,6 +399,7 @@ public class UtilityCommands { ) @CommandPermissions("worldedit.fixwater") @Logging(PLACEMENT) + @SynchronousSettingExpected public int fixWater( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The radius to fix in") @@ -415,6 +421,7 @@ public class UtilityCommands { ) @CommandPermissions("worldedit.removeabove") @Logging(PLACEMENT) + @SynchronousSettingExpected public int removeAbove( Actor actor, World world, LocalSession session, EditSession editSession, @Arg(desc = "The apothem of the square to remove from", def = "1") @@ -440,6 +447,7 @@ public class UtilityCommands { ) @CommandPermissions("worldedit.removebelow") @Logging(PLACEMENT) + @SynchronousSettingExpected public int removeBelow( Actor actor, World world, LocalSession session, EditSession editSession, @Arg(desc = "The apothem of the square to remove from", def = "1") @@ -465,6 +473,7 @@ public class UtilityCommands { ) @CommandPermissions("worldedit.removenear") @Logging(PLACEMENT) + @SynchronousSettingExpected public int removeNear( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The mask of blocks to remove") @@ -527,6 +536,7 @@ public class UtilityCommands { ) @CommandPermissions("worldedit.snow") @Logging(PLACEMENT) + @SynchronousSettingExpected public int snow( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The radius of the cylinder to snow in", def = "10") @@ -566,6 +576,7 @@ public class UtilityCommands { ) @CommandPermissions("worldedit.thaw") @Logging(PLACEMENT) + @SynchronousSettingExpected public int thaw( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The radius of the cylinder to thaw in", def = "10") @@ -595,6 +606,7 @@ public class UtilityCommands { ) @CommandPermissions("worldedit.green") @Logging(PLACEMENT) + @SynchronousSettingExpected public int green( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The radius of the cylinder to convert in", def = "10") @@ -629,6 +641,7 @@ public class UtilityCommands { ) @CommandPermissions("worldedit.extinguish") @Logging(PLACEMENT) + @SynchronousSettingExpected public int extinguish( Actor actor, LocalSession session, EditSession editSession, @Arg(desc = "The radius of the square to remove in", def = "") @@ -843,55 +856,6 @@ public class UtilityCommands { } } -// @Command( -// name = "/hollowr", -// desc = "Hollow out a space recursively with a pattern" -// ) -// @CommandPermissions("worldedit.hollowr") -// @Logging(PLACEMENT) -// public int hollowr( -// Actor actor, -// LocalSession session, -// EditSession editSession, -// @Arg(desc = "The radius to hollow out") Expression radiusExp, -// @ArgFlag(name = 'p', desc = "The blocks to fill with") Pattern pattern, -// @ArgFlag(name = 'm', desc = "The blocks remove", def = "") Mask mask -// ) throws WorldEditException { -// //FAWE start -// double radius = radiusExp.evaluate(); -// //FAWE end -// radius = Math.max(1, radius); -// we.checkMaxRadius(radius); -// if (mask == null) { -// Mask mask = new MaskIntersection( -// new RegionMask(new EllipsoidRegion(null, origin, Vector3.at(radius, radius, radius))), -// new BoundedHeightMask( -// Math.max(lowerBound, minY), -// Math.min(maxY, origin.getBlockY()) -// ), -// Masks.negate(new ExistingBlockMask(this)) -// ); -// } -// -// // Want to replace blocks -// BlockReplace replace = new BlockReplace(this, pattern); -// -// // Pick how we're going to visit blocks -// RecursiveVisitor visitor; -// //FAWE start - provide extent for preloading, min/max y -// if (recursive) { -// visitor = new RecursiveVisitor(mask, replace, (int) (radius * 2 + 1), minY, maxY, this); -// } else { -// visitor = new DownwardVisitor(mask, replace, origin.getBlockY(), (int) (radius * 2 + 1), minY, maxY, this); -// } -// //FAWE end -// -// BlockVector3 pos = session.getPlacementPosition(actor); -// int affected = editSession.res(pos, pattern, radius, depth, true); -// actor.print(Caption.of("worldedit.fillr.created", TextComponent.of(affected))); -// return affected; -// } - public static List> filesToEntry(final File root, final List files, final UUID uuid) { return files.stream() .map(input -> { // Keep this functional, as transform is evaluated lazily diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java index 299908d99..e1996520a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/AreaPickaxe.java @@ -64,7 +64,7 @@ public class AreaPickaxe implements BlockTool { return false; } - try (EditSession editSession = session.createEditSession(player, "AreaPickaxe")) { + try (EditSession editSession = session.createEditSession(player, "AreaPickaxe", true)) { editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop); int maxY = editSession.getMaxY(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java index 2d35b2226..304fb9e77 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java @@ -89,7 +89,7 @@ public class BlockDataCyler implements DoubleActionBlockTool { Property objProp = (Property) currentProperty; BaseBlock newBlock = block.with(objProp, currentProperty.getValues().get(index)); - try (EditSession editSession = session.createEditSession(player)) { + try (EditSession editSession = session.createEditSession(player, null, true)) { try { editSession.setBlock(blockPoint, newBlock); player.print(Caption.of( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java index 75ef200c6..957ed3d83 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockReplacer.java @@ -63,7 +63,7 @@ public class BlockReplacer implements DoubleActionBlockTool { ) { BlockBag bag = session.getBlockBag(player); - try (EditSession editSession = session.createEditSession(player)) { + try (EditSession editSession = session.createEditSession(player, null, true)) { try { BlockVector3 position = clicked.toVector().toBlockPoint(); editSession.setBlock(position, pattern); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java index 6021102a2..74b06b1f5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BrushTool.java @@ -440,7 +440,7 @@ public class BrushTool Caption.of("fawe.error.no-perm", StringMan.join(current.getPermissions(), ","))); return false; } - try (EditSession editSession = session.createEditSession(player, current.toString())) { + try (EditSession editSession = session.createEditSession(player, current.toString(), brush.setsSynchronously())) { Location target = player.getBlockTrace(getRange(), true, traceMask); if (target == null) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java index 385fcd2f3..81d755b8c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloatingTreeRemover.java @@ -86,7 +86,7 @@ public class FloatingTreeRemover implements BlockTool { return true; } - try (EditSession editSession = session.createEditSession(player, "FloatingTreeRemover")) { + try (EditSession editSession = session.createEditSession(player, "FloatingTreeRemover", true)) { try { final Set blockSet = bfs(world, clicked.toVector().toBlockPoint()); if (blockSet == null) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java index 3d8d63f7d..6381e9356 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/FloodFillTool.java @@ -82,7 +82,7 @@ public class FloodFillTool implements BlockTool { return true; } - try (EditSession editSession = session.createEditSession(player, "FloodFillTool")) { + try (EditSession editSession = session.createEditSession(player, "FloodFillTool", true)) { try { //FAWE start - Respect masks Mask mask = initialType.toMask(editSession); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java index 9e60fdcf3..b1686ccd5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/LongRangeBuildTool.java @@ -61,7 +61,7 @@ public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTo } BlockBag bag = session.getBlockBag(player); - try (EditSession editSession = session.createEditSession(player, "LongRangeBuildTool")) { + try (EditSession editSession = session.createEditSession(player, "LongRangeBuildTool", true)) { try { BlockVector3 blockPoint = pos.toVector().toBlockPoint(); BaseBlock applied = secondary.applyBlock(blockPoint); @@ -90,7 +90,7 @@ public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTo } BlockBag bag = session.getBlockBag(player); - try (EditSession editSession = session.createEditSession(player, "LongRangeBuildTool")) { + try (EditSession editSession = session.createEditSession(player, "LongRangeBuildTool", true)) { try { BlockVector3 blockPoint = pos.toVector().toBlockPoint(); BaseBlock applied = primary.applyBlock(blockPoint); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java index 9fad39f9d..a8b666ff6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/RecursivePickaxe.java @@ -79,7 +79,7 @@ public class RecursivePickaxe implements BlockTool { return false; } - try (EditSession editSession = session.createEditSession(player, "RecursivePickaxe")) { + try (EditSession editSession = session.createEditSession(player, "RecursivePickaxe", true)) { editSession.getSurvivalExtent().setToolUse(config.superPickaxeManyDrop); //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java index b35865fb3..152f7016a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/SinglePickaxe.java @@ -62,7 +62,7 @@ public class SinglePickaxe implements BlockTool { return false; } - try (EditSession editSession = session.createEditSession(player)) { + try (EditSession editSession = session.createEditSession(player, null, true)) { try { editSession.getSurvivalExtent().setToolUse(config.superPickaxeDrop); editSession.setBlock(blockPoint, BlockTypes.AIR.getDefaultState()); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/StackTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/StackTool.java index 614bbcf32..8aa5761f5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/StackTool.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/StackTool.java @@ -59,7 +59,7 @@ public class StackTool implements BlockTool { } BlockBag bag = session.getBlockBag(player); - try (EditSession editSession = session.createEditSession(player)) { + try (EditSession editSession = session.createEditSession(player, null, true)) { BlockStateHolder block = editSession.getFullBlock(clicked.toVector().toBlockPoint()); try { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/TreePlanter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/TreePlanter.java index 1f52ff103..b2f6ae7cf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/TreePlanter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/TreePlanter.java @@ -60,7 +60,7 @@ public class TreePlanter implements BlockTool { @Nullable Direction face ) { - try (EditSession editSession = session.createEditSession(player)) { + try (EditSession editSession = session.createEditSession(player, null, true)) { try { boolean successful = false; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/Brush.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/Brush.java index 8efe2ab77..e38ae0d99 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/Brush.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/brush/Brush.java @@ -40,4 +40,15 @@ public interface Brush { */ void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws MaxChangedBlocksException; + //FAWE start + /** + * If this brush is expected to set blocks synchronously, i.e. from one thread (at a time) + * + * @since TODO + */ + default boolean setsSynchronously() { + return true; + } + //FAWE end + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/ConfirmHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/ConfirmHandler.java index 067f9cfeb..5d6b66483 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/ConfirmHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/ConfirmHandler.java @@ -12,7 +12,7 @@ import java.lang.reflect.Method; import java.util.Optional; /** - * Logs called commands to a logger. + * Handles commands indicated as requiring confirmation. */ public class ConfirmHandler implements CommandCallListener { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/PreloadHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/PreloadHandler.java index 9e1dc106f..037c94e5b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/PreloadHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/PreloadHandler.java @@ -11,7 +11,7 @@ import java.lang.reflect.Method; import java.util.Optional; /** - * Logs called commands to a logger. + * Initialises preloading of chunks. */ public class PreloadHandler implements CommandCallListener { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/SynchronousSettingExpected.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/SynchronousSettingExpected.java new file mode 100644 index 000000000..3cc936fda --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/SynchronousSettingExpected.java @@ -0,0 +1,22 @@ +package com.sk89q.worldedit.command.util.annotation; + +import org.enginehub.piston.inject.InjectAnnotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Indicates it is expected that blocks will only be set synchronously, i.e. from one thread (at a time) + * + * @since TODO + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ + ElementType.METHOD +}) +@InjectAnnotation +public @interface SynchronousSettingExpected { + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/package-info.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/package-info.java index 006432a73..f7f293277 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/package-info.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/util/annotation/package-info.java @@ -8,6 +8,7 @@ * {@link com.sk89q.worldedit.command.util.annotation.PatternList}, * {@link com.sk89q.worldedit.command.util.annotation.Preload}, * {@link com.sk89q.worldedit.command.util.annotation.PreloadHandler}, + * {@link com.sk89q.worldedit.command.util.annotation.SynchronousSettingExpected}, * {@link com.sk89q.worldedit.command.util.annotation.Step}, * {@link com.sk89q.worldedit.command.util.annotation.Time} */ diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java index b03e4ce54..65fc7c196 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java @@ -24,6 +24,7 @@ import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.extension.platform.binding.Bindings; import com.fastasyncworldedit.core.extension.platform.binding.ConsumeBindings; +import com.fastasyncworldedit.core.extension.platform.binding.EditSessionHolder; import com.fastasyncworldedit.core.extension.platform.binding.PrimitiveBindings; import com.fastasyncworldedit.core.extension.platform.binding.ProvideBindings; import com.fastasyncworldedit.core.internal.command.MethodInjector; @@ -154,7 +155,6 @@ import org.enginehub.piston.inject.MemoizingValueAccess; import org.enginehub.piston.inject.MergedValueAccess; import org.enginehub.piston.part.SubCommandPart; import org.enginehub.piston.suggestion.Suggestion; -import org.enginehub.piston.util.HelpGenerator; import org.enginehub.piston.util.ValueProvider; import javax.annotation.Nonnull; @@ -227,7 +227,6 @@ public final class PlatformCommandManager { new ConfirmHandler(), new PreloadHandler() //FAWE end - )); // setup separate from main constructor // ensures that everything is definitely assigned @@ -312,20 +311,6 @@ public final class PlatformCommandManager { } ); //FAWE start - /* - globalInjectedValues.injectValue(Key.of(EditSession.class), - context -> { - LocalSession localSession = context.injectedValue(Key.of(LocalSession.class)) - .orElseThrow(() -> new IllegalStateException("No LocalSession")); - return context.injectedValue(Key.of(Actor.class)) - .map(actor -> { - EditSession editSession = localSession.createEditSession(actor); - editSession.enableStandardMode(); - Request.request().setEditSession(editSession); - return editSession; - }); - }); - */ // TODO: Ping @MattBDev to reimplement 2020-02-04 // globalInjectedValues.injectValue(Key.of(CFICommands.CFISettings.class), // context -> context.injectedValue(Key.of(Actor.class)) @@ -866,10 +851,10 @@ public final class PlatformCommandManager { store.injectValue(Key.of(InjectedValueStore.class), ValueProvider.constant(store)); store.injectValue(Key.of(Event.class), ValueProvider.constant(event)); //FAWE start - allow giving editsessions - if (event instanceof CommandEvent) { - EditSession session = ((CommandEvent) event).getSession(); + if (event instanceof CommandEvent commandEvent) { + EditSession session = commandEvent.getSession(); if (session != null) { - store.injectValue(Key.of(EditSession.class), context -> Optional.of(session)); + store.injectValue(Key.of(EditSessionHolder.class), context -> Optional.of(new EditSessionHolder(session))); } } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java index cd3ef56d5..ab919b35f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BiomeMask.java @@ -94,7 +94,7 @@ public class BiomeMask extends AbstractExtentMask { @Override public boolean test(BlockVector3 vector) { - BiomeType biome = getExtent().getBiome(vector); + BiomeType biome = vector.getBiome(getExtent()); return biomes.contains(biome); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockCategoryMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockCategoryMask.java index bad9781ea..a1b869efb 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockCategoryMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockCategoryMask.java @@ -46,7 +46,7 @@ public class BlockCategoryMask extends AbstractExtentMask { @Override public boolean test(BlockVector3 vector) { - return category.contains(getExtent().getBlock(vector)); + return category.contains(vector.getBlock(getExtent())); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java index 9f191a4cc..c7d3473f3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java @@ -204,7 +204,7 @@ public class BlockMask extends ABlockMask { @Override public boolean test(BlockVector3 vector) { - int test = getExtent().getBlock(vector).getOrdinal(); + int test = vector.getBlock(getExtent()).getOrdinal(); return ordinals[test] || replacesAir() && test == 0; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockStateMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockStateMask.java index ac558520c..0c563cdf7 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockStateMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockStateMask.java @@ -56,7 +56,7 @@ public class BlockStateMask extends AbstractExtentMask { //FAWE start @Override public boolean test(BlockVector3 vector) { - return test(getExtent().getBlock(vector)); + return test(vector.getBlock(getExtent())); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockTypeMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockTypeMask.java index 17f1419e5..c3567b6d5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockTypeMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockTypeMask.java @@ -124,7 +124,7 @@ public class BlockTypeMask extends AbstractExtentMask { //FAWE start @Override public boolean test(BlockVector3 vector) { - return test(getExtent().getBlock(vector).getBlockType()); + return test(vector.getBlock(getExtent()).getBlockType()); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java index b75a4cd1e..be62c2eae 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/ExistingBlockMask.java @@ -41,7 +41,7 @@ public class ExistingBlockMask extends AbstractExtentMask { @Override public boolean test(BlockVector3 vector) { - return !getExtent().getBlock(vector).getBlockType().getMaterial().isAir(); + return !vector.getBlock(getExtent()).getBlockType().getMaterial().isAir(); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/InverseSingleBlockStateMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/InverseSingleBlockStateMask.java index e8b14b95a..6bb39b958 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/InverseSingleBlockStateMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/InverseSingleBlockStateMask.java @@ -29,7 +29,7 @@ public class InverseSingleBlockStateMask extends ABlockMask { @Override public boolean test(BlockVector3 vector) { - int test = getExtent().getBlock(vector).getOrdinal(); + int test = vector.getBlock(getExtent()).getOrdinal(); if (isAir && test == 0) { return false; } diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index a56d98695..fea3e7dd5 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -141,6 +141,7 @@ "fawe.error.limit.max-brush-radius": "Maximum brush radius in limit: {0}", "fawe.error.limit.max-radius": "Maximum radius in limit: {0}", "fawe.error.no-valid-on-hotbar": "No valid block types on hotbar", + "fawe.error.no-process-non-synchronous-edit": "No processor holder was found but edit is non-synchronous", "fawe.cancel.count": "Cancelled {0} edits.", "fawe.cancel.reason.confirm": "Use //confirm to execute {0}", "fawe.cancel.reason.confirm.region": "Your selection is large ({0} -> {1}, containing {3} blocks). Use //confirm to execute {2}", @@ -151,6 +152,7 @@ "fawe.cancel.reason.low.memory": "Low memory", "fawe.cancel.reason.max.changes": "Too many blocks changed", "fawe.cancel.reason.max.checks": "Too many block checks", + "fawe.cancel.reason.max.fails": "Too many fails", "fawe.cancel.reason.max.tiles": "Too many block entities", "fawe.cancel.reason.max.entities": "Too many entities", "fawe.cancel.reason.max.iterations": "Max iterations", From d1f9d3d6d50a61c5199b23797880df32bfa9888f Mon Sep 17 00:00:00 2001 From: Jordan Date: Sun, 28 Jul 2024 11:16:25 +0200 Subject: [PATCH 220/220] fix: improve FAWE stream history (#2844) - reset "origin"/relative X/Z when larger than short min/max value so we do not write incorrect positions - history size can be larger than int max value - fixes #2583 --- .../command/tool/brush/CopyPastaBrush.java | 2 +- .../core/database/RollbackDatabase.java | 48 ++++++++++++++----- .../history/changeset/AbstractChangeSet.java | 2 +- .../changeset/AbstractDelegateChangeSet.java | 5 ++ .../changeset/FaweStreamChangeSet.java | 48 +++++++++++++++---- .../core/util/MainUtil.java | 2 +- .../com/sk89q/worldedit/LocalSession.java | 2 +- .../worldedit/command/HistorySubCommands.java | 4 +- .../history/changeset/ChangeSet.java | 13 +++++ 9 files changed, 97 insertions(+), 29 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CopyPastaBrush.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CopyPastaBrush.java index b635c1e7d..1b60124cb 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CopyPastaBrush.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/command/tool/brush/CopyPastaBrush.java @@ -91,7 +91,7 @@ public class CopyPastaBrush implements Brush, ResettableTool { newClipboard.setOrigin(position); ClipboardHolder holder = new ClipboardHolder(newClipboard); session.setClipboard(holder); - int blocks = builder.size(); + long blocks = builder.longSize(); player.print(Caption.of("fawe.worldedit.copy.command.copy", blocks)); } else { AffineTransform transform = null; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java index f8207f2dc..e40683f2e 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/database/RollbackDatabase.java @@ -64,26 +64,47 @@ public class RollbackDatabase extends AsyncNotifyQueue { public Future init() { return call(() -> { try (PreparedStatement stmt = connection.prepareStatement("CREATE TABLE IF NOT EXISTS`" + this.prefix + - "edits` (`player` BLOB(16) NOT NULL,`id` INT NOT NULL, `time` INT NOT NULL,`x1`" + - "INT NOT NULL,`x2` INT NOT NULL,`z1` INT NOT NULL,`z2` INT NOT NULL,`y1`" + - "INT NOT NULL, `y2` INT NOT NULL, `size` INT NOT NULL, `command` VARCHAR, PRIMARY KEY (player, id))")) { + "_edits` (`player` BLOB(16) NOT NULL,`id` INT NOT NULL, `time` INT NOT NULL,`x1` " + + "INT NOT NULL,`x2` INT NOT NULL,`z1` INT NOT NULL,`z2` INT NOT NULL,`y1` " + + "INT NOT NULL, `y2` INT NOT NULL, `size` BIGINT NOT NULL, `command` VARCHAR, PRIMARY KEY (player, id))")) { stmt.executeUpdate(); } - try (PreparedStatement stmt = connection.prepareStatement("ALTER TABLE`" + this.prefix + "edits` ADD COLUMN `command` VARCHAR")) { + String alterTablePrefix = "ALTER TABLE`" + this.prefix + "edits` "; + try (PreparedStatement stmt = + connection.prepareStatement(alterTablePrefix + "ADD COLUMN `command` VARCHAR")) { stmt.executeUpdate(); } catch (SQLException ignored) { } // Already updated - try (PreparedStatement stmt = connection.prepareStatement("ALTER TABLE`" + this.prefix + "edits` ADD SIZE INT DEFAULT 0 NOT NULL")) { + try (PreparedStatement stmt = + connection.prepareStatement(alterTablePrefix + "ADD COLUMN `size` BIGINT DEFAULT 0 NOT NULL")) { stmt.executeUpdate(); } catch (SQLException ignored) { } // Already updated + + boolean migrated = false; + try (PreparedStatement stmt = + connection.prepareStatement("INSERT INTO `" + this.prefix + "_edits` " + + "(player, id, time, x1, x2, z1, z2, y1, y2, size, command) " + + "SELECT player, id, time, x1, x2, z1, z2, y1, y2, size, command " + + "FROM `" + this.prefix + "edits`")) { + + stmt.executeUpdate(); + migrated = true; + } catch (SQLException ignored) { + } // Already updated + if (migrated) { + try (PreparedStatement stmt = connection.prepareStatement("DROP TABLE `" + this.prefix + "edits`")) { + stmt.executeUpdate(); + } + } return true; }); } public Future delete(UUID uuid, int id) { return call(() -> { - try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM`" + this.prefix + "edits` WHERE `player`=? AND `id`=?")) { + try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM`" + this.prefix + "_edits` WHERE `player`=? " + + "AND `id`=?")) { stmt.setBytes(1, toBytes(uuid)); stmt.setInt(2, id); return stmt.executeUpdate(); @@ -94,7 +115,7 @@ public class RollbackDatabase extends AsyncNotifyQueue { public Future getEdit(@Nonnull UUID uuid, int id) { return call(() -> { try (PreparedStatement stmt = connection.prepareStatement("SELECT * FROM`" + this.prefix + - "edits` WHERE `player`=? AND `id`=?")) { + "_edits` WHERE `player`=? AND `id`=?")) { stmt.setBytes(1, toBytes(uuid)); stmt.setInt(2, id); ResultSet result = stmt.executeQuery(); @@ -119,7 +140,7 @@ public class RollbackDatabase extends AsyncNotifyQueue { CuboidRegion region = new CuboidRegion(BlockVector3.at(x1, y1, z1), BlockVector3.at(x2, y2, z2)); long time = result.getInt("time") * 1000L; - long size = result.getInt("size"); + long size = result.getLong("size"); String command = result.getString("command"); @@ -135,7 +156,7 @@ public class RollbackDatabase extends AsyncNotifyQueue { long now = System.currentTimeMillis() / 1000; final int then = (int) (now - diff); return call(() -> { - try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM`" + this.prefix + "edits` WHERE `time` ? AND `x2` >= ? AND `x1` <= ? @@ -202,7 +223,8 @@ public class RollbackDatabase extends AsyncNotifyQueue { } if (delete && uuid != null) { try (PreparedStatement stmt = connection.prepareStatement("DELETE FROM`" + this.prefix + - "edits` WHERE `player`=? AND `time`>? AND `x2`>=? AND `x1`<=? AND `y2`>=? AND `y1`<=? AND `z2`>=? AND `z1`<=?")) { + "_edits` WHERE `player`=? AND `time`>? AND `x2`>=? AND `x1`<=? AND `y2`>=? AND `y1`<=? AND `z2`>=? " + + "AND `z1`<=?")) { byte[] uuidBytes = ByteBuffer .allocate(16) .putLong(uuid.getMostSignificantBits()) @@ -249,7 +271,7 @@ public class RollbackDatabase extends AsyncNotifyQueue { RollbackOptimizedHistory[] copy = IntStream.range(0, size) .mapToObj(i -> historyChanges.poll()).toArray(RollbackOptimizedHistory[]::new); - try (PreparedStatement stmt = connection.prepareStatement("INSERT OR REPLACE INTO`" + this.prefix + "edits`" + + try (PreparedStatement stmt = connection.prepareStatement("INSERT OR REPLACE INTO`" + this.prefix + "_edits`" + " (`player`,`id`,`time`,`x1`,`x2`,`z1`,`z2`,`y1`,`y2`,`command`,`size`) VALUES(?,?,?,?,?,?,?,?,?,?,?)")) { // `player`,`id`,`time`,`x1`,`x2`,`z1`,`z2`,`y1`,`y2`,`command`,`size`) VALUES(?,?,?,?,?,?,?,?,?,?,?)" for (RollbackOptimizedHistory change : copy) { @@ -270,7 +292,7 @@ public class RollbackDatabase extends AsyncNotifyQueue { stmt.setInt(8, pos1.y() - 128); stmt.setInt(9, pos2.y() - 128); stmt.setString(10, change.getCommand()); - stmt.setInt(11, change.size()); + stmt.setLong(11, change.longSize()); stmt.executeUpdate(); stmt.clearParameters(); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java index 08165577f..346543a0b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java @@ -306,7 +306,7 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { } public boolean isEmpty() { - return queue.isEmpty() && workerSemaphore.availablePermits() == 1 && size() == 0; + return queue.isEmpty() && workerSemaphore.availablePermits() == 1 && longSize() == 0; } public void add(BlockVector3 loc, BaseBlock from, BaseBlock to) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractDelegateChangeSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractDelegateChangeSet.java index 195a5fdbd..a44e73013 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractDelegateChangeSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractDelegateChangeSet.java @@ -176,6 +176,11 @@ public class AbstractDelegateChangeSet extends AbstractChangeSet { return parent.size(); } + @Override + public long longSize() { + return parent.longSize(); + } + @Override public void delete() { parent.delete(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/FaweStreamChangeSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/FaweStreamChangeSet.java index ad7c82c9f..e7132bf5a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/FaweStreamChangeSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/FaweStreamChangeSet.java @@ -25,6 +25,7 @@ import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.NoSuchElementException; @@ -35,11 +36,18 @@ import java.util.NoSuchElementException; public abstract class FaweStreamChangeSet extends AbstractChangeSet { public static final int HEADER_SIZE = 9; - private static final int version = 1; + private static final int VERSION = 2; + // equivalent to Short#MIN_VALUE three times stored with [(x) & 0xff, ((rx) >> 8) & 0xff] + private static final byte[] MAGIC_NEW_RELATIVE = new byte[]{0, (byte) 128, 0, (byte) 128, 0, (byte) 128}; private int mode; private final int compression; private final int minY; + protected long blockSize; + private int originX; + private int originZ; + private int version; + protected FaweStreamIdDelegate idDel; protected FaweStreamPositionDelegate posDel; @@ -192,6 +200,20 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet { int rx = -lx + (lx = x); int ry = -ly + (ly = y); int rz = -lz + (lz = z); + // Use LE/GE to ensure we don't accidentally write MAGIC_NEW_RELATIVE + if (rx >= Short.MAX_VALUE || rz >= Short.MAX_VALUE || rx <= Short.MIN_VALUE || rz <= Short.MIN_VALUE) { + stream.write(MAGIC_NEW_RELATIVE); + stream.write((byte) (x >> 24)); + stream.write((byte) (x >> 16)); + stream.write((byte) (x >> 8)); + stream.write((byte) (x)); + stream.write((byte) (z >> 24)); + stream.write((byte) (z >> 16)); + stream.write((byte) (z >> 8)); + stream.write((byte) (z)); + rx = 0; + rz = 0; + } stream.write((rx) & 0xff); stream.write(((rx) >> 8) & 0xff); stream.write((rz) & 0xff); @@ -203,6 +225,12 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet { @Override public int readX(FaweInputStream is) throws IOException { is.readFully(buffer); + // Don't break reading version 1 history (just in case) + if (version == 2 && Arrays.equals(buffer, MAGIC_NEW_RELATIVE)) { + lx = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + is.read()); + lz = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + is.read()); + is.readFully(buffer); + } return lx = lx + ((buffer[0] & 0xFF) | (buffer[1] << 8)); } @@ -222,7 +250,7 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet { public void writeHeader(OutputStream os, int x, int y, int z) throws IOException { os.write(mode); // Allows for version detection of history in case of changes to format. - os.write(version); + os.write(VERSION); setOrigin(x, z); os.write((byte) (x >> 24)); os.write((byte) (x >> 16)); @@ -238,8 +266,8 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet { public void readHeader(InputStream is) throws IOException { // skip mode int mode = is.read(); - int version = is.read(); - if (version != FaweStreamChangeSet.version) { + version = is.read(); + if (version != 1 && version != VERSION) { // version 1 is fine throw new UnsupportedOperationException(String.format("Version %s history not supported!", version)); } // origin @@ -266,12 +294,17 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet { } @Override - public int size() { + public long longSize() { // Flush so we can accurately get the size flush(); return blockSize; } + @Override + public int size() { + return (int) longSize(); + } + public abstract int getCompressedSize(); public abstract long getSizeInMemory(); @@ -304,11 +337,6 @@ public abstract class FaweStreamChangeSet extends AbstractChangeSet { public abstract NBTInputStream getTileRemoveIS() throws IOException; - protected int blockSize; - - private int originX; - private int originZ; - public void setOrigin(int x, int z) { originX = x; originZ = z; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java index 6b693162e..83f951c13 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java @@ -217,7 +217,7 @@ public class MainUtil { // } else if (changeSet instanceof CPUOptimizedChangeSet) { // return changeSet.size() + 32; } else if (changeSet != null) { - return changeSet.size() * 128L; + return changeSet.longSize() * 128; // Approx } else { return 0; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index aa5f51e57..3dd5f5638 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -500,7 +500,7 @@ public class LocalSession implements TextureHolder { if (Settings.settings().HISTORY.USE_DISK) { LocalSession.MAX_HISTORY_SIZE = Integer.MAX_VALUE; } - if (changeSet.size() == 0) { + if (changeSet.longSize() == 0) { return; } loadSessionHistoryFromDisk(player.getUniqueId(), world); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistorySubCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistorySubCommands.java index 8d28ad1eb..38fc18415 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistorySubCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/HistorySubCommands.java @@ -251,7 +251,7 @@ public class HistorySubCommands { long seconds = (System.currentTimeMillis() - edit.getBDFile().lastModified()) / 1000; String timeStr = MainUtil.secToTime(seconds); - int size = edit.size(); + long size = edit.longSize(); boolean biomes = edit.getBioFile().exists(); boolean createdEnts = edit.getEnttFile().exists(); boolean removedEnts = edit.getEntfFile().exists(); @@ -335,7 +335,7 @@ public class HistorySubCommands { long seconds = (System.currentTimeMillis() - rollback.getBDFile().lastModified()) / 1000; String timeStr = MainUtil.secToTime(seconds); - int size = edit.size(); + long size = edit.longSize(); TranslatableComponent elem = Caption.of( "fawe.worldedit.history.find.element", diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/ChangeSet.java b/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/ChangeSet.java index b4ab9adc1..890b247d6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/ChangeSet.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/ChangeSet.java @@ -81,11 +81,24 @@ public interface ChangeSet extends Closeable { * Get the number of stored changes. * * @return the change count + * @deprecated History could be larger than int max value so FAWE prefers {@link ChangeSet#longSize()} */ + @Deprecated(since = "TODO") int size(); //FAWE start + /** + * Get the number of stored changes. + * History could be larger than int max value so FAWE prefers this method. + * + * @return the change count + * @since TODO + */ + default long longSize() { + return size(); + } + /** * Close the changeset. */