From 51e238c352c0851b02ca459a21d239fdbd798684 Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 15 Jun 2023 10:18:01 +0200 Subject: [PATCH 01/28] feat: add new tree types to tree tool and brush (#2286) * feat: add new tree types - implements #2197 * Remove nonsensical test case --------- Co-authored-by: Alexander Brandes --- .../test/java/com/sk89q/worldedit/bukkit/BukkitWorldTest.java | 1 - .../src/main/java/com/sk89q/worldedit/util/TreeGenerator.java | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/worldedit-bukkit/src/test/java/com/sk89q/worldedit/bukkit/BukkitWorldTest.java b/worldedit-bukkit/src/test/java/com/sk89q/worldedit/bukkit/BukkitWorldTest.java index 447f2ec9a..df6b33b7b 100644 --- a/worldedit-bukkit/src/test/java/com/sk89q/worldedit/bukkit/BukkitWorldTest.java +++ b/worldedit-bukkit/src/test/java/com/sk89q/worldedit/bukkit/BukkitWorldTest.java @@ -26,7 +26,6 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; public class BukkitWorldTest { - @Test public void testTreeTypeMapping() { for (TreeGenerator.TreeType type : TreeGenerator.TreeType.values()) { assertNotNull(BukkitWorld.toBukkitTreeType(type), "No mapping for: " + type); 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 7d7d71e75..cf5c05278 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 @@ -165,6 +165,9 @@ public final class TreeGenerator { } //FAWE end }, + MANGROVE("Mangrove tree", "mangrove"), + TALL_MANGROVE("Tall mangrove tree", "tall_mangrove"), + CHERRY("Cherry blossom", "cherry"), RANDOM("Random tree", "rand", "random") { @Override public boolean generate(EditSession editSession, BlockVector3 pos) throws MaxChangedBlocksException { From 7a7373fd3d87267cf16b0329e5cb017baec46257 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Sat, 17 Jun 2023 16:16:16 +0200 Subject: [PATCH 02/28] Update paperweight --- worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts index c9a239ebf..4c0d110e2 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/ - the().paperDevBundle("1.20-R0.1-20230609.070122-4") + the().paperDevBundle("1.20.1-R0.1-20230617.023453-15") compileOnly("io.papermc:paperlib") } From 78fb74665f9e3cb9f34f6c262cd980dffe46cd78 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Jun 2023 16:36:57 +0200 Subject: [PATCH 03/28] Update plugin com.modrinth.minotaur to v2.8.1 (#2298) 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 426eb4c4f..a393413f3 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -3,7 +3,7 @@ import io.papermc.paperweight.userdev.attribute.Obfuscation plugins { `java-library` - id("com.modrinth.minotaur") version "2.8.0" + id("com.modrinth.minotaur") version "2.8.1" } project.description = "Bukkit" From 135c77cfb5073cb4b94e16d2f732abd17d32ff66 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sun, 18 Jun 2023 15:03:51 +0100 Subject: [PATCH 04/28] chore: minor changes - null check get tile in ThreadUnsafeCharBlocks - 0 to reserved ID --- .../adapter/impl/fawe/v1_17_R1_2/PaperweightGetBlocks.java | 2 +- .../bukkit/adapter/impl/fawe/v1_18_R2/PaperweightGetBlocks.java | 2 +- .../bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java | 2 +- .../bukkit/adapter/impl/fawe/v1_19_R2/PaperweightGetBlocks.java | 2 +- .../bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks.java | 2 +- .../bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks.java | 2 +- .../core/history/changeset/SimpleChangeSetSummary.java | 2 +- .../queue/implementation/blocks/ThreadUnsafeCharBlocks.java | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) 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 09fa8f7a5..85be84901 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 @@ -415,7 +415,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != 0) { + if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { BlockEntity tile = entry.getValue(); if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { if (beacons == null) { 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 06a74cfd1..4e435e7ee 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 @@ -408,7 +408,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != 0) { + if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { BlockEntity tile = entry.getValue(); if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { if (beacons == null) { diff --git a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java index e0a851c1b..6466ea828 100644 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java @@ -406,7 +406,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != 0) { + if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { BlockEntity tile = entry.getValue(); if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { if (beacons == null) { diff --git a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightGetBlocks.java index 3ee8314fd..9edb79974 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightGetBlocks.java @@ -408,7 +408,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != 0) { + if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { BlockEntity tile = entry.getValue(); if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { if (beacons == null) { 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 1b10ddd77..ba1bfe574 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 @@ -408,7 +408,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != 0) { + if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { BlockEntity tile = entry.getValue(); if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { if (beacons == null) { 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 38c871ea8..0dd292207 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 @@ -386,7 +386,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } int ordinal = set.getBlock(lx, ly, lz).getOrdinal(); - if (ordinal != 0) { + if (ordinal != BlockTypesCache.ReservedIDs.__RESERVED__) { BlockEntity tile = entry.getValue(); if (PaperLib.isPaper() && tile instanceof BeaconBlockEntity) { if (beacons == null) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/SimpleChangeSetSummary.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/SimpleChangeSetSummary.java index 7b6565355..dadb7ee83 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/SimpleChangeSetSummary.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/SimpleChangeSetSummary.java @@ -50,7 +50,7 @@ public class SimpleChangeSetSummary implements ChangeSetSummary { public Map getBlocks() { HashMap map = new HashMap<>(); for (int i = 0; i < blocks.length; i++) { - if (blocks[i] != 0) { + if (blocks[i] != BlockTypesCache.ReservedIDs.__RESERVED__) { BlockState state = BlockTypesCache.states[i]; map.put(state, blocks[i]); } 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 f3dda058f..ca0dd3442 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 @@ -122,7 +122,7 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks { @Override public CompoundTag getTile(int x, int y, int z) { - return tiles.get(x, y, z); + return tiles == null ? null : tiles.get(x, y, z); } @Override From f0aef9887078ada7895a73e89206543d177e53cf Mon Sep 17 00:00:00 2001 From: Jordan Date: Sun, 18 Jun 2023 18:08:31 +0200 Subject: [PATCH 05/28] fix: don't "double-up" a setblocks if a region is being set (#2299) - Fixes #2294 --- .../core/queue/implementation/ParallelQueueExtent.java | 1 + 1 file changed, 1 insertion(+) 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 0d7436ca5..2d2b45aae 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 @@ -193,6 +193,7 @@ public class ParallelQueueExtent extends PassthroughExtent { public int setBlocks(Set vset, Pattern pattern) { if (vset instanceof Region) { this.changes = setBlocks((Region) vset, pattern); + return this.changes; } // TODO optimize parallel for (BlockVector3 blockVector3 : vset) { From 39de48cdb117d1734d1374bac5fe54b0d71deebe Mon Sep 17 00:00:00 2001 From: Jordan Date: Sun, 18 Jun 2023 18:31:49 +0200 Subject: [PATCH 06/28] chore: Address kotlin String#capitalize() deprecation (#2308) * chore: Address kotlin String#capitalize() deprecation - Fixes #2283 - Don't bother with the longer version that allows Locales, we don't need that * Address comments --- buildSrc/src/main/kotlin/LibsConfig.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/LibsConfig.kt b/buildSrc/src/main/kotlin/LibsConfig.kt index d2c1a8e1d..4fd69cb65 100644 --- a/buildSrc/src/main/kotlin/LibsConfig.kt +++ b/buildSrc/src/main/kotlin/LibsConfig.kt @@ -204,7 +204,7 @@ fun Project.applyLibrariesConfiguration() { from(libsComponent) group = "com.fastasyncworldedit" - artifactId = "FastAsyncWorldEdit-Libs-${project.name.capitalize()}" + artifactId = "FastAsyncWorldEdit-Libs-${project.name.replaceFirstChar(Char::titlecase)}" version = version pom { From 1ede11b12910b288fe8d63c0d68a9e6dcdc48e6b Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 19 Jun 2023 15:34:02 +0200 Subject: [PATCH 07/28] fix: use new array when creating palette (#2305) - Fixes #2291 --- .../bukkit/adapter/NMSAdapter.java | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/NMSAdapter.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/NMSAdapter.java index a69d7865f..b41da1679 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/NMSAdapter.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/NMSAdapter.java @@ -30,7 +30,8 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl { ordinal = BlockTypesCache.ReservedIDs.AIR; nonAir--; } - case BlockTypesCache.ReservedIDs.AIR, BlockTypesCache.ReservedIDs.CAVE_AIR, BlockTypesCache.ReservedIDs.VOID_AIR -> nonAir--; + case BlockTypesCache.ReservedIDs.AIR, BlockTypesCache.ReservedIDs.CAVE_AIR, BlockTypesCache.ReservedIDs.VOID_AIR -> + nonAir--; } int palette = blockToPalette[ordinal]; if (palette == Integer.MAX_VALUE) { @@ -73,6 +74,8 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl { CachedBukkitAdapter adapter, short[] nonEmptyBlockCount ) { + // Write to new array to avoid editing SET array + char[] copy = new char[set.length]; short nonAir = 4096; int num_palette = 0; char[] getArr = null; @@ -83,23 +86,19 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl { if (getArr == null) { getArr = get.apply(layer); } - // write to set array as this should be a copied array, and will be important when the changes are written - // to the GET chunk cached by FAWE - set[i] = switch (ordinal = getArr[i]) { + switch (ordinal = getArr[i]) { case BlockTypesCache.ReservedIDs.__RESERVED__ -> { nonAir--; - yield (ordinal = BlockTypesCache.ReservedIDs.AIR); + ordinal = BlockTypesCache.ReservedIDs.AIR; } - case BlockTypesCache.ReservedIDs.AIR, BlockTypesCache.ReservedIDs.CAVE_AIR, - BlockTypesCache.ReservedIDs.VOID_AIR -> { - nonAir--; - yield ordinal; - } - default -> ordinal; - }; + case BlockTypesCache.ReservedIDs.AIR, BlockTypesCache.ReservedIDs.CAVE_AIR, BlockTypesCache.ReservedIDs.VOID_AIR -> + nonAir--; + } } - case BlockTypesCache.ReservedIDs.AIR, BlockTypesCache.ReservedIDs.CAVE_AIR, BlockTypesCache.ReservedIDs.VOID_AIR -> nonAir--; + case BlockTypesCache.ReservedIDs.AIR, BlockTypesCache.ReservedIDs.CAVE_AIR, BlockTypesCache.ReservedIDs.VOID_AIR -> + nonAir--; } + copy[i] = ordinal; int palette = blockToPalette[ordinal]; if (palette == Integer.MAX_VALUE) { blockToPalette[ordinal] = num_palette; @@ -117,7 +116,7 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl { System.arraycopy(adapter.getOrdinalToIbdID(), 0, blockToPalette, 0, adapter.getOrdinalToIbdID().length); } for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; + char ordinal = copy[i]; if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { LOGGER.error("Empty (__RESERVED__) ordinal given where not expected, default to air."); ordinal = BlockTypesCache.ReservedIDs.AIR; From a8c8a0fbd62d3bf1e0ea794fd1a6ed26c50a4153 Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 19 Jun 2023 15:34:54 +0200 Subject: [PATCH 08/28] fix: always return the changeset from EditSessionBuilder (#2302) - Ensure history will actually always be closed if combine-stages is false - Fixes #2148 --- .../main/java/com/sk89q/worldedit/EditSessionBuilder.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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 ead916f45..ea27f03b5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSessionBuilder.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSessionBuilder.java @@ -72,7 +72,6 @@ import org.apache.logging.log4j.Logger; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import java.util.Arrays; import java.util.HashSet; import java.util.Locale; import java.util.Set; @@ -99,7 +98,6 @@ public final class EditSessionBuilder { private RelightMode relightMode; private Relighter relighter; private Boolean wnaMode; - private AbstractChangeSet changeTask; private Extent bypassHistory; private Extent bypassAll; private Extent extent; @@ -522,7 +520,6 @@ public final class EditSessionBuilder { changeSet = new BlockBagChangeSet(changeSet, blockBag, limit.INVENTORY_MODE == 1); } if (combineStages) { - changeTask = changeSet; this.extent = extent.enableHistory(changeSet); } else { this.extent = new HistoryExtent(extent, changeSet); @@ -699,7 +696,7 @@ public final class EditSessionBuilder { * Get the change set that will be used for history */ public AbstractChangeSet getChangeTask() { - return changeTask; + return changeSet; } /** From 01be53ed655364f9573b05a52eb26c89a5e9b974 Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 19 Jun 2023 15:36:47 +0200 Subject: [PATCH 09/28] fix: add missing BlockType constructor (#2306) - Deprecate public BlockType constructors - People really should not be initialising their own block types. This can and most likely will cause issues. - Fixes #2290 --- .../worldedit/world/block/BlockType.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) 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 01a5d5c8a..e5a466e29 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 @@ -78,13 +78,35 @@ public class BlockType implements Keyed, Pattern { this.id = i == -1 ? id : id.substring(0, i); this.settings = new BlockTypesCache.Settings(this, id, internalId, states); } + //FAWE end + //FAWE start + /** + * @deprecated You should not be initialising your own BlockTypes, use {@link BlockTypes#get(String)} instead. If there is + * a specific requirement to actually create new block types, please contact the FAWE devs to discuss. Use + * {@link BlockTypes#get(String)} instead. + */ + @Deprecated(since = "TODO") + //FAWE end + public BlockType(String id) { + this(id, null); + } + + //FAWE start + /** + * @deprecated You should not be initialising your own BlockTypes, use {@link BlockTypes#get(String)} instead. If there is + * a specific requirement to actually create new block types, please contact the FAWE devs to discuss. Use + * {@link BlockTypes#get(String)} instead. + */ + @Deprecated(since = "TODO") + //FAWE end public BlockType(String id, Function values) { // If it has no namespace, assume minecraft. if (!id.contains(":")) { id = "minecraft:" + id; } this.id = id; + //FAWE start //TODO fix the line below this.settings = new BlockTypesCache.Settings(this, id, 0, null); } From 8ca25fa7d7ec04d51edd5a21444312891bec3101 Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 19 Jun 2023 22:46:01 +0200 Subject: [PATCH 10/28] fix: towny max bounds are exclusive (#2301) fix: towny max bounds are exlusive - Fixes #2293 --- .../fastasyncworldedit/bukkit/regions/TownyFeature.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/TownyFeature.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/TownyFeature.java index 7c5aa7e6f..ca5c81a6a 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/TownyFeature.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/TownyFeature.java @@ -1,7 +1,6 @@ package com.fastasyncworldedit.bukkit.regions; import com.fastasyncworldedit.core.regions.FaweMask; -import com.palmergames.bukkit.towny.Towny; import com.palmergames.bukkit.towny.TownyAPI; import com.palmergames.bukkit.towny.object.Resident; import com.palmergames.bukkit.towny.object.Town; @@ -12,7 +11,6 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import org.apache.logging.log4j.Logger; -import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.Listener; @@ -22,11 +20,8 @@ public class TownyFeature extends BukkitMaskManager implements Listener { private static final Logger LOGGER = LogManagerCompat.getLogger(); - private final Plugin towny; - public TownyFeature(Plugin townyPlugin) { super(townyPlugin.getName()); - this.towny = townyPlugin; LOGGER.info("Plugin 'Towny' found. Using it now."); } @@ -73,7 +68,7 @@ public class TownyFeature extends BukkitMaskManager implements Listener { final Location loc1 = mycoord.getLowerMostCornerLocation(); final Location loc2 = mycoord.getUpperMostCornerLocation(); final BlockVector3 pos1 = BlockVector3.at(loc1.getX(), loc1.getY(), loc1.getZ()); - final BlockVector3 pos2 = BlockVector3.at(loc2.getX(), loc2.getY(), loc2.getZ()); + final BlockVector3 pos2 = BlockVector3.at(loc2.getX() - 1, loc2.getY(), loc2.getZ() - 1); return new FaweMask(new CuboidRegion(pos1, pos2)) { @Override public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) { From 88533118bcb20f288f33c245d40fc6a3f9805ab3 Mon Sep 17 00:00:00 2001 From: Jordan Date: Mon, 19 Jun 2023 22:46:10 +0200 Subject: [PATCH 11/28] fix: uncache the chunk SET at a better time in ChunkHolder to prevent "lost" changes (#2300) - blocks could still be set to the ChunkHolder during a call - create a new chunk SET in that case - make cached get/set volatile to improve thread safety --- .../queue/implementation/chunk/ChunkHolder.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) 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 7390758bc..9172d8b3e 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 @@ -45,8 +45,8 @@ public class ChunkHolder> implements IQueueChunk { private final ReentrantWrappedStampedLock calledLock = new ReentrantWrappedStampedLock(); - private IChunkGet chunkExisting; // The existing chunk (e.g. a clipboard, or the world, before changes) - private IChunkSet chunkSet; // The blocks to be set to the chunkExisting + private volatile IChunkGet chunkExisting; // The existing chunk (e.g. a clipboard, or the world, before changes) + private volatile IChunkSet chunkSet; // The blocks to be set to the chunkExisting private IBlockDelegate delegate; // delegate handles the abstraction of the chunk layers private IQueueExtent extent; // the parent queue extent which has this chunk private int chunkX; @@ -1042,13 +1042,12 @@ public class ChunkHolder> implements IQueueChunk { calledLock.lock(); final long stamp = calledLock.getStampChecked(); if (chunkSet != null && !chunkSet.isEmpty()) { + this.delegate = GET; chunkSet.setBitMask(bitMask); try { - return this.call(chunkSet.createCopy(), () -> { - this.delegate = NULL; - chunkSet = null; - calledLock.unlock(stamp); - }); + IChunkSet copy = chunkSet.createCopy(); + chunkSet = null; + return this.call(copy, () -> calledLock.unlock(stamp)); } catch (Throwable t) { calledLock.unlock(); throw t; From d961aa91bce8c44e921741a8e7d71d3fe3679006 Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 22 Jun 2023 11:24:03 +0100 Subject: [PATCH 12/28] fix: fix regex block masking (#2242) --- .../core/function/mask/BlockMaskBuilder.java | 374 +++++++----------- .../core/math/FastBitSet.java | 4 + .../world/block/FuzzyBlockState.java | 2 +- 3 files changed, 156 insertions(+), 224 deletions(-) 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 5bfeb766c..2471ff262 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 @@ -20,12 +20,11 @@ import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; -import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -36,10 +35,12 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.function.BiPredicate; import java.util.function.Predicate; +import java.util.regex.Pattern; import java.util.stream.Collectors; +import static com.google.common.base.Preconditions.checkNotNull; + public class BlockMaskBuilder { private static final Operator GREATER = (a, b) -> a > b; @@ -63,58 +64,97 @@ public class BlockMaskBuilder { this.bitSets = bitSets; } - private boolean filterRegex(BlockType blockType, PropertyKey key, String regex) { + private boolean handleRegex(BlockType blockType, PropertyKey key, String regex, FuzzyStateAllowingBuilder builder) { Property property = blockType.getProperty(key); if (property == null) { return false; } - List values = property.getValues(); boolean result = false; + List values = property.getValues(); for (int i = 0; i < values.size(); i++) { - Object value = values.get(i); - if (!value.toString().matches(regex) && has(blockType, property, i)) { - filter(blockType, property, i); + if (values.get(i).toString().matches(regex)) { + builder.allow(property, i); result = true; } } return result; } - private boolean filterOperator(BlockType blockType, PropertyKey key, Operator operator, CharSequence value) { + private boolean handleOperator( + BlockType blockType, + PropertyKey key, + Operator operator, + CharSequence stringValue, + FuzzyStateAllowingBuilder builder + ) { Property property = blockType.getProperty(key); if (property == null) { return false; } - int index = property.getIndexFor(value); + int index = property.getIndexFor(stringValue); List values = property.getValues(); boolean result = false; for (int i = 0; i < values.size(); i++) { - if (!operator.test(index, i) && has(blockType, property, i)) { - filter(blockType, property, i); + if (operator.test(index, i)) { + builder.allow(property, i); result = true; } } return result; } - private boolean filterRegexOrOperator(BlockType type, PropertyKey key, Operator operator, CharSequence value) { - boolean result = false; - if (!type.hasProperty(key)) { - if (operator == EQUAL) { - result = bitSets[type.getInternalId()] != null; - remove(type); + private boolean handleRegexOrOperator( + BlockType type, + PropertyKey key, + Operator operator, + CharSequence value, + FuzzyStateAllowingBuilder builder + ) { + if (!type.hasProperty(key) && operator == EQUAL) { + return false; + } + if (value.length() == 0) { + return false; + } + if ((operator == EQUAL || operator == EQUAL_OR_NULL) && !StringMan.isAlphanumericUnd(value)) { + return handleRegex(type, key, value.toString(), builder); + } else { + return handleOperator(type, key, operator, value, builder); + } + } + + private void add(FuzzyStateAllowingBuilder builder) { + long[] states = bitSets[builder.getType().getInternalId()]; + if (states == ALL) { + bitSets[builder.getType().getInternalId()] = states = FastBitSet.create(builder.getType().getMaxStateId() + 1); + FastBitSet.unsetAll(states); + } + applyRecursive(0, builder.getType().getInternalId(), builder, states); + } + + private void applyRecursive( + int propertiesIndex, + int state, + FuzzyStateAllowingBuilder builder, + long[] states + ) { + AbstractProperty current = (AbstractProperty) builder.getType().getProperties().get(propertiesIndex); + List values = current.getValues(); + if (propertiesIndex + 1 < builder.getType().getProperties().size()) { + for (int i = 0; i < values.size(); i++) { + if (builder.allows(current) || builder.allows(current, i)) { + int newState = current.modifyIndex(state, i); + applyRecursive(propertiesIndex + 1, newState, builder, states); + } } } else { - if (value.length() == 0) { - return result; - } - if ((operator == EQUAL || operator == EQUAL_OR_NULL) && !StringMan.isAlphanumericUnd(value)) { - result = filterRegex(type, key, value.toString()); - } else { - result = filterOperator(type, key, operator, value); + for (int i = 0; i < values.size(); i++) { + if (builder.allows(current) || builder.allows(current, i)) { + int index = current.modifyIndex(state, i) >> BlockTypesCache.BIT_OFFSET; + FastBitSet.set(states, index); + } } } - return result; } public BlockMaskBuilder addRegex(final String input) throws InputParseException { @@ -130,26 +170,28 @@ public class BlockMaskBuilder { charSequence.setString(input); charSequence.setSubstring(0, propStart); - BlockType type = null; - List blockTypeList = null; + List blockTypeList; + List builders; if (StringMan.isAlphanumericUnd(charSequence)) { - type = BlockTypes.parse(charSequence.toString()); + BlockType type = BlockTypes.parse(charSequence.toString()); + blockTypeList = Collections.singletonList(type); + builders = Collections.singletonList(new FuzzyStateAllowingBuilder(type)); add(type); } else { String regex = charSequence.toString(); blockTypeList = new ArrayList<>(); - for (BlockType myType : BlockTypesCache.values) { - if (myType.getId().matches(regex)) { - blockTypeList.add(myType); - add(myType); + builders = new ArrayList<>(); + Pattern pattern = Pattern.compile("(minecraft:)?" + regex); + for (BlockType type : BlockTypesCache.values) { + if (pattern.matcher(type.getId()).find()) { + blockTypeList.add(type); + builders.add(new FuzzyStateAllowingBuilder(type)); + add(type); } } if (blockTypeList.isEmpty()) { throw new InputParseException(Caption.of("fawe.error.no-block-found", TextComponent.of(input))); } - if (blockTypeList.size() == 1) { - type = blockTypeList.get(0); - } } // Empty string charSequence.setSubstring(0, 0); @@ -169,11 +211,11 @@ public class BlockMaskBuilder { } case ']', ',' -> { charSequence.setSubstring(last, i); - if (key == null && PropertyKey.getByName(charSequence) == null) { + if (key == null && (key = PropertyKey.getByName(charSequence)) == null) { suggest( input, charSequence.toString(), - type != null ? Collections.singleton(type) : blockTypeList + blockTypeList ); } if (operator == null) { @@ -182,34 +224,20 @@ public class BlockMaskBuilder { () -> Arrays.asList("=", "~", "!", "<", ">", "<=", ">=") ); } - boolean filtered = false; - if (type != null) { - filtered = filterRegexOrOperator(type, key, operator, charSequence); - } else { - for (BlockType myType : blockTypeList) { - filtered |= filterRegexOrOperator(myType, key, operator, charSequence); + for (int index = 0; index < blockTypeList.size(); index++) { + if (!handleRegexOrOperator( + blockTypeList.get(index), + key, + operator, + charSequence, + builders.get(index) + )) { + // If we cannot find a matching property for all to mask, do not mask the block + blockTypeList.remove(index); + builders.remove(index); + index--; } } - if (!filtered) { - String value = charSequence.toString(); - final PropertyKey fKey = key; - Collection types = type != null ? Collections.singleton(type) : blockTypeList; - throw new SuggestInputParseException(Caption.of("fawe.error.no-value-for-input", input), () -> { - HashSet values = new HashSet<>(); - types.stream().filter(t -> t.hasProperty(fKey)).forEach(t -> { - Property p = t.getProperty(fKey); - for (int j = 0; j < p.getValues().size(); j++) { - if (has(t, p, j)) { - String o = p.getValues().get(j).toString(); - if (o.startsWith(value)) { - values.add(o); - } - } - } - }); - return new ArrayList<>(values); - }); - } // Reset state key = null; operator = null; @@ -235,7 +263,7 @@ public class BlockMaskBuilder { suggest( input, charSequence.toString(), - type != null ? Collections.singleton(type) : blockTypeList + blockTypeList ); } } @@ -245,13 +273,18 @@ public class BlockMaskBuilder { } } } + for (FuzzyStateAllowingBuilder builder : builders) { + if (builder.allows()) { + add(builder); + } + } } else { if (StringMan.isAlphanumericUnd(input)) { add(BlockTypes.parse(input)); } else { boolean success = false; for (BlockType myType : BlockTypesCache.values) { - if (myType.getId().matches(input)) { + if (myType.getId().matches("(minecraft:)?" + input)) { add(myType); success = true; } @@ -275,16 +308,6 @@ public class BlockMaskBuilder { return this; } - private boolean has(BlockType type, Property property, int index) { - AbstractProperty prop = (AbstractProperty) property; - long[] states = bitSets[type.getInternalId()]; - if (states == null) { - return false; - } - int localI = index << prop.getBitOffset() >> BlockTypesCache.BIT_OFFSET; - return (states == ALL || FastBitSet.get(states, localI)); - } - private void suggest(String input, String property, Collection finalTypes) throws InputParseException { throw new SuggestInputParseException(Caption.of("worldedit.error.parser.unknown-property", property, input), () -> { Set keys = PropertyKeySet.empty(); @@ -381,42 +404,6 @@ public class BlockMaskBuilder { return this; } - @SuppressWarnings({"unchecked", "rawtypes"}) - public BlockMaskBuilder filter( - Predicate typePredicate, - BiPredicate, T>> allowed - ) { - for (int i = 0; i < bitSets.length; i++) { - long[] states = bitSets[i]; - if (states == null) { - continue; - } - BlockType type = BlockTypes.get(i); - if (!typePredicate.test(type)) { - bitSets[i] = null; - continue; - } - List> properties = (List>) type.getProperties(); - for (AbstractProperty prop : properties) { - List values = prop.getValues(); - for (int j = 0; j < values.size(); j++) { - int localI = j << prop.getBitOffset() >> BlockTypesCache.BIT_OFFSET; - if (states == ALL || FastBitSet.get(states, localI)) { - if (!allowed.test(type, new AbstractMap.SimpleEntry(prop, values.get(j)))) { - if (states == ALL) { - bitSets[i] = states = FastBitSet.create(type.getMaxStateId() + 1); - FastBitSet.setAll(states); - } - FastBitSet.clear(states, localI); - reset(false); - } - } - } - } - } - return this; - } - public BlockMaskBuilder add(BlockType type) { bitSets[type.getInternalId()] = ALL; return this; @@ -478,117 +465,6 @@ public class BlockMaskBuilder { return this; } - @SuppressWarnings({"unchecked", "rawtypes"}) - public BlockMaskBuilder addAll( - Predicate typePredicate, - BiPredicate, ?>> propPredicate - ) { - for (int i = 0; i < bitSets.length; i++) { - long[] states = bitSets[i]; - if (states == ALL) { - continue; - } - BlockType type = BlockTypes.get(i); - if (!typePredicate.test(type)) { - continue; - } - for (AbstractProperty prop : (List>) type.getProperties()) { - List values = prop.getValues(); - for (int j = 0; j < values.size(); j++) { - int localI = j << prop.getBitOffset() >> BlockTypesCache.BIT_OFFSET; - if (states == null || !FastBitSet.get(states, localI)) { - if (propPredicate.test(type, new AbstractMap.SimpleEntry(prop, values.get(j)))) { - if (states == null) { - bitSets[i] = states = FastBitSet.create(type.getMaxStateId() + 1); - } - FastBitSet.set(states, localI); - reset(false); - } - } - } - } - } - return this; - } - - public BlockMaskBuilder add(BlockType type, Property property, int index) { - AbstractProperty prop = (AbstractProperty) property; - long[] states = bitSets[type.getInternalId()]; - if (states == ALL) { - return this; - } - - List values = property.getValues(); - int localI = index << prop.getBitOffset() >> BlockTypesCache.BIT_OFFSET; - if (states == null || !FastBitSet.get(states, localI)) { - if (states == null) { - bitSets[type.getInternalId()] = states = FastBitSet.create(type.getMaxStateId() + 1); - } - set(type, states, property, index); - reset(false); - } - return this; - } - - public BlockMaskBuilder filter(BlockType type, Property property, int index) { - AbstractProperty prop = (AbstractProperty) property; - long[] states = bitSets[type.getInternalId()]; - if (states == null) { - return this; - } - List values = property.getValues(); - int localI = index << prop.getBitOffset() >> BlockTypesCache.BIT_OFFSET; - if (states == ALL || FastBitSet.get(states, localI)) { - if (states == ALL) { - bitSets[type.getInternalId()] = states = FastBitSet.create(type.getMaxStateId() + 1); - FastBitSet.setAll(states); - } - clear(type, states, property, index); - reset(false); - } - return this; - } - - private void applyRecursive(List properties, int propertiesIndex, int state, long[] states, boolean set) { - AbstractProperty current = (AbstractProperty) properties.get(propertiesIndex); - List values = current.getValues(); - if (propertiesIndex + 1 < properties.size()) { - for (int i = 0; i < values.size(); i++) { - int newState = current.modifyIndex(state, i); - applyRecursive(properties, propertiesIndex + 1, newState, states, set); - } - } else { - for (int i = 0; i < values.size(); i++) { - int index = current.modifyIndex(state, i) >> BlockTypesCache.BIT_OFFSET; - if (set) { - FastBitSet.set(states, index); - } else { - FastBitSet.clear(states, index); - } - } - } - } - - private void set(BlockType type, long[] bitSet, Property property, int index) { - FastBitSet.set(bitSet, index); - if (type.getProperties().size() > 1) { - ArrayList properties = new ArrayList<>(type.getProperties()); - properties.remove(property); - int state = ((AbstractProperty) property).modifyIndex(type.getInternalId(), index); - applyRecursive(properties, 0, state, bitSet, true); - } - } - - private void clear(BlockType type, long[] bitSet, Property property, int index) { - FastBitSet.clear(bitSet, index); - if (type.getProperties().size() > 1) { - ArrayList properties = new ArrayList<>(type.getProperties()); - properties.remove(property); - int state = ((AbstractProperty) property).modifyIndex(type.getInternalId(), index); - applyRecursive(properties, 0, state, bitSet, false); - } - } - public BlockMaskBuilder optimize() { if (!optimizedStates) { for (int i = 0; i < bitSets.length; i++) { @@ -667,4 +543,56 @@ public class BlockMaskBuilder { } + private static class FuzzyStateAllowingBuilder { + + private final BlockType type; + private final Map, List> masked = new HashMap<>(); + + private FuzzyStateAllowingBuilder(BlockType type) { + this.type = type; + } + + private BlockType getType() { + return this.type; + } + + private List> getMaskedProperties() { + return masked + .entrySet() + .stream() + .filter(e -> !e.getValue().isEmpty()) + .map(Map.Entry::getKey) + .collect(Collectors.toList()); + } + + private void allow(Property property, int index) { + checkNotNull(property); + if (!type.hasProperty(property.getKey())) { + throw new IllegalArgumentException(String.format( + "Property %s cannot be applied to block type %s", + property.getName(), + type.getId() + )); + } + masked.computeIfAbsent(property, k -> new ArrayList<>()).add(index); + } + + private boolean allows() { + //noinspection SimplifyStreamApiCallChains - Marginally faster like this + return !masked.isEmpty() && !masked.values().stream().anyMatch(List::isEmpty); + } + + private boolean allows(Property property) { + return !masked.containsKey(property); + } + + private boolean allows(Property property, int index) { + if (!masked.containsKey(property)) { + return true; + } + return masked.get(property).contains(index); + } + + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/FastBitSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/FastBitSet.java index 92754b669..fa7199d83 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/FastBitSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/FastBitSet.java @@ -69,6 +69,10 @@ public class FastBitSet { Arrays.fill(bits, -1L); } + public static void unsetAll(long[] bits) { + Arrays.fill(bits, 0); + } + public static void and(long[] bits, final long[] other) { final int end = Math.min(other.length, bits.length); for (int i = 0; i < end; ++i) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/FuzzyBlockState.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/FuzzyBlockState.java index ee4ab12ad..b32fee41f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/FuzzyBlockState.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/FuzzyBlockState.java @@ -182,7 +182,7 @@ public class FuzzyBlockState extends BlockState { checkNotNull(property); checkNotNull(value); checkNotNull(type, "The type must be set before the properties!"); - type.getProperty(property.getName()); // Verify the property is valid for this type + checkNotNull(type.getProperty(property.getName())); // Verify the property is valid for this type values.put(property, value); return this; } From 9f0a0dbd355bf5497744bfcf023f69c0c224cba7 Mon Sep 17 00:00:00 2001 From: Jordan Date: Thu, 22 Jun 2023 20:32:54 +0100 Subject: [PATCH 13/28] fix: ensure mask is initialised upon visiting a point in BreadthFirstSearch (#2314) fix: ensure mask is initialised upon visiting a point in BreadFirstSearch --- .../com/sk89q/worldedit/function/visitor/BreadthFirstSearch.java | 1 + 1 file changed, 1 insertion(+) 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 c1b36ef6b..7f3e5da63 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 @@ -229,6 +229,7 @@ public abstract class BreadthFirstSearch implements Operation { */ public void visit(BlockVector3 position) { if (!visited.contains(position)) { + isVisitable(position, position); // Ignore this, just to initialize mask on this point queue.add(position); visited.add(position); } From c0037aa0835a1b3a87eeff10e86345e39e343fba Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Fri, 23 Jun 2023 14:56:47 +0200 Subject: [PATCH 14/28] [ci skip] Remove unsupported versions from template --- .github/ISSUE_TEMPLATE/bug_report.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 22993216e..3b9cf1767 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -29,10 +29,6 @@ body: options: - '1.20' - '1.19.4' - - '1.19.3' - - '1.19.2' - - '1.19.1' - - '1.19' - '1.18.2' - '1.17.1' - '1.16.5' From 05d5ad161a00deb8d42fcd1776b95e0de06f30e4 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 23 Jun 2023 21:57:51 +0100 Subject: [PATCH 15/28] chore: add obnoxious error message if using p2 v7 with FAWE main branch --- .../java/com/fastasyncworldedit/bukkit/FaweBukkit.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java index e4f66dea3..34ed78be2 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java @@ -320,6 +320,15 @@ public class FaweBukkit implements IFawe, Listener { if (PlotSquared.get().getVersion().version[0] == 6) { WEManager.weManager().addManager(new com.fastasyncworldedit.bukkit.regions.plotsquared.PlotSquaredFeature()); LOGGER.info("Plugin 'PlotSquared' v6 found. Using it now."); + } else if (PlotSquared.get().getVersion().version[0] == 7) { + WEManager.weManager().addManager(new com.fastasyncworldedit.bukkit.regions.plotsquared.PlotSquaredFeature()); + LOGGER.error("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + LOGGER.error("!! !!"); + LOGGER.error("!! ERROR: PlotSquared v7 found. This FAWE version does not support PlotSquared V7 !!"); + LOGGER.error("!! Follow the instructions when notified of v7 release candidates the and use FAWE from !!"); + LOGGER.error("!! https://ci.athion.net/job/FastAsyncWorldEdit-Pull-Requests/view/change-requests/job/PR-2075/ !!"); + LOGGER.error("!! !!"); + LOGGER.error("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); } else { LOGGER.error("Incompatible version of PlotSquared found. Please use PlotSquared v6."); LOGGER.info("https://www.spigotmc.org/resources/77506/"); From 924805af8fc5b7d6a111b92ebdbadb6fdbc07958 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sun, 25 Jun 2023 13:52:13 +0100 Subject: [PATCH 16/28] fix: fix obnoxious error message if using p2 v7 with FAWE main branch --- .../src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java index 34ed78be2..c2c9923e7 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java @@ -325,7 +325,7 @@ public class FaweBukkit implements IFawe, Listener { LOGGER.error("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); LOGGER.error("!! !!"); LOGGER.error("!! ERROR: PlotSquared v7 found. This FAWE version does not support PlotSquared V7 !!"); - LOGGER.error("!! Follow the instructions when notified of v7 release candidates the and use FAWE from !!"); + LOGGER.error("!! Follow the instructions when notified of v7 release candidates and use FAWE from !!"); LOGGER.error("!! https://ci.athion.net/job/FastAsyncWorldEdit-Pull-Requests/view/change-requests/job/PR-2075/ !!"); LOGGER.error("!! !!"); LOGGER.error("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); From 97ee71bbd08dc93005a125f0723e562dcd41861f Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Tue, 27 Jun 2023 13:56:30 +0200 Subject: [PATCH 17/28] Update settings name in queue.target_size warning --- .../src/main/java/com/fastasyncworldedit/core/Fawe.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 8f4818f2f..eb7eaf8ce 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/Fawe.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/Fawe.java @@ -356,8 +356,8 @@ public class Fawe { ); if (Settings.settings().QUEUE.TARGET_SIZE < 4 * Settings.settings().QUEUE.PARALLEL_THREADS) { LOGGER.error( - "queue.target_size is {}, and queue.parallel_threads is {}. It is HIGHLY recommended that queue" + - ".target_size be at least four times queue.parallel_threads or greater.", + "queue.target-size is {}, and queue.parallel_threads is {}. It is HIGHLY recommended that queue" + + ".target-size be at least four times queue.parallel-threads or greater.", Settings.settings().QUEUE.TARGET_SIZE, Settings.settings().QUEUE.PARALLEL_THREADS ); From 476ba4ab418648ed6d5f3a91bba6f9c78d5dede2 Mon Sep 17 00:00:00 2001 From: Jordan Date: Tue, 27 Jun 2023 17:36:54 +0100 Subject: [PATCH 18/28] refactor: efficiency improvements to some editsession methods (#2304) --- .../java/com/sk89q/worldedit/EditSession.java | 273 +++++++++++------- 1 file changed, 172 insertions(+), 101 deletions(-) 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 1b405fe75..f8a08148b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -2161,10 +2161,12 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { final int ceilRadiusX = (int) Math.ceil(radiusX); final int ceilRadiusZ = (int) Math.ceil(radiusZ); - double xSqr; - double zSqr; - double distanceSq; + double xSqr, zSqr, distanceSq; + double xn, zn; + double dx2, dz2; double nextXn = 0; + double nextZn, nextMinZn; + int xx, x_x, zz, z_z, yy; if (thickness != 0) { double nextMinXn = 0; @@ -2172,19 +2174,18 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { final double minInvRadiusZ = 1 / (radiusZ - thickness); forX: for (int x = 0; x <= ceilRadiusX; ++x) { - final double xn = nextXn; - double dx2 = nextMinXn * nextMinXn; + xn = nextXn; + dx2 = nextMinXn * nextMinXn; nextXn = (x + 1) * invRadiusX; nextMinXn = (x + 1) * minInvRadiusX; - double nextZn = 0; - double nextMinZn = 0; + nextZn = 0; + nextMinZn = 0; xSqr = xn * xn; + xx = px + x; + x_x = px - x; forZ: for (int z = 0; z <= ceilRadiusZ; ++z) { - final double zn = nextZn; - double dz2 = nextMinZn * nextMinZn; - nextZn = (z + 1) * invRadiusZ; - nextMinZn = (z + 1) * minInvRadiusZ; + zn = nextZn; zSqr = zn * zn; distanceSq = xSqr + zSqr; if (distanceSq > 1) { @@ -2193,16 +2194,23 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { } break forZ; } + dz2 = nextMinZn * nextMinZn; + nextZn = (z + 1) * invRadiusZ; + nextMinZn = (z + 1) * minInvRadiusZ; if ((dz2 + nextMinXn * nextMinXn <= 1) && (nextMinZn * nextMinZn + dx2 <= 1)) { continue; } + zz = pz + z; + z_z = pz - z; + for (int y = 0; y < height; ++y) { - this.setBlock(mutableBlockVector3.setComponents(px + x, py + y, pz + z), block); - this.setBlock(mutableBlockVector3.setComponents(px - x, py + y, pz + z), block); - this.setBlock(mutableBlockVector3.setComponents(px + x, py + y, pz - z), block); - this.setBlock(mutableBlockVector3.setComponents(px - x, py + y, pz - z), block); + yy = py + y; + this.setBlock(xx, yy, zz, block); + this.setBlock(x_x, yy, zz, block); + this.setBlock(xx, yy, z_z, block); + this.setBlock(x_x, yy, z_z, block); } } } @@ -2210,14 +2218,17 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { //FAWE end forX: for (int x = 0; x <= ceilRadiusX; ++x) { - final double xn = nextXn; + xn = nextXn; nextXn = (x + 1) * invRadiusX; - double nextZn = 0; + nextZn = 0; xSqr = xn * xn; + // FAWE start + xx = px + x; + x_x = px - x; + //FAWE end forZ: for (int z = 0; z <= ceilRadiusZ; ++z) { - final double zn = nextZn; - nextZn = (z + 1) * invRadiusZ; + zn = nextZn; zSqr = zn * zn; distanceSq = xSqr + zSqr; if (distanceSq > 1) { @@ -2227,18 +2238,27 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { break forZ; } + // FAWE start + nextZn = (z + 1) * invRadiusZ; + //FAWE end if (!filled) { if ((zSqr + nextXn * nextXn <= 1) && (nextZn * nextZn + xSqr <= 1)) { continue; } } + //FAWE start + zz = pz + z; + z_z = pz - z; + //FAWE end + for (int y = 0; y < height; ++y) { - //FAWE start - mutable - this.setBlock(mutableBlockVector3.setComponents(px + x, py + y, pz + z), block); - this.setBlock(mutableBlockVector3.setComponents(px - x, py + y, pz + z), block); - this.setBlock(mutableBlockVector3.setComponents(px + x, py + y, pz - z), block); - this.setBlock(mutableBlockVector3.setComponents(px - x, py + y, pz - z), block); + //FAWE start + yy = py + y; + this.setBlock(xx, yy, zz, block); + this.setBlock(x_x, yy, zz, block); + this.setBlock(xx, yy, z_z, block); + this.setBlock(x_x, yy, z_z, block); //FAWE end } } @@ -2293,7 +2313,6 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { int px = pos.getBlockX(); int py = pos.getBlockY(); int pz = pos.getBlockZ(); - MutableBlockVector3 mutable = new MutableBlockVector3(); final int ceilRadiusX = (int) Math.ceil(radiusX); final int ceilRadiusY = (int) Math.ceil(radiusY); @@ -2301,31 +2320,43 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { double threshold = 0.5; + double dx, dy, dz, dxy, dxz, dyz, dxyz; + int xx, x_x, yy, y_y, zz, z_z; + double xnx, yny, znz; double nextXn = 0; - double dx; - double dy; - double dz; - double dxy; - double dxyz; + double nextYn, nextZn; + double nextXnSq, nextYnSq, nextZnSq; + double xn, yn, zn; forX: for (int x = 0; x <= ceilRadiusX; ++x) { - final double xn = nextXn; + xn = nextXn; dx = xn * xn; nextXn = (x + 1) * invRadiusX; - double nextYn = 0; + nextXnSq = nextXn * nextXn; + nextYn = 0; + xx = px + x; + x_x = px - x; + xnx = x * nx; forY: for (int y = 0; y <= ceilRadiusY; ++y) { - final double yn = nextYn; + yn = nextYn; dy = yn * yn; dxy = dx + dy; nextYn = (y + 1) * invRadiusY; - double nextZn = 0; + nextYnSq = nextYn * nextYn; + nextZn = 0; + yy = py + y; + y_y = py - y; + yny = y * ny; forZ: for (int z = 0; z <= ceilRadiusZ; ++z) { - final double zn = nextZn; + zn = nextZn; dz = zn * zn; dxyz = dxy + dz; + dxz = dx + dz; + dyz = dy + dz; nextZn = (z + 1) * invRadiusZ; + nextZnSq = nextZn * nextZn; if (dxyz > 1) { if (z == 0) { if (y == 0) { @@ -2336,34 +2367,37 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { break forZ; } if (!filled) { - if (nextXn * nextXn + dy + dz <= 1 && nextYn * nextYn + dx + dz <= 1 && nextZn * nextZn + dx + dy <= 1) { + if (nextXnSq + dyz <= 1 && nextYnSq + dxz <= 1 && nextZnSq + dxy <= 1) { continue; } } + zz = pz + z; + z_z = pz - z; + znz = z * nz; - if (Math.abs((x) * nx + (y) * ny + (z) * nz) < threshold) { - setBlock(mutable.setComponents(px + x, py + y, pz + z), block); + if (Math.abs(xnx + yny + znz) < threshold) { + setBlock(xx, yy, zz, block); } - if (Math.abs((-x) * nx + (y) * ny + (z) * nz) < threshold) { - setBlock(mutable.setComponents(px - x, py + y, pz + z), block); + if (Math.abs(-xnx + yny + znz) < threshold) { + setBlock(x_x, yy, zz, block); } - if (Math.abs((x) * nx + (-y) * ny + (z) * nz) < threshold) { - setBlock(mutable.setComponents(px + x, py - y, pz + z), block); + if (Math.abs(xnx - yny + znz) < threshold) { + setBlock(xx, y_y, zz, block); } - if (Math.abs((x) * nx + (y) * ny + (-z) * nz) < threshold) { - setBlock(mutable.setComponents(px + x, py + y, pz - z), block); + if (Math.abs(xnx + yny - znz) < threshold) { + setBlock(xx, yy, z_z, block); } - if (Math.abs((-x) * nx + (-y) * ny + (z) * nz) < threshold) { - setBlock(mutable.setComponents(px - x, py - y, pz + z), block); + if (Math.abs(-xnx - yny + znz) < threshold) { + setBlock(x_x, y_y, zz, block); } - if (Math.abs((x) * nx + (-y) * ny + (-z) * nz) < threshold) { - setBlock(mutable.setComponents(px + x, py - y, pz - z), block); + if (Math.abs(xnx - yny - znz) < threshold) { + setBlock(xx, y_y, z_z, block); } - if (Math.abs((-x) * nx + (y) * ny + (-z) * nz) < threshold) { - setBlock(mutable.setComponents(px - x, py + y, pz - z), block); + if (Math.abs(-xnx + yny - znz) < threshold) { + setBlock(x_x, yy, z_z, block); } - if (Math.abs((-x) * nx + (-y) * ny + (-z) * nz) < threshold) { - setBlock(mutable.setComponents(px - x, py - y, pz - z), block); + if (Math.abs(-xnx - yny - znz) < threshold) { + setBlock(x_x, y_y, z_z, block); } } } @@ -2418,29 +2452,38 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { final int ceilRadiusZ = (int) Math.ceil(radiusZ); //FAWE start - int yy; - //FAWE end - double nextXn = 0; + double nextYn, nextZn; + double nextXnSq, nextYnSq, nextZnSq; + double xn, yn, zn, dx, dy, dz; + double dxy, dxz, dyz, dxyz; + int xx, x_x, yy, zz, z_z; + forX: for (int x = 0; x <= ceilRadiusX; ++x) { - final double xn = nextXn; - double dx = xn * xn; + xn = nextXn; + dx = xn * xn; nextXn = (x + 1) * invRadiusX; - double nextZn = 0; + nextXnSq = nextXn * nextXn; + xx = px + x; + x_x = px - x; + nextZn = 0; forZ: for (int z = 0; z <= ceilRadiusZ; ++z) { - final double zn = nextZn; - double dz = zn * zn; - double dxz = dx + dz; + zn = nextZn; + dz = zn * zn; + dxz = dx + dz; nextZn = (z + 1) * invRadiusZ; - double nextYn = 0; + nextZnSq = nextZn * nextZn; + zz = pz + z; + z_z = pz - z; + nextYn = 0; forY: for (int y = 0; y <= ceilRadiusY; ++y) { - final double yn = nextYn; - double dy = yn * yn; - double dxyz = dxz + dy; + yn = nextYn; + dy = yn * yn; + dxyz = dxz + dy; nextYn = (y + 1) * invRadiusY; if (dxyz > 1) { @@ -2453,40 +2496,45 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { break forY; } + nextYnSq = nextYn * nextYn; + dxy = dx + dy; + dyz = dy + dz; + if (!filled) { - if (nextXn * nextXn + dy + dz <= 1 && nextYn * nextYn + dx + dz <= 1 && nextZn * nextZn + dx + dy <= 1) { + if (nextXnSq + dyz <= 1 && nextYnSq + dxz <= 1 && nextZnSq + dxy <= 1) { continue; } } //FAWE start yy = py + y; if (yy <= maxY) { - this.setBlock(px + x, py + y, pz + z, block); + this.setBlock(xx, yy, zz, block); if (x != 0) { - this.setBlock(px - x, py + y, pz + z, block); + this.setBlock(x_x, yy, zz, block); } if (z != 0) { - this.setBlock(px + x, py + y, pz - z, block); + this.setBlock(xx, yy, z_z, block); if (x != 0) { - this.setBlock(px - x, py + y, pz - z, block); + this.setBlock(x_x, yy, z_z, block); } } } if (y != 0 && (yy = py - y) >= minY) { - this.setBlock(px + x, yy, pz + z, block); + this.setBlock(xx, yy, zz, block); if (x != 0) { - this.setBlock(px - x, yy, pz + z, block); + this.setBlock(x_x, yy, zz, block); } if (z != 0) { - this.setBlock(px + x, yy, pz - z, block); + this.setBlock(xx, yy, z_z, block); if (x != 0) { - this.setBlock(px - x, yy, pz - z, block); + this.setBlock(x_x, yy, z_z, block); } } } } } } + //FAWE end return changes; //FAWE end @@ -2509,17 +2557,22 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { int bz = position.getZ(); int height = size; + int yy, xx, x_x, zz, z_z; for (int y = 0; y <= height; ++y) { size--; + yy = y + by; for (int x = 0; x <= size; ++x) { + xx = bx + x; + x_x = bx - x; for (int z = 0; z <= size; ++z) { - + zz = bz + z; + z_z = bz - z; if ((filled && z <= size && x <= size) || z == size || x == size) { - setBlock(x + bx, y + by, z + bz, block); - setBlock(-x + bx, y + by, z + bz, block); - setBlock(x + bx, y + by, -z + bz, block); - setBlock(-x + bx, y + by, -z + bz, block); + setBlock(xx, yy, zz, block); + setBlock(x_x, yy, zz, block); + setBlock(xx, yy, z_z, block); + setBlock(x_x, yy, z_z, block); } } } @@ -3774,19 +3827,28 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { int radiusSqr = (int) (size * size); int sizeInt = (int) size * 2; + int xx, yy, zz; + double distance; + double noise; + if (sphericity == 1) { + double nx, ny, nz; + double d1, d2; for (int x = -sizeInt; x <= sizeInt; x++) { - double nx = seedX + x * distort; - double d1 = x * x * modX; + nx = seedX + x * distort; + d1 = x * x * modX; + xx = px + x; for (int y = -sizeInt; y <= sizeInt; y++) { - double d2 = d1 + y * y * modY; - double ny = seedY + y * distort; + d2 = d1 + y * y * modY; + ny = seedY + y * distort; + yy = py + y; for (int z = -sizeInt; z <= sizeInt; z++) { - double nz = seedZ + z * distort; - double distance = d2 + z * z * modZ; - double noise = amplitude * SimplexNoise.noise(nx, ny, nz); + nz = seedZ + z * distort; + distance = d2 + z * z * modZ; + zz = pz + z; + noise = amplitude * SimplexNoise.noise(nx, ny, nz); if (distance + distance * noise < radiusSqr) { - setBlock(px + x, py + y, pz + z, pattern); + setBlock(xx, yy, zz, pattern); } } } @@ -3803,39 +3865,48 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { MutableVector3 mutable = new MutableVector3(); double roughness = 1 - sphericity; + int x; + int y; + int z; + double xScaled; + double yScaled; + double zScaled; + double manDist; + double distSqr; for (int xr = -sizeInt; xr <= sizeInt; xr++) { + xx = px + xr; for (int yr = -sizeInt; yr <= sizeInt; yr++) { + yy = py + yr; for (int zr = -sizeInt; zr <= sizeInt; zr++) { + zz = pz + zr; // pt == mutable as it's a MutableVector3 // so it must be set each time - mutable.mutX(xr); - mutable.mutY(yr); - mutable.mutZ(zr); + mutable.setComponents(xr, yr, zr); Vector3 pt = transform.apply(mutable); - int x = MathMan.roundInt(pt.getX()); - int y = MathMan.roundInt(pt.getY()); - int z = MathMan.roundInt(pt.getZ()); + x = MathMan.roundInt(pt.getX()); + y = MathMan.roundInt(pt.getY()); + z = MathMan.roundInt(pt.getZ()); - double xScaled = Math.abs(x) * modX; - double yScaled = Math.abs(y) * modY; - double zScaled = Math.abs(z) * modZ; - double manDist = xScaled + yScaled + zScaled; - double distSqr = x * x * modX + z * z * modZ + y * y * modY; + xScaled = Math.abs(x) * modX; + yScaled = Math.abs(y) * modY; + zScaled = Math.abs(z) * modZ; + manDist = xScaled + yScaled + zScaled; + distSqr = x * x * modX + z * z * modZ + y * y * modY; - double distance = Math.sqrt(distSqr) * sphericity + MathMan.max( + distance = Math.sqrt(distSqr) * sphericity + MathMan.max( manDist, xScaled * manScaleX, yScaled * manScaleY, zScaled * manScaleZ ) * roughness; - double noise = amplitude * SimplexNoise.noise( + noise = amplitude * SimplexNoise.noise( seedX + x * distort, seedZ + z * distort, seedZ + z * distort ); if (distance + distance * noise < r) { - setBlock(px + xr, py + yr, pz + zr, pattern); + setBlock(xx, yy, zz, pattern); } } } From 0554b31f1195c7561564ef066058ecf2f6d73e80 Mon Sep 17 00:00:00 2001 From: Jordan Date: Tue, 27 Jun 2023 17:37:09 +0100 Subject: [PATCH 19/28] feat: implement removal of entities if they would be in a block after the edit (#2311) - Includes some refactoring to EditSessionBuilder to prevent doubling-up of processors that are also extents - Better ordering of the EditSessionBuilder process/extent code to match where extents actually end up in the stack - Fixes #1941 --- .../core/configuration/Settings.java | 7 +- .../EntityInBlockRemovingProcessor.java | 57 ++++++++++++ .../core/extent/processor/ProcessorScope.java | 3 +- .../sk89q/worldedit/EditSessionBuilder.java | 88 +++++++++++-------- .../function/entity/ExtentEntityCopy.java | 12 +-- 5 files changed, 115 insertions(+), 52 deletions(-) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/EntityInBlockRemovingProcessor.java 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 90ed792fa..a8d28d048 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 @@ -622,10 +622,11 @@ public class Settings extends Config { public boolean PERSISTENT_BRUSHES = true; @Comment({ - "[SAFE] Keep entities that are positioned in non-air blocks when editing an area", - "Might cause client-side FPS lag in some situations" + "[SAFE] Keep entities that are positioned in non-air blocks when editing an area (default: true)", + " - Might cause client-side FPS lag in some situations", + " - Requires fast-placement to be true" }) - public boolean KEEP_ENTITIES_IN_BLOCKS = false; + public boolean KEEP_ENTITIES_IN_BLOCKS = true; @Comment({ "[SAFE] Attempt to remove entities from the world if they were not present in the expected chunk (default: 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 new file mode 100644 index 000000000..0a8839409 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/EntityInBlockRemovingProcessor.java @@ -0,0 +1,57 @@ +package com.fastasyncworldedit.core.extent.processor; + +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.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.world.block.BlockTypes; +import org.jetbrains.annotations.Nullable; + +/** + * Processor that removes existing entities that would not be in air after the edit + * + * @since TODO + */ +public class EntityInBlockRemovingProcessor implements IBatchProcessor { + + @Override + public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { + for (CompoundTag tag : get.getEntities()) { + // Empty tags for seemingly non-existent entities can exist? + if (tag.getList("Pos").size() == 0) { + continue; + } + BlockVector3 pos = tag.getEntityPosition().toBlockPoint(); + int x = pos.getX() & 15; + int y = pos.getY(); + int z = pos.getZ() & 15; + if (!set.hasSection(y >> 4)) { + continue; + } + if (set.getBlock(x, y, z).getBlockType() != BlockTypes.__RESERVED__ && !set + .getBlock(x, y, z) + .getBlockType() + .getMaterial() + .isAir()) { + set.removeEntity(tag.getUUID()); + } + } + return set; + } + + @Nullable + @Override + public Extent construct(final Extent child) { + throw new UnsupportedOperationException("Processing only"); + } + + @Override + public ProcessorScope getScope() { + // After block removal but before history + return ProcessorScope.CUSTOM; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/ProcessorScope.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/ProcessorScope.java index e3f09e0a3..503351fb7 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/ProcessorScope.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/ProcessorScope.java @@ -7,7 +7,8 @@ package com.fastasyncworldedit.core.extent.processor; * - CHANGING_BLOCKS (processors that may ADD or CHANGE blocks being set) * - REMOVING_BLOCKS (processors that may ADD, CHANGE or REMOVE blocks being set) * - CUSTOM (processors that do not specify a SCOPE) - * - READING_SET_BLOCKS (processors that do not alter blocks at all, and read the blocks that are actually going to set, e.g. history processors) + * - READING_SET_BLOCKS (processors that do not alter blocks at all, and read the blocks that are actually going to set, e.g. + * history processors). There is no guarantee that changes made here will be stored in history. */ public enum ProcessorScope { ADDING_BLOCKS(0), 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 ea27f03b5..e5c53a45b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSessionBuilder.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSessionBuilder.java @@ -32,6 +32,7 @@ import com.fastasyncworldedit.core.extent.NullExtent; import com.fastasyncworldedit.core.extent.SingleRegionExtent; import com.fastasyncworldedit.core.extent.SlowExtent; import com.fastasyncworldedit.core.extent.StripNBTExtent; +import com.fastasyncworldedit.core.extent.processor.EntityInBlockRemovingProcessor; import com.fastasyncworldedit.core.extent.processor.heightmap.HeightmapProcessor; import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter; import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode; @@ -543,25 +544,6 @@ public final class EditSessionBuilder { } } } - FaweRegionExtent regionExtent = null; - if (disallowedRegions != null) { // Always use MultiRegionExtent if we have blacklist regions - regionExtent = new MultiRegionExtent(this.extent, this.limit, allowedRegions, disallowedRegions); - } else if (allowedRegions == null) { - allowedRegions = new Region[]{RegionWrapper.GLOBAL()}; - } else { - if (allowedRegions.length == 0) { - regionExtent = new NullExtent(this.extent, FaweCache.NO_REGION); - } else { - if (allowedRegions.length == 1) { - regionExtent = new SingleRegionExtent(this.extent, this.limit, allowedRegions[0]); - } else { - regionExtent = new MultiRegionExtent(this.extent, this.limit, allowedRegions, null); - } - } - } - if (placeChunks && regionExtent != null) { - queue.addProcessor(regionExtent); - } // There's no need to do the below (and it'll also just be a pain to implement) if we're not placing chunks if (placeChunks) { if (((relightMode != null && relightMode != RelightMode.NONE) || (relightMode == null && Settings.settings().LIGHTING.MODE > 0))) { @@ -571,6 +553,11 @@ public final class EditSessionBuilder { queue.addProcessor(new RelightProcessor(relighter)); } queue.addProcessor(new HeightmapProcessor(world.getMinY(), world.getMaxY())); + + if (!Settings.settings().EXPERIMENTAL.KEEP_ENTITIES_IN_BLOCKS) { + queue.addProcessor(new EntityInBlockRemovingProcessor()); + } + IBatchProcessor platformProcessor = WorldEdit .getInstance() .getPlatformManager() @@ -590,24 +577,13 @@ public final class EditSessionBuilder { } else { relighter = NullRelighter.INSTANCE; } - Consumer onErrorMessage; - if (getActor() != null) { - onErrorMessage = c -> getActor().print(Caption.of("fawe.error.occurred-continuing", c)); - } else { - onErrorMessage = c -> { - }; - } - if (limit != null && !limit.isUnlimited() && regionExtent != null) { - this.extent = new LimitExtent(regionExtent, limit, onErrorMessage); - } else if (limit != null && !limit.isUnlimited()) { - this.extent = new LimitExtent(this.extent, limit, onErrorMessage); - } else if (regionExtent != null) { - this.extent = regionExtent; - } if (this.limit != null && this.limit.STRIP_NBT != null && !this.limit.STRIP_NBT.isEmpty()) { - this.extent = new StripNBTExtent(this.extent, this.limit.STRIP_NBT); + StripNBTExtent ext = new StripNBTExtent(this.extent, this.limit.STRIP_NBT); if (placeChunks) { - queue.addProcessor((IBatchProcessor) this.extent); + queue.addProcessor(ext); + } + if (!placeChunks || !combineStages) { + this.extent = ext; } } if (this.limit != null && !this.limit.isUnlimited()) { @@ -620,12 +596,50 @@ public final class EditSessionBuilder { } Set> remaps = this.limit.REMAP_PROPERTIES; if (!limitBlocks.isEmpty() || (remaps != null && !remaps.isEmpty())) { - this.extent = new DisallowedBlocksExtent(this.extent, limitBlocks, remaps); + DisallowedBlocksExtent ext = new DisallowedBlocksExtent(this.extent, limitBlocks, remaps); if (placeChunks) { - queue.addProcessor((IBatchProcessor) this.extent); + queue.addProcessor(ext); + } + if (!placeChunks || !combineStages) { + this.extent = ext; } } } + + FaweRegionExtent regionExtent = null; + if (disallowedRegions != null) { // Always use MultiRegionExtent if we have blacklist regions + regionExtent = new MultiRegionExtent(this.extent, this.limit, allowedRegions, disallowedRegions); + } else if (allowedRegions == null) { + allowedRegions = new Region[]{RegionWrapper.GLOBAL()}; + } else { + if (allowedRegions.length == 0) { + regionExtent = new NullExtent(this.extent, FaweCache.NO_REGION); + } else { + if (allowedRegions.length == 1) { + regionExtent = new SingleRegionExtent(this.extent, this.limit, allowedRegions[0]); + } else { + regionExtent = new MultiRegionExtent(this.extent, this.limit, allowedRegions, null); + } + } + } + if (regionExtent != null) { + if (placeChunks) { + queue.addProcessor(regionExtent); + } + if (!placeChunks || !combineStages) { + this.extent = regionExtent; + } + } + Consumer onErrorMessage; + if (getActor() != null) { + onErrorMessage = c -> getActor().print(Caption.of("fawe.error.occurred-continuing", c)); + } else { + onErrorMessage = c -> { + }; + } + if (limit != null && !limit.isUnlimited()) { + this.extent = new LimitExtent(this.extent, limit, onErrorMessage); + } this.extent = wrapExtent(this.extent, eventBus, event, EditSession.Stage.BEFORE_HISTORY); } return this; 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 88f151e28..7a034d7bd 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 @@ -160,17 +160,7 @@ public class ExtentEntityCopy implements EntityFunction { // Remove if (isRemoving() && success) { //FAWE start - UUID uuid = null; - if (tag.containsKey("UUID")) { - int[] arr = tag.getIntArray("UUID"); - uuid = new UUID((long) arr[0] << 32 | (arr[1] & 0xFFFFFFFFL), (long) arr[2] << 32 | (arr[3] & 0xFFFFFFFFL)); - } else if (tag.containsKey("UUIDMost")) { - uuid = new UUID(tag.getLong("UUIDMost"), tag.getLong("UUIDLeast")); - } else if (tag.containsKey("WorldUUIDMost")) { - uuid = new UUID(tag.getLong("WorldUUIDMost"), tag.getLong("WorldUUIDLeast")); - } else if (tag.containsKey("PersistentIDMSB")) { - uuid = new UUID(tag.getLong("PersistentIDMSB"), tag.getLong("PersistentIDLSB")); - } + UUID uuid = entity.getState().getNbtData().getUUID(); if (uuid != null) { if (source != null) { source.removeEntity( From 24325d91ba6a5b75ef730fc15695664444169eb0 Mon Sep 17 00:00:00 2001 From: Jordan Date: Wed, 28 Jun 2023 09:24:20 +0100 Subject: [PATCH 20/28] feat: improve (region) fawe mask handling (#2312) * feat: improve fawe mask handling - Actually cache masks, even if the player has left the region - Fix P2 isValid test for single plots - Fixes #1946 * Fix incorrect delegated method --- .../fastasyncworldedit/bukkit/FaweBukkit.java | 2 +- .../regions/GriefPreventionFeature.java | 3 - .../bukkit/regions/ResidenceFeature.java | 8 +- .../plotsquared/PlotSquaredFeature.java | 75 ++++++++++++------- .../core/regions/FaweMask.java | 20 +++++ .../core/regions/FaweMaskManager.java | 10 ++- .../core/util/WEManager.java | 68 ++++++++--------- 7 files changed, 112 insertions(+), 74 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java index c2c9923e7..46bf125c5 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java @@ -225,7 +225,7 @@ public class FaweBukkit implements IFawe, Listener { final Plugin residencePlugin = Bukkit.getServer().getPluginManager().getPlugin("Residence"); if (residencePlugin != null && residencePlugin.isEnabled()) { try { - managers.add(new ResidenceFeature(residencePlugin, this)); + managers.add(new ResidenceFeature(residencePlugin)); LOGGER.info("Attempting to use plugin 'Residence'"); } catch (Throwable ignored) { } diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/GriefPreventionFeature.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/GriefPreventionFeature.java index e7fd9ad3a..9f302d057 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/GriefPreventionFeature.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/GriefPreventionFeature.java @@ -2,10 +2,7 @@ package com.fastasyncworldedit.bukkit.regions; import com.fastasyncworldedit.core.regions.FaweMask; import com.fastasyncworldedit.core.util.TaskManager; -import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.BukkitWorld; -import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/ResidenceFeature.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/ResidenceFeature.java index d72769176..a7c13cef5 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/ResidenceFeature.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/ResidenceFeature.java @@ -3,7 +3,6 @@ package com.fastasyncworldedit.bukkit.regions; import com.bekvon.bukkit.residence.Residence; import com.bekvon.bukkit.residence.protection.ClaimedResidence; import com.bekvon.bukkit.residence.protection.CuboidArea; -import com.fastasyncworldedit.bukkit.FaweBukkit; import com.fastasyncworldedit.core.regions.FaweMask; import com.fastasyncworldedit.core.util.TaskManager; import com.sk89q.worldedit.bukkit.BukkitAdapter; @@ -19,13 +18,8 @@ public class ResidenceFeature extends BukkitMaskManager implements Listener { private static final Logger LOGGER = LogManagerCompat.getLogger(); - private final FaweBukkit plugin; - private final Plugin residence; - - public ResidenceFeature(final Plugin residencePlugin, final FaweBukkit p3) { + public ResidenceFeature(final Plugin residencePlugin) { super(residencePlugin.getName()); - this.residence = residencePlugin; - this.plugin = p3; LOGGER.info("Plugin 'Residence' found. Using it now."); } 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 cd6f5ae22..46ba12f68 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 @@ -67,28 +67,32 @@ public class PlotSquaredFeature extends FaweMaskManager { * @param plot the {@link Plot} * @param type the {@link MaskType} * @return {@code true} if the player is the plot owner, trusted, has the permission fawe.plotsquared.member - * or fawe.plotsquared.admin and the NoWorldeditFlag is not set; otherwise {@code false} + * or fawe.plotsquared.admin and the NoWorldeditFlag is not set; otherwise {@code false} */ - public boolean isAllowed(Player player, Plot plot, MaskType type) { + public boolean isAllowed(Player player, Plot plot, MaskType type, boolean notify) { if (plot == null) { return false; } UUID uid = player.getUniqueId(); if (plot.getFlag(NoWorldeditFlag.class)) { - player.print(Caption.of( - "fawe.cancel.reason.no.region.reason", - Caption.of("fawe.cancel.reason.no.region.plot.noworldeditflag") - )); + if (notify) { + player.print(Caption.of( + "fawe.cancel.reason.no.region.reason", + Caption.of("fawe.cancel.reason.no.region.plot.noworldeditflag") + )); + } return false; } if (plot.isOwner(uid) || player.hasPermission("fawe.plotsquared.admin")) { return true; } if (type != MaskType.MEMBER) { - player.print(Caption.of( - "fawe.cancel.reason.no.region.reason", - Caption.of("fawe.cancel.reason.no.region.plot.owner.only") - )); + if (notify) { + player.print(Caption.of( + "fawe.cancel.reason.no.region.reason", + Caption.of("fawe.cancel.reason.no.region.plot.owner.only") + )); + } return false; } if (plot.getTrusted().contains(uid) || plot.getTrusted().contains(DBFunc.EVERYONE)) { @@ -96,26 +100,32 @@ public class PlotSquaredFeature extends FaweMaskManager { } if (plot.getMembers().contains(uid) || plot.getMembers().contains(DBFunc.EVERYONE)) { if (!player.hasPermission("fawe.plotsquared.member")) { - player.print(Caption.of( - "fawe.cancel.reason.no.region.reason", - Caption.of("fawe.error.no-perm", "fawe.plotsquared.member") - )); + if (notify) { + player.print(Caption.of( + "fawe.cancel.reason.no.region.reason", + Caption.of("fawe.error.no-perm", "fawe.plotsquared.member") + )); + } return false; } if (!plot.getOwners().isEmpty() && plot.getOwners().stream().anyMatch(this::playerOnline)) { return true; } else { - player.print(Caption.of( - "fawe.cancel.reason.no.region.reason", - Caption.of("fawe.cancel.reason.no.region.plot.owner.offline") - )); + if (notify) { + player.print(Caption.of( + "fawe.cancel.reason.no.region.reason", + Caption.of("fawe.cancel.reason.no.region.plot.owner.offline") + )); + } return false; } } - player.print(Caption.of( - "fawe.cancel.reason.no.region.reason", - Caption.of("fawe.cancel.reason.no.region.not.added") - )); + if (notify) { + player.print(Caption.of( + "fawe.cancel.reason.no.region.reason", + Caption.of("fawe.cancel.reason.no.region.not.added") + )); + } return false; } @@ -128,14 +138,19 @@ public class PlotSquaredFeature extends FaweMaskManager { } @Override - public FaweMask getMask(Player player, MaskType type, boolean isWhitelist) { + public FaweMask getMask(final Player player, final MaskType type, final boolean isWhitelist) { + return getMask(player, type, isWhitelist, true); + } + + @Override + public FaweMask getMask(Player player, MaskType type, boolean isWhitelist, boolean notify) { final PlotPlayer pp = PlotPlayer.from(BukkitAdapter.adapt(player)); if (pp == null) { return null; } final Set regions; Plot plot = pp.getCurrentPlot(); - if (isAllowed(player, plot, type)) { + if (isAllowed(player, plot, type, notify)) { regions = plot.getRegions(); } else { plot = null; @@ -184,19 +199,23 @@ public class PlotSquaredFeature extends FaweMaskManager { private final Plot plot; private final WeakReference> connectedPlots; + private final boolean singlePlot; private PlotSquaredMask(Region region, Plot plot) { super(region); this.plot = plot; - connectedPlots = new WeakReference<>(plot.getConnectedPlots()); + Set connected = plot.getConnectedPlots(); + connectedPlots = new WeakReference<>(connected); + singlePlot = connected.size() == 1; } @Override - public boolean isValid(Player player, MaskType type) { - if (!connectedPlots.refersTo(plot.getConnectedPlots()) || (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot))) { + public boolean isValid(Player player, MaskType type, boolean notify) { + if ((!connectedPlots.refersTo(plot.getConnectedPlots()) && !singlePlot) || (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone( + plot))) { return false; } - return isAllowed(player, plot, type); + return isAllowed(player, plot, type, notify); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMask.java index 907769f51..4ea8c2c06 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMask.java @@ -17,10 +17,30 @@ public class FaweMask implements IDelegateRegion { return region; } + /** + * Test if the mask is still valid + * + * @param player player to test + * @param type type of mask + * @return if still valid + */ public boolean isValid(Player player, FaweMaskManager.MaskType type) { return false; } + /** + * Test if the mask is still valid + * + * @param player player to test + * @param type type of mask + * @param notify if the player should be notified + * @return if still valid + * @since TODO + */ + public boolean isValid(Player player, FaweMaskManager.MaskType type, boolean notify) { + return isValid(player, type); + } + @Override public Region clone() { throw new UnsupportedOperationException("Clone not supported"); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMaskManager.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMaskManager.java index 60c6e6be9..c52cc17e7 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMaskManager.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/FaweMaskManager.java @@ -1,7 +1,6 @@ package com.fastasyncworldedit.core.regions; import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.regions.filter.RegionFilter; import com.sk89q.worldedit.entity.Player; import java.util.Locale; @@ -28,6 +27,15 @@ public abstract class FaweMaskManager { */ public abstract FaweMask getMask(final Player player, MaskType type, boolean isWhitelist); + /** + * Get a {@link FaweMask} for the given player and {@link MaskType}. If isWhitelist is false, will return a "blacklist" mask. + * + * @since TODO + */ + public FaweMask getMask(final Player player, MaskType type, boolean isWhitelist, boolean notify) { + return getMask(player, type, isWhitelist); + } + public boolean isExclusive() { return Settings.settings().REGION_RESTRICTIONS_OPTIONS.EXCLUSIVE_MANAGERS.contains(this.key); } 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 439b486e3..17b7882f2 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 @@ -108,27 +108,22 @@ public class WEManager { } player.setMeta("lastMaskWorld", world); Set masks = player.getMeta("lastMask"); - Set backupRegions = new HashSet<>(); Set regions = new HashSet<>(); - if (masks == null || !isWhitelist) { masks = new HashSet<>(); } else { synchronized (masks) { boolean removed = false; + boolean inMask = false; if (!masks.isEmpty()) { Iterator iterator = masks.iterator(); while (iterator.hasNext()) { FaweMask mask = iterator.next(); - if (mask.isValid(player, type)) { + if (mask.isValid(player, type, false)) { Region region = mask.getRegion(); - if (region.contains(loc.toBlockPoint())) { - regions.add(region); - } else { - removed = true; - backupRegions.add(region); - } + inMask |= region.contains(loc.toBlockPoint()); + regions.add(region); } else { if (Settings.settings().ENABLED_COMPONENTS.DEBUG) { player.printDebug(Caption.of("fawe.error.region-mask-invalid", mask.getClass().getSimpleName())); @@ -138,39 +133,44 @@ public class WEManager { } } } - if (!removed) { + if (!removed && inMask) { return regions.toArray(new Region[0]); } - masks.clear(); } } - for (FaweMaskManager manager : managers) { - if (player.hasPermission("fawe." + manager.getKey())) { - try { - if (manager.isExclusive() && !masks.isEmpty()) { - continue; - } - final FaweMask mask = manager.getMask(player, FaweMaskManager.MaskType.getDefaultMaskType(), isWhitelist); - if (mask != null) { - regions.add(mask.getRegion()); - masks.add(mask); - if (manager.isExclusive()) { - break; + synchronized (masks) { + for (FaweMaskManager manager : managers) { + if (player.hasPermission("fawe." + manager.getKey())) { + try { + if (manager.isExclusive() && !masks.isEmpty()) { + continue; } + final FaweMask mask = manager.getMask( + player, + FaweMaskManager.MaskType.getDefaultMaskType(), + isWhitelist, + masks.isEmpty() + ); + if (mask != null) { + regions.add(mask.getRegion()); + masks.add(mask); + if (manager.isExclusive()) { + break; + } + } + } catch (Throwable e) { + e.printStackTrace(); } - } catch (Throwable e) { - e.printStackTrace(); + } else { + player.printError(TextComponent.of("Missing permission " + "fawe." + manager.getKey())); } - } else { - player.printError(TextComponent.of("Missing permission " + "fawe." + manager.getKey())); } - } - if (isWhitelist) { - regions.addAll(backupRegions); - if (!masks.isEmpty()) { - player.setMeta("lastMask", masks); - } else { - player.deleteMeta("lastMask"); + if (isWhitelist) { + if (!masks.isEmpty()) { + player.setMeta("lastMask", masks); + } else { + player.deleteMeta("lastMask"); + } } } return regions.toArray(new Region[0]); From 770bb0087a46c1c0fdc8743b8ce61bce1cb2ab50 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Thu, 29 Jun 2023 12:23:26 +0200 Subject: [PATCH 21/28] Drop support for minor 1.19 versions (#2316) * Drop support for minor 1.19 versions * More work --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + build.gradle.kts | 4 +- buildSrc/src/main/kotlin/CommonJavaConfig.kt | 2 +- settings.gradle.kts | 2 +- .../adapters/adapter-1_19/build.gradle.kts | 16 - .../ext/fawe/v1_19_R1/PaperweightAdapter.java | 1009 ------ .../v1_19_R1/PaperweightDataConverters.java | 2955 ----------------- .../fawe/v1_19_R1/PaperweightFakePlayer.java | 99 - .../PaperweightWorldNativeAccess.java | 210 -- .../v1_19_R1/PaperweightBlockMaterial.java | 189 -- .../fawe/v1_19_R1/PaperweightFaweAdapter.java | 701 ---- .../PaperweightFaweWorldNativeAccess.java | 286 -- .../fawe/v1_19_R1/PaperweightGetBlocks.java | 1164 ------- .../v1_19_R1/PaperweightGetBlocks_Copy.java | 248 -- .../v1_19_R1/PaperweightMapChunkUtil.java | 35 - .../v1_19_R1/PaperweightPlatformAdapter.java | 703 ---- .../v1_19_R1/PaperweightPostProcessor.java | 175 - .../PaperweightStarlightRelighter.java | 205 -- .../PaperweightStarlightRelighterFactory.java | 28 - .../nbt/PaperweightLazyCompoundTag.java | 161 - .../fawe/v1_19_R1/regen/PaperweightRegen.java | 564 ---- .../adapters/adapter-1_19_3/build.gradle.kts | 17 - .../ext/fawe/v1_19_R2/PaperweightAdapter.java | 1029 ------ .../v1_19_R2/PaperweightDataConverters.java | 2800 ---------------- .../fawe/v1_19_R2/PaperweightFakePlayer.java | 93 - .../PaperweightWorldNativeAccess.java | 180 - .../v1_19_R2/PaperweightBlockMaterial.java | 189 -- .../fawe/v1_19_R2/PaperweightFaweAdapter.java | 706 ---- .../PaperweightFaweWorldNativeAccess.java | 286 -- .../fawe/v1_19_R2/PaperweightGetBlocks.java | 1166 ------- .../v1_19_R2/PaperweightGetBlocks_Copy.java | 248 -- .../v1_19_R2/PaperweightMapChunkUtil.java | 34 - .../v1_19_R2/PaperweightPlatformAdapter.java | 700 ---- .../v1_19_R2/PaperweightPostProcessor.java | 175 - .../PaperweightStarlightRelighter.java | 205 -- .../PaperweightStarlightRelighterFactory.java | 28 - .../nbt/PaperweightLazyCompoundTag.java | 161 - .../fawe/v1_19_R2/regen/PaperweightRegen.java | 594 ---- .../adapters/adapter-1_20/build.gradle.kts | 2 +- worldedit-bukkit/build.gradle.kts | 2 +- 40 files changed, 7 insertions(+), 17365 deletions(-) delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/build.gradle.kts delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightDataConverters.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightFakePlayer.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightWorldNativeAccess.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightBlockMaterial.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightFaweAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightFaweWorldNativeAccess.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks_Copy.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightMapChunkUtil.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPlatformAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPostProcessor.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightStarlightRelighter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightStarlightRelighterFactory.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/nbt/PaperweightLazyCompoundTag.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/regen/PaperweightRegen.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/build.gradle.kts delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightDataConverters.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightFakePlayer.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightWorldNativeAccess.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightBlockMaterial.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightFaweAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightFaweWorldNativeAccess.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightGetBlocks.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightGetBlocks_Copy.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightMapChunkUtil.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightPlatformAdapter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightPostProcessor.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightStarlightRelighter.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightStarlightRelighterFactory.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/nbt/PaperweightLazyCompoundTag.java delete mode 100644 worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/regen/PaperweightRegen.java diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 3b9cf1767..83d9f52d8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -27,6 +27,7 @@ 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.1' - '1.20' - '1.19.4' - '1.18.2' diff --git a/build.gradle.kts b/build.gradle.kts index f1d4bb80e..642d6d09b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -83,7 +83,7 @@ allprojects { } applyCommonConfiguration() -val supportedVersions = listOf("1.16.5", "1.17", "1.17.1", "1.18.2", "1.19", "1.19.1", "1.19.2", "1.19.3", "1.19.4", "1.20") +val supportedVersions = listOf("1.16.5", "1.17.1", "1.18.2", "1.19.4", "1.20", "1.20.1") tasks { supportedVersions.forEach { @@ -97,7 +97,7 @@ tasks { } } runServer { - minecraftVersion("1.19.3") + minecraftVersion("1.20.1") pluginJars(*project(":worldedit-bukkit").getTasksByName("shadowJar", false).map { (it as Jar).archiveFile } .toTypedArray()) diff --git a/buildSrc/src/main/kotlin/CommonJavaConfig.kt b/buildSrc/src/main/kotlin/CommonJavaConfig.kt index 06a587525..8542fe252 100644 --- a/buildSrc/src/main/kotlin/CommonJavaConfig.kt +++ b/buildSrc/src/main/kotlin/CommonJavaConfig.kt @@ -64,7 +64,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean "https://www.antlr.org/api/Java/", "https://docs.enginehub.org/javadoc/org.enginehub.piston/core/0.5.7/", "https://docs.enginehub.org/javadoc/org.enginehub.piston/default-impl/0.5.7/", - "https://jd.papermc.io/paper/1.19/", + "https://jd.papermc.io/paper/1.20/", "https://intellectualsites.github.io/fastasyncworldedit-javadocs/worldedit-core/" ) docTitle = "${rootProject.name}-${project.description}" + " " + "${rootProject.version}" diff --git a/settings.gradle.kts b/settings.gradle.kts index 8e8ebe625..05439cd10 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,7 +2,7 @@ rootProject.name = "FastAsyncWorldEdit" include("worldedit-libs") -listOf("legacy", "1_17_1", "1_18_2", "1_19", "1_19_3","1_19_4", "1_20").forEach { +listOf("legacy", "1_17_1", "1_18_2", "1_19_4", "1_20").forEach { include("worldedit-bukkit:adapters:adapter-$it") } diff --git a/worldedit-bukkit/adapters/adapter-1_19/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_19/build.gradle.kts deleted file mode 100644 index cfb2cfe03..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/build.gradle.kts +++ /dev/null @@ -1,16 +0,0 @@ -import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension - -plugins { - java -} - -applyPaperweightAdapterConfiguration() - -repositories { - gradlePluginPortal() -} - -dependencies { - the().paperDevBundle("1.19.2-R0.1-20221206.184705-189") - compileOnly("io.papermc:paperlib") -} diff --git a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightAdapter.java deleted file mode 100644 index 1e8ed0c56..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightAdapter.java +++ /dev/null @@ -1,1009 +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_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.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.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_19_R1.PaperweightFaweAdapter; -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.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.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_19_R1.CraftServer; -import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R1.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_19_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_19_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 != 3105 && dataVersion != 3117 && dataVersion != 3120) { - throw new UnsupportedClassVersionError("Not 1.19, 1.19.1 or 1.19.2!"); - } - - worldsField = CraftServer.class.getDeclaredField("worlds"); - worldsField.setAccessible(true); - - getChunkFutureMainThreadMethod = ServerChunkCache.class.getDeclaredMethod( - Refraction.pickName("getChunkFutureMainThread", "c"), - 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).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) { - entity.save(tag); - } - - 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); - } - - @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 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.saveWithId(); - //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) { - CompoundBinaryTag nativeTag = state.getNbt(); - if (nativeTag != null) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeBinary(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; - } - } - - @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("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, CompoundBinaryTag nbtData) { - ((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create( - new StructureBlockEntity( - new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()), - Blocks.STRUCTURE_BLOCK.defaultBlockState() - ), - __ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(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(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.setNbt(((CompoundBinaryTag) toNativeBinary(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.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.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(), - new LevelStem( - originalWorld.dimensionTypeRegistration(), - newOpts.dimensions().get(worldDimKey).generator() - ), - 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) 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 = blockEntity.saveWithId(); - //FAWE start - BinaryTag - state = state.toBaseBlock(((CompoundBinaryTag) toNativeBinary(tag))); - //FAWE end - } - extent.setBlock(vec, state.toBaseBlock()); - if (options.shouldRegenBiomes()) { - Biome origBiome = chunk.getNoiseBiome(vec.getX(), vec.getY(), vec.getZ()).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 { - 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) { - net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); - ListBinaryTag foreignList = (ListBinaryTag) foreign; - 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", "ag") - ); - 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, @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/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightDataConverters.java deleted file mode 100644 index c9d8928bb..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightDataConverters.java +++ /dev/null @@ -1,2955 +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_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.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.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 buildUnoptimized() { - return this.fixer = new WrappedDataFixer(DataFixers.getDataFixer()); - } - - @Override - public DataFixer buildOptimized(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 ignored) { - } - - if (object == null) { - try { - object = Component.Serializer.fromJson(s); - } catch (JsonParseException ignored) { - } - } - - if (object == null) { - try { - object = Component.Serializer.fromJsonLenient(s); - } catch (JsonParseException ignored) { - } - } - - 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; - - for (final JsonElement jsonelement1 : jsonarray) { - 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 ignored) { - } - - if (object == null) { - try { - object = Component.Serializer.fromJson(s1); - } catch (JsonParseException ignored) { - } - } - - if (object == null) { - try { - object = Component.Serializer.fromJsonLenient(s1); - } catch (JsonParseException ignored) { - } - } - - 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/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightFakePlayer.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightFakePlayer.java deleted file mode 100644 index 43964319c..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightFakePlayer.java +++ /dev/null @@ -1,99 +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_R1; - -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, null); - } - - @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/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightWorldNativeAccess.java deleted file mode 100644 index 3f748bb9d..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R1/PaperweightWorldNativeAccess.java +++ /dev/null @@ -1,210 +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_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.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_19_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_19_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.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(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()); - } - } - - @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/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightBlockMaterial.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightBlockMaterial.java deleted file mode 100644 index 812cd4e24..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightBlockMaterial.java +++ /dev/null @@ -1,189 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_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_19_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.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_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", "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)); - } - - 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/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightFaweAdapter.java deleted file mode 100644 index b9aa9cf7f..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightFaweAdapter.java +++ /dev/null @@ -1,701 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R1; - -import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter; -import com.fastasyncworldedit.bukkit.adapter.IDelegateBukkitImplAdapter; -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.fastasyncworldedit.core.util.TaskManager; -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.EditSession; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.blocks.TileEntityBlock; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.BukkitWorld; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_19_R1.PaperweightAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R1.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_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.TreeGenerator; -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 io.papermc.lib.PaperLib; -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.ClientboundLevelChunkWithLightPacket; -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.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.TreeType; -import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.v1_19_R1.CraftChunk; -import org.bukkit.craftbukkit.v1_19_R1.CraftServer; -import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R1.block.CraftBlockState; -import org.bukkit.craftbukkit.v1_19_R1.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_19_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_19_R1.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; -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 CachedBukkitAdapter implements - IDelegateBukkitImplAdapter { - - 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(); - } - - 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 Registry.BLOCK.get(new ResourceLocation(blockType.getNamespace(), blockType.getResource())); - } - - @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 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); - - 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); - 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((CompoundBinaryTag) toNativeBinary(tag)); - } - } - - return state.toBaseBlock(); - } - - @Override - public Set getSupportedSideEffects() { - return SideEffectSet.defaults().getSideEffectsToApply(); - } - - 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; - } - 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<>(((CraftWorld) world).getHandle()) - ); - } - - @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 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 = ((CraftWorld) world).getHandle(); - 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( - ((CraftWorld) world).getHandle(), - 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) fromNative(baseItemStack.getNbtData()))); - return CraftItemStack.asCraftMirror(stack); - } - - @Override - public boolean generateTree( - TreeGenerator.TreeType treeType, EditSession editSession, BlockVector3 blockVector3, - org.bukkit.World bukkitWorld - ) { - TreeType bukkitType = BukkitWorld.toBukkitTreeType(treeType); - if (bukkitType == TreeType.CHORUS_PLANT) { - blockVector3 = blockVector3.add( - 0, - 1, - 0 - ); // bukkit skips the feature gen which does this offset normally, so we have to add it back - } - ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle(); - final BlockVector3 finalBlockVector = blockVector3; - // Sync to main thread to ensure no clashes occur - Map placed = TaskManager.taskManager().sync(() -> { - serverLevel.captureTreeGeneration = true; - serverLevel.captureBlockStates = true; - try { - if (!bukkitWorld.generateTree(BukkitAdapter.adapt(bukkitWorld, finalBlockVector), bukkitType)) { - return null; - } - return ImmutableMap.copyOf(serverLevel.capturedBlockStates); - } finally { - serverLevel.captureBlockStates = false; - serverLevel.captureTreeGeneration = false; - serverLevel.capturedBlockStates.clear(); - } - }); - if (placed == null || placed.isEmpty()) { - return false; - } - for (CraftBlockState craftBlockState : placed.values()) { - if (craftBlockState == null || craftBlockState.getType() == Material.AIR) { - continue; - } - editSession.setBlock(craftBlockState.getX(), craftBlockState.getY(), craftBlockState.getZ(), - BukkitAdapter.adapt(((org.bukkit.block.BlockState) craftBlockState).getBlockData()) - ); - } - return true; - } - - @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 = (WritableRegistry) ((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() { - 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/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightFaweWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightFaweWorldNativeAccess.java deleted file mode 100644 index 0e7f6ea0c..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightFaweWorldNativeAccess.java +++ /dev/null @@ -1,286 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_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.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_19_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_19_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_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java deleted file mode 100644 index 6466ea828..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks.java +++ /dev/null @@ -1,1164 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_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_19_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_19_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_19_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.Future; -import java.util.concurrent.Semaphore; -import java.util.concurrent.locks.ReadWriteLock; -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::saveWithId)); - private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin - .getInstance() - .getBukkitImplAdapter()); - private final ReadWriteLock sectionLock = new ReentrantReadWriteLock(); - 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 LevelChunkSection[] sections; - private LevelChunk levelChunk; - private DataLayer[] blockLight; - private DataLayer[] skyLight; - private boolean createCopy = false; - private PaperweightGetBlocks_Copy copy = null; - private boolean forceLoadSections = true; - private boolean lightUpdate = false; - - 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(Registry.BIOME_REGISTRY); - this.biomeHolderIdMap = biomeRegistry.asHolderIdMap(); - } - - public int getChunkX() { - return chunkX; - } - - public int getChunkZ() { - return chunkZ; - } - - @Override - public boolean isCreateCopy() { - return createCopy; - } - - @Override - public void setCreateCopy(boolean createCopy) { - this.createCopy = createCopy; - } - - @Override - public IChunkGet getCopy() { - return copy; - } - - @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() { - 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) { - forceLoadSections = false; - copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null; - 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 { - setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes()); - } - } - } - continue; - } - - bitMask |= 1 << getSectionIndex; - - char[] setArr = set.load(layerNo); - - // 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(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .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 - ); - 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.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.setUnsaved(true); - // 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) { - char[] blocks = new char[4096]; - System.arraycopy(super.blocks[layer], 0, blocks, 0, 4096); - return blocks; - } - } - } - return PaperweightGetBlocks.this.update(layer, null, true); - } - - @Override - public synchronized void send(int mask, boolean lighting) { - 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 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; - sectionLock.readLock().lock(); - LevelChunkSection[] tmp = sections; - sectionLock.readLock().unlock(); - 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 - ) { - 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(); - } - 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 = sectionBiomes[index]; - if (biomeType == null) { - continue; - } - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .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/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks_Copy.java deleted file mode 100644 index c0b69ac80..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightGetBlocks_Copy.java +++ /dev/null @@ -1,248 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_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_19_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.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 PalettedContainer>[] 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(); - 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 void setCreateCopy(boolean createCopy) { - } - - @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()].get(x >> 2, (y & 15) >> 2, z >> 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 PalettedContainer[getSectionCount()]; - } - 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 - 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(); - 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/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightMapChunkUtil.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightMapChunkUtil.java deleted file mode 100644 index ead60b212..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightMapChunkUtil.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_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_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPlatformAdapter.java deleted file mode 100644 index ae3d91027..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPlatformAdapter.java +++ /dev/null @@ -1,703 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_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.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.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.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.EntityBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -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 net.minecraft.world.level.gameevent.GameEventDispatcher; -import net.minecraft.world.level.gameevent.GameEventListener; -import org.bukkit.craftbukkit.v1_19_R1.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.lang.reflect.Parameter; -import java.lang.reflect.Type; -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.function.Function; - -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 fieldNonEmptyBlockCount; - - private static final MethodHandle methodGetVisibleChunk; - - private static final int CHUNKSECTION_BASE; - private static final int CHUNKSECTION_SHIFT; - - private static final Field fieldThreadingDetector; - private static final long fieldThreadingDetectorOffset; - - private static final Field fieldLock; - private static final long fieldLockOffset; - - private static final MethodHandle methodRemoveGameEventListener; - private static final MethodHandle methodremoveTickingBlockEntity; - - private static final Field fieldRemove; - - 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 { - 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); - fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "f")); - fieldNonEmptyBlockCount.setAccessible(true); - - Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( - "getVisibleChunkIfPresent", - "b" - ), long.class); - getVisibleChunkIfPresent.setAccessible(true); - methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent); - - Unsafe unsafe = ReflectionUtils.getUnsafe(); - if (!PaperLib.isPaper()) { - fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f")); - fieldThreadingDetectorOffset = unsafe.objectFieldOffset(fieldThreadingDetector); - - fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c")); - fieldLockOffset = unsafe.objectFieldOffset(fieldLock); - } else { - // in paper, the used methods are synchronized properly - fieldThreadingDetector = null; - fieldThreadingDetectorOffset = -1; - - fieldLock = null; - fieldLockOffset = -1; - } - - Method removeGameEventListener = LevelChunk.class.getDeclaredMethod( - Refraction.pickName("removeGameEventListener", "a"), - BlockEntity.class, - ServerLevel.class - ); - removeGameEventListener.setAccessible(true); - methodRemoveGameEventListener = MethodHandles.lookup().unreflect(removeGameEventListener); - - Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod( - Refraction.pickName( - "removeBlockEntityTicker", - "l" - ), BlockPos.class - ); - removeBlockEntityTicker.setAccessible(true); - methodremoveTickingBlockEntity = MethodHandles.lookup().unreflect(removeBlockEntityTicker); - - fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p")); - fieldRemove.setAccessible(true); - - CHUNKSECTION_BASE = unsafe.arrayBaseOffset(LevelChunkSection[].class); - int scale = unsafe.arrayIndexScale(LevelChunkSection[].class); - if ((scale & (scale - 1)) != 0) { - throw new Error("data type scale not a power of two"); - } - CHUNKSECTION_SHIFT = 31 - Integer.numberOfLeadingZeros(scale); - 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", "P")); - SERVER_LEVEL_ENTITY_MANAGER.setAccessible(true); - } catch (NoSuchFieldException ignored) { - } - POST_CHUNK_REWRITE = chunkRewrite; - } 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 - ) { - long offset = ((long) layer << CHUNKSECTION_SHIFT) + CHUNKSECTION_BASE; - if (layer >= 0 && layer < sections.length) { - return ReflectionUtils.getUnsafe().compareAndSwapObject(sections, offset, expected, value); - } - 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) { - Unsafe unsafe = ReflectionUtils.getUnsafe(); - PalettedContainer blocks = section.getStates(); - ThreadingDetector currentThreadingDetector = (ThreadingDetector) unsafe.getObject( - blocks, - fieldThreadingDetectorOffset - ); - synchronized (currentThreadingDetector) { - Semaphore currentLock = (Semaphore) unsafe.getObject(currentThreadingDetector, fieldLockOffset); - if (currentLock instanceof DelegateSemaphore delegateSemaphore) { - return delegateSemaphore; - } - DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); - unsafe.putObject(currentThreadingDetector, fieldLockOffset, 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 = (CraftChunk) future.get(); - 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 - io.papermc.paper.util.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("deprecation") - 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); - 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; - } - TaskManager.taskManager().task(() -> { - 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); - } - - /** - * 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().ownedRegistryOrThrow(Registry.BIOME_REGISTRY); - 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(); - } - - 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/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPostProcessor.java deleted file mode 100644 index 4bbf3baca..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightPostProcessor.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_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_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightStarlightRelighter.java deleted file mode 100644 index 8e1e763b1..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightStarlightRelighter.java +++ /dev/null @@ -1,205 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R1; - -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.lighting.NMSRelighter; -import com.fastasyncworldedit.core.extent.processor.lighting.Relighter; -import com.fastasyncworldedit.core.queue.IQueueChunk; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.util.TaskManager; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; -import it.unimi.dsi.fastutil.longs.LongArraySet; -import it.unimi.dsi.fastutil.longs.LongIterator; -import it.unimi.dsi.fastutil.longs.LongSet; -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 org.apache.logging.log4j.Logger; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Consumer; -import java.util.function.IntConsumer; - -public class PaperweightStarlightRelighter implements Relighter { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - private static final int CHUNKS_PER_BATCH = 1024; // 32 * 32 - private static final int CHUNKS_PER_BATCH_SQRT_LOG2 = 5; // for shifting - - 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); - - - private final ServerLevel serverLevel; - private final ReentrantLock lock = new ReentrantLock(); - private final Long2ObjectLinkedOpenHashMap regions = new Long2ObjectLinkedOpenHashMap<>(); - private final ReentrantLock areaLock = new ReentrantLock(); - private final NMSRelighter delegate; - - @SuppressWarnings("rawtypes") - public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent queue) { - this.serverLevel = serverLevel; - this.delegate = new NMSRelighter(queue); - } - - @Override - public boolean addChunk(int cx, int cz, byte[] skipReason, int bitmask) { - areaLock.lock(); - try { - long key = MathMan.pairInt(cx >> CHUNKS_PER_BATCH_SQRT_LOG2, cz >> CHUNKS_PER_BATCH_SQRT_LOG2); - // TODO probably submit here already if chunks.size == CHUNKS_PER_BATCH? - LongSet chunks = this.regions.computeIfAbsent(key, k -> new LongArraySet(CHUNKS_PER_BATCH >> 2)); - chunks.add(ChunkPos.asLong(cx, cz)); - } finally { - areaLock.unlock(); - } - return true; - } - - @Override - public void addLightUpdate(int x, int y, int z) { - delegate.addLightUpdate(x, y, z); - } - - /* - * This method is called "recursively", iterating and removing elements - * from the regions linked map. This way, chunks are loaded in batches to avoid - * OOMEs. - */ - @Override - public void fixLightingSafe(boolean sky) { - this.areaLock.lock(); - try { - if (regions.isEmpty()) { - return; - } - LongSet first = regions.removeFirst(); - fixLighting(first, () -> fixLightingSafe(true)); - } finally { - this.areaLock.unlock(); - } - } - - /* - * Processes a set of chunks and runs an action afterwards. - * The action is run async, the chunks are partly processed on the main thread - * (as required by the server). - */ - private void fixLighting(LongSet chunks, Runnable andThen) { - // convert from long keys to ChunkPos - Set coords = new HashSet<>(); - LongIterator iterator = chunks.iterator(); - while (iterator.hasNext()) { - coords.add(new ChunkPos(iterator.nextLong())); - } - TaskManager.taskManager().task(() -> { - // trigger chunk load and apply ticket on main thread - List> futures = new ArrayList<>(); - for (ChunkPos pos : coords) { - futures.add(serverLevel.getWorld().getChunkAtAsync(pos.x, pos.z) - .thenAccept(c -> serverLevel.getChunkSource().addTicketAtLevel( - FAWE_TICKET, - pos, - LIGHT_LEVEL, - Unit.INSTANCE - )) - ); - } - // collect futures and trigger relight once all chunks are loaded - CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenAccept(v -> - invokeRelight( - coords, - c -> { - }, // no callback for single chunks required - i -> { - if (i != coords.size()) { - LOGGER.warn("Processed {} chunks instead of {}", i, coords.size()); - } - // post process chunks on main thread - TaskManager.taskManager().task(() -> postProcessChunks(coords)); - // call callback on our own threads - TaskManager.taskManager().async(andThen); - } - ) - ); - }); - } - - private 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 - */ - private 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); - } - } - - @Override - public void clear() { - - } - - @Override - public void removeLighting() { - this.delegate.removeLighting(); - } - - @Override - public void fixBlockLighting() { - fixLightingSafe(true); - } - - @Override - public void fixSkyLighting() { - fixLightingSafe(true); - } - - @Override - public boolean isEmpty() { - return true; - } - - @Override - public ReentrantLock getLock() { - return this.lock; - } - - @Override - public boolean isFinished() { - return false; - } - - @Override - public void close() throws Exception { - fixLightingSafe(true); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightStarlightRelighterFactory.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightStarlightRelighterFactory.java deleted file mode 100644 index d7ff69151..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/PaperweightStarlightRelighterFactory.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_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.IQueueChunk; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import com.sk89q.worldedit.world.World; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; - -import javax.annotation.Nonnull; - -public class PaperweightStarlightRelighterFactory implements RelighterFactory { - - @Override - public @Nonnull - @SuppressWarnings("rawtypes") - 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/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/nbt/PaperweightLazyCompoundTag.java deleted file mode 100644 index ff9b73642..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/nbt/PaperweightLazyCompoundTag.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_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 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_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/regen/PaperweightRegen.java deleted file mode 100644 index ebe096996..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R1/regen/PaperweightRegen.java +++ /dev/null @@ -1,564 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_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_19_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.data.BuiltinRegistries; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.MinecraftServer; -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.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.WorldGenSettings; -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.craftbukkit.v1_19_R1.CraftServer; -import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_19_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.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; - -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 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", "g")); - generatorSettingBaseSupplierField.setAccessible(true); - - generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "f")); - generatorSettingFlatField.setAccessible(true); - - delegateField = CustomChunkGenerator.class.getDeclaredField("delegate"); - delegateField.setAccessible(true); - - chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "L")); - chunkSourceField.setAccessible(true); - - ringPositionsField = ChunkGenerator.class.getDeclaredField(Refraction.pickName("ringPositions", "i")); - ringPositionsField.setAccessible(true); - - hasGeneratedPositionsField = ChunkGenerator.class.getDeclaredField(Refraction.pickName("hasGeneratedPositions", "j")); - 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(); - if (!(originalChunkProvider instanceof ServerChunkCache)) { - return false; - } - - //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.chunkStati.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(); - 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()); - - BiomeProvider biomeProvider = getBiomeProvider(); - - //init world - freshWorld = Fawe.instance().getQueueHandler().sync((Supplier) () -> new ServerLevel( - server, - server.executor, - session, - newWorldData, - originalServerWorld.dimension(), - newOpts.dimensions().getOrThrow(levelStemResourceKey), - new RegenNoOpWorldLoadListener(), - originalServerWorld.isDebug(), - seed, - ImmutableList.of(), - false, - environment, - generator, - biomeProvider - ) { - private final Holder singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.asHolderIdMap().byId( - 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(originalGenerator.structureSets, generatorSettingFlat); - } else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) { - Holder generatorSettingBaseSupplier = (Holder) generatorSettingBaseSupplierField.get( - originalGenerator); - BiomeSource biomeSource; - if (options.hasBiomeType()) { - biomeSource = new FixedBiomeSource(BuiltinRegistries.BIOME - .asHolderIdMap() - .byId(WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()))); - } else { - biomeSource = originalGenerator.getBiomeSource(); - } - chunkGenerator = new NoiseBasedChunkGenerator(originalGenerator.structureSets, - noiseBasedChunkGenerator.noises, - 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; - - if (seed == originalOpts.seed() && !options.hasBiomeType()) { - // Optimisation for needless ring position calculation when the seed and biome is the same. - boolean hasGeneratedPositions = hasGeneratedPositionsField.getBoolean(originalGenerator); - if (hasGeneratedPositions) { - Map>> ringPositions = - (Map>>) ringPositionsField.get( - originalGenerator); - Map>> copy = new Object2ObjectArrayMap<>(ringPositions); - ringPositionsField.set(chunkGenerator, copy); - hasGeneratedPositionsField.setBoolean(chunkGenerator, true); - } - } - - 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; - } - }; - - ReflectionUtils.unsafeSet(chunkSourceField, 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(Registry.BIOME_REGISTRY), 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(() -> 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) 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(Long xz, 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_19_3/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_19_3/build.gradle.kts deleted file mode 100644 index 4706a5752..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/build.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -import io.papermc.paperweight.userdev.PaperweightUserDependenciesExtension - -plugins { - java -} - -applyPaperweightAdapterConfiguration() - -repositories { - gradlePluginPortal() -} - -dependencies { - // https://papermc.io/repo/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/ - the().paperDevBundle("1.19.3-R0.1-20230312.180621-141") - compileOnly("io.papermc:paperlib") -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightAdapter.java deleted file mode 100644 index ddaa2c6b4..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightAdapter.java +++ /dev/null @@ -1,1029 +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_R2; - -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.ByteArrayTag; -import com.sk89q.jnbt.ByteTag; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.DoubleTag; -import com.sk89q.jnbt.EndTag; -import com.sk89q.jnbt.FloatTag; -import com.sk89q.jnbt.IntArrayTag; -import com.sk89q.jnbt.IntTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.LongArrayTag; -import com.sk89q.jnbt.LongTag; -import com.sk89q.jnbt.NBTConstants; -import com.sk89q.jnbt.ShortTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; -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.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.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_R2.CraftServer; -import org.bukkit.craftbukkit.v1_19_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R2.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_19_R2.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_19_R2.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 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 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 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 != 3218) { - throw new UnsupportedClassVersionError("Not 1.19.3!"); - } - - 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) { - entity.save(tag); - } - - private static Block getBlockFromType(BlockType blockType) { - - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK).get(ResourceLocation.tryParse(blockType.getId())); - } - - private static Item getItemFromType(ItemType itemType) { - return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.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); - } - - @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((CompoundBinaryTag) toNativeBinary(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(() -> (CompoundBinaryTag) toNativeBinary(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().getId(), craftWorld.getHandle()); - - if (createdEntity != null) { - CompoundBinaryTag nativeTag = state.getNbt(); - if (nativeTag != null) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeBinary(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) 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" }) - @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, CompoundBinaryTag nbtData) { - ((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create( - new StructureBlockEntity( - new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()), - Blocks.STRUCTURE_BLOCK.defaultBlockState() - ), - __ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(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().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.setNbt(((CompoundBinaryTag) toNativeBinary(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.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.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("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.getBlockX(), vec.getBlockY(), vec.getBlockZ()); - 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(((CompoundBinaryTag) toNativeBinary(tag))); - } - extent.setBlock(vec, state.toBaseBlock()); - if (options.shouldRegenBiomes()) { - Biome origBiome = chunk.getNoiseBiome(vec.getX(), vec.getY(), vec.getZ()).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.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 - */ - @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) { - net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); - ListBinaryTag foreignList = (ListBinaryTag) foreign; - 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()); - } - } - - @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", "ag") - ); - 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_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightDataConverters.java deleted file mode 100644 index 7e735efdb..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightDataConverters.java +++ /dev/null @@ -1,2800 +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_R2; - -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.jnbt.CompoundTag; -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.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 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; -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 { - - //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 buildUnoptimized() { - return this.fixer = new WrappedDataFixer(DataFixers.getDataFixer()); - } - - @Override - public DataFixer buildOptimized(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_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightFakePlayer.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightFakePlayer.java deleted file mode 100644 index 874b5323f..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/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_R2; - -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_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightWorldNativeAccess.java deleted file mode 100644 index 32d5682b1..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R2/PaperweightWorldNativeAccess.java +++ /dev/null @@ -1,180 +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_R2; - -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_19_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R2.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 { - 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(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()); - } - } - - // 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_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightBlockMaterial.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightBlockMaterial.java deleted file mode 100644 index 69528e201..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightBlockMaterial.java +++ /dev/null @@ -1,189 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2; - -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_R2.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_R2.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_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightFaweAdapter.java deleted file mode 100644 index 7cfce755e..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightFaweAdapter.java +++ /dev/null @@ -1,706 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2; - -import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter; -import com.fastasyncworldedit.bukkit.adapter.IDelegateBukkitImplAdapter; -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.fastasyncworldedit.core.util.TaskManager; -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.EditSession; -import com.sk89q.worldedit.blocks.BaseItemStack; -import com.sk89q.worldedit.blocks.TileEntityBlock; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.bukkit.BukkitWorld; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; -import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_19_R2.PaperweightAdapter; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2.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.TreeGenerator; -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 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.nbt.IntTag; -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.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.TreeType; -import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.v1_19_R2.CraftChunk; -import org.bukkit.craftbukkit.v1_19_R2.CraftServer; -import org.bukkit.craftbukkit.v1_19_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R2.block.CraftBlockState; -import org.bukkit.craftbukkit.v1_19_R2.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_19_R2.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_19_R2.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; -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 CachedBukkitAdapter implements - IDelegateBukkitImplAdapter { - - 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(); - } - - 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(new ResourceLocation(blockType.getNamespace(), blockType.getResource())); - } - - @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 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); - - 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); - 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((CompoundBinaryTag) toNativeBinary(tag)); - } - } - - return state.toBaseBlock(); - } - - @Override - public Set getSupportedSideEffects() { - return SideEffectSet.defaults().getSideEffectsToApply(); - } - - 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; - } - 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<>(((CraftWorld) world).getHandle()) - ); - } - - @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 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 = ((CraftWorld) world).getHandle(); - 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( - ((CraftWorld) world).getHandle(), - new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ()) - ); - } - - @Override - public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) { - ItemStack stack = new ItemStack( - DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM) - .get(ResourceLocation.tryParse(baseItemStack.getType().getId())), - baseItemStack.getAmount() - ); - stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(baseItemStack.getNbtData()))); - return CraftItemStack.asCraftMirror(stack); - } - - @Override - public boolean generateTree( - TreeGenerator.TreeType treeType, EditSession editSession, BlockVector3 blockVector3, - org.bukkit.World bukkitWorld - ) { - TreeType bukkitType = BukkitWorld.toBukkitTreeType(treeType); - if (bukkitType == TreeType.CHORUS_PLANT) { - blockVector3 = blockVector3.add( - 0, - 1, - 0 - ); // bukkit skips the feature gen which does this offset normally, so we have to add it back - } - ServerLevel serverLevel = ((CraftWorld) bukkitWorld).getHandle(); - final BlockVector3 finalBlockVector = blockVector3; - // Sync to main thread to ensure no clashes occur - Map placed = TaskManager.taskManager().sync(() -> { - serverLevel.captureTreeGeneration = true; - serverLevel.captureBlockStates = true; - try { - if (!bukkitWorld.generateTree(BukkitAdapter.adapt(bukkitWorld, finalBlockVector), bukkitType)) { - return null; - } - return ImmutableMap.copyOf(serverLevel.capturedBlockStates); - } finally { - serverLevel.captureBlockStates = false; - serverLevel.captureTreeGeneration = false; - serverLevel.capturedBlockStates.clear(); - } - }); - if (placed == null || placed.isEmpty()) { - return false; - } - for (CraftBlockState craftBlockState : placed.values()) { - if (craftBlockState == null || craftBlockState.getType() == Material.AIR) { - continue; - } - editSession.setBlock(craftBlockState.getX(), craftBlockState.getY(), craftBlockState.getZ(), - BukkitAdapter.adapt(((org.bukkit.block.BlockState) craftBlockState).getBlockData()) - ); - } - return true; - } - - @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() - .registryOrThrow(BIOME); - ResourceLocation resourceLocation = ResourceLocation.tryParse(biomeType.getId()); - 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_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightFaweWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightFaweWorldNativeAccess.java deleted file mode 100644 index e5c26aba5..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightFaweWorldNativeAccess.java +++ /dev/null @@ -1,286 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2; - -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_19_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R2.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_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightGetBlocks.java deleted file mode 100644 index 9edb79974..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightGetBlocks.java +++ /dev/null @@ -1,1166 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2; - -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_R2.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_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R2.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.Future; -import java.util.concurrent.Semaphore; -import java.util.concurrent.locks.ReadWriteLock; -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 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 LevelChunkSection[] sections; - private LevelChunk levelChunk; - private DataLayer[] blockLight; - private DataLayer[] skyLight; - private boolean createCopy = false; - private PaperweightGetBlocks_Copy copy = null; - private boolean forceLoadSections = true; - private boolean lightUpdate = false; - - 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 void setCreateCopy(boolean createCopy) { - this.createCopy = createCopy; - } - - @Override - public IChunkGet getCopy() { - return copy; - } - - @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() { - 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) { - forceLoadSections = false; - copy = createCopy ? new PaperweightGetBlocks_Copy(levelChunk) : null; - 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 { - setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes()); - } - } - } - continue; - } - - bitMask |= 1 << getSectionIndex; - - char[] setArr = set.load(layerNo); - - // 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(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .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 - ); - 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.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.setUnsaved(true); - // 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) { - char[] blocks = new char[4096]; - System.arraycopy(super.blocks[layer], 0, blocks, 0, 4096); - return blocks; - } - } - } - return PaperweightGetBlocks.this.update(layer, null, true); - } - - @Override - public synchronized void send(int mask, boolean lighting) { - 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 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; - sectionLock.readLock().lock(); - LevelChunkSection[] tmp = sections; - sectionLock.readLock().unlock(); - 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 - ) { - 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(); - } - 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 = sectionBiomes[index]; - if (biomeType == null) { - continue; - } - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .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_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightGetBlocks_Copy.java deleted file mode 100644 index c56de7093..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightGetBlocks_Copy.java +++ /dev/null @@ -1,248 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2; - -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_R2.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.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 PalettedContainer>[] 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(); - 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 void setCreateCopy(boolean createCopy) { - } - - @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()].get(x >> 2, (y & 15) >> 2, z >> 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 PalettedContainer[getSectionCount()]; - } - 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 - 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(); - 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_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightMapChunkUtil.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightMapChunkUtil.java deleted file mode 100644 index c8acc3cd2..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightMapChunkUtil.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2; - -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_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightPlatformAdapter.java deleted file mode 100644 index 479df3b1a..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightPlatformAdapter.java +++ /dev/null @@ -1,700 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2; - -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.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.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.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.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.bukkit.craftbukkit.v1_19_R2.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.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 fieldNonEmptyBlockCount; - - private static final MethodHandle methodGetVisibleChunk; - - private static final int CHUNKSECTION_BASE; - private static final int CHUNKSECTION_SHIFT; - - private static final Field fieldThreadingDetector; - private static final long fieldThreadingDetectorOffset; - - private static final Field fieldLock; - private static final long fieldLockOffset; - - private static final MethodHandle methodRemoveGameEventListener; - private static final MethodHandle methodremoveTickingBlockEntity; - - private static final Field fieldRemove; - - 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 { - 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); - fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "f")); - fieldNonEmptyBlockCount.setAccessible(true); - - Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( - "getVisibleChunkIfPresent", - "b" - ), long.class); - getVisibleChunkIfPresent.setAccessible(true); - methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent); - - Unsafe unsafe = ReflectionUtils.getUnsafe(); - if (!PaperLib.isPaper()) { - fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f")); - fieldThreadingDetectorOffset = unsafe.objectFieldOffset(fieldThreadingDetector); - - fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c")); - fieldLockOffset = unsafe.objectFieldOffset(fieldLock); - } else { - // in paper, the used methods are synchronized properly - fieldThreadingDetector = null; - fieldThreadingDetectorOffset = -1; - - fieldLock = null; - fieldLockOffset = -1; - } - - Method removeGameEventListener = LevelChunk.class.getDeclaredMethod( - Refraction.pickName("removeGameEventListener", "a"), - BlockEntity.class, - ServerLevel.class - ); - removeGameEventListener.setAccessible(true); - methodRemoveGameEventListener = MethodHandles.lookup().unreflect(removeGameEventListener); - - Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod( - Refraction.pickName( - "removeBlockEntityTicker", - "l" - ), BlockPos.class - ); - removeBlockEntityTicker.setAccessible(true); - methodremoveTickingBlockEntity = MethodHandles.lookup().unreflect(removeBlockEntityTicker); - - fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p")); - fieldRemove.setAccessible(true); - - CHUNKSECTION_BASE = unsafe.arrayBaseOffset(LevelChunkSection[].class); - int scale = unsafe.arrayIndexScale(LevelChunkSection[].class); - if ((scale & (scale - 1)) != 0) { - throw new Error("data type scale not a power of two"); - } - CHUNKSECTION_SHIFT = 31 - Integer.numberOfLeadingZeros(scale); - 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", "P")); - SERVER_LEVEL_ENTITY_MANAGER.setAccessible(true); - } catch (NoSuchFieldException ignored) { - } - POST_CHUNK_REWRITE = chunkRewrite; - } 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 - ) { - long offset = ((long) layer << CHUNKSECTION_SHIFT) + CHUNKSECTION_BASE; - if (layer >= 0 && layer < sections.length) { - return ReflectionUtils.getUnsafe().compareAndSwapObject(sections, offset, expected, value); - } - 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) { - Unsafe unsafe = ReflectionUtils.getUnsafe(); - PalettedContainer blocks = section.getStates(); - ThreadingDetector currentThreadingDetector = (ThreadingDetector) unsafe.getObject( - blocks, - fieldThreadingDetectorOffset - ); - synchronized (currentThreadingDetector) { - Semaphore currentLock = (Semaphore) unsafe.getObject(currentThreadingDetector, fieldLockOffset); - if (currentLock instanceof DelegateSemaphore delegateSemaphore) { - return delegateSemaphore; - } - DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); - unsafe.putObject(currentThreadingDetector, fieldLockOffset, 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 = (CraftChunk) future.get(); - 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 - io.papermc.paper.util.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("deprecation") - 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); - 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; - } - TaskManager.taskManager().task(() -> { - 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); - } - - /** - * 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(); - } - - 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_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightPostProcessor.java deleted file mode 100644 index a3f016f42..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightPostProcessor.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2; - -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_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightStarlightRelighter.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightStarlightRelighter.java deleted file mode 100644 index 642250aa0..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightStarlightRelighter.java +++ /dev/null @@ -1,205 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2; - -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.lighting.NMSRelighter; -import com.fastasyncworldedit.core.extent.processor.lighting.Relighter; -import com.fastasyncworldedit.core.queue.IQueueChunk; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.util.TaskManager; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap; -import it.unimi.dsi.fastutil.longs.LongArraySet; -import it.unimi.dsi.fastutil.longs.LongIterator; -import it.unimi.dsi.fastutil.longs.LongSet; -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 org.apache.logging.log4j.Logger; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.locks.ReentrantLock; -import java.util.function.Consumer; -import java.util.function.IntConsumer; - -public class PaperweightStarlightRelighter implements Relighter { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - private static final int CHUNKS_PER_BATCH = 1024; // 32 * 32 - private static final int CHUNKS_PER_BATCH_SQRT_LOG2 = 5; // for shifting - - 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); - - - private final ServerLevel serverLevel; - private final ReentrantLock lock = new ReentrantLock(); - private final Long2ObjectLinkedOpenHashMap regions = new Long2ObjectLinkedOpenHashMap<>(); - private final ReentrantLock areaLock = new ReentrantLock(); - private final NMSRelighter delegate; - - @SuppressWarnings("rawtypes") - public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent queue) { - this.serverLevel = serverLevel; - this.delegate = new NMSRelighter(queue); - } - - @Override - public boolean addChunk(int cx, int cz, byte[] skipReason, int bitmask) { - areaLock.lock(); - try { - long key = MathMan.pairInt(cx >> CHUNKS_PER_BATCH_SQRT_LOG2, cz >> CHUNKS_PER_BATCH_SQRT_LOG2); - // TODO probably submit here already if chunks.size == CHUNKS_PER_BATCH? - LongSet chunks = this.regions.computeIfAbsent(key, k -> new LongArraySet(CHUNKS_PER_BATCH >> 2)); - chunks.add(ChunkPos.asLong(cx, cz)); - } finally { - areaLock.unlock(); - } - return true; - } - - @Override - public void addLightUpdate(int x, int y, int z) { - delegate.addLightUpdate(x, y, z); - } - - /* - * This method is called "recursively", iterating and removing elements - * from the regions linked map. This way, chunks are loaded in batches to avoid - * OOMEs. - */ - @Override - public void fixLightingSafe(boolean sky) { - this.areaLock.lock(); - try { - if (regions.isEmpty()) { - return; - } - LongSet first = regions.removeFirst(); - fixLighting(first, () -> fixLightingSafe(true)); - } finally { - this.areaLock.unlock(); - } - } - - /* - * Processes a set of chunks and runs an action afterwards. - * The action is run async, the chunks are partly processed on the main thread - * (as required by the server). - */ - private void fixLighting(LongSet chunks, Runnable andThen) { - // convert from long keys to ChunkPos - Set coords = new HashSet<>(); - LongIterator iterator = chunks.iterator(); - while (iterator.hasNext()) { - coords.add(new ChunkPos(iterator.nextLong())); - } - TaskManager.taskManager().task(() -> { - // trigger chunk load and apply ticket on main thread - List> futures = new ArrayList<>(); - for (ChunkPos pos : coords) { - futures.add(serverLevel.getWorld().getChunkAtAsync(pos.x, pos.z) - .thenAccept(c -> serverLevel.getChunkSource().addTicketAtLevel( - FAWE_TICKET, - pos, - LIGHT_LEVEL, - Unit.INSTANCE - )) - ); - } - // collect futures and trigger relight once all chunks are loaded - CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenAccept(v -> - invokeRelight( - coords, - c -> { - }, // no callback for single chunks required - i -> { - if (i != coords.size()) { - LOGGER.warn("Processed {} chunks instead of {}", i, coords.size()); - } - // post process chunks on main thread - TaskManager.taskManager().task(() -> postProcessChunks(coords)); - // call callback on our own threads - TaskManager.taskManager().async(andThen); - } - ) - ); - }); - } - - private 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 - */ - private 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); - } - } - - @Override - public void clear() { - - } - - @Override - public void removeLighting() { - this.delegate.removeLighting(); - } - - @Override - public void fixBlockLighting() { - fixLightingSafe(true); - } - - @Override - public void fixSkyLighting() { - fixLightingSafe(true); - } - - @Override - public boolean isEmpty() { - return true; - } - - @Override - public ReentrantLock getLock() { - return this.lock; - } - - @Override - public boolean isFinished() { - return false; - } - - @Override - public void close() throws Exception { - fixLightingSafe(true); - } - -} diff --git a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightStarlightRelighterFactory.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightStarlightRelighterFactory.java deleted file mode 100644 index 3741b552c..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/PaperweightStarlightRelighterFactory.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2; - -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.IQueueChunk; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import com.sk89q.worldedit.world.World; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R2.CraftWorld; - -import javax.annotation.Nonnull; - -public class PaperweightStarlightRelighterFactory implements RelighterFactory { - - @Override - public @Nonnull - @SuppressWarnings("rawtypes") - 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_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/nbt/PaperweightLazyCompoundTag.java deleted file mode 100644 index 9ff3c1f61..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/nbt/PaperweightLazyCompoundTag.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2.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_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/regen/PaperweightRegen.java deleted file mode 100644 index 74dccf63b..000000000 --- a/worldedit-bukkit/adapters/adapter-1_19_3/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R2/regen/PaperweightRegen.java +++ /dev/null @@ -1,594 +0,0 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_19_R2.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_R2.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.craftbukkit.v1_19_R2.CraftServer; -import org.bukkit.craftbukkit.v1_19_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R2.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", "L")); - 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(); - if (!(originalChunkProvider instanceof ServerChunkCache)) { - return false; - } - - //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.chunkStati.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); - } - } - - - ReflectionUtils.unsafeSet(chunkSourceField, 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(() -> 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) 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(Long xz, 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 index 4c0d110e2..cf13348ff 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/ - the().paperDevBundle("1.20.1-R0.1-20230617.023453-15") + the().paperDevBundle("1.20.1-R0.1-20230623.105806-29") compileOnly("io.papermc:paperlib") } diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index a393413f3..9a9ffd86b 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -206,7 +206,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", "1.19.4", "1.19.3", "1.19.2", "1.19.1", "1.19", "1.18.2", "1.17.1", "1.16.5")) + gameVersions.addAll(listOf("1.20.1", "1.20", "1.19.4", "1.18.2", "1.17.1", "1.16.5")) loaders.addAll(listOf("paper", "spigot")) changelog.set("The changelog is available on GitHub: https://github.com/IntellectualSites/" + "FastAsyncWorldEdit/releases/tag/${project.version}") From e5cbf33317ea4c983b79fd6bc44afbce2dd1cb16 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Thu, 29 Jun 2023 12:29:37 +0200 Subject: [PATCH 22/28] Release 2.6.4 --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 642d6d09b..eb458b391 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 903064fd4106c57862dd576cf53f7ea59b702be7 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Thu, 29 Jun 2023 12:46:35 +0200 Subject: [PATCH 23/28] Back to snapshot for development --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index eb458b391..781f1fba2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,7 +34,7 @@ logger.lifecycle(""" ******************************************* """) -var rootVersion by extra("2.6.4") +var rootVersion by extra("2.6.5") 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 83a4987252593b24897cf94479fde160db2988a5 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Fri, 30 Jun 2023 19:36:35 +0100 Subject: [PATCH 24/28] chore: queue progress messages are not implemented --- .../com/fastasyncworldedit/core/configuration/Settings.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 a8d28d048..bb5f16eb3 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 @@ -584,7 +584,8 @@ public class Settings extends Config { @Comment({"Display constant titles about the progress of a user's edit", " - false = disabled", " - title = Display progress titles", - " - chat = Display progress in chat" + " - chat = Display progress in chat", + " - Currently not implemented" }) public String DISPLAY = "false"; @Comment("How often edit progress is displayed") From c880badaf410adcbaf4cb2eb10e05986620c4be4 Mon Sep 17 00:00:00 2001 From: Alexander Brandes Date: Sat, 1 Jul 2023 10:32:39 +0200 Subject: [PATCH 25/28] [ci skip] Update renovate.json --- .github/renovate.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/renovate.json b/.github/renovate.json index 2c23e9441..787e44030 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -4,6 +4,7 @@ "config:base", ":semanticCommitsDisabled" ], + "automerge": true, "ignoreDeps": [ "guava", "com.google.guava:guava", From 4583acda6bf96f421e85ea700c2d96d7e6817440 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Jul 2023 08:46:19 +0000 Subject: [PATCH 26/28] Update auto.value to v1.10.2 (#2324) 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 892d1c7cf..6f198a85c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,7 +19,7 @@ sparsebitset = "1.2" parallelgzip = "1.0.5" adventure = "4.9.3" truezip = "6.8.4" -auto-value = "1.10.1" +auto-value = "1.10.2" findbugs = "3.0.2" rhino-runtime = "1.7.14" zstd-jni = "1.4.8-1" # Not latest as it can be difficult to obtain latest ZSTD libs From e680e8fe1f4588d87759f685b0af1f7df9ff6683 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Jul 2023 08:47:03 +0000 Subject: [PATCH 27/28] Update dependency com.palmergames.bukkit.towny:towny to v0.99.2.5 (#2325) 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 6f198a85c..9ffe90850 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "16.18.1" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.99.1.2" +towny = "0.99.2.5" # Third party bstats = "3.0.2" From a0acbc716800ac97ec9f330b36c0a3e11900dfbe Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Jul 2023 18:49:40 +0200 Subject: [PATCH 28/28] Update dependency org.mockito:mockito-core to v5.4.0 (#2328) 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 9ffe90850..4588bc54c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -36,7 +36,7 @@ text = "3.0.4" piston = "0.5.7" # Tests -mockito = "5.3.1" +mockito = "5.4.0" # Gradle plugins pluginyml = "0.5.3" diff --git a/worldedit-sponge/build.gradle.kts b/worldedit-sponge/build.gradle.kts index e895e2989..aba91acea 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.3.1") + testImplementation("org.mockito:mockito-core:5.4.0") } <<<<<<< HEAD