diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 289b5db07..0d8a2cc90 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -29,7 +29,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.18' + - '1.18.1' - '1.17.1' - '1.16.5' - '1.15.2' diff --git a/.github/stale.yml b/.github/stale.yml index 7d95c1f66..c6ad3e8fe 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -1,4 +1,4 @@ -daysUntilStale: 60 +daysUntilStale: 30 daysUntilClose: 7 only: issues exemptLabels: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3137c908c..d793bb26e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,47 +1,47 @@ -name: "build" +name: build -on: ["pull_request", "push"] +on: [pull_request, push] jobs: build: - runs-on: "ubuntu-latest" + runs-on: ubuntu-latest steps: - - name: "Checkout Repository" - uses: "actions/checkout@v2.4.0" - - name : "Validate Gradle Wrapper" - uses : "gradle/wrapper-validation-action@v1.0.4" - - name: "Setup Java" - uses: "actions/setup-java@v2.3.1" + - name: Checkout Repository + uses: actions/checkout@v2.4.0 + - name : Validate Gradle Wrapper + uses : gradle/wrapper-validation-action@v1.0.4 + - name: Setup Java + uses: actions/setup-java@v2.3.1 with: - distribution: "temurin" - cache: 'gradle' - java-version: "17" - - name: "Clean Build" - run: "./gradlew clean build --no-daemon" - - name: "Determine release status" - if: "${{ runner.os == 'Linux' }}" + distribution: temurin + cache: gradle + java-version: 17 + - name: Clean Build + run: ./gradlew clean build --no-daemon + - name: Determine release status + if: ${{ runner.os == 'Linux' }} run: | if [ "$(./gradlew properties | awk '/^version:/ { print $2; }' | grep '\-SNAPSHOT')" ]; then echo "STATUS=snapshot" >> $GITHUB_ENV else echo "STATUS=release" >> $GITHUB_ENV fi - - name: "Publish Release" - if: "${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main'}}" - run: "./gradlew publishToSonatype closeSonatypeStagingRepository" + - name: Publish Release + if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main'}} + run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository env: - ORG_GRADLE_PROJECT_sonatypeUsername: "${{ secrets.SONATYPE_USERNAME }}" - ORG_GRADLE_PROJECT_sonatypePassword: "${{ secrets.SONATYPE_PASSWORD }}" - ORG_GRADLE_PROJECT_signingKey: "${{ secrets.SIGNING_KEY }}" - ORG_GRADLE_PROJECT_signingPassword: "${{ secrets.SIGNING_PASSWORD }}" - - name: "Publish Snapshot" - if: "${{ runner.os == 'Linux' && env.STATUS != 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}" - run: "./gradlew publishToSonatype" + ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }} + ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }} + ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGNING_KEY }} + ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGNING_PASSWORD }} + - name: Publish Snapshot + if: ${{ runner.os == 'Linux' && env.STATUS != 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main' }} + run: ./gradlew publishToSonatype env: - ORG_GRADLE_PROJECT_sonatypeUsername: "${{ secrets.SONATYPE_USERNAME }}" - ORG_GRADLE_PROJECT_sonatypePassword: "${{ secrets.SONATYPE_PASSWORD }}" - - name: "Archive Artifacts" - uses: "actions/upload-artifact@v2.2.4" + ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }} + ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }} + - name: Archive Artifacts + uses: actions/upload-artifact@v2.2.4 with: - name: "FastAsyncWorldEdit-Bukkit-SNAPSHOT" - path: "worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-*.jar" + name: FastAsyncWorldEdit-Bukkit-SNAPSHOT + path: worldedit-bukkit/build/libs/FastAsyncWorldEdit-Bukkit-*.jar diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 021ad30ce..976495eda 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -1,4 +1,4 @@ -name: "draft release" +name: draft release on: push: @@ -7,8 +7,8 @@ on: jobs: update_release_draft: - runs-on: "ubuntu-latest" + runs-on: ubuntu-latest steps: - - uses: "release-drafter/release-drafter@v5.15.0" + - uses: release-drafter/release-drafter@v5.15.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/COMPILING.md b/COMPILING.md index 31703d4f5..b80ee040c 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -1,12 +1,12 @@ Compiling ========= -You can compile FastAsyncWorldEdit as long as you have some version of Java greater than or equal to 16 installed. Gradle will download JDK 16 specifically if needed, +You can compile FastAsyncWorldEdit as long as you have some version of Java greater than or equal to 17 installed. Gradle will download JDK 17 specifically if needed, but it needs some version of Java to bootstrap from. Note that if you have JRE 8 installed, Gradle will currently attempt to use that to compile, which will not work. It is easiest to uninstall JRE 8 and replace it with JDK 16. -You can get the JDK 16 [here](https://adoptium.net/). +You can get the JDK 17 [here](https://adoptium.net/). The build process uses Gradle, which you do *not* need to download. FastAsyncWorldEdit is a multi-module project with three active modules: @@ -44,7 +44,7 @@ If you want to use FastAsyncWorldEdit, use the `FastAsyncWorldEdit-` ## Other commands -* `gradlew idea` will generate an [IntelliJ IDEA](http://www.jetbrains.com/idea/) module for each folder. +* `gradlew idea` will generate an [IntelliJ IDEA](https://www.jetbrains.com/idea/) module for each folder. _Possibly broken_: * `gradlew eclipse` will generate an [Eclipse](https://www.eclipse.org/downloads/) project for each folder. diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index 466a35458..000000000 --- a/Jenkinsfile +++ /dev/null @@ -1,10 +0,0 @@ -pipeline { - agent any - stages { - stage('Build pull request') { - steps { - sh './gradlew clean build' - } - } - } -} diff --git a/README.md b/README.md index 2ff28be7f..3cb346f35 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ FastAsyncWorldEdit is a fork of WorldEdit that has huge speed and memory improve * Use it in creative, survival in single player or on your server. * Use it on your Minecraft server to fix grieving and mistakes. -Java Edition required. FastAsyncWorldEdit is compatible with Bukkit, Spigot, Paper, and Tuinity. +Java Edition required. FastAsyncWorldEdit is compatible with Bukkit, Spigot and Paper. ## Download FastAsyncWorldEdit * Spigot: https://www.spigotmc.org/resources/fast-async-worldedit.13932/ diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 564784f81..f0f8bf4b2 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -31,7 +31,7 @@ dependencies { implementation(gradleApi()) implementation("org.ajoberstar.grgit:grgit-gradle:4.1.1") implementation("gradle.plugin.com.github.johnrengelman:shadow:7.1.1") - implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.3.0-SNAPSHOT") + implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.3.2") } kotlin { diff --git a/buildSrc/src/main/kotlin/CommonJavaConfig.kt b/buildSrc/src/main/kotlin/CommonJavaConfig.kt index a01093e68..0f4d2e857 100644 --- a/buildSrc/src/main/kotlin/CommonJavaConfig.kt +++ b/buildSrc/src/main/kotlin/CommonJavaConfig.kt @@ -62,7 +62,6 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean "https://javadoc.io/doc/com.google.code.findbugs/jsr305/3.0.2/", "https://jd.adventure.kyori.net/api/4.9.3/", "https://javadoc.io/doc/org.apache.logging.log4j/log4j-api/2.14.1/", - "https://javadoc.io/doc/com.google.guava/guava/31.0.1/", "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/", diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8396e75dd..d50d7f988 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,10 +3,10 @@ fastutil = "8.5.6" log4j = "2.17.0" guava = "31.0.1-jre" -gson = "2.8.8" +gson = "2.8.9" # Platform expectations -paper = "1.18-R0.1-SNAPSHOT" +paper = "1.18.1-R0.1-SNAPSHOT" # Plugins vault = "1.7.1" @@ -20,7 +20,6 @@ residence = "4.5._13.1" towny = "0.97.5.0" protocollib = "4.7.0" plotsquaredV6 = "6.2.0" -plotsquaredV4 = "4.514" redprotect = "1.9.6" # Third party @@ -28,7 +27,7 @@ flow-math = "1.0.3" paperlib = "1.0.8-SNAPSHOT" bstats = "2.2.1" serverlib = "2.3.1" -paster = "1.1.1" +paster = "1.1.3" sparsebitset = "1.2" parallelgzip = "1.0.5" adventure = "4.9.3" @@ -80,7 +79,6 @@ towny = { group = "com.github.TownyAdvanced", name = "Towny", version.ref = "tow protocollib = { group = "com.comphenix.protocol", name = "ProtocolLib", version.ref = "protocollib" } plotsquaredV6Bukkit = { group = "com.plotsquared", name = "PlotSquared-Bukkit", version.ref = "plotsquaredV6" } plotsquaredV6Core = { group = "com.plotsquared", name = "PlotSquared-Core", version.ref = "plotsquaredV6" } -plotsquaredV4 = { group = "com.github.intellectualsites.plotsquared", name = "PlotSquared-API", version.ref = "plotsquaredV4" } redprotect = { group = "net.fabiozumbi12", name = "redprotect", version.ref = "redprotect" } # Third Party diff --git a/settings.gradle.kts b/settings.gradle.kts index a9756b094..89dc64163 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -3,7 +3,7 @@ rootProject.name = "FastAsyncWorldEdit" include("worldedit-libs") include("worldedit-bukkit:adapters:adapter-legacy") -// include("worldedit-bukkit:adapters:adapter-1_17_1") +include("worldedit-bukkit:adapters:adapter-1_17_1") include("worldedit-bukkit:adapters:adapter-1_18") listOf("bukkit", "core", "cli").forEach { diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_17_1/build.gradle.kts index 7a44e517d..d9c2fcc45 100644 --- a/worldedit-bukkit/adapters/adapter-1_17_1/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_17_1/build.gradle.kts @@ -15,19 +15,49 @@ plugins { } repositories { + mavenCentral() maven { name = "PaperMC" url = uri("https://papermc.io/repo/repository/maven-public/") + } + maven { + name = "Athion" + url = uri("https://ci.athion.net/plugin/repository/tools/") content { - includeModule("io.papermc", "paperlib") + includeModule("io.papermc", "paper-server") } } + maven { + name = "OSS Sonatype Snapshots" + url = uri("https://oss.sonatype.org/content/repositories/snapshots/") + } + maven { + name = "Mojang" + url = uri("https://libraries.minecraft.net/") + } } artifacts { add("default", file("./src/main/resources/worldedit-adapter-1.17.1.jar")) } -dependencies { - compileOnly(libs.paperlib) +java { + toolchain.languageVersion.set(JavaLanguageVersion.of(17)) +} + +configurations.all { + attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17) +} + + +dependencies { + compileOnly("io.papermc.paper:paper-api:1.17.1-R0.1-SNAPSHOT") + compileOnly(project(":worldedit-bukkit")) + compileOnly(project(":worldedit-core")) + compileOnly("io.papermc:paper-server:1_17_r1_2") + compileOnly(libs.paperlib) + compileOnly("com.mojang:datafixerupper:4.0.26") + compileOnly("com.mojang:authlib:2.3.31") + compileOnly("com.mojang:brigadier:1.0.18") + compileOnly("io.netty:netty-all:4.1.25.Final") } diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightAdapter.java index 3cc940eb7..ab2530fed 100644 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/PaperweightAdapter.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.bukkit.adapter.ext.fawe; +import com.google.common.base.Preconditions; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -35,8 +36,10 @@ import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.Refraction; +import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_17_R1_2.PaperweightFaweAdapter; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extension.platform.Watchdog; import com.sk89q.worldedit.extent.Extent; @@ -316,9 +319,31 @@ public final class PaperweightAdapter implements BukkitImplAdapter> 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(); @@ -328,19 +353,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter> 4, z >> 4); final BlockPos blockPos = new BlockPos(x, y, z); - final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(blockPos); - int internalId = Block.getId(blockData); - BlockState state = BlockStateIdAccess.getBlockStateById(internalId); - if (state == null) { - org.bukkit.block.Block bukkitBlock = location.getBlock(); - state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); - } // Read the NBT data BlockEntity te = chunk.getBlockEntity(blockPos); if (te != null) { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - readTileEntityIntoTag(te, tag); // Load data + net.minecraft.nbt.CompoundTag tag = te.save(new net.minecraft.nbt.CompoundTag()); //FAWE start - BinaryTag return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag)); //FAWE end @@ -748,8 +765,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter state = BlockStateIdAccess.getBlockStateById(internalId); + BlockStateHolder state = ((PaperweightFaweAdapter) WorldEditPlugin + .getInstance() + .getBukkitImplAdapter()).adapt(blockData); Objects.requireNonNull(state); BlockEntity blockEntity = chunk.getBlockEntity(pos); if (blockEntity != null) { diff --git a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java index 2a7af851f..8433a9fc1 100644 --- a/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_17_1/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_17_R1_2/PaperweightFaweAdapter.java @@ -230,9 +230,24 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements return Registry.BLOCK.get(new ResourceLocation(blockType.getNamespace(), blockType.getResource())); } - @SuppressWarnings("deprecation") + @Deprecated @Override - public BaseBlock getBlock(Location location) { + 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); + return adapt(blockData); + } + + @Override + public BaseBlock getFullBlock(final Location location) { Preconditions.checkNotNull(location); CraftWorld craftWorld = ((CraftWorld) location.getWorld()); @@ -240,18 +255,22 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements int y = location.getBlockY(); int z = location.getBlockZ(); - final ServerLevel serverLevel = craftWorld.getHandle(); - LevelChunk levelChunk = serverLevel.getChunk(x >> 4, z >> 4); + final ServerLevel handle = craftWorld.getHandle(); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); final BlockPos blockPos = new BlockPos(x, y, z); - org.bukkit.block.Block bukkitBlock = location.getBlock(); - BlockState state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); + 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 = levelChunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK); + BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK); if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - blockEntity.save(tag); // readTileEntityIntoTag - load data + //TODO 1.18 recheck logic, I may skipped loading - NMF + net.minecraft.nbt.CompoundTag tag = blockEntity.save(new net.minecraft.nbt.CompoundTag()); return state.toBaseBlock((CompoundTag) toNative(tag)); } } 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 725ce504d..61dcd63f8 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 @@ -25,7 +25,6 @@ import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BlockTypes; import io.papermc.lib.PaperLib; import io.papermc.paper.event.block.BeaconDeactivatedEvent; import net.minecraft.core.BlockPos; @@ -151,7 +150,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (light != null) { lightUpdate = true; try { - fillLightNibble(light, LightLayer.SKY, minSectionPosition, maxSectionPosition); + fillLightNibble(light, LightLayer.BLOCK, minSectionPosition, maxSectionPosition); } catch (Throwable e) { e.printStackTrace(); } @@ -546,25 +545,27 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } // Biomes - BiomeType[] biomes = set.getBiomes(); + BiomeType[][] biomes = set.getBiomes(); if (biomes != null) { // set biomes ChunkBiomeContainer currentBiomes = nmsChunk.getBiomes(); if (createCopy) { copy.storeBiomes(currentBiomes); } - for (int y = 0, i = 0; y < 64; y++) { - for (int z = 0; z < 4; z++) { - for (int x = 0; x < 4; x++, i++) { - final BiomeType biome = biomes[i]; - if (biome != null) { - Biome nmsBiome = - nmsWorld.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).get( - ResourceLocation.tryParse(biome.getId())); - if (nmsBiome == null) { - throw new NullPointerException("BiomeBase null for BiomeType " + biome.getId()); + for (int layer = 0; layer < 16; layer++) { + for (int y = 0, i = 0; y < 4; y++) { + for (int z = 0; z < 4; z++) { + for (int x = 0; x < 4; x++, i++) { + final BiomeType biome = biomes[layer][i]; + if (biome != null) { + Biome nmsBiome = + nmsWorld.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).get( + ResourceLocation.tryParse(biome.getId())); + if (nmsBiome == null) { + throw new NullPointerException("BiomeBase null for BiomeType " + biome.getId()); + } + currentBiomes.setBiome(x, (layer << 2) + y, z, nmsBiome); } - currentBiomes.setBiome(x, y, z, nmsBiome); } } } @@ -925,7 +926,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc private char ordinal(net.minecraft.world.level.block.state.BlockState ibd, PaperweightFaweAdapter adapter) { if (ibd == null) { - return BlockTypes.AIR.getDefaultState().getOrdinalChar(); + return 1; } else { return adapter.adaptToChar(ibd); } diff --git a/worldedit-bukkit/adapters/adapter-1_18/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_18/build.gradle.kts index c1f95639f..241ab7d14 100644 --- a/worldedit-bukkit/adapters/adapter-1_18/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_18/build.gradle.kts @@ -12,7 +12,6 @@ repositories { } dependencies { - paperDevBundle("1.18-rc3-R0.1-20211129.221606-5") //TODO 1.18 switch to mainline + paperDevBundle("1.18.1-R0.1-20211218.091106-15") compileOnly(libs.paperlib) - compileOnly(libs.paper) } diff --git a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightAdapter.java index 9522d3ced..01b5ac23f 100644 --- a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightAdapter.java @@ -30,27 +30,15 @@ import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec; import com.mojang.serialization.Dynamic; 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.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.Refraction; +import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.PaperweightFaweAdapter; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extension.platform.Watchdog; import com.sk89q.worldedit.extent.Extent; @@ -70,6 +58,20 @@ import com.sk89q.worldedit.util.SideEffect; 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; @@ -142,6 +144,7 @@ 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; @@ -163,12 +166,11 @@ import java.util.concurrent.ForkJoinPool; 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 { +public final class PaperweightAdapter implements BukkitImplAdapter { private final Logger logger = Logger.getLogger(getClass().getCanonicalName()); @@ -186,8 +188,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter { CraftServer.class.cast(Bukkit.getServer()); int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion(); - if (dataVersion != 2860) { - throw new UnsupportedClassVersionError("Not 1.18!"); + if (dataVersion != 2860 && dataVersion != 2865) { + throw new UnsupportedClassVersionError("Not 1.18 or 1.18.1!"); } serverWorldsField = CraftServer.class.getDeclaredField("worlds"); @@ -235,7 +237,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter { * Read the given NBT data into the given tile entity. * * @param tileEntity the tile entity - * @param tag the tag + * @param tag the tag */ static void readTagIntoTileEntity(net.minecraft.nbt.CompoundTag tag, BlockEntity tileEntity) { tileEntity.load(tag); @@ -255,7 +257,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter { /** * Create an entity using the given entity ID. * - * @param id the entity ID + * @param id the entity ID * @param world the world * @return an entity or null */ @@ -268,7 +270,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter { * Write the given NBT data into the given entity. * * @param entity the entity - * @param tag the tag + * @param tag the tag */ private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) { entity.load(tag); @@ -278,7 +280,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter { * Write the entity's NBT data to the given tag. * * @param entity the entity - * @param tag the tag + * @param tag the tag */ private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag tag) { entity.save(tag); @@ -321,9 +323,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter { 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); + 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()); @@ -349,7 +350,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter { BlockEntity te = chunk.getBlockEntity(blockPos); if (te != null) { net.minecraft.nbt.CompoundTag tag = te.saveWithId(); - return state.toBaseBlock((CompoundTag) toNative(tag)); + //FAWE start - BinaryTag + return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag)); + //FAWE end } return state.toBaseBlock(); @@ -357,8 +360,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter { @Override public WorldNativeAccess createWorldNativeAccess(org.bukkit.World world) { - return new PaperweightWorldNativeAccess(this, - new WeakReference<>(((CraftWorld) world).getHandle())); + return new PaperweightWorldNativeAccess( + this, + new WeakReference<>(((CraftWorld) world).getHandle()) + ); } private static net.minecraft.core.Direction adapt(Direction face) { @@ -470,7 +475,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter { return TranslatableComponent.of(CraftItemStack.asNMSCopy(BukkitAdapter.adapt(itemStack)).getDescriptionId()); } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings({"unchecked", "rawtypes"}) @Override public Map> getProperties(BlockType blockType) { Map> properties = Maps.newTreeMap(String::compareTo); @@ -482,11 +487,25 @@ public final class PaperweightAdapter implements BukkitImplAdapter { if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { property = new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); } else if (state instanceof DirectionProperty) { - property = new DirectionalProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).collect(Collectors.toList())); + property = 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) { - property = new EnumProperty(state.getName(), - (List) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).collect(Collectors.toList())); + property = 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) { property = new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); } else { @@ -499,13 +518,13 @@ public final class PaperweightAdapter implements BukkitImplAdapter { } @Override - public void sendFakeNBT(Player player, BlockVector3 pos, CompoundTag nbtData) { + public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) { ((CraftPlayer) player).getHandle().networkManager.send(ClientboundBlockEntityDataPacket.create( new StructureBlockEntity( new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()), Blocks.STRUCTURE_BLOCK.defaultBlockState() ), - __ -> (net.minecraft.nbt.CompoundTag) fromNative(nbtData) + __ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) )); } @@ -550,7 +569,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter { } fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack); fakePlayer.absMoveTo(position.getBlockX(), position.getBlockY(), position.getBlockZ(), - (float) face.toVector().toYaw(), (float) face.toVector().toPitch()); + (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); @@ -559,7 +579,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter { 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()) { + 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(); @@ -573,7 +596,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter { 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())); + return blockData.canSurvive( + ((CraftWorld) world).getHandle(), + new BlockPos(position.getX(), position.getY(), position.getZ()) + ); } @Override @@ -591,7 +617,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter { Environment env = bukkitWorld.getEnvironment(); ChunkGenerator gen = bukkitWorld.getGenerator(); - Path tempDir = Files.createTempDirectory("WorldEditWorldGen"); + Path tempDir = Files.createTempDirectory("FastAsyncWorldEditWorldGen"); LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir); ResourceKey worldDimKey = getWorldDimKey(env); try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("worldeditregentempworld", worldDimKey)) { @@ -675,7 +701,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter { } @SuppressWarnings("unchecked") - private Dynamic recursivelySetSeed(Dynamic dynamic, long seed, Set> seen) { + private Dynamic recursivelySetSeed( + Dynamic dynamic, + long seed, + Set> seen + ) { if (!seen.add(dynamic)) { return dynamic; } @@ -699,7 +729,8 @@ public final class PaperweightAdapter implements BukkitImplAdapter { } @SuppressWarnings("unchecked") - private void regenForWorld(Region region, Extent extent, ServerLevel serverWorld, RegenOptions options) throws WorldEditException { + private void regenForWorld(Region region, Extent extent, ServerLevel serverWorld, RegenOptions options) throws + WorldEditException { List> chunkLoadings = submitChunkLoadTasks(region, serverWorld); BlockableEventLoop executor; try { @@ -728,13 +759,16 @@ public final class PaperweightAdapter implements BukkitImplAdapter { 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); + 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(); - state = state.toBaseBlock(((CompoundTag) toNative(tag))); + //FAWE start - BinaryTag + state = state.toBaseBlock(((CompoundBinaryTag) toNativeBinary(tag))); + //FAWE end } extent.setBlock(vec, state.toBaseBlock()); if (options.shouldRegenBiomes()) { @@ -818,48 +852,50 @@ public final class PaperweightAdapter implements BukkitImplAdapter { * @param foreign non-native NMS NBT structure * @return native WorldEdit NBT structure */ - Tag toNative(net.minecraft.nbt.Tag foreign) { + //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<>(); + 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, toNative(base)); + values.put(str, toNativeBinary(base)); } - return new CompoundTag(values); + return CompoundBinaryTag.from(values); } else if (foreign instanceof net.minecraft.nbt.ByteTag) { - return new ByteTag(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); + return ByteBinaryTag.of(((net.minecraft.nbt.ByteTag) foreign).getAsByte()); } else if (foreign instanceof net.minecraft.nbt.ByteArrayTag) { - return new ByteArrayTag(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); + return ByteArrayBinaryTag.of(((net.minecraft.nbt.ByteArrayTag) foreign).getAsByteArray()); } else if (foreign instanceof net.minecraft.nbt.DoubleTag) { - return new DoubleTag(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); + return DoubleBinaryTag.of(((net.minecraft.nbt.DoubleTag) foreign).getAsDouble()); } else if (foreign instanceof net.minecraft.nbt.FloatTag) { - return new FloatTag(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); + return FloatBinaryTag.of(((net.minecraft.nbt.FloatTag) foreign).getAsFloat()); } else if (foreign instanceof net.minecraft.nbt.IntTag) { - return new IntTag(((net.minecraft.nbt.IntTag) foreign).getAsInt()); + return IntBinaryTag.of(((net.minecraft.nbt.IntTag) foreign).getAsInt()); } else if (foreign instanceof net.minecraft.nbt.IntArrayTag) { - return new IntArrayTag(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); + return IntArrayBinaryTag.of(((net.minecraft.nbt.IntArrayTag) foreign).getAsIntArray()); } else if (foreign instanceof net.minecraft.nbt.LongArrayTag) { - return new LongArrayTag(((net.minecraft.nbt.LongArrayTag) foreign).getAsLongArray()); + 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 new ListTag(ByteTag.class, new ArrayList()); + return ListBinaryTag.empty(); } } else if (foreign instanceof net.minecraft.nbt.LongTag) { - return new LongTag(((net.minecraft.nbt.LongTag) foreign).getAsLong()); + return LongBinaryTag.of(((net.minecraft.nbt.LongTag) foreign).getAsLong()); } else if (foreign instanceof net.minecraft.nbt.ShortTag) { - return new ShortTag(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); + return ShortBinaryTag.of(((net.minecraft.nbt.ShortTag) foreign).getAsShort()); } else if (foreign instanceof net.minecraft.nbt.StringTag) { - return new StringTag(foreign.getAsString()); + return StringBinaryTag.of(foreign.getAsString()); } else if (foreign instanceof net.minecraft.nbt.EndTag) { - return new EndTag(); + return EndBinaryTag.get(); } else { throw new IllegalArgumentException("Don't know how to make native " + foreign.getClass().getCanonicalName()); } @@ -870,19 +906,17 @@ public final class PaperweightAdapter implements BukkitImplAdapter { * * @param foreign the foreign tag * @return the converted tag - * @throws SecurityException on error + * @throws SecurityException on error * @throws IllegalArgumentException on error */ - private ListTag toNativeList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException { - List values = new ArrayList<>(); - int type = foreign.getElementType(); + 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(toNative(tag)); + values.add(toNativeBinary(tag)); } - Class cls = NBTConstants.getClassFromType(type); - return new ListTag(cls, values); + return values.build(); } /** @@ -891,50 +925,51 @@ public final class PaperweightAdapter implements BukkitImplAdapter { * @param foreign structure to convert * @return non-native structure */ - net.minecraft.nbt.Tag fromNative(Tag foreign) { + @Override + public net.minecraft.nbt.Tag fromNativeBinary(BinaryTag foreign) { if (foreign == null) { return null; } - if (foreign instanceof CompoundTag) { + if (foreign instanceof CompoundBinaryTag) { net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - for (Map.Entry entry : ((CompoundTag) foreign) - .getValue().entrySet()) { - tag.put(entry.getKey(), fromNative(entry.getValue())); + for (String key : ((CompoundBinaryTag) foreign).keySet()) { + tag.put(key, fromNativeBinary(((CompoundBinaryTag) foreign).get(key))); } return tag; - } else if (foreign instanceof ByteTag) { - return net.minecraft.nbt.ByteTag.valueOf(((ByteTag) foreign).getValue()); - } else if (foreign instanceof ByteArrayTag) { - return new net.minecraft.nbt.ByteArrayTag(((ByteArrayTag) foreign).getValue()); - } else if (foreign instanceof DoubleTag) { - return net.minecraft.nbt.DoubleTag.valueOf(((DoubleTag) foreign).getValue()); - } else if (foreign instanceof FloatTag) { - return net.minecraft.nbt.FloatTag.valueOf(((FloatTag) foreign).getValue()); - } else if (foreign instanceof IntTag) { - return net.minecraft.nbt.IntTag.valueOf(((IntTag) foreign).getValue()); - } else if (foreign instanceof IntArrayTag) { - return new net.minecraft.nbt.IntArrayTag(((IntArrayTag) foreign).getValue()); - } else if (foreign instanceof LongArrayTag) { - return new net.minecraft.nbt.LongArrayTag(((LongArrayTag) foreign).getValue()); - } else if (foreign instanceof ListTag) { + } 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(); - ListTag foreignList = (ListTag) foreign; - for (Tag t : foreignList.getValue()) { - tag.add(fromNative(t)); + ListBinaryTag foreignList = (ListBinaryTag) foreign; + for (BinaryTag t : foreignList) { + tag.add(fromNativeBinary(t)); } return tag; - } else if (foreign instanceof LongTag) { - return net.minecraft.nbt.LongTag.valueOf(((LongTag) foreign).getValue()); - } else if (foreign instanceof ShortTag) { - return net.minecraft.nbt.ShortTag.valueOf(((ShortTag) foreign).getValue()); - } else if (foreign instanceof StringTag) { - return net.minecraft.nbt.StringTag.valueOf(((StringTag) foreign).getValue()); - } else if (foreign instanceof EndTag) { + } 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() { @@ -947,6 +982,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter { } private class SpigotWatchdog implements Watchdog { + private final Field instanceField; private final Field lastTickField; @@ -971,9 +1007,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter { logger.log(Level.WARNING, "Failed to tick watchdog", e); } } + } private static class MojangWatchdog implements Watchdog { + private final DedicatedServer server; private final Field tickField; @@ -993,9 +1031,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter { } catch (IllegalAccessException ignored) { } } + } private static class NoOpWorldLoadListener implements ChunkProgressListener { + @Override public void updateSpawnPos(ChunkPos spawnPos) { } @@ -1015,5 +1055,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter { @Override public void setChunkRadius(int radius) { } + } + } diff --git a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightDataConverters.java index fa0b99a96..a445ed37d 100644 --- a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightDataConverters.java +++ b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightDataConverters.java @@ -34,7 +34,7 @@ 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; @@ -49,6 +49,7 @@ 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; @@ -62,31 +63,31 @@ 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" }) +@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((CompoundTag) original, srcVer); + return (T) fixChunk((CompoundBinaryTag) original, srcVer); } else if (type == FixTypes.BLOCK_ENTITY) { - return (T) fixBlockEntity((CompoundTag) original, srcVer); + return (T) fixBlockEntity((CompoundBinaryTag) original, srcVer); } else if (type == FixTypes.ENTITY) { - return (T) fixEntity((CompoundTag) original, srcVer); + return (T) fixEntity((CompoundBinaryTag) original, srcVer); } else if (type == FixTypes.BLOCK_STATE) { return (T) fixBlockState((String) original, srcVer); } else if (type == FixTypes.ITEM_TYPE) { @@ -97,28 +98,34 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return original; } - private CompoundTag fixChunk(CompoundTag originalChunk, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative(originalChunk); + 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 (CompoundTag) adapter.toNative(fixed); + return (CompoundBinaryTag) adapter.toNativeBinary(fixed); } - private CompoundTag fixBlockEntity(CompoundTag origTileEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative(origTileEnt); + 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 (CompoundTag) adapter.toNative(fixed); + return (CompoundBinaryTag) adapter.toNativeBinary(fixed); } - private CompoundTag fixEntity(CompoundTag origEnt, int srcVer) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) adapter.fromNative(origEnt); + 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 (CompoundTag) adapter.toNative(fixed); + 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(); + net.minecraft.nbt.CompoundTag fixed = (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update( + References.BLOCK_STATE, + dynamic, + srcVer, + DATA_VERSION + ).getValue(); return nbtToState(fixed); } @@ -128,7 +135,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo if (tagCompound.contains("Properties", 10)) { sb.append('['); net.minecraft.nbt.CompoundTag props = tagCompound.getCompound("Properties"); - sb.append(props.getAllKeys().stream().map(k -> k + "=" + props.getString(k).replace("\"", "")).collect(Collectors.joining(","))); + sb.append(props + .getAllKeys() + .stream() + .map(k -> k + "=" + props.getString(k).replace("\"", "")) + .collect(Collectors.joining(","))); sb.append(']'); } return sb.toString(); @@ -220,6 +231,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo @SuppressWarnings("unchecked") private class WrappedDataFixer implements DataFixer { + private final DataFixer realFixer; WrappedDataFixer(DataFixer realFixer) { @@ -240,7 +252,12 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return realFixer.update(type, dynamic, sourceVer, targetVer); } - private net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int desiredVersion) { + 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) { @@ -265,6 +282,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo public Schema getSchema(int i) { return realFixer.getSchema(i); } + } public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp) { @@ -275,7 +293,12 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return convert(type.getDFUType(), cmp, sourceVer); } - public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { + 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); } @@ -288,16 +311,25 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo 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) { + 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(); + 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 { @@ -305,6 +337,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo int getDataVersion(); net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp); + } @@ -582,7 +615,13 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return key; } - private static void convertCompound(LegacyType type, net.minecraft.nbt.CompoundTag cmp, String key, int sourceVer, int targetVer) { + 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)); } @@ -658,6 +697,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataInspectorBlockEntity implements DataInspector { @@ -840,6 +880,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } @@ -859,7 +900,12 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } - abstract net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer); + abstract net.minecraft.nbt.CompoundTag inspectChecked( + net.minecraft.nbt.CompoundTag nbttagcompound, + int sourceVer, + int targetVer + ); + } private static class DataInspectorItemList extends DataInspectorTagged { @@ -878,6 +924,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return nbttagcompound; } + } private static class DataInspectorItem extends DataInspectorTagged { @@ -896,6 +943,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return nbttagcompound; } + } private static class DataConverterMaterialId implements DataConverter { @@ -1296,6 +1344,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterBanner implements DataConverter { @@ -1342,6 +1391,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterPotionId implements DataConverter { @@ -1619,7 +1669,15 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo private static class DataConverterMinecart implements DataConverter { - private static final List a = Lists.newArrayList("MinecartRideable", "MinecartChest", "MinecartFurnace", "MinecartTNT", "MinecartSpawner", "MinecartHopper", "MinecartCommandBlock"); + private static final List a = Lists.newArrayList( + "MinecartRideable", + "MinecartChest", + "MinecartFurnace", + "MinecartTNT", + "MinecartSpawner", + "MinecartHopper", + "MinecartCommandBlock" + ); DataConverterMinecart() { } @@ -1643,6 +1701,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterMobSpawner implements DataConverter { @@ -1687,6 +1746,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } } + } private static class DataConverterUUID implements DataConverter { @@ -1705,11 +1765,47 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterHealth implements DataConverter { - private static final Set a = Sets.newHashSet("ArmorStand", "Bat", "Blaze", "CaveSpider", "Chicken", "Cow", "Creeper", "EnderDragon", "Enderman", "Endermite", "EntityHorse", "Ghast", "Giant", "Guardian", "LavaSlime", "MushroomCow", "Ozelot", "Pig", "PigZombie", "Rabbit", "Sheep", "Shulker", "Silverfish", "Skeleton", "Slime", "SnowMan", "Spider", "Squid", "Villager", "VillagerGolem", "Witch", "WitherBoss", "Wolf", "Zombie"); + private static final Set a = Sets.newHashSet( + "ArmorStand", + "Bat", + "Blaze", + "CaveSpider", + "Chicken", + "Cow", + "Creeper", + "EnderDragon", + "Enderman", + "Endermite", + "EntityHorse", + "Ghast", + "Giant", + "Guardian", + "LavaSlime", + "MushroomCow", + "Ozelot", + "Pig", + "PigZombie", + "Rabbit", + "Sheep", + "Shulker", + "Silverfish", + "Skeleton", + "Slime", + "SnowMan", + "Spider", + "Squid", + "Villager", + "VillagerGolem", + "Witch", + "WitherBoss", + "Wolf", + "Zombie" + ); DataConverterHealth() { } @@ -1738,6 +1834,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterSaddle implements DataConverter { @@ -1762,6 +1859,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterHanging implements DataConverter { @@ -1800,6 +1898,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterDropChances implements DataConverter { @@ -1823,13 +1922,15 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo if (cmp.contains("ArmorDropChances", 9)) { nbttaglist = cmp.getList("ArmorDropChances", 5); - if (nbttaglist.size() == 4 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F && nbttaglist.getFloat(2) == 0.0F && nbttaglist.getFloat(3) == 0.0F) { + if (nbttaglist.size() == 4 && nbttaglist.getFloat(0) == 0.0F && nbttaglist.getFloat(1) == 0.0F && nbttaglist.getFloat( + 2) == 0.0F && nbttaglist.getFloat(3) == 0.0F) { cmp.remove("ArmorDropChances"); } } return cmp; } + } private static class DataConverterRiding implements DataConverter { @@ -1865,6 +1966,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo nbttagcompound.remove("Riding"); return nbttagcompound1; } + } private static class DataConverterBook implements DataConverter { @@ -1933,6 +2035,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterCookedFish implements DataConverter { @@ -1953,6 +2056,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterZombie implements DataConverter { @@ -1995,6 +2099,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo private int convert(int i) { return i >= 0 && i < 6 ? i : -1; } + } private static class DataConverterVBO implements DataConverter { @@ -2010,6 +2115,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo cmp.putString("useVbo", "true"); return cmp; } + } private static class DataConverterGuardian implements DataConverter { @@ -2032,6 +2138,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterSkeleton implements DataConverter { @@ -2060,6 +2167,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterZombieType implements DataConverter { @@ -2098,6 +2206,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterHorse implements DataConverter { @@ -2140,6 +2249,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterTileEntity implements DataConverter { @@ -2302,7 +2412,8 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) { String s = cmp.getString("id"); - if ("minecraft:potion".equals(s) || "minecraft:splash_potion".equals(s) || "minecraft:lingering_potion".equals(s) || "minecraft:tipped_arrow".equals(s)) { + if ("minecraft:potion".equals(s) || "minecraft:splash_potion".equals(s) || "minecraft:lingering_potion".equals(s) || "minecraft:tipped_arrow".equals( + s)) { net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompound("tag"); if (!nbttagcompound1.contains("Potion", 8)) { @@ -2316,6 +2427,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterShulker implements DataConverter { @@ -2334,11 +2446,12 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterShulkerBoxItem implements DataConverter { - public static final String[] a = new String[] { "minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box" }; + public static final String[] a = new String[]{"minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box"}; DataConverterShulkerBoxItem() { } @@ -2375,6 +2488,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterShulkerBoxBlock implements DataConverter { @@ -2393,6 +2507,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterLang implements DataConverter { @@ -2411,6 +2526,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterTotem implements DataConverter { @@ -2429,6 +2545,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterBedBlock implements DataConverter { @@ -2476,6 +2593,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterBedItem implements DataConverter { @@ -2494,12 +2612,14 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataConverterSignText implements DataConverter { public static final Gson a = new GsonBuilder().registerTypeAdapter(Component.class, new JsonDeserializer() { - MutableComponent a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { + MutableComponent a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws + JsonParseException { if (jsonelement.isJsonPrimitive()) { return new TextComponent(jsonelement.getAsString()); } else if (jsonelement.isJsonArray()) { @@ -2509,7 +2629,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo while (iterator.hasNext()) { JsonElement jsonelement1 = (JsonElement) iterator.next(); - MutableComponent ichatbasecomponent1 = this.a(jsonelement1, jsonelement1.getClass(), jsondeserializationcontext); + MutableComponent ichatbasecomponent1 = this.a( + jsonelement1, + jsonelement1.getClass(), + jsondeserializationcontext + ); if (ichatbasecomponent == null) { ichatbasecomponent = ichatbasecomponent1; @@ -2524,7 +2648,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo } } - public Object deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException { + public Object deserialize( + JsonElement jsonelement, + Type type, + JsonDeserializationContext jsondeserializationcontext + ) throws JsonParseException { return this.a(jsonelement, type, jsondeserializationcontext); } }).create(); @@ -2590,9 +2718,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo 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)) { @@ -2605,9 +2735,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataInspectorLevelPlayer implements DataInspector { + @Override public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { if (cmp.contains("Player", 10)) { @@ -2616,9 +2748,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataInspectorStructure implements DataInspector { + @Override public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { net.minecraft.nbt.ListTag nbttaglist; @@ -2649,9 +2783,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataInspectorChunks implements DataInspector { + @Override public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { if (cmp.contains("Level", 10)) { @@ -2663,7 +2799,15 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo nbttaglist = nbttagcompound1.getList("Entities", 10); for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); + nbttaglist.set( + j, + convert( + LegacyType.ENTITY, + (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), + sourceVer, + targetVer + ) + ); } } @@ -2671,16 +2815,26 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo nbttaglist = nbttagcompound1.getList("TileEntities", 10); for (j = 0; j < nbttaglist.size(); ++j) { - nbttaglist.set(j, convert(LegacyType.BLOCK_ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer)); + nbttaglist.set( + j, + convert( + LegacyType.BLOCK_ENTITY, + (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), + sourceVer, + targetVer + ) + ); } } } return cmp; } + } private static class DataInspectorEntityPassengers implements DataInspector { + @Override public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { if (cmp.contains("Passengers", 9)) { @@ -2693,9 +2847,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataInspectorPlayer implements DataInspector { + @Override public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) { convertItems(cmp, "Inventory", sourceVer, targetVer); @@ -2710,9 +2866,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataInspectorVillagers implements DataInspector { + ResourceLocation entityVillager = getKey("EntityVillager"); @Override @@ -2736,9 +2894,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataInspectorMobSpawnerMinecart implements DataInspector { + ResourceLocation entityMinecartMobSpawner = getKey("EntityMinecartMobSpawner"); ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); @@ -2753,9 +2913,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataInspectorMobSpawnerMobs implements DataInspector { + ResourceLocation tileEntityMobSpawner = getKey("TileEntityMobSpawner"); @Override @@ -2776,9 +2938,11 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } private static class DataInspectorCommandBlock implements DataInspector { + ResourceLocation tileEntityCommand = getKey("TileEntityCommand"); @Override @@ -2791,5 +2955,7 @@ class PaperweightDataConverters extends DataFixerBuilder implements com.sk89q.wo return cmp; } + } + } diff --git a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightFakePlayer.java b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightFakePlayer.java index d67ed35a1..33656c5f8 100644 --- a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightFakePlayer.java +++ b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightFakePlayer.java @@ -37,7 +37,11 @@ import java.util.OptionalInt; import java.util.UUID; class PaperweightFakePlayer extends ServerPlayer { - private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]"); + + private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile( + UUID.nameUUIDFromBytes("worldedit".getBytes()), + "[WorldEdit]" + ); private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D); PaperweightFakePlayer(ServerLevel world) { @@ -95,4 +99,5 @@ class PaperweightFakePlayer extends ServerPlayer { @Override public void openTextEdit(SignBlockEntity sign) { } + } diff --git a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightWorldNativeAccess.java index 3776a9e6d..82f13cfb7 100644 --- a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_18_R1/PaperweightWorldNativeAccess.java @@ -19,29 +19,29 @@ package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R1; -import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.internal.block.BlockStateIdAccess; import com.sk89q.worldedit.internal.wna.WorldNativeAccess; import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.SideEffectSet; +import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.world.block.BlockState; import net.minecraft.core.BlockPos; -import net.minecraft.nbt.Tag; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.LevelChunk; import org.bukkit.craftbukkit.v1_18_R1.CraftWorld; import org.bukkit.craftbukkit.v1_18_R1.block.data.CraftBlockData; import org.bukkit.event.block.BlockPhysicsEvent; +import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.util.Objects; -import javax.annotation.Nullable; -public class PaperweightWorldNativeAccess implements WorldNativeAccess { +public class PaperweightWorldNativeAccess implements + WorldNativeAccess { + private static final int UPDATE = 1; private static final int NOTIFY = 2; @@ -83,12 +83,19 @@ public class PaperweightWorldNativeAccess implements WorldNativeAccess tileEntity.save(new net.minecraft.nbt.CompoundTag()))); - // TODO 1.18 save -> saveAdditional + : new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); } public Block getBlock() { diff --git a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightFaweAdapter.java index 160dcbed7..d7e1c8914 100644 --- a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightFaweAdapter.java @@ -1,5 +1,6 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1; +import ca.spottedleaf.starlight.common.light.StarLightEngine; import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter; import com.fastasyncworldedit.bukkit.adapter.IDelegateBukkitImplAdapter; import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory; @@ -22,7 +23,6 @@ import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R1.PaperweightAdapter; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.nbt.PaperweightLazyCompoundTag; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.regen.PaperweightRegen; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.internal.block.BlockStateIdAccess; @@ -55,7 +55,7 @@ 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.ClientboundLevelChunkPacketData; +import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ChunkHolder; @@ -229,9 +229,24 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements return Registry.BLOCK.get(new ResourceLocation(blockType.getNamespace(), blockType.getResource())); } - @SuppressWarnings("deprecation") + @Deprecated @Override - public BaseBlock getBlock(Location location) { + 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); + return adapt(blockData); + } + + @Override + public BaseBlock getFullBlock(final Location location) { Preconditions.checkNotNull(location); CraftWorld craftWorld = ((CraftWorld) location.getWorld()); @@ -239,19 +254,21 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements int y = location.getBlockY(); int z = location.getBlockZ(); - final ServerLevel serverLevel = craftWorld.getHandle(); - LevelChunk levelChunk = serverLevel.getChunk(x >> 4, z >> 4); + final ServerLevel handle = craftWorld.getHandle(); + LevelChunk chunk = handle.getChunk(x >> 4, z >> 4); final BlockPos blockPos = new BlockPos(x, y, z); - org.bukkit.block.Block bukkitBlock = location.getBlock(); - BlockState state = BukkitAdapter.adapt(bukkitBlock.getBlockData()); + 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 = levelChunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK); + BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK); if (blockEntity != null) { - net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); - //TODO save -> saveAdditional - blockEntity.save(tag); // readTileEntityIntoTag - load data + net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); return state.toBaseBlock((CompoundTag) toNative(tag)); } } @@ -305,12 +322,6 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements if (existing == blockState) { return true; } - if (section == null) { - if (blockState.isAir()) { - return true; - } - levelChunkSections[y4] = section = new LevelChunkSection(y4 << 4); - } levelChunk.setBlockState(blockPos, blockState, false); } if (update) { @@ -482,7 +493,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements stream.filter(entityPlayer -> checkPlayer == null || entityPlayer == checkPlayer) .forEach(entityPlayer -> { synchronized (chunkPacket) { - ClientboundLevelChunkPacketData nmsPacket = (ClientboundLevelChunkPacketData) chunkPacket.getNativePacket(); + ClientboundLevelChunkWithLightPacket nmsPacket = (ClientboundLevelChunkWithLightPacket) chunkPacket.getNativePacket(); if (nmsPacket == null) { nmsPacket = mapUtil.create(this, chunkPacket); chunkPacket.setNativePacket(nmsPacket); @@ -600,7 +611,8 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements @Override public boolean regenerate(org.bukkit.World bukkitWorld, Region region, Extent target, RegenOptions options) throws Exception { - return new PaperweightRegen(bukkitWorld, region, target, options).regenerate(); +// return new PaperweightRegen(bukkitWorld, region, target, options).regenerate(); + return false; } @Override @@ -644,7 +656,7 @@ public final class PaperweightFaweAdapter extends CachedBukkitAdapter implements @Override public RelighterFactory getRelighterFactory() { try { - Class.forName("ca.spottedleaf.starlight.light.StarLightEngine"); + Class.forName("ca.spottedleaf.starlight.common.light.StarLightEngine"); if (PaperweightStarlightRelighter.isUsable()) { return new PaperweightStarlightRelighterFactory(); } diff --git a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightFaweWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightFaweWorldNativeAccess.java index d9575fc3f..e6bb23523 100644 --- a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightFaweWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightFaweWorldNativeAccess.java @@ -275,8 +275,21 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ()); private static final Function nmsTile2We = - tileEntity -> new PaperweightLazyCompoundTag(Suppliers.memoize( - //TODO save -> saveAdditional - () -> tileEntity.save(new net.minecraft.nbt.CompoundTag()))); + tileEntity -> new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin .getInstance() .getBukkitImplAdapter()); @@ -100,6 +97,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc private final int maxHeight; private final int minSectionPosition; private final int maxSectionPosition; + private final Registry biomeRegistry; private LevelChunkSection[] sections; private LevelChunk levelChunk; private DataLayer[] blockLight; @@ -124,6 +122,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc this.maxSectionPosition = maxHeight >> 4; this.skyLight = new DataLayer[getSectionCount()]; this.blockLight = new DataLayer[getSectionCount()]; + this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY); } public int getChunkX() { @@ -154,7 +153,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (light != null) { lightUpdate = true; try { - fillLightNibble(light, LightLayer.SKY, minSectionPosition, maxSectionPosition); + fillLightNibble(light, LightLayer.BLOCK, minSectionPosition, maxSectionPosition); } catch (Throwable e) { e.printStackTrace(); } @@ -194,19 +193,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc @Override public BiomeType getBiomeType(int x, int y, int z) { - ChunkBiomeContainer index = getChunk().getBiomes(); - Biome biomes = null; - if (y == -1) { - for (y = serverLevel.getMinBuildHeight(); y < serverLevel.getMaxBuildHeight(); y += 4) { - biomes = index.getNoiseBiome(x >> 2, y >> 2, z >> 2); - if (biomes != null) { - break; - } - } - } else { - biomes = index.getNoiseBiome(x >> 2, y >> 2, z >> 2); - } - return biomes != null ? PaperweightPlatformAdapter.adapt(biomes, serverLevel) : null; + LevelChunkSection section = getSections(false)[(y >> 4) - getMinSectionPosition()]; + Biome biomes = section.getNoiseBiome(x >> 2, (y & 15) >> 2, z >> 2); + return PaperweightPlatformAdapter.adapt(biomes, serverLevel); } @Override @@ -217,10 +206,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (dataLayer != null) { lightUpdate = true; synchronized (dataLayer) { - byte[] bytes = PaperLib.isPaper() ? dataLayer.getIfSet() : dataLayer.getData(); - if (!PaperLib.isPaper() || bytes != DataLayer.EMPTY_NIBBLE) { - Arrays.fill(bytes, (byte) 0); - } + byte[] bytes = dataLayer.getData(); + Arrays.fill(bytes, (byte) 0); } } if (sky) { @@ -233,10 +220,8 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (dataLayer1 != null) { lightUpdate = true; synchronized (dataLayer1) { - byte[] bytes = PaperLib.isPaper() ? dataLayer1.getIfSet() : dataLayer1.getData(); - if (!PaperLib.isPaper() || bytes != DataLayer.EMPTY_NIBBLE) { - Arrays.fill(bytes, (byte) 0); - } + byte[] bytes = dataLayer1.getData(); + Arrays.fill(bytes, (byte) 0); } } } @@ -251,7 +236,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (blockEntity == null) { return null; } - return new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.save(new net.minecraft.nbt.CompoundTag()))); + return new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)); } @Override @@ -450,18 +435,67 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } } } + 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().copy()); + } + + if (existingSection == null) { + PalettedContainer biomeData = PaperweightPlatformAdapter.getBiomePalettedContainer( + biomes[setSectionIndex], + biomeRegistry + ); + LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + new char[4096], + fastmode, + adapter, + biomeRegistry, + biomeData + ); + if (PaperweightPlatformAdapter.setSectionAtomic(levelChunkSections, null, newSection, getSectionIndex)) { + updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); + continue; + } else { + existingSection = levelChunkSections[getSectionIndex]; + if (existingSection == null) { + LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, + getSectionIndex + ); + continue; + } + } + } else { + PalettedContainer biomeData = existingSection.getBiomes(); + setBiomesToPalettedContainer(biomes[setSectionIndex], biomeData); + } + } + } continue; } - int layer = layerNo - getMinSectionPosition(); - bitMask |= 1 << layer; + bitMask |= 1 << getSectionIndex; char[] tmp = set.load(layerNo); char[] setArr = new char[4096]; @@ -469,26 +503,44 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was // submitted to keep loaded internal chunks to queue target size. - synchronized (super.sectionLocks[layer]) { + synchronized (super.sectionLocks[getSectionIndex]) { + + LevelChunkSection newSection; + LevelChunkSection existingSection = levelChunkSections[getSectionIndex]; + if (createCopy) { char[] tmpLoad = loadPrivately(layerNo); char[] copyArr = new char[4096]; System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); - copy.storeSection(layer, copyArr); + copy.storeSection(getSectionIndex, copyArr); + if (biomes != null && existingSection != null) { + copy.storeBiomes(getSectionIndex, existingSection.getBiomes().copy()); + } } - LevelChunkSection newSection; - LevelChunkSection existingSection = levelChunkSections[layer]; if (existingSection == null) { - newSection = PaperweightPlatformAdapter.newChunkSection(layerNo, setArr, fastmode, adapter); - if (PaperweightPlatformAdapter.setSectionAtomic(levelChunkSections, null, newSection, layer)) { - updateGet(nmsChunk, levelChunkSections, newSection, setArr, layer); + PalettedContainer biomeData = biomes == null ? new PalettedContainer<>( + biomeRegistry, + biomeRegistry.getOrThrow(Biomes.PLAINS), + PalettedContainer.Strategy.SECTION_BIOMES, + null + ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeRegistry); + newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + setArr, + fastmode, + adapter, + biomeRegistry, + biomeData + ); + if (PaperweightPlatformAdapter.setSectionAtomic(levelChunkSections, null, newSection, getSectionIndex)) { + updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex); continue; } else { - existingSection = levelChunkSections[layer]; + existingSection = levelChunkSections[getSectionIndex]; if (existingSection == null) { LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - +layer + getSectionIndex ); continue; } @@ -507,10 +559,10 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc this.levelChunk = nmsChunk; this.sections = null; this.reset(); - } else if (existingSection != getSections(false)[layer]) { - this.sections[layer] = existingSection; + } else if (existingSection != getSections(false)[getSectionIndex]) { + this.sections[getSectionIndex] = existingSection; this.reset(); - } else if (!Arrays.equals(update(layer, new char[4096], true), loadPrivately(layerNo))) { + } else if (!Arrays.equals(update(getSectionIndex, new char[4096], true), loadPrivately(layerNo))) { this.reset(layerNo); /*} else if (lock.isModified()) { this.reset(layerNo);*/ @@ -518,51 +570,34 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } finally { sectionLock.writeLock().unlock(); } + + PalettedContainer biomeData = existingSection.getBiomes(); + + if (biomes != null && biomes[setSectionIndex] != null) { + setBiomesToPalettedContainer(biomes[setSectionIndex], biomeData); + } + newSection = PaperweightPlatformAdapter.newChunkSection( layerNo, this::loadPrivately, setArr, fastmode, - adapter + adapter, + biomeRegistry, + biomeData ); if (!PaperweightPlatformAdapter.setSectionAtomic( levelChunkSections, existingSection, newSection, - layer + getSectionIndex )) { LOGGER.error("Skipping invalid null section. chunk: {}, {} layer: {}", chunkX, chunkZ, - +layer + getSectionIndex ); } else { - updateGet(nmsChunk, levelChunkSections, newSection, setArr, layer); - } - } - } - } - - // Biomes - BiomeType[] biomes = set.getBiomes(); - if (biomes != null) { - // set biomes - ChunkBiomeContainer currentBiomes = nmsChunk.getBiomes(); - if (createCopy) { - copy.storeBiomes(currentBiomes); - } - for (int y = 0, i = 0; y < 64; y++) { - for (int z = 0; z < 4; z++) { - for (int x = 0; x < 4; x++, i++) { - final BiomeType biome = biomes[i]; - if (biome != null) { - Biome nmsBiome = - nmsWorld.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).get( - ResourceLocation.tryParse(biome.getId())); - if (nmsBiome == null) { - throw new NullPointerException("BiomeBase null for BiomeType " + biome.getId()); - } - currentBiomes.setBiome(x, y, z, nmsBiome); - } + updateGet(nmsChunk, levelChunkSections, newSection, setArr, getSectionIndex); } } } @@ -665,7 +700,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } entity.load(tag); entity.absMoveTo(x, y, z, yaw, pitch); - nmsWorld.addEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); + nmsWorld.addFreshEntity(entity, CreatureSpawnEvent.SpawnReason.CUSTOM); } } } @@ -718,7 +753,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc // Set Modified nmsChunk.setLightCorrect(true); // Set Modified nmsChunk.mustNotSave = false; - nmsChunk.isUnsaved(); // TODO 1.18 revisit + nmsChunk.setUnsaved(true); // send to player if (Settings.IMP.LIGHTING.MODE == 0 || !Settings.IMP.LIGHTING.DELAY_PACKET_SENDING) { this.send(finalMask, finalLightUpdate); @@ -857,10 +892,17 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc lock.acquire(); final PalettedContainer blocks = section.getStates(); - final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(blocks); - final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get(blocks); + final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocks); + final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); - final int bitsPerEntry = (int) PaperweightPlatformAdapter.fieldBitsPerEntry.get(bits); + if (bits instanceof ZeroBitStorage) { + Arrays.fill(data, (char) 0); + 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); @@ -924,7 +966,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc private char ordinal(net.minecraft.world.level.block.state.BlockState ibd, PaperweightFaweAdapter adapter) { if (ibd == null) { - return BlockTypes.AIR.getDefaultState().getOrdinalChar(); + return 1; } else { return adapter.adaptToChar(ibd); } @@ -999,6 +1041,32 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } } + private void setBiomesToPalettedContainer( + final BiomeType[] biomes, + PalettedContainer data + ) { + int index = 0; + if (biomes == null) { + return; + } + 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; + } + data.set( + x, + y, + z, + biomeRegistry.get(ResourceLocation.tryParse(biomeType.getId())) + ); + } + } + } + } + @Override public boolean hasSection(int layer) { layer -= getMinSectionPosition(); @@ -1028,8 +1096,10 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc try { final PalettedContainer blocksExisting = existing.getStates(); + final Object dataObject = PaperweightPlatformAdapter.fieldData.get(blocksExisting); + //TODO this field doesn't exist in 1.18 final Palette palette = (Palette) PaperweightPlatformAdapter.fieldPalette.get( - blocksExisting); + dataObject); int paletteSize; if (palette instanceof LinearPalette || palette instanceof HashMapPalette) { diff --git a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightGetBlocks_Copy.java index 2915de82e..d07b8b9b1 100644 --- a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightGetBlocks_Copy.java @@ -18,7 +18,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.chunk.ChunkBiomeContainer; +import net.minecraft.world.level.chunk.PalettedContainer; import javax.annotation.Nullable; import java.util.HashMap; @@ -36,7 +36,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final int minHeight; private final int maxHeight; private final ServerLevel serverLevel; - private ChunkBiomeContainer chunkBiomeContainer; + private PalettedContainer[] biomes = null; protected PaperweightGetBlocks_Copy(ServerLevel world) { this.serverLevel = world; @@ -52,8 +52,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { blockEntity.getBlockPos().getY(), blockEntity.getBlockPos().getZ() ), - new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.save(new net.minecraft.nbt.CompoundTag()))) - //TODO 1.18 save -> saveAdditional + new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)) ); } @@ -142,27 +141,9 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { return minHeight >> 4; } - protected void storeBiomes(ChunkBiomeContainer chunkBiomeContainer) { - // The to do one line below is pre-paperweight and needs to be revised - // TODO revisit last parameter, BiomeStorage[] *would* be more efficient - this.chunkBiomeContainer = new ChunkBiomeContainer(chunkBiomeContainer.biomeRegistry, serverLevel, - chunkBiomeContainer.writeBiomes() - ); - } - @Override public BiomeType getBiomeType(int x, int y, int z) { - Biome biome = null; - if (y == -1) { - for (y = serverLevel.getMinBuildHeight(); y <= serverLevel.getMaxBuildHeight(); y += 4) { - biome = this.chunkBiomeContainer.getNoiseBiome(x >> 2, y >> 2, z >> 2); - if (biome != null) { - break; - } - } - } else { - biome = this.chunkBiomeContainer.getNoiseBiome(x >> 2, y >> 2, z >> 2); - } + Biome biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); return biome != null ? PaperweightPlatformAdapter.adapt(biome, serverLevel) : null; } @@ -189,6 +170,13 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { blocks[layer] = data; } + protected void storeBiomes(int layer, PalettedContainer biomeData) { + if (biomes == null) { + biomes = new PalettedContainer[getSectionCount()]; + } + biomes[layer] = biomeData; + } + @Override public BaseBlock getFullBlock(int x, int y, int z) { BlockState state = BlockTypesCache.states[get(x, y, z)]; diff --git a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightMapChunkUtil.java b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightMapChunkUtil.java index 093648f3e..5f59cc498 100644 --- a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightMapChunkUtil.java +++ b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/PaperweightMapChunkUtil.java @@ -4,16 +4,19 @@ import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil; import com.sk89q.worldedit.bukkit.adapter.Refraction; import net.minecraft.network.protocol.game.ClientboundLevelChunkPacketData; -public class PaperweightMapChunkUtil extends MapChunkUtil { +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 = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("x", "b")); - fieldBitMask = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("z", "c")); - fieldHeightMap = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("availableSections", "d")); - fieldChunkData = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("biomes", "f")); - fieldBlockEntities = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("buffer", "g")); - fieldFull = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("blockEntitiesTags", "h")); + 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); @@ -24,7 +27,7 @@ public class PaperweightMapChunkUtil extends MapChunkUtil dataConstructor; + public static final Field fieldStorage; public static final Field fieldPalette; - public static final Field fieldBits; - public static final Field fieldBitsPerEntry; public static final Field fieldTickingFluidContent; public static final Field fieldTickingBlockCount; public static final Field fieldNonEmptyBlockCount; - private static final Field fieldBiomes; - 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; @@ -92,15 +107,18 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { static { try { - fieldBits = PalettedContainer.class.getDeclaredField(Refraction.pickName("bits", "l")); - fieldBits.setAccessible(true); - fieldStorage = PalettedContainer.class.getDeclaredField(Refraction.pickName("storage", "c")); - fieldStorage.setAccessible(true); - fieldPalette = PalettedContainer.class.getDeclaredField(Refraction.pickName("palette", "k")); - fieldPalette.setAccessible(true); + fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d")); + fieldData.setAccessible(true); - fieldBitsPerEntry = BitStorage.class.getDeclaredField(Refraction.pickName("bits", "c")); - fieldBitsPerEntry.setAccessible(true); + Class dataClazz = fieldData.getType(); + dataConstructor = dataClazz.getDeclaredConstructors()[0]; + dataConstructor.setAccessible(true); + + //TODO FIXME 1.18 + fieldStorage = dataClazz.getDeclaredField(Refraction.pickName("storage", "b")); + fieldStorage.setAccessible(true); + fieldPalette = dataClazz.getDeclaredField(Refraction.pickName("palette", "c")); + fieldPalette.setAccessible(true); fieldTickingFluidContent = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "h")); fieldTickingFluidContent.setAccessible(true); @@ -109,27 +127,27 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "f")); fieldNonEmptyBlockCount.setAccessible(true); - fieldBiomes = ChunkBiomeContainer.class.getDeclaredField(Refraction.pickName("biomes", "f")); - fieldBiomes.setAccessible(true); - Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( "getVisibleChunkIfPresent", - "getVisibleChunk" + "b" ), long.class); getVisibleChunkIfPresent.setAccessible(true); methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent); Unsafe unsafe = ReflectionUtils.getUnsafe(); - fieldLock = PalettedContainer.class.getDeclaredField(Refraction.pickName("lock", "m")); + fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f")); + fieldThreadingDetectorOffset = unsafe.objectFieldOffset(fieldThreadingDetector); + + fieldLock = ThreadingDetector.class.getDeclaredField(Refraction.pickName("lock", "c")); fieldLockOffset = unsafe.objectFieldOffset(fieldLock); fieldGameEventDispatcherSections = LevelChunk.class.getDeclaredField(Refraction.pickName( - "gameEventDispatcherSections", "x")); + "gameEventDispatcherSections", "t")); fieldGameEventDispatcherSections.setAccessible(true); Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod( Refraction.pickName( "removeBlockEntityTicker", - "l" + "m" ), BlockPos.class ); removeBlockEntityTicker.setAccessible(true); @@ -166,18 +184,21 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } static DelegateSemaphore applyLock(LevelChunkSection section) { - //todo there has to be a better way to do this. Maybe using a() in DataPaletteBlock which acquires the lock in NMS? try { synchronized (section) { Unsafe unsafe = ReflectionUtils.getUnsafe(); PalettedContainer blocks = section.getStates(); - Semaphore currentLock = (Semaphore) unsafe.getObject(blocks, fieldLockOffset); - if (currentLock instanceof DelegateSemaphore) { - return (DelegateSemaphore) currentLock; + ThreadingDetector currentThreadingDetector = (ThreadingDetector) unsafe.getObject(blocks, + fieldThreadingDetectorOffset) ; + synchronized(currentThreadingDetector) { + Semaphore currentLock = (Semaphore) unsafe.getObject(currentThreadingDetector, fieldLockOffset); + if (currentLock instanceof DelegateSemaphore) { + return (DelegateSemaphore) currentLock; + } + DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); + unsafe.putObject(currentThreadingDetector, fieldLockOffset, newLock); + return newLock; } - DelegateSemaphore newLock = new DelegateSemaphore(1, currentLock); - unsafe.putObject(blocks, fieldLockOffset, newLock); - return newLock; } } catch (Throwable e) { e.printStackTrace(); @@ -248,21 +269,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } LevelChunk levelChunk = optional.get(); TaskManager.IMP.task(() -> { - ClientboundLevelChunkPacketData chunkPacket = new ClientboundLevelChunkPacketData(levelChunk); - nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(chunkPacket)); - if (lighting) { - //This needs to be true otherwise Minecraft will update lighting from/at the chunk edges (bad) - boolean trustEdges = true; - ClientboundLightUpdatePacket packet = - new ClientboundLightUpdatePacket(coordIntPair, nmsWorld.getChunkSource().getLightEngine(), null, null, - trustEdges - ); - nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); - } + ClientboundLevelChunkWithLightPacket packet = + new ClientboundLevelChunkWithLightPacket(levelChunk, nmsWorld.getChunkSource().getLightEngine(), null, null + , true, false); // last false is to not bother with x-ray + nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); }); } - private static Stream nearbyPlayers(ServerLevel serverLevel, ChunkPos coordIntPair) { + private static List nearbyPlayers(ServerLevel serverLevel, ChunkPos coordIntPair) { return serverLevel.getChunkSource().chunkMap.getPlayers(coordIntPair, false); } @@ -271,17 +285,19 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { */ public static LevelChunkSection newChunkSection( final int layer, final char[] blocks, boolean fastmode, - CachedBukkitAdapter adapter + CachedBukkitAdapter adapter, Registry biomeRegistry, + @Nullable PalettedContainer biomes ) { - return newChunkSection(layer, null, blocks, fastmode, adapter); + return newChunkSection(layer, null, blocks, fastmode, adapter, biomeRegistry, biomes); } public static LevelChunkSection newChunkSection( final int layer, final Function get, char[] set, - boolean fastmode, CachedBukkitAdapter adapter + boolean fastmode, CachedBukkitAdapter adapter, Registry biomeRegistry, + @Nullable PalettedContainer biomes ) { if (set == null) { - return newChunkSection(layer); + return newChunkSection(layer, biomeRegistry, biomes); } final int[] blockToPalette = FaweCache.IMP.BLOCK_TO_PALETTE.get(); final int[] paletteToBlock = FaweCache.IMP.PALETTE_TO_BLOCK.get(); @@ -302,17 +318,18 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } int num_palette = num_palette_buffer[0]; // BlockStates + int bitsPerEntry = MathMan.log2nlz(num_palette - 1); - if (Settings.IMP.PROTOCOL_SUPPORT_FIX || num_palette != 1) { - bitsPerEntry = Math.max(bitsPerEntry, 4); // Protocol support breaks <4 bits per entry - } else { - bitsPerEntry = Math.max(bitsPerEntry, 1); // For some reason minecraft needs 4096 bits to store 0 entries - } - if (bitsPerEntry > 8) { + Object configuration = + PalettedContainer.Strategy.SECTION_STATES.getConfiguration(new FakeIdMapBlock(num_palette), bitsPerEntry); + if (bitsPerEntry > 0 && bitsPerEntry < 5) { + bitsPerEntry = 4; + } else if (bitsPerEntry > 8) { bitsPerEntry = MathMan.log2nlz(Block.BLOCK_STATE_REGISTRY.size() - 1); } - final int blocksPerLong = MathMan.floorZero((double) 64 / bitsPerEntry); + 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) { @@ -320,55 +337,63 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { blockStates[i] = 0; } } else { - final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntry, 4096, blockStates); + final BitArrayUnstretched bitArray = new BitArrayUnstretched(bitsPerEntryNonZero, 4096, blockStates); bitArray.fromRaw(blocksCopy); } - LevelChunkSection levelChunkSection = newChunkSection(layer); - // set palette & data bits - final PalettedContainer dataPaletteBlocks = - levelChunkSection.getStates(); - // private DataPalette h; - // protected DataBits a; final long[] bits = Arrays.copyOfRange(blockStates, 0, blockBitArrayEnd); - final BitStorage nmsBits = new BitStorage(bitsPerEntry, 4096, bits); - final Palette blockStatePalettedContainer; - if (bitsPerEntry <= 4) { - blockStatePalettedContainer = new LinearPalette<>(Block.BLOCK_STATE_REGISTRY, bitsPerEntry, dataPaletteBlocks, - NbtUtils::readBlockState - ); - } else if (bitsPerEntry < 9) { - blockStatePalettedContainer = new HashMapPalette<>( - Block.BLOCK_STATE_REGISTRY, - bitsPerEntry, - dataPaletteBlocks, - NbtUtils::readBlockState, - NbtUtils::writeBlockState - ); + final BitStorage nmsBits; + if (bitsPerEntry == 0) { + nmsBits = new ZeroBitStorage(4096); } else { - blockStatePalettedContainer = LevelChunkSection.GLOBAL_BLOCKSTATE_PALETTE; + nmsBits = new SimpleBitStorage(bitsPerEntry, 4096, bits); } - - // set palette if required + final Palette blockStatePalette; + List palette; if (bitsPerEntry < 9) { + palette = new ArrayList<>(); for (int i = 0; i < num_palette; i++) { - final int ordinal = paletteToBlock[i]; + int ordinal = paletteToBlock[i]; blockToPalette[ordinal] = Integer.MAX_VALUE; final BlockState state = BlockTypesCache.states[ordinal]; - final net.minecraft.world.level.block.state.BlockState blockState = ((PaperweightBlockMaterial) state.getMaterial()).getState(); - blockStatePalettedContainer.idFor(blockState); + palette.add(((PaperweightBlockMaterial) state.getMaterial()).getState()); } + } else { + palette = List.of(); } + + // Create palette with data + 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, + null, + null + ); + LevelChunkSection levelChunkSection; try { - fieldStorage.set(dataPaletteBlocks, nmsBits); - fieldPalette.set(dataPaletteBlocks, blockStatePalettedContainer); - fieldBits.set(dataPaletteBlocks, bitsPerEntry); + //fieldStorage.set(dataPaletteBlocks, nmsBits); + //fieldPalette.set(dataPaletteBlocks, blockStatePalettedContainer); + if (biomes == null) { + biomes = new PalettedContainer<>( + biomeRegistry, + biomeRegistry.getOrThrow(Biomes.PLAINS), + PalettedContainer.Strategy.SECTION_BIOMES, + null + ); + } + levelChunkSection = new LevelChunkSection(layer, blockStatePalettedContainer, biomes); setCount(ticking_blocks.size(), 4096 - air, levelChunkSection); if (!fastmode) { - ticking_blocks.forEach((pos, ordinal) -> levelChunkSection - .setBlockState(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ(), - Block.stateById(ordinal) - )); + ticking_blocks.forEach((pos, ordinal) -> levelChunkSection.setBlockState( + pos.getBlockX(), + pos.getBlockY(), + pos.getBlockZ(), + Block.stateById(ordinal) + )); } } catch (final IllegalAccessException e) { throw new RuntimeException(e); @@ -381,8 +406,123 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } } - private static LevelChunkSection newChunkSection(int layer) { - return new LevelChunkSection(layer); + private static LevelChunkSection newChunkSection( + int layer, Registry biomeRegistry, + @Nullable PalettedContainer biomes + ) { + PalettedContainer dataPaletteBlocks = new PalettedContainer<>( + Block.BLOCK_STATE_REGISTRY, + Blocks.AIR.defaultBlockState(), + PalettedContainer.Strategy.SECTION_STATES, + null + ); + PalettedContainer biomesPalette = biomes != null ? biomes : new PalettedContainer<>( + biomeRegistry, + biomeRegistry.getOrThrow(Biomes.PLAINS), + PalettedContainer.Strategy.SECTION_BIOMES, + null + ); + return new LevelChunkSection(layer, dataPaletteBlocks, biomesPalette); + } + + /** + * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. + */ + public static PalettedContainer getBiomePalettedContainer(BiomeType[] biomes, Registry biomeRegistry) { + if (biomes == null) { + return null; + } + // 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))) { + Biome biome; + if (biomeType == null) { + biome = biomeRegistry.getOrThrow(Biomes.PLAINS); + } else { + biome = biomeRegistry.get(ResourceLocation.tryParse(biomeType.getId())); + } + 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.getOrThrow(Biomes.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; + } + Biome biome = biomeRegistry.get(ResourceLocation.tryParse(biomeType.getId())); + if (biome == null) { + continue; + } + biomePalettedContainer.set(x, y, z, biome); + } + } + } + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + return biomePalettedContainer; } public static void setCount(final int tickingBlockCount, final int nonEmptyBlockCount, final LevelChunkSection section) throws @@ -392,15 +532,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldNonEmptyBlockCount.setShort(section, (short) nonEmptyBlockCount); } - public static Biome[] getBiomeArray(ChunkBiomeContainer chunkBiomeContainer) { - try { - return (Biome[]) fieldBiomes.get(chunkBiomeContainer); - } catch (IllegalAccessException e) { - e.printStackTrace(); - return null; - } - } - public static BiomeType adapt(Biome biome, LevelAccessor levelAccessor) { ResourceLocation resourceLocation = levelAccessor.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY).getKey( biome); @@ -415,6 +546,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { try { // Do the method ourselves to avoid trying to reflect generic method parameters + // similar to removeGameEventListener if (levelChunk.loaded || levelChunk.level.isClientSide()) { BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos()); if (blockEntity != null) { @@ -446,4 +578,68 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { } } + static class FakeIdMapBlock implements IdMap { + + private final int size; + + FakeIdMapBlock(int size) { + this.size = size; + } + + @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; + } + + @Override + public int size() { + return size; + } + + @NotNull + @Override + public Iterator iterator() { + return Collections.emptyIterator(); + } + + } + + static class FakeIdMapBiome implements IdMap { + + private final int size; + + FakeIdMapBiome(int size) { + this.size = size; + } + + @Override + public int getId(final Biome entry) { + return 0; + } + + @Nullable + @Override + public Biome byId(final int index) { + return null; + } + + @Override + public int size() { + return size; + } + + @NotNull + @Override + public Iterator iterator() { + return Collections.emptyIterator(); + } + + } + } diff --git a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/nbt/PaperweightLazyCompoundTag.java b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/nbt/PaperweightLazyCompoundTag.java index 33c1f545a..3dfebd31c 100644 --- a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/nbt/PaperweightLazyCompoundTag.java +++ b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/nbt/PaperweightLazyCompoundTag.java @@ -94,8 +94,9 @@ public class PaperweightLazyCompoundTag extends LazyCompoundTag { public List getList(String key) { net.minecraft.nbt.Tag tag = compoundTagSupplier.get().get(key); - if (tag instanceof net.minecraft.nbt.ListTag nbtList) { + if (tag instanceof net.minecraft.nbt.ListTag) { ArrayList list = new ArrayList<>(); + net.minecraft.nbt.ListTag nbtList = (net.minecraft.nbt.ListTag) tag; for (net.minecraft.nbt.Tag elem : nbtList) { if (elem instanceof net.minecraft.nbt.CompoundTag) { list.add(new PaperweightLazyCompoundTag((net.minecraft.nbt.CompoundTag) elem)); diff --git a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/regen/PaperweightRegen.java b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/regen/PaperweightRegen.java index 3fa31eebe..f916ebb91 100644 --- a/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/regen/PaperweightRegen.java +++ b/worldedit-bukkit/adapters/adapter-1_18/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_18_R1/regen/PaperweightRegen.java @@ -1,721 +1,722 @@ -package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_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.Codec; -import com.mojang.serialization.Dynamic; -import com.mojang.serialization.Lifecycle; -import com.sk89q.worldedit.bukkit.adapter.Refraction; -import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.PaperweightGetBlocks; -import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.io.file.SafeFiles; -import com.sk89q.worldedit.world.RegenOptions; -import io.papermc.lib.PaperLib; -import net.minecraft.core.MappedRegistry; -import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; -import net.minecraft.data.BuiltinRegistries; -import net.minecraft.data.worldgen.biome.Biomes; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtOps; -import net.minecraft.resources.RegistryReadOps; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerChunkCache; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ThreadedLevelLightEngine; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.util.LinearCongruentialGenerator; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.LevelSettings; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.OverworldBiomeSource; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.chunk.ChunkStatus; -import net.minecraft.world.level.chunk.LevelChunk; -import net.minecraft.world.level.chunk.ProtoChunk; -import net.minecraft.world.level.chunk.UpgradeData; -import net.minecraft.world.level.dimension.LevelStem; -import net.minecraft.world.level.levelgen.FlatLevelSource; -import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; -import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; -import net.minecraft.world.level.levelgen.SimpleRandomSource; -import net.minecraft.world.level.levelgen.WorldGenSettings; -import net.minecraft.world.level.levelgen.XoroshiroRandomSource; -import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; -import net.minecraft.world.level.levelgen.synth.ImprovedNoise; -import net.minecraft.world.level.newbiome.area.Area; -import net.minecraft.world.level.newbiome.area.AreaFactory; -import net.minecraft.world.level.newbiome.context.BigContext; -import net.minecraft.world.level.newbiome.layer.Layer; -import net.minecraft.world.level.newbiome.layer.Layers; -import net.minecraft.world.level.newbiome.layer.traits.PixelTransformer; -import net.minecraft.world.level.storage.LevelStorageSource; -import net.minecraft.world.level.storage.PrimaryLevelData; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_18_R1.CraftServer; -import org.bukkit.craftbukkit.v1_18_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_18_R1.generator.CustomChunkGenerator; -import org.bukkit.generator.BlockPopulator; - -import javax.annotation.Nullable; -import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.nio.file.Path; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BooleanSupplier; -import java.util.function.LongFunction; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -public class PaperweightRegen extends Regenerator { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - private static final Field serverWorldsField; - private static final Field worldPaperConfigField; - private static final Field flatBedrockField; - private static final Field generatorSettingFlatField; - private static final Field generatorSettingBaseSupplierField; - private static final Field delegateField; - private static final Field chunkProviderField; - - //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; - } - worldPaperConfigField = tmpPaperConfigField; - flatBedrockField = tmpFlatBedrockField; - - generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName( - "settings", "g")); - generatorSettingBaseSupplierField.setAccessible(true); - - generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "e")); - generatorSettingFlatField.setAccessible(true); - - delegateField = CustomChunkGenerator.class.getDeclaredField("delegate"); - delegateField.setAccessible(true); - - chunkProviderField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "C")); - chunkProviderField.setAccessible(true); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - //runtime - private ServerLevel originalServerWorld; - private ServerChunkCache originalChunkProvider; - private ServerLevel freshWorld; - private ServerChunkCache freshChunkProvider; - private LevelStorageSource.LevelStorageAccess session; - private StructureManager structureManager; - private ThreadedLevelLightEngine threadedLevelLightEngine; - private ChunkGenerator chunkGenerator; - - private Path tempDir; - - private boolean generateFlatBedrock = false; - - public PaperweightRegen(org.bukkit.World originalBukkitWorld, Region region, Extent target, RegenOptions options) { - super(originalBukkitWorld, region, target, options); - } - - @Override - protected boolean prepare() { - this.originalServerWorld = ((CraftWorld) originalBukkitWorld).getHandle(); - originalChunkProvider = originalServerWorld.getChunkSource(); - if (!(originalChunkProvider instanceof ServerChunkCache)) { - return false; - } - - //flat bedrock? (only on paper) - if (worldPaperConfigField != null) { - try { - generateFlatBedrock = flatBedrockField.getBoolean(worldPaperConfigField.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 - 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("worldeditregentempworld", levelStemResourceKey); - PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData; - - MinecraftServer server = originalServerWorld.getCraftServer().getServer(); - PrimaryLevelData levelProperties = (PrimaryLevelData) server.getWorldData(); - RegistryReadOps nbtRegOps = RegistryReadOps.createAndLoad( - NbtOps.INSTANCE, server.resources.getResourceManager(), - RegistryAccess.builtin() - ); - WorldGenSettings newOpts = WorldGenSettings.CODEC - .encodeStart(nbtRegOps, levelProperties.worldGenSettings()) - .flatMap(tag -> WorldGenSettings.CODEC.parse(this.recursivelySetSeed( - new Dynamic<>(nbtRegOps, tag), - seed, - new HashSet<>() - ))) - .result() - .orElseThrow(() -> new IllegalStateException("Unable to map GeneratorOptions")); - LevelSettings newWorldSettings = new LevelSettings( - "worldeditregentempworld", - originalWorldData.settings.gameType(), - originalWorldData.settings.hardcore(), - originalWorldData.settings.difficulty(), - originalWorldData.settings.allowCommands(), - originalWorldData.settings.gameRules(), - originalWorldData.settings.getDataPackConfig() - ); - PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, Lifecycle.stable()); - - //init world - freshWorld = Fawe.get().getQueueHandler().sync((Supplier) () -> new ServerLevel( - server, - server.executor, - session, - newWorldData, - originalServerWorld.dimension(), - originalServerWorld.dimensionType(), - new RegenNoOpWorldLoadListener(), - // placeholder. Required for new ChunkProviderServer, but we create and then set it later - newOpts.dimensions().get(levelStemResourceKey).generator(), - originalServerWorld.isDebug(), - seed, - ImmutableList.of(), - false, - environment, - generator, - originalBukkitWorld.getBiomeProvider() - ) { - private final Biome singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.get(ResourceLocation.tryParse( - options - .getBiomeType() - .getId())) : null; - - @Override - public void tick(BooleanSupplier shouldKeepTicking) { //no ticking - } - - @Override - public Biome getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) { - if (options.hasBiomeType()) { - return singleBiome; - } - return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome(biomeX, biomeY, biomeZ); - } - }).get(); - freshWorld.noSave = true; - removeWorldFromWorldsMap(); - newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name - if (worldPaperConfigField != null) { - worldPaperConfigField.set(freshWorld, originalServerWorld.paperConfig); - } - - //generator - if (originalChunkProvider.getGenerator() instanceof FlatLevelSource) { - FlatLevelGeneratorSettings generatorSettingFlat = (FlatLevelGeneratorSettings) generatorSettingFlatField.get( - originalChunkProvider.getGenerator()); - chunkGenerator = new FlatLevelSource(generatorSettingFlat); - } else if (originalChunkProvider.getGenerator() instanceof NoiseBasedChunkGenerator) { - Supplier generatorSettingBaseSupplier = (Supplier) generatorSettingBaseSupplierField - .get(originalChunkProvider.getGenerator()); - BiomeSource biomeSource = originalChunkProvider.getGenerator().getBiomeSource(); - if (biomeSource instanceof OverworldBiomeSource) { - biomeSource = fastOverworldBiomeSource(biomeSource); - } - chunkGenerator = new NoiseBasedChunkGenerator(biomeSource, seed, generatorSettingBaseSupplier); - } else if (originalChunkProvider.getGenerator() instanceof CustomChunkGenerator) { - chunkGenerator = (ChunkGenerator) delegateField.get(originalChunkProvider.getGenerator()); - } else { - LOGGER.error("Unsupported generator type {}", originalChunkProvider.getGenerator().getClass().getName()); - return false; - } - if (generator != null) { - chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator); - generateConcurrent = generator.isParallelCapable(); - } - - freshChunkProvider = new ServerChunkCache( - freshWorld, - session, - server.getFixerUpper(), - server.getStructureManager(), - server.executor, - chunkGenerator, - freshWorld.spigotConfig.viewDistance, - server.forceSynchronousWrites(), - new RegenNoOpWorldLoadListener(), - (chunkCoordIntPair, state) -> { - }, - () -> server.overworld().getDataStorage() - ) { - // redirect to LevelChunks created in #createChunks - @Override - public ChunkAccess getChunk(int x, int z, ChunkStatus chunkstatus, boolean flag) { - return getChunkAt(x, z); - } - }; - - ReflectionUtils.unsafeSet(chunkProviderField, freshWorld, freshChunkProvider); - //let's start then - structureManager = server.getStructureManager(); - threadedLevelLightEngine = freshChunkProvider.getLightEngine(); - - return true; - } - - @Override - protected void cleanup() { - try { - session.close(); - } catch (Exception ignored) { - } - - //shutdown chunk provider - try { - Fawe.get().getQueueHandler().sync(() -> { - try { - freshChunkProvider.close(false); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); - } catch (Exception ignored) { - } - - //remove world from server - try { - Fawe.get().getQueueHandler().sync(this::removeWorldFromWorldsMap); - } catch (Exception ignored) { - } - - //delete directory - try { - SafeFiles.tryHardToDeleteDir(tempDir); - } catch (Exception ignored) { - } - } - - @Override - protected ProtoChunk createProtoChunk(int x, int z) { - return PaperLib.isPaper() - ? new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld, freshWorld) // paper - : new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld); // spigot - } - - @Override - protected LevelChunk createChunk(ProtoChunk protoChunk) { - return new LevelChunk( - freshWorld, - protoChunk, - null // we don't want to add entities - ); - } - - @Override - protected ChunkStatusWrap getFullChunkStatus() { - return new ChunkStatusWrap(ChunkStatus.FULL); - } - - @Override - protected List getBlockPopulators() { - return originalServerWorld.getWorld().getPopulators(); - } - - @Override - protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) { - // BlockPopulator#populate has to be called synchronously for TileEntity access - TaskManager.IMP.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 - private void removeWorldFromWorldsMap() { - Fawe.get().getQueueHandler().sync(() -> { - try { - Map map = (Map) serverWorldsField.get(Bukkit.getServer()); - map.remove("worldeditregentempworld"); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - }); - } - - private ResourceKey getWorldDimKey(org.bukkit.World.Environment env) { - switch (env) { - case NETHER: - return LevelStem.NETHER; - case THE_END: - return LevelStem.END; - case NORMAL: - default: - return LevelStem.OVERWORLD; - } - } - - private Dynamic recursivelySetSeed( - Dynamic dynamic, - long seed, - Set> dynamicSet - ) { - return !dynamicSet.add(dynamic) ? dynamic : dynamic.updateMapValues((pair) -> { - if (pair.getFirst().asString("").equals("seed")) { - return pair.mapSecond((v) -> v.createLong(seed)); - } else { - //TODO 1.18 address raw access - return ((Dynamic) pair.getSecond()).getValue() instanceof CompoundTag - ? pair.mapSecond((v) -> this.recursivelySetSeed((Dynamic) v, seed, dynamicSet)) - : pair; - - } - }); - } - - private BiomeSource fastOverworldBiomeSource(BiomeSource biomeSource) throws Exception { - Field legacyBiomeInitLayerField = OverworldBiomeSource.class.getDeclaredField( - Refraction.pickName("legacyBiomeInitLayer", "i")); - legacyBiomeInitLayerField.setAccessible(true); - Field largeBiomesField = OverworldBiomeSource.class.getDeclaredField(Refraction.pickName("largeBiomes", "j")); - largeBiomesField.setAccessible(true); - Field biomeRegistryField = OverworldBiomeSource.class.getDeclaredField(Refraction.pickName("biomes", "k")); - biomeRegistryField.setAccessible(true); - Field areaLazyField = Layer.class.getDeclaredField(Refraction.pickName("area", "b")); - areaLazyField.setAccessible(true); - Method initAreaFactoryMethod = Layers.class.getDeclaredMethod( - Refraction.pickName("getDefaultLayer", "a"), - boolean.class, - int.class, - int.class, - LongFunction.class - ); - initAreaFactoryMethod.setAccessible(true); - - //init new WorldChunkManagerOverworld - boolean legacyBiomeInitLayer = legacyBiomeInitLayerField.getBoolean(biomeSource); - boolean largebiomes = largeBiomesField.getBoolean(biomeSource); - Registry biomeRegistryMojang = (Registry) biomeRegistryField.get(biomeSource); - Registry biomeRegistry; - if (options.hasBiomeType()) { - Biome biome = BuiltinRegistries.BIOME.get(ResourceLocation.tryParse(options.getBiomeType().getId())); - biomeRegistry = new MappedRegistry<>( - ResourceKey.createRegistryKey(new ResourceLocation("fawe_biomes")), - Lifecycle.experimental() - ); - ((MappedRegistry) biomeRegistry).registerMapping(0, BuiltinRegistries.BIOME.getResourceKey(biome).get(), biome, - Lifecycle.experimental() - ); - } else { - biomeRegistry = biomeRegistryMojang; - } - - //replace genLayer - AreaFactory factory = (AreaFactory) initAreaFactoryMethod.invoke( - null, - legacyBiomeInitLayer, - largebiomes ? 6 : 4, - 4, - (LongFunction) (salt -> new FastWorldGenContextArea(seed, salt)) - ); - biomeSource = new FastOverworldBiomeSource(biomeRegistry, new FastGenLayer(factory)); - - return biomeSource; - } - - private static class FastOverworldBiomeSource extends BiomeSource { - - private final Registry biomeRegistry; - private final boolean isSingleRegistry; - private final FastGenLayer fastGenLayer; - - public FastOverworldBiomeSource( - Registry biomeRegistry, - FastGenLayer genLayer - ) { - super(biomeRegistry.stream().collect(Collectors.toList())); - this.biomeRegistry = biomeRegistry; - this.isSingleRegistry = biomeRegistry.entrySet().size() == 1; - this.fastGenLayer = genLayer; - } - - @Override - protected Codec codec() { - return OverworldBiomeSource.CODEC; - } - - @Override - public BiomeSource withSeed(final long seed) { - return null; - } - - @Override - public Biome getNoiseBiome(int biomeX, int biomeY, int biomeZ) { - if (this.isSingleRegistry) { - return this.biomeRegistry.byId(0); - } - return this.fastGenLayer.get(this.biomeRegistry, biomeX, biomeZ); - } - - } - - private static class FastWorldGenContextArea implements BigContext { - - private final ConcurrentHashMap sharedAreaMap = new ConcurrentHashMap<>(); - private final ImprovedNoise improvedNoise; - private final long magicrandom; - private final ConcurrentHashMap map = new ConcurrentHashMap<>(); //needed for multithreaded generation - - public FastWorldGenContextArea(long seed, long lconst) { - this.magicrandom = mix(seed, lconst); - this.improvedNoise = new ImprovedNoise(new XoroshiroRandomSource(seed)); - } - - private static long mix(long seed, long salt) { - long l = LinearCongruentialGenerator.next(salt, salt); - l = LinearCongruentialGenerator.next(l, salt); - l = LinearCongruentialGenerator.next(l, salt); - long m = LinearCongruentialGenerator.next(seed, l); - m = LinearCongruentialGenerator.next(m, l); - m = LinearCongruentialGenerator.next(m, l); - return m; - } - - @Override - public FastAreaLazy createResult(PixelTransformer pixelTransformer) { - return new FastAreaLazy(sharedAreaMap, pixelTransformer); - } - - @Override - public void initRandom(long x, long z) { - long l = this.magicrandom; - l = LinearCongruentialGenerator.next(l, x); - l = LinearCongruentialGenerator.next(l, z); - l = LinearCongruentialGenerator.next(l, x); - l = LinearCongruentialGenerator.next(l, z); - this.map.put(Thread.currentThread().getId(), l); - } - - @Override - public int nextRandom(int y) { - long tid = Thread.currentThread().getId(); - long e = this.map.computeIfAbsent(tid, i -> 0L); - int mod = (int) Math.floorMod(e >> 24L, (long) y); - this.map.put(tid, LinearCongruentialGenerator.next(e, this.magicrandom)); - return mod; - } - - @Override - public ImprovedNoise getBiomeNoise() { - return this.improvedNoise; - } - - } - - private static class FastGenLayer extends Layer { - - private final FastAreaLazy fastAreaLazy; - - public FastGenLayer(AreaFactory factory) { - super(() -> null); - this.fastAreaLazy = factory.make(); - } - - @Override - public Biome get(Registry registry, int x, int z) { - ResourceKey key = Biomes.byId(this.fastAreaLazy.get(x, z)); - if (key == null) { - return registry.get(Biomes.byId(0)); - } - Biome biome = registry.get(key); - if (biome == null) { - return registry.get(Biomes.byId(0)); - } - return biome; - } - - } - - private record FastAreaLazy(ConcurrentHashMap sharedMap, - PixelTransformer transformer) implements Area { - //ConcurrentHashMap is 50% faster that Long2IntLinkedOpenHashMap in a synchronized context - //using a map for each thread worsens the performance significantly due to cache misses (factor 5) - - @Override - public int get(int x, int z) { - long zx = ChunkPos.asLong(x, z); - return this.sharedMap.computeIfAbsent(zx, i -> this.transformer.apply(x, z)); - } - - } - - private static class RegenNoOpWorldLoadListener implements ChunkProgressListener { - - private RegenNoOpWorldLoadListener() { - } - - @Override - public void updateSpawnPos(ChunkPos spawnPos) { - } - - @Override - public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) { - } - - @Override - public void start() { - - } - - @Override - public void stop() { - } - - // TODO Paper only(?) @Override - public void setChunkRadius(int radius) { - } - - } - - private class FastProtoChunk extends ProtoChunk { - - // avoid warning on paper - public FastProtoChunk(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor world, ServerLevel serverLevel) { - super(pos, upgradeData, world, serverLevel); - } - - // compatibility with spigot - public FastProtoChunk(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor levelHeightAccessor) { - super(pos, upgradeData, levelHeightAccessor); - } - - public boolean generateFlatBedrock() { - return generateFlatBedrock; - } - - // no one will ever see the entities! - @Override - public List getEntities() { - return Collections.emptyList(); - } - - } - - protected class ChunkStatusWrap extends ChunkStatusWrapper { - - private final ChunkStatus chunkStatus; - - public ChunkStatusWrap(ChunkStatus chunkStatus) { - this.chunkStatus = chunkStatus; - } - - @Override - public int requiredNeighborChunkRadius() { - return chunkStatus.getRange(); - } - - @Override - public String name() { - return chunkStatus.getName(); - } - - @Override - public CompletableFuture processChunk(Long xz, List accessibleChunks) { - return chunkStatus.generate( - Runnable::run, // TODO revisit, we might profit from this somehow? - freshWorld, - chunkGenerator, - structureManager, - threadedLevelLightEngine, - c -> CompletableFuture.completedFuture(Either.left(c)), - accessibleChunks - ); - } - - } - -} +//package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_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.Codec; +//import com.mojang.serialization.Dynamic; +//import com.mojang.serialization.Lifecycle; +//import com.sk89q.worldedit.bukkit.adapter.Refraction; +//import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R1.PaperweightGetBlocks; +//import com.sk89q.worldedit.extent.Extent; +//import com.sk89q.worldedit.internal.util.LogManagerCompat; +//import com.sk89q.worldedit.regions.Region; +//import com.sk89q.worldedit.util.io.file.SafeFiles; +//import com.sk89q.worldedit.world.RegenOptions; +//import io.papermc.lib.PaperLib; +//import net.minecraft.core.MappedRegistry; +//import net.minecraft.core.Registry; +//import net.minecraft.core.RegistryAccess; +//import net.minecraft.data.BuiltinRegistries; +//import net.minecraft.data.worldgen.biome.Biomes; +//import net.minecraft.nbt.CompoundTag; +//import net.minecraft.nbt.NbtOps; +//import net.minecraft.resources.RegistryReadOps; +//import net.minecraft.resources.ResourceKey; +//import net.minecraft.resources.ResourceLocation; +//import net.minecraft.server.MinecraftServer; +//import net.minecraft.server.level.ServerChunkCache; +//import net.minecraft.server.level.ServerLevel; +//import net.minecraft.server.level.ThreadedLevelLightEngine; +//import net.minecraft.server.level.progress.ChunkProgressListener; +//import net.minecraft.util.LinearCongruentialGenerator; +//import net.minecraft.world.level.ChunkPos; +//import net.minecraft.world.level.Level; +//import net.minecraft.world.level.LevelHeightAccessor; +//import net.minecraft.world.level.LevelSettings; +//import net.minecraft.world.level.biome.Biome; +//import net.minecraft.world.level.biome.BiomeSource; +//import net.minecraft.world.level.biome.MultiNoiseBiomeSource; +//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.flat.FlatLevelGeneratorSettings; +//import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; +//import net.minecraft.world.level.levelgen.synth.ImprovedNoise; +//import net.minecraft.world.level.storage.LevelStorageSource; +//import net.minecraft.world.level.storage.PrimaryLevelData; +//import org.apache.logging.log4j.Logger; +//import org.bukkit.Bukkit; +//import org.bukkit.craftbukkit.v1_18_R1.CraftServer; +//import org.bukkit.craftbukkit.v1_18_R1.CraftWorld; +//import org.bukkit.craftbukkit.v1_18_R1.generator.CustomChunkGenerator; +//import org.bukkit.generator.BlockPopulator; +// +//import javax.annotation.Nullable; +//import java.io.IOException; +//import java.lang.reflect.Field; +//import java.lang.reflect.Method; +//import java.nio.file.Path; +//import java.util.Collections; +//import java.util.HashSet; +//import java.util.LinkedHashMap; +//import java.util.List; +//import java.util.Map; +//import java.util.Random; +//import java.util.Set; +//import java.util.concurrent.CompletableFuture; +//import java.util.concurrent.ConcurrentHashMap; +//import java.util.function.BooleanSupplier; +//import java.util.function.LongFunction; +//import java.util.function.Supplier; +//import java.util.stream.Collectors; +// +//public class PaperweightRegen extends Regenerator { +// +// private static final Logger LOGGER = LogManagerCompat.getLogger(); +// +// private static final Field serverWorldsField; +// private static final Field worldPaperConfigField; +// private static final Field flatBedrockField; +// private static final Field generatorSettingFlatField; +// private static final Field generatorSettingBaseSupplierField; +// private static final Field delegateField; +// private static final Field chunkProviderField; +// +// //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; +// } +// worldPaperConfigField = tmpPaperConfigField; +// flatBedrockField = tmpFlatBedrockField; +// +// generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName( +// "settings", "g")); +// generatorSettingBaseSupplierField.setAccessible(true); +// +// generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "e")); +// generatorSettingFlatField.setAccessible(true); +// +// delegateField = CustomChunkGenerator.class.getDeclaredField("delegate"); +// delegateField.setAccessible(true); +// +// chunkProviderField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "C")); +// chunkProviderField.setAccessible(true); +// } catch (Exception e) { +// throw new RuntimeException(e); +// } +// } +// +// //runtime +// private ServerLevel originalServerWorld; +// private ServerChunkCache originalChunkProvider; +// private ServerLevel freshWorld; +// private ServerChunkCache freshChunkProvider; +// private LevelStorageSource.LevelStorageAccess session; +// private StructureManager structureManager; +// private ThreadedLevelLightEngine threadedLevelLightEngine; +// private ChunkGenerator chunkGenerator; +// +// private Path tempDir; +// +// private boolean generateFlatBedrock = false; +// +// public PaperweightRegen(org.bukkit.World originalBukkitWorld, Region region, Extent target, RegenOptions options) { +// super(originalBukkitWorld, region, target, options); +// } +// +// @Override +// protected boolean prepare() { +// this.originalServerWorld = ((CraftWorld) originalBukkitWorld).getHandle(); +// originalChunkProvider = originalServerWorld.getChunkSource(); +// if (!(originalChunkProvider instanceof ServerChunkCache)) { +// return false; +// } +// +// //flat bedrock? (only on paper) +// if (worldPaperConfigField != null) { +// try { +// generateFlatBedrock = flatBedrockField.getBoolean(worldPaperConfigField.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 +// 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("worldeditregentempworld", levelStemResourceKey); +// PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData; +// +// MinecraftServer server = originalServerWorld.getCraftServer().getServer(); +// PrimaryLevelData levelProperties = (PrimaryLevelData) server.getWorldData(); +// RegistryReadOps nbtRegOps = RegistryReadOps.createAndLoad( +// NbtOps.INSTANCE, server.resources.getResourceManager(), +// RegistryAccess.builtin() +// ); +// WorldGenSettings newOpts = WorldGenSettings.CODEC +// .encodeStart(nbtRegOps, levelProperties.worldGenSettings()) +// .flatMap(tag -> WorldGenSettings.CODEC.parse(this.recursivelySetSeed( +// new Dynamic<>(nbtRegOps, tag), +// seed, +// new HashSet<>() +// ))) +// .result() +// .orElseThrow(() -> new IllegalStateException("Unable to map GeneratorOptions")); +// LevelSettings newWorldSettings = new LevelSettings( +// "worldeditregentempworld", +// originalWorldData.settings.gameType(), +// originalWorldData.settings.hardcore(), +// originalWorldData.settings.difficulty(), +// originalWorldData.settings.allowCommands(), +// originalWorldData.settings.gameRules(), +// originalWorldData.settings.getDataPackConfig() +// ); +// PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, Lifecycle.stable()); +// +// //init world +// freshWorld = Fawe.get().getQueueHandler().sync((Supplier) () -> new ServerLevel( +// server, +// server.executor, +// session, +// newWorldData, +// originalServerWorld.dimension(), +// originalServerWorld.dimensionType(), +// new RegenNoOpWorldLoadListener(), +// // placeholder. Required for new ChunkProviderServer, but we create and then set it later +// newOpts.dimensions().get(levelStemResourceKey).generator(), +// originalServerWorld.isDebug(), +// seed, +// ImmutableList.of(), +// false, +// environment, +// generator, +// originalBukkitWorld.getBiomeProvider() +// ) { +// private final Biome singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.get(ResourceLocation.tryParse( +// options +// .getBiomeType() +// .getId())) : null; +// +// @Override +// public void tick(BooleanSupplier shouldKeepTicking) { //no ticking +// } +// +// @Override +// public Biome getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) { +// if (options.hasBiomeType()) { +// return singleBiome; +// } +// return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome(biomeX, biomeY, biomeZ, +// PaperweightRegen.this.chunkGenerator.climateSampler()); +// } +// }).get(); +// freshWorld.noSave = true; +// removeWorldFromWorldsMap(); +// newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name +// if (worldPaperConfigField != null) { +// worldPaperConfigField.set(freshWorld, originalServerWorld.paperConfig); +// } +// +// //generator +// if (originalChunkProvider.getGenerator() instanceof FlatLevelSource) { +// FlatLevelGeneratorSettings generatorSettingFlat = (FlatLevelGeneratorSettings) generatorSettingFlatField.get( +// originalChunkProvider.getGenerator()); +// chunkGenerator = new FlatLevelSource(generatorSettingFlat); +// } else if (originalChunkProvider.getGenerator() instanceof NoiseBasedChunkGenerator) { +// Supplier generatorSettingBaseSupplier = (Supplier) generatorSettingBaseSupplierField +// .get(originalChunkProvider.getGenerator()); +// BiomeSource biomeSource = originalChunkProvider.getGenerator().getBiomeSource(); +// if (biomeSource instanceof MultiNoiseBiomeSource) { +// biomeSource = fastMultiNoiseBiomeSource(biomeSource); +// } +// chunkGenerator = new NoiseBasedChunkGenerator(((NoiseBasedChunkGenerator) chunkGenerator).noises, biomeSource, seed, +// generatorSettingBaseSupplier +// ); +// } else if (originalChunkProvider.getGenerator() instanceof CustomChunkGenerator) { +// chunkGenerator = (ChunkGenerator) delegateField.get(originalChunkProvider.getGenerator()); +// } else { +// LOGGER.error("Unsupported generator type {}", originalChunkProvider.getGenerator().getClass().getName()); +// return false; +// } +// if (generator != null) { +// chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator); +// generateConcurrent = generator.isParallelCapable(); +// } +// +// freshChunkProvider = new ServerChunkCache( +// freshWorld, +// session, +// server.getFixerUpper(), +// server.getStructureManager(), +// server.executor, +// chunkGenerator, +// freshWorld.spigotConfig.viewDistance, +// server.forceSynchronousWrites(), +// new RegenNoOpWorldLoadListener(), +// (chunkCoordIntPair, state) -> { +// }, +// () -> server.overworld().getDataStorage() +// ) { +// // redirect to LevelChunks created in #createChunks +// @Override +// public ChunkAccess getChunk(int x, int z, ChunkStatus chunkstatus, boolean flag) { +// return getChunkAt(x, z); +// } +// }; +// +// ReflectionUtils.unsafeSet(chunkProviderField, freshWorld, freshChunkProvider); +// //let's start then +// structureManager = server.getStructureManager(); +// threadedLevelLightEngine = freshChunkProvider.getLightEngine(); +// +// return true; +// } +// +// @Override +// protected void cleanup() { +// try { +// session.close(); +// } catch (Exception ignored) { +// } +// +// //shutdown chunk provider +// try { +// Fawe.get().getQueueHandler().sync(() -> { +// try { +// freshChunkProvider.close(false); +// } catch (IOException e) { +// throw new RuntimeException(e); +// } +// }); +// } catch (Exception ignored) { +// } +// +// //remove world from server +// try { +// Fawe.get().getQueueHandler().sync(this::removeWorldFromWorldsMap); +// } catch (Exception ignored) { +// } +// +// //delete directory +// try { +// SafeFiles.tryHardToDeleteDir(tempDir); +// } catch (Exception ignored) { +// } +// } +// +// @Override +// protected ProtoChunk createProtoChunk(int x, int z) { +// return PaperLib.isPaper() +// ? new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld, freshWorld) // paper +// : new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld); // spigot +// } +// +// @Override +// protected LevelChunk createChunk(ProtoChunk protoChunk) { +// return new LevelChunk( +// freshWorld, +// protoChunk, +// null // we don't want to add entities +// ); +// } +// +// @Override +// protected ChunkStatusWrap getFullChunkStatus() { +// return new ChunkStatusWrap(ChunkStatus.FULL); +// } +// +// @Override +// protected List getBlockPopulators() { +// return originalServerWorld.getWorld().getPopulators(); +// } +// +// @Override +// protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) { +// // BlockPopulator#populate has to be called synchronously for TileEntity access +// TaskManager.IMP.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 +// private void removeWorldFromWorldsMap() { +// Fawe.get().getQueueHandler().sync(() -> { +// try { +// Map map = (Map) serverWorldsField.get(Bukkit.getServer()); +// map.remove("worldeditregentempworld"); +// } catch (IllegalAccessException e) { +// throw new RuntimeException(e); +// } +// }); +// } +// +// private ResourceKey getWorldDimKey(org.bukkit.World.Environment env) { +// switch (env) { +// case NETHER: +// return LevelStem.NETHER; +// case THE_END: +// return LevelStem.END; +// case NORMAL: +// default: +// return LevelStem.OVERWORLD; +// } +// } +// +// private Dynamic recursivelySetSeed( +// Dynamic dynamic, +// long seed, +// Set> dynamicSet +// ) { +// return !dynamicSet.add(dynamic) ? dynamic : dynamic.updateMapValues((pair) -> { +// if (pair.getFirst().asString("").equals("seed")) { +// return pair.mapSecond((v) -> v.createLong(seed)); +// } else { +// return ((Dynamic) pair.getSecond()).getValue() instanceof CompoundTag +// ? pair.mapSecond((v) -> this.recursivelySetSeed((Dynamic) v, seed, dynamicSet)) +// : pair; +// +// } +// }); +// } +// +// private BiomeSource fastMultiNoiseBiomeSource(BiomeSource biomeSource) throws Exception { +// Field legacyBiomeInitLayerField = MultiNoiseBiomeSource.class.getDeclaredField( +// Refraction.pickName("legacyBiomeInitLayer", "i")); +// legacyBiomeInitLayerField.setAccessible(true); +// Field largeBiomesField = NoiseGeneratorSettings.class.getDeclaredField(Refraction.pickName("largeBiomes", "j")); +// largeBiomesField.setAccessible(true); +// Field biomeRegistryField = MultiNoiseBiomeSource.class.getDeclaredField(Refraction.pickName("biomes", "k")); +// biomeRegistryField.setAccessible(true); +// Field areaLazyField = Layer.class.getDeclaredField(Refraction.pickName("area", "b")); +// areaLazyField.setAccessible(true); +// Method initAreaFactoryMethod = Layers.class.getDeclaredMethod( +// Refraction.pickName("getDefaultLayer", "a"), +// boolean.class, +// int.class, +// int.class, +// LongFunction.class +// ); +// initAreaFactoryMethod.setAccessible(true); +// +// //init new WorldChunkManagerOverworld +// boolean legacyBiomeInitLayer = legacyBiomeInitLayerField.getBoolean(biomeSource); +// boolean largebiomes = largeBiomesField.getBoolean(biomeSource); +// Registry biomeRegistryMojang = (Registry) biomeRegistryField.get(biomeSource); +// Registry biomeRegistry; +// if (options.hasBiomeType()) { +// Biome biome = BuiltinRegistries.BIOME.get(ResourceLocation.tryParse(options.getBiomeType().getId())); +// biomeRegistry = new MappedRegistry<>( +// ResourceKey.createRegistryKey(new ResourceLocation("fawe_biomes")), +// Lifecycle.experimental() +// ); +// ((MappedRegistry) biomeRegistry).registerMapping(0, BuiltinRegistries.BIOME.getResourceKey(biome).get(), biome, +// Lifecycle.experimental() +// ); +// } else { +// biomeRegistry = biomeRegistryMojang; +// } +// +// //replace genLayer +// AreaFactory factory = (AreaFactory) initAreaFactoryMethod.invoke( +// null, +// legacyBiomeInitLayer, +// largebiomes ? 6 : 4, +// 4, +// (LongFunction) (salt -> new FastWorldGenContextArea(seed, salt)) +// ); +// biomeSource = new FastOverworldBiomeSource(biomeRegistry, new FastGenLayer(factory)); +// +// return biomeSource; +// } +// +// private static class FastOverworldBiomeSource extends BiomeSource { +// +// private final Registry biomeRegistry; +// private final boolean isSingleRegistry; +// private final FastGenLayer fastGenLayer; +// +// public FastOverworldBiomeSource( +// Registry biomeRegistry, +// FastGenLayer genLayer +// ) { +// super(biomeRegistry.stream().collect(Collectors.toList())); +// this.biomeRegistry = biomeRegistry; +// this.isSingleRegistry = biomeRegistry.entrySet().size() == 1; +// this.fastGenLayer = genLayer; +// } +// +// @Override +// protected Codec codec() { +// return MultiNoiseBiomeSource.CODEC; +// } +// +// @Override +// public BiomeSource withSeed(final long seed) { +// return null; +// } +// +// @Override +// public Biome getNoiseBiome(int biomeX, int biomeY, int biomeZ) { +// if (this.isSingleRegistry) { +// return this.biomeRegistry.byId(0); +// } +// return this.fastGenLayer.get(this.biomeRegistry, biomeX, biomeZ); +// } +// +// } +// +// private static class FastWorldGenContextArea implements BigContext { +// +// private final ConcurrentHashMap sharedAreaMap = new ConcurrentHashMap<>(); +// private final ImprovedNoise improvedNoise; +// private final long magicrandom; +// private final ConcurrentHashMap map = new ConcurrentHashMap<>(); //needed for multithreaded generation +// +// public FastWorldGenContextArea(long seed, long lconst) { +// this.magicrandom = mix(seed, lconst); +// this.improvedNoise = new ImprovedNoise(new SimpleRandomSource(seed)); +// } +// +// private static long mix(long seed, long salt) { +// long l = LinearCongruentialGenerator.next(salt, salt); +// l = LinearCongruentialGenerator.next(l, salt); +// l = LinearCongruentialGenerator.next(l, salt); +// long m = LinearCongruentialGenerator.next(seed, l); +// m = LinearCongruentialGenerator.next(m, l); +// m = LinearCongruentialGenerator.next(m, l); +// return m; +// } +// +// @Override +// public FastAreaLazy createResult(PixelTransformer pixelTransformer) { +// return new FastAreaLazy(sharedAreaMap, pixelTransformer); +// } +// +// @Override +// public void initRandom(long x, long z) { +// long l = this.magicrandom; +// l = LinearCongruentialGenerator.next(l, x); +// l = LinearCongruentialGenerator.next(l, z); +// l = LinearCongruentialGenerator.next(l, x); +// l = LinearCongruentialGenerator.next(l, z); +// this.map.put(Thread.currentThread().getId(), l); +// } +// +// @Override +// public int nextRandom(int y) { +// long tid = Thread.currentThread().getId(); +// long e = this.map.computeIfAbsent(tid, i -> 0L); +// int mod = (int) Math.floorMod(e >> 24L, (long) y); +// this.map.put(tid, LinearCongruentialGenerator.next(e, this.magicrandom)); +// return mod; +// } +// +// @Override +// public ImprovedNoise getBiomeNoise() { +// return this.improvedNoise; +// } +// +// } +// +// private static class FastGenLayer extends Layer { +// +// private final FastAreaLazy fastAreaLazy; +// +// public FastGenLayer(AreaFactory factory) { +// super(() -> null); +// this.fastAreaLazy = factory.make(); +// } +// +// @Override +// public Biome get(Registry registry, int x, int z) { +// ResourceKey key = Biomes.byId(this.fastAreaLazy.get(x, z)); +// if (key == null) { +// return registry.get(Biomes.byId(0)); +// } +// Biome biome = registry.get(key); +// if (biome == null) { +// return registry.get(Biomes.byId(0)); +// } +// return biome; +// } +// +// } +// +// private static class FastAreaLazy implements Area { +// +// private final PixelTransformer transformer; +// //ConcurrentHashMap is 50% faster that Long2IntLinkedOpenHashMap in a synchronized context +// //using a map for each thread worsens the performance significantly due to cache misses (factor 5) +// private final ConcurrentHashMap sharedMap; +// +// public FastAreaLazy(ConcurrentHashMap sharedMap, PixelTransformer transformer) { +// this.sharedMap = sharedMap; +// this.transformer = transformer; +// } +// +// @Override +// public int get(int x, int z) { +// long zx = ChunkPos.asLong(x, z); +// return this.sharedMap.computeIfAbsent(zx, i -> this.transformer.apply(x, z)); +// } +// +// } +// +// private static class RegenNoOpWorldLoadListener implements ChunkProgressListener { +// +// private RegenNoOpWorldLoadListener() { +// } +// +// @Override +// public void updateSpawnPos(ChunkPos spawnPos) { +// } +// +// @Override +// public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) { +// } +// +// @Override +// public void start() { +// +// } +// +// @Override +// public void stop() { +// } +// +// // TODO Paper only(?) @Override +// public void setChunkRadius(int radius) { +// } +// +// } +// +// private class FastProtoChunk extends ProtoChunk { +// +// // avoid warning on paper +// public FastProtoChunk(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor world, ServerLevel serverLevel) { +// super(pos, upgradeData, world, serverLevel); +// } +// +// // compatibility with spigot +// public FastProtoChunk(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor levelHeightAccessor) { +// super(pos, upgradeData, levelHeightAccessor); +// } +// +// public boolean generateFlatBedrock() { +// return generateFlatBedrock; +// } +// +// // no one will ever see the entities! +// @Override +// public List getEntities() { +// return Collections.emptyList(); +// } +// +// } +// +// protected class ChunkStatusWrap extends ChunkStatusWrapper { +// +// private final ChunkStatus chunkStatus; +// +// public ChunkStatusWrap(ChunkStatus chunkStatus) { +// this.chunkStatus = chunkStatus; +// } +// +// @Override +// public int requiredNeighborChunkRadius() { +// return chunkStatus.getRange(); +// } +// +// @Override +// public String name() { +// return chunkStatus.getName(); +// } +// +// @Override +// public CompletableFuture processChunk(Long xz, List accessibleChunks) { +// return chunkStatus.generate( +// Runnable::run, // TODO revisit, we might profit from this somehow? +// freshWorld, +// chunkGenerator, +// structureManager, +// threadedLevelLightEngine, +// c -> CompletableFuture.completedFuture(Either.left(c)), +// accessibleChunks +// ); +// } +// +// } +// +//} diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index dcddb468e..89dc6a653 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -102,7 +102,6 @@ dependencies { compileOnly(libs.protocollib) { isTransitive = false } compileOnly(libs.plotsquaredV6Bukkit) { isTransitive = false } compileOnly(libs.plotsquaredV6Core) { isTransitive = false } - compileOnly(libs.plotsquaredV4) { isTransitive = false } // Third party compileOnly(libs.flowmath) { 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 5e5671dcf..3d02b0de7 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/FaweBukkit.java @@ -310,14 +310,12 @@ public class FaweBukkit implements IFawe, Listener { if (plotSquared == null) { return; } - if (plotSquared.getClass().getPackage().toString().contains("intellectualsites")) { - WEManager.IMP.addManager(new com.fastasyncworldedit.bukkit.regions.plotsquaredv4.PlotSquaredFeature()); - LOGGER.info("Plugin 'PlotSquared' found. Using it now."); - } else if (PlotSquared.get().getVersion().version[0] == 6) { + if (PlotSquared.get().getVersion().version[0] == 6) { WEManager.IMP.addManager(new com.fastasyncworldedit.bukkit.regions.plotsquared.PlotSquaredFeature()); - LOGGER.info("Plugin 'PlotSquared' found. Using it now."); + LOGGER.info("Plugin 'PlotSquared' v6 found. Using it now."); } else { LOGGER.error("Incompatible version of PlotSquared found. Please use PlotSquared v6."); + LOGGER.info("https://www.spigotmc.org/resources/77506/"); } } diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java index f8d8cef2e..e0d13a36b 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IDelegateBukkitImplAdapter.java @@ -59,7 +59,7 @@ public interface IDelegateBukkitImplAdapter extends BukkitImplAdapter { } @Override - default BaseBlock getBlock(Location location) { + default BlockState getBlock(Location location) { return getParent().getBlock(location); } 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 2f6dd6863..9f6b97d6a 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 @@ -4,7 +4,6 @@ import com.fastasyncworldedit.core.FAWEPlatformAdapterImpl; import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.world.block.BlockID; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BlockState; @@ -24,8 +23,8 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl { int num_palette = 0; for (int i = 0; i < 4096; i++) { char ordinal = set[i]; - if (ordinal == BlockID.__RESERVED__) { - ordinal = BlockID.AIR; + if (ordinal == 0) { + ordinal = 1; } int palette = blockToPalette[ordinal]; if (palette == Integer.MAX_VALUE) { @@ -43,17 +42,17 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl { } System.arraycopy(adapter.getOrdinalToIbdID(), 0, blockToPalette, 0, adapter.getOrdinalToIbdID().length); } - char lastOrdinal = BlockID.__RESERVED__; + char lastOrdinal = 0; boolean lastticking = false; boolean tick_placed = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_PLACED; for (int i = 0; i < 4096; i++) { char ordinal = set[i]; switch (ordinal) { - case BlockID.__RESERVED__: - ordinal = BlockID.AIR; - case BlockID.AIR: - case BlockID.CAVE_AIR: - case BlockID.VOID_AIR: + case 0: + ordinal = 1; + case 1: + case 2: + case 3: air++; break; default: @@ -95,13 +94,13 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl { char[] getArr = null; for (int i = 0; i < 4096; i++) { char ordinal = set[i]; - if (ordinal == BlockID.__RESERVED__) { + if (ordinal == 0) { if (getArr == null) { getArr = get.apply(layer); } ordinal = getArr[i]; - if (ordinal == BlockID.__RESERVED__) { - ordinal = BlockID.AIR; + if (ordinal == 0) { + ordinal = 1; } } int palette = blockToPalette[ordinal]; @@ -120,24 +119,24 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl { } System.arraycopy(adapter.getOrdinalToIbdID(), 0, blockToPalette, 0, adapter.getOrdinalToIbdID().length); } - char lastOrdinal = BlockID.__RESERVED__; + char lastOrdinal = 0; boolean lastticking = false; boolean tick_placed = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_PLACED; boolean tick_existing = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_EXISTING; for (int i = 0; i < 4096; i++) { char ordinal = set[i]; switch (ordinal) { - case BlockID.__RESERVED__: { + case 0: { if (getArr == null) { getArr = get.apply(layer); } ordinal = getArr[i]; switch (ordinal) { - case BlockID.__RESERVED__: - ordinal = BlockID.AIR; - case BlockID.AIR: - case BlockID.CAVE_AIR: - case BlockID.VOID_AIR: + case 0: + ordinal = 1; + case 1: + case 2: + case 3: air++; break; default: @@ -164,9 +163,9 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl { set[i] = ordinal; break; } - case BlockID.AIR: - case BlockID.CAVE_AIR: - case BlockID.VOID_AIR: + case 1: + case 2: + case 3: air++; break; } 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 5dfc76ee9..33ddb4fa8 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 @@ -4,9 +4,6 @@ import com.fastasyncworldedit.core.FaweAPI; import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.regions.FaweMask; import com.fastasyncworldedit.core.regions.FaweMaskManager; -import com.fastasyncworldedit.core.regions.filter.RegionFilter; -import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler; -import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.database.DBFunc; import com.plotsquared.core.player.PlotPlayer; @@ -62,6 +59,15 @@ public class PlotSquaredFeature extends FaweMaskManager { */ } + /** + * Whether the player is allowed to use FAWE on a PlotSquared plot. + * + * @param player the {@link Player} + * @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} + */ public boolean isAllowed(Player player, Plot plot, MaskType type) { if (plot == null) { return false; diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/FaweChunkManager.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/FaweChunkManager.java deleted file mode 100644 index 4f50f63ac..000000000 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/FaweChunkManager.java +++ /dev/null @@ -1,172 +0,0 @@ -package com.fastasyncworldedit.bukkit.regions.plotsquaredv4; - -import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.util.TaskManager; -import com.github.intellectualsites.plotsquared.plot.object.Location; -import com.github.intellectualsites.plotsquared.plot.object.Plot; -import com.github.intellectualsites.plotsquared.plot.util.ChunkManager; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.MaxChangedBlocksException; -import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.function.operation.ForwardExtentCopy; -import com.sk89q.worldedit.function.operation.Operations; -import com.sk89q.worldedit.math.BlockVector2; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.CuboidRegion; -import com.sk89q.worldedit.world.World; - -import java.util.concurrent.CompletableFuture; - -import static org.bukkit.Bukkit.getWorld; - -public class FaweChunkManager extends ChunkManager { - - private final ChunkManager parent; - - public FaweChunkManager(ChunkManager parent) { - this.parent = parent; - } - - @Override - public int[] countEntities(Plot plot) { - return parent.countEntities(plot); - } - - @Override - public CompletableFuture loadChunk(String world, BlockVector2 loc, boolean force) { - return parent.loadChunk(world, loc, force); - } - - @Override - public void unloadChunk(String world, BlockVector2 loc, boolean save) { - parent.unloadChunk(world, loc, save); - } - - @Override - public void clearAllEntities(Location pos1, Location pos2) { - parent.clearAllEntities(pos1, pos2); - } - - @Override - public void swap( - final Location pos1, - final Location pos2, - final Location pos3, - final Location pos4, - final Runnable whenDone - ) { - if (!Settings.IMP.PLOTSQUARED_INTEGRATION.COPY_AND_SWAP) { - parent.swap(pos1, pos2, pos3, pos4, whenDone); - } - TaskManager.IMP.async(() -> { - synchronized (FaweChunkManager.class) { - //todo because of the following code this should proably be in the Bukkit module - World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorld())); - World pos3World = BukkitAdapter.adapt(getWorld(pos3.getWorld())); - EditSession sessionA = WorldEdit.getInstance().newEditSessionBuilder().world(pos1World) - .checkMemory(false) - .fastMode(true) - .limitUnlimited() - .changeSetNull() - .build(); - EditSession sessionB = WorldEdit.getInstance().newEditSessionBuilder().world(pos3World) - .checkMemory(false) - .fastMode(true) - .limitUnlimited() - .changeSetNull() - .build(); - CuboidRegion regionA = new CuboidRegion( - BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()), - BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ()) - ); - CuboidRegion regionB = new CuboidRegion( - BlockVector3.at(pos3.getX(), pos3.getY(), pos3.getZ()), - BlockVector3.at(pos4.getX(), pos4.getY(), pos4.getZ()) - ); - ForwardExtentCopy copyA = new ForwardExtentCopy(sessionA, regionA, sessionB, regionB.getMinimumPoint()); - ForwardExtentCopy copyB = new ForwardExtentCopy(sessionB, regionB, sessionA, regionA.getMinimumPoint()); - try { - Operations.completeLegacy(copyA); - Operations.completeLegacy(copyB); - sessionA.flushQueue(); - sessionB.flushQueue(); - } catch (MaxChangedBlocksException e) { - e.printStackTrace(); - } - TaskManager.IMP.task(whenDone); - } - }); - } - - @Override - public boolean copyRegion(final Location pos1, final Location pos2, final Location pos3, final Runnable whenDone) { - if (!Settings.IMP.PLOTSQUARED_INTEGRATION.COPY_AND_SWAP) { - return parent.copyRegion(pos1, pos2, pos3, whenDone); - } - TaskManager.IMP.async(() -> { - synchronized (FaweChunkManager.class) { - World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorld())); - World pos3World = BukkitAdapter.adapt(getWorld(pos3.getWorld())); - EditSession from = WorldEdit.getInstance().newEditSessionBuilder().world(pos1World) - .checkMemory(false) - .fastMode(true) - .limitUnlimited() - .changeSetNull() - .build(); - EditSession to = WorldEdit.getInstance().newEditSessionBuilder().world(pos3World) - .checkMemory(false) - .fastMode(true) - .limitUnlimited() - .changeSetNull() - .build(); - CuboidRegion region = new CuboidRegion( - BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()), - BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ()) - ); - ForwardExtentCopy copy = new ForwardExtentCopy( - from, - region, - to, - BlockVector3.at(pos3.getX(), pos3.getY(), pos3.getZ()) - ); - try { - Operations.completeLegacy(copy); - to.flushQueue(); - } catch (MaxChangedBlocksException e) { - e.printStackTrace(); - } - } - TaskManager.IMP.task(whenDone); - }); - return true; - } - - @Override - public boolean regenerateRegion(final Location pos1, final Location pos2, boolean ignore, final Runnable whenDone) { - TaskManager.IMP.async(() -> { - synchronized (FaweChunkManager.class) { - World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorld())); - try (EditSession editSession = WorldEdit - .getInstance() - .newEditSessionBuilder() - .world(pos1World) - .checkMemory(false) - .fastMode(true) - .limitUnlimited() - .changeSetNull() - .build()) { - CuboidRegion region = new CuboidRegion( - BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()), - BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ()) - ); - editSession.regenerate(region); - editSession.flushQueue(); - } - TaskManager.IMP.task(whenDone); - } - }); - return true; - } - -} diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/FaweLocalBlockQueue.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/FaweLocalBlockQueue.java deleted file mode 100644 index fb27c01ed..000000000 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/FaweLocalBlockQueue.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.fastasyncworldedit.bukkit.regions.plotsquaredv4; - -import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.FaweAPI; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.math.MutableBlockVector3; -import com.fastasyncworldedit.core.queue.IQueueChunk; -import com.fastasyncworldedit.core.queue.IQueueExtent; -import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.function.pattern.Pattern; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.world.World; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.block.BaseBlock; -import com.sk89q.worldedit.world.block.BlockState; - -// TODO FIXME -public class FaweLocalBlockQueue extends LocalBlockQueue { - - public final IQueueExtent instance; - private final World world; - private final BlockVector3 mutable = new MutableBlockVector3(); - - public FaweLocalBlockQueue(String worldName) { - super(worldName); - this.world = FaweAPI.getWorld(worldName); - instance = Fawe.get().getQueueHandler().getQueue(world); - Fawe.get().getQueueHandler().unCache(); - } - - @Override - public boolean next() { - if (!instance.isEmpty()) { - instance.flush(); - } - return false; - } - - @Override - public void startSet(boolean parallel) { - Fawe.get().getQueueHandler().startSet(parallel); - } - - @Override - public void endSet(boolean parallel) { - Fawe.get().getQueueHandler().endSet(parallel); - } - - @Override - public int size() { - return instance.isEmpty() ? 0 : 1; - } - - @Override - public void optimize() { - } - - @Override - public void setModified(long l) { - } - - @Override - public long getModified() { - return instance.size(); - } - - @Override - public boolean setBlock(final int x, final int y, final int z, final BlockState id) { - return instance.setBlock(x, y, z, id); - } - - @Override - public boolean setBlock(int x, int y, int z, Pattern pattern) { - mutable.setComponents(x, y, z); - return pattern.apply(instance, mutable, mutable); - } - - @Override - public boolean setBlock(final int x, final int y, final int z, final BaseBlock id) { - return instance.setBlock(x, y, z, id); - } - - @Override - public BlockState getBlock(int x, int y, int z) { - return instance.getBlock(x, y, z); - } - - @Override - public boolean setBiome(int x, int z, BiomeType biomeType) { - return instance.setBiome(x, 0, z, biomeType); - } - - @Override - public String getWorld() { - return world.getId(); - } - - @Override - public void flush() { - instance.flush(); - } - - @Override - public boolean enqueue() { - boolean val = super.enqueue(); - instance.enableQueue(); - return val; - } - - @Override - public void refreshChunk(int x, int z) { - world.refreshChunk(x, z); - } - - @Override - public void fixChunkLighting(int x, int z) { - } - - @Override - public void regenChunk(int x, int z) { - instance.regenerateChunk(x, z, null, null); - } - - @Override - public boolean setTile(int x, int y, int z, CompoundTag tag) { - instance.setTile(x, y, z, (com.sk89q.jnbt.CompoundTag) FaweCache.IMP.asTag(tag)); - return true; - } - -} diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/FaweSchematicHandler.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/FaweSchematicHandler.java deleted file mode 100644 index 06921cb12..000000000 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/FaweSchematicHandler.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.fastasyncworldedit.bukkit.regions.plotsquaredv4; - -import com.fastasyncworldedit.core.FaweAPI; -import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.extent.clipboard.ReadOnlyClipboard; -import com.fastasyncworldedit.core.extent.clipboard.io.FastSchematicWriter; -import com.fastasyncworldedit.core.jnbt.CompressedCompoundTag; -import com.fastasyncworldedit.core.jnbt.CompressedSchematicTag; -import com.fastasyncworldedit.core.util.IOUtil; -import com.fastasyncworldedit.core.util.TaskManager; -import com.github.intellectualsites.plotsquared.plot.PlotSquared; -import com.github.intellectualsites.plotsquared.plot.object.Location; -import com.github.intellectualsites.plotsquared.plot.object.RunnableVal; -import com.github.intellectualsites.plotsquared.plot.util.MainUtil; -import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler; -import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.NBTOutputStream; -import com.sk89q.jnbt.Tag; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; -import com.sk89q.worldedit.extent.clipboard.Clipboard; -import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.CuboidRegion; -import com.sk89q.worldedit.world.World; -import net.jpountz.lz4.LZ4BlockInputStream; -import org.anarres.parallelgzip.ParallelGZIPOutputStream; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.net.URL; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import static org.bukkit.Bukkit.getWorld; - -public class FaweSchematicHandler extends SchematicHandler { - - @Override - public boolean restoreTile(LocalBlockQueue queue, CompoundTag compoundTag, int x, int y, int z) { - if (queue instanceof FaweLocalBlockQueue) { - queue.setTile(x, y, z, compoundTag); - return true; - } - return false; - } - - @Override - public void getCompoundTag(final String world, final Set regions, final RunnableVal whenDone) { - TaskManager.IMP.async(() -> { - Location[] corners = MainUtil.getCorners(world, regions); - Location pos1 = corners[0]; - Location pos2 = corners[1]; - World adaptedWorld = BukkitAdapter.adapt(getWorld(world)); - final CuboidRegion region = new CuboidRegion( - BlockVector3.at(pos1.getX(), pos1.getY(), pos1.getZ()), - BlockVector3.at(pos2.getX(), pos2.getY(), pos2.getZ()) - ); - final EditSession editSession = WorldEdit.getInstance().newEditSessionBuilder().world(adaptedWorld) - .checkMemory(false) - .fastMode(true) - .limitUnlimited() - .changeSetNull() - .build(); - - ReadOnlyClipboard clipboard = ReadOnlyClipboard.of(editSession, region, false, true); - - Clipboard holder = new BlockArrayClipboard(region, clipboard); - - CompressedSchematicTag tag = new CompressedSchematicTag(holder); - whenDone.run(tag); - }); - } - - @Override - public boolean save(CompoundTag tag, String path) { - if (tag == null) { - PlotSquared.debug("&cCannot save empty tag"); - return false; - } - try { - File tmp = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), path); - tmp.getParentFile().mkdirs(); - if (tag instanceof CompressedCompoundTag) { - CompressedCompoundTag cTag = (CompressedCompoundTag) tag; - if (cTag instanceof CompressedSchematicTag) { - Clipboard clipboard = (Clipboard) cTag.getSource(); - try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new BufferedOutputStream( - new ParallelGZIPOutputStream(stream)))) { - new FastSchematicWriter(output).write(clipboard); - } - } else { - try (OutputStream stream = new FileOutputStream(tmp); BufferedOutputStream output = new BufferedOutputStream( - new ParallelGZIPOutputStream(stream))) { - LZ4BlockInputStream is = cTag.adapt(cTag.getSource()); - IOUtil.copy(is, stream); - } - } - } else { - try (OutputStream stream = new FileOutputStream(tmp); NBTOutputStream output = new NBTOutputStream(new ParallelGZIPOutputStream( - stream))) { - Map map = tag.getValue(); - output.writeNamedTag("Schematic", map.getOrDefault("Schematic", tag)); - } - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - return false; - } - return true; - } - - @Override - public void upload(final CompoundTag tag, final UUID uuid, final String file, final RunnableVal whenDone) { - if (tag == null) { - PlotSquared.debug("&cCannot save empty tag"); - com.github.intellectualsites.plotsquared.plot.util.TaskManager.runTask(whenDone); - return; - } - CompoundTag weTag = (CompoundTag) FaweCache.IMP.asTag(tag); - if (weTag instanceof CompressedSchematicTag) { - Clipboard clipboard = ((CompressedSchematicTag) weTag).getSource(); - URL url = FaweAPI.upload(clipboard, BuiltInClipboardFormat.SPONGE_SCHEMATIC); - whenDone.run(url); - return; - } - MainUtil.upload(uuid, file, "schem", new RunnableVal() { - @Override - public void run(OutputStream output) { - try { - try (ParallelGZIPOutputStream gzip = new ParallelGZIPOutputStream(output)) { - try (NBTOutputStream nos = new NBTOutputStream(gzip)) { - Map map = weTag.getValue(); - nos.writeNamedTag("Schematic", map.getOrDefault("Schematic", weTag)); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - } - }, whenDone); - } - -} diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/FaweTrim.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/FaweTrim.java deleted file mode 100644 index 0c5f02b59..000000000 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/FaweTrim.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.fastasyncworldedit.bukkit.regions.plotsquaredv4; - -import com.fastasyncworldedit.core.util.TaskManager; -import com.github.intellectualsites.plotsquared.commands.CommandDeclaration; -import com.github.intellectualsites.plotsquared.plot.commands.CommandCategory; -import com.github.intellectualsites.plotsquared.plot.commands.RequiredType; -import com.github.intellectualsites.plotsquared.plot.commands.SubCommand; -import com.github.intellectualsites.plotsquared.plot.config.Captions; -import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; -import com.github.intellectualsites.plotsquared.plot.util.WorldUtil; - -@CommandDeclaration( - command = "trimchunks", - permission = "plots.admin", - description = "Delete unmodified portions of your plotworld", - requiredType = RequiredType.PLAYER, - category = CommandCategory.ADMINISTRATION) -public class FaweTrim extends SubCommand { - - private boolean ran = false; - - @Override - public boolean onCommand(final PlotPlayer plotPlayer, final String[] strings) { - if (ran) { - plotPlayer.sendMessage("Already running!"); - return false; - } - if (strings.length != 2) { - plotPlayer.sendMessage( - "First make a backup of your world called then stand in the middle of an empty plot"); - plotPlayer.sendMessage("use /plot trimall "); - return false; - } - if (!WorldUtil.IMP.isWorld(strings[0])) { - Captions.NOT_VALID_PLOT_WORLD.send(plotPlayer, strings[0]); - return false; - } - ran = true; - TaskManager.IMP.async(new Runnable() { - @Override - public void run() { - try { - // TODO NOT IMPLEMENTED -// PlotTrim trim = new PlotTrim(plotPlayer, plotPlayer.getPlotAreaAbs(), strings[0], Boolean.parseBoolean(strings[1])); -// Location loc = plotPlayer.getLocation(); -// trim.setChunk(loc.getX() >> 4, loc.getZ() >> 4); -// trim.run(); -// plotPlayer.sendMessage("Done!"); - } catch (Throwable e) { - e.printStackTrace(); - } - ran = false; - } - }); - return true; - } - -} diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/PlotSetBiome.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/PlotSetBiome.java deleted file mode 100644 index 3d8e1c8d3..000000000 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/PlotSetBiome.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.fastasyncworldedit.bukkit.regions.plotsquaredv4; - -import com.fastasyncworldedit.core.util.TaskManager; -import com.github.intellectualsites.plotsquared.commands.Command; -import com.github.intellectualsites.plotsquared.commands.CommandDeclaration; -import com.github.intellectualsites.plotsquared.plot.commands.CommandCategory; -import com.github.intellectualsites.plotsquared.plot.commands.MainCommand; -import com.github.intellectualsites.plotsquared.plot.commands.RequiredType; -import com.github.intellectualsites.plotsquared.plot.config.Captions; -import com.github.intellectualsites.plotsquared.plot.object.Plot; -import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; -import com.github.intellectualsites.plotsquared.plot.object.RunnableVal2; -import com.github.intellectualsites.plotsquared.plot.object.RunnableVal3; -import com.github.intellectualsites.plotsquared.plot.util.MainUtil; -import com.github.intellectualsites.plotsquared.plot.util.Permissions; -import com.github.intellectualsites.plotsquared.plot.util.StringMan; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.WorldEdit; -import com.sk89q.worldedit.bukkit.BukkitAdapter; -import com.sk89q.worldedit.extension.platform.Capability; -import com.sk89q.worldedit.regions.CuboidRegion; -import com.sk89q.worldedit.world.biome.BiomeType; -import com.sk89q.worldedit.world.biome.BiomeTypes; -import com.sk89q.worldedit.world.biome.Biomes; -import com.sk89q.worldedit.world.registry.BiomeRegistry; -import org.bukkit.Bukkit; - -import java.util.Collection; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ThreadLocalRandom; - -@CommandDeclaration( - command = "generatebiome", - permission = "plots.generatebiome", - category = CommandCategory.APPEARANCE, - requiredType = RequiredType.NONE, - description = "Generate a biome in your plot", - aliases = {"bg", "gb"}, - usage = "/plots generatebiome " -) -public class PlotSetBiome extends Command { - - public PlotSetBiome() { - super(MainCommand.getInstance(), true); - } - - @Override - public CompletableFuture execute( - final PlotPlayer player, - String[] args, - RunnableVal3 confirm, - RunnableVal2 whenDone - ) throws CommandException { - final Plot plot = check(player.getCurrentPlot(), Captions.NOT_IN_PLOT); - checkTrue(plot.isOwner(player.getUUID()) || Permissions - .hasPermission(player, "plots.admin.command.generatebiome"), Captions.NO_PLOT_PERMS); - if (plot.getRunning() != 0) { - Captions.WAIT_FOR_TIMER.send(player); - return null; - } - checkTrue(args.length == 1, Captions.COMMAND_SYNTAX, getUsage()); - final Set regions = plot.getRegions(); - BiomeRegistry biomeRegistry = WorldEdit - .getInstance() - .getPlatformManager() - .queryCapability(Capability.GAME_HOOKS) - .getRegistries() - .getBiomeRegistry(); - Collection knownBiomes = BiomeTypes.values(); - final BiomeType biome = Biomes.findBiomeByName(knownBiomes, args[0], biomeRegistry); - if (biome == null) { - String biomes = StringMan - .join(BiomeType.REGISTRY.values(), Captions.BLOCK_LIST_SEPARATOR.getTranslated()); - Captions.NEED_BIOME.send(player); - MainUtil.sendMessage(player, Captions.SUBCOMMAND_SET_OPTIONS_HEADER + biomes); - return CompletableFuture.completedFuture(false); - } - confirm.run(this, () -> { - if (plot.getRunning() != 0) { - Captions.WAIT_FOR_TIMER.send(player); - return; - } - plot.addRunning(); - TaskManager.IMP.async(() -> { - EditSession session = WorldEdit.getInstance().newEditSessionBuilder().world(BukkitAdapter.adapt(Bukkit.getWorld( - plot.getArea().worldname))) - .checkMemory(false) - .allowedRegionsEverywhere() - .actor(BukkitAdapter.adapt(Bukkit.getPlayer(player.getUUID()))) - .limitUnlimited() - .build(); - long seed = ThreadLocalRandom.current().nextLong(); - for (CuboidRegion region : regions) { - session.regenerate(region, biome, seed); - } - session.flushQueue(); - plot.removeRunning(); - }); - }, null); - - return CompletableFuture.completedFuture(true); - } - -} diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/PlotSquaredFeature.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/PlotSquaredFeature.java deleted file mode 100644 index 5a2b5484f..000000000 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/plotsquaredv4/PlotSquaredFeature.java +++ /dev/null @@ -1,225 +0,0 @@ -package com.fastasyncworldedit.bukkit.regions.plotsquaredv4; - -import com.fastasyncworldedit.core.FaweAPI; -import com.fastasyncworldedit.core.configuration.Caption; -import com.fastasyncworldedit.core.regions.FaweMask; -import com.fastasyncworldedit.core.regions.FaweMaskManager; -import com.fastasyncworldedit.core.regions.RegionWrapper; -import com.github.intellectualsites.plotsquared.plot.commands.MainCommand; -import com.github.intellectualsites.plotsquared.plot.config.Settings; -import com.github.intellectualsites.plotsquared.plot.database.DBFunc; -import com.github.intellectualsites.plotsquared.plot.flag.Flags; -import com.github.intellectualsites.plotsquared.plot.listener.WEManager; -import com.github.intellectualsites.plotsquared.plot.object.Plot; -import com.github.intellectualsites.plotsquared.plot.object.PlotArea; -import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer; -import com.github.intellectualsites.plotsquared.plot.util.ChunkManager; -import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler; -import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler; -import com.sk89q.worldedit.entity.Player; -import com.sk89q.worldedit.internal.util.LogManagerCompat; -import com.sk89q.worldedit.math.BlockVector3; -import com.sk89q.worldedit.regions.CuboidRegion; -import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.regions.RegionIntersection; -import com.sk89q.worldedit.world.World; -import org.apache.logging.log4j.Logger; -import org.bukkit.Bukkit; - -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; - -public class PlotSquaredFeature extends FaweMaskManager { - - private static final Logger LOGGER = LogManagerCompat.getLogger(); - - public PlotSquaredFeature() { - super("PlotSquared"); - LOGGER.info("Optimizing PlotSquared"); - if (com.fastasyncworldedit.core.configuration.Settings.IMP.ENABLED_COMPONENTS.PLOTSQUARED_V4_HOOK) { - Settings.Enabled_Components.WORLDEDIT_RESTRICTIONS = false; - try { - setupBlockQueue(); - setupSchematicHandler(); - setupChunkManager(); - } catch (Throwable ignored) { - LOGGER.info("Please update PlotSquared: https://www.spigotmc.org/resources/77506/"); - } - if (Settings.PLATFORM.toLowerCase(Locale.ROOT).startsWith("bukkit")) { - new FaweTrim(); - } - if (MainCommand.getInstance().getCommand("generatebiome") == null) { - new PlotSetBiome(); - } - } - // TODO: revisit this later on - /* - try { - if (Settings.Enabled_Components.WORLDS) { - new ReplaceAll(); - } - } catch (Throwable e) { - log.debug("You need to update PlotSquared to access the CFI and REPLACEALL commands"); - } - */ - } - - public static String getName(UUID uuid) { - return UUIDHandler.getName(uuid); - } - - private void setupBlockQueue() throws RuntimeException { - // If it's going to fail, throw an error now rather than later - //QueueProvider provider = QueueProvider.of(FaweLocalBlockQueue.class, null); - //GlobalBlockQueue.IMP.setProvider(provider); - //HybridPlotManager.REGENERATIVE_CLEAR = false; - //log.debug(" - QueueProvider: " + FaweLocalBlockQueue.class); - //log.debug(" - HybridPlotManager.REGENERATIVE_CLEAR: " + HybridPlotManager.REGENERATIVE_CLEAR); - } - - private void setupChunkManager() throws RuntimeException { - ChunkManager.manager = new FaweChunkManager(ChunkManager.manager); - LOGGER.info(" - ChunkManager: {}", ChunkManager.manager); - } - - private void setupSchematicHandler() throws RuntimeException { - SchematicHandler.manager = new FaweSchematicHandler(); - LOGGER.info(" - SchematicHandler: {}", SchematicHandler.manager); - } - - public boolean isAllowed(Player player, Plot plot, MaskType type) { - if (plot == null) { - return false; - } - UUID uid = player.getUniqueId(); - if (Flags.NO_WORLDEDIT.isTrue(plot)) { - 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") - )); - return false; - } - if (plot.getTrusted().contains(uid) || plot.getTrusted().contains(DBFunc.EVERYONE)) { - return true; - } - 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") - )); - 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") - )); - return false; - } - } - player.print(Caption.of( - "fawe.cancel.reason.no.region.reason", - Caption.of("fawe.cancel.reason.no.region.not.added") - )); - return false; - } - - private boolean playerOnline(UUID uuid) { - if (uuid == null) { - return false; - } - org.bukkit.entity.Player player = Bukkit.getPlayer(uuid); - return player != null && player.isOnline(); - } - - @Override - public FaweMask getMask(Player player, MaskType type) { - final PlotPlayer pp = PlotPlayer.wrap(player.getUniqueId()); - if (pp == null) { - return null; - } - final Set regions; - Plot plot = pp.getCurrentPlot(); - if (isAllowed(player, plot, type)) { - regions = plot.getRegions(); - } else { - plot = null; - regions = WEManager.getMask(pp); - if (regions.size() == 1) { - CuboidRegion region = regions.iterator().next(); - if (region.getMinimumPoint().getX() == Integer.MIN_VALUE && region - .getMaximumPoint() - .getX() == Integer.MAX_VALUE) { - regions.clear(); - } - } - } - if (regions.isEmpty()) { - return null; - } - PlotArea area = pp.getApplicablePlotArea(); - int min = area != null ? area.MIN_BUILD_HEIGHT : 0; - int max = area != null ? Math.min(255, area.MAX_BUILD_HEIGHT) : 255; - final HashSet faweRegions = new HashSet<>(); - for (CuboidRegion current : regions) { - faweRegions.add(new RegionWrapper( - current.getMinimumX(), - current.getMaximumX(), - min, - max, - current.getMinimumZ(), - current.getMaximumZ() - )); - } - final CuboidRegion region = regions.iterator().next(); - final BlockVector3 pos1 = BlockVector3.at(region.getMinimumX(), min, region.getMinimumZ()); - final BlockVector3 pos2 = BlockVector3.at(region.getMaximumX(), max, region.getMaximumZ()); - final Plot finalPlot = plot; - if (Settings.Done.RESTRICT_BUILDING && Flags.DONE.isSet(finalPlot) || regions.isEmpty()) { - return null; - } - - Region maskedRegion; - if (regions.size() == 1) { - maskedRegion = new CuboidRegion(pos1, pos2); - } else { - World world = FaweAPI.getWorld(area.worldname); - List weRegions = regions.stream() - .map(r -> new CuboidRegion( - world, - BlockVector3.at(r.getMinimumX(), r.getMinimumY(), r.getMinimumZ()), - BlockVector3.at(r.getMaximumX(), r.getMaximumY(), r.getMaximumZ()) - )) - .collect(Collectors.toList()); - maskedRegion = new RegionIntersection(world, weRegions); - } - - return new FaweMask(maskedRegion) { - @Override - public boolean isValid(Player player, MaskType type) { - if (Settings.Done.RESTRICT_BUILDING && Flags.DONE.isSet(finalPlot)) { - return false; - } - return isAllowed(player, finalPlot, type); - } - }; - } - -} diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 9208881ef..3c7da3f12 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -520,7 +520,7 @@ public class BukkitWorld extends AbstractWorld { public BaseBlock getFullBlock(BlockVector3 position) { BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); if (adapter != null) { - return adapter.getBlock(BukkitAdapter.adapt(getWorld(), position)); + return adapter.getFullBlock(BukkitAdapter.adapt(getWorld(), position)); } else { return getBlock(position).toBaseBlock(); } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index 75946fe01..8ea0a918d 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -138,12 +138,12 @@ public class WorldEditPlugin extends JavaPlugin { platform = new BukkitServerInterface(this, getServer()); worldEdit.getPlatformManager().register(platform); - //FAWE start - Rename config to config-legacy.yml TODO: Chose a better name in the future - createDefaultConfiguration("config-legacy.yml"); // Create the default configuration file for WorldEdit, for us it's 'config-legacy.yml' + //FAWE start - Migrate from config-legacy to worldedit-config + migrateLegacyConfig(); //FAWE end //FAWE start - Modify WorldEdit config name - config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "config-legacy.yml"), true), this); + config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "worldedit-config.yml"), true), this); //FAWE end //FAWE start - Setup permission attachments @@ -422,6 +422,19 @@ public class WorldEditPlugin extends JavaPlugin { } } + private void migrateLegacyConfig() { + File legacy = new File(getDataFolder(), "config-legacy.yml"); + if (legacy.exists()) { + try { + legacy.renameTo(new File(getDataFolder(), "worldedit-config.yml")); + LOGGER.info("Migrated config-legacy.yml to worldedit-config.yml"); + } catch (Exception e) { + LOGGER.error("Unable to rename legacy config file", e); + } + } + createDefaultConfiguration("worldedit-config.yml"); + } + private void copyDefaultConfig(InputStream input, File actual, String name) { try (FileOutputStream output = new FileOutputStream(actual)) { byte[] buf = new byte[8192]; diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java index 8f2e4008e..799e52bb9 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/BukkitImplAdapter.java @@ -106,7 +106,15 @@ public interface BukkitImplAdapter extends IBukkitAdapter { * @param location the location * @return the block */ - BaseBlock getBlock(Location location); + BlockState getBlock(Location location); + + /** + * Get the block at the given location. + * + * @param location the location + * @return the block + */ + BaseBlock getFullBlock(Location location); /** * Create a {@link WorldNativeAccess} for the given world reference. diff --git a/worldedit-bukkit/src/main/resources/defaults/config-legacy.yml b/worldedit-bukkit/src/main/resources/defaults/worldedit-config.yml similarity index 61% rename from worldedit-bukkit/src/main/resources/defaults/config-legacy.yml rename to worldedit-bukkit/src/main/resources/defaults/worldedit-config.yml index 51817009c..8140cade6 100644 --- a/worldedit-bukkit/src/main/resources/defaults/config-legacy.yml +++ b/worldedit-bukkit/src/main/resources/defaults/worldedit-config.yml @@ -10,39 +10,39 @@ # in categories, like "max-blocks-changed", are placed in the "limits" # category. # - If you want to check the format of this file before putting it -# into WorldEdit, paste it into http://yaml-online-parser.appspot.com/ +# into WorldEdit, paste it into https://yaml-online-parser.appspot.com/ # and see if it gives you "ERROR:". # - Lines starting with # are comments, so they are ignored. # - If you want to allow blocks, make sure to change "disallowed-blocks" to [] # -limits : - max-blocks-changed : +limits: + max-blocks-changed: # Ignored, use FAWE config limits - default : -1 - maximum : -1 - max-polygonal-points : - default : -1 - maximum : 20 - max-radius : -1 - max-super-pickaxe-size : 5 - max-brush-radius : 100 - butcher-radius : - default : -1 - maximum : -1 - disallowed-blocks : + default: -1 + maximum: -1 + max-polygonal-points: + default: -1 + maximum: 20 + max-radius: -1 + max-super-pickaxe-size: 5 + max-brush-radius: 100 + butcher-radius: + default: -1 + maximum: -1 + disallowed-blocks: - "minecraft:wheat" - "minecraft:fire" - "minecraft:redstone_wire" -use-inventory : - enable : false - allow-override : true - creative-mode-overrides : false +use-inventory: + enable: false + allow-override: true + creative-mode-overrides: false -logging : - log-commands : false - file : worldedit.log +logging: + log-commands: false + file: worldedit.log # The format of custom log message. This is java general format string (java.util.Formatter). Arguments are: # 1$ : date - a Date object representing event time of the log record. # 2$ : source - a string representing the caller, if available; otherwise, the logger's name. @@ -53,44 +53,44 @@ logging : # For details see: # https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html # https://docs.oracle.com/javase/8/docs/api/java/util/logging/SimpleFormatter.html#format-java.util.logging.LogRecord- - format : "[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s]: %5$s%6$s%n" + format: "[%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %4$s]: %5$s%6$s%n" -super-pickaxe : - drop-items : true - many-drop-items : false +super-pickaxe: + drop-items: true + many-drop-items: false -snapshots : - directory : +snapshots: + directory: -navigation-wand : - item : minecraft:compass - max-distance : 100 +navigation-wand: + item: minecraft:compass + max-distance: 100 -scripting : - timeout : 3000 - dir : craftscripts +scripting: + timeout: 3000 + dir: craftscripts -saving : - dir : schematics +saving: + dir: schematics -files : - allow-symbolic-links : false +files: + allow-symbolic-links: false -history : - size : 15 - expiration : 10 +history: + size: 15 + expiration: 10 -calculation : - timeout : 100 +calculation: + timeout: 100 -debugging : - trace-unflushed-sessions : false +debugging: + trace-unflushed-sessions: false -wand-item : minecraft:wooden_axe -shell-save-type : -no-double-slash : false -no-op-permissions : false -debug : false -show-help-on-first-use : true -server-side-cui : true -command-block-support : false +wand-item: minecraft:wooden_axe +shell-save-type: +no-double-slash: false +no-op-permissions: false +debug: false +show-help-on-first-use: true +server-side-cui: true +command-block-support: false diff --git a/worldedit-bukkit/src/test/java/com/fastasyncworldedit/util/StubServer.java b/worldedit-bukkit/src/test/java/com/fastasyncworldedit/util/StubServer.java index 864f82a9f..e81e849f3 100644 --- a/worldedit-bukkit/src/test/java/com/fastasyncworldedit/util/StubServer.java +++ b/worldedit-bukkit/src/test/java/com/fastasyncworldedit/util/StubServer.java @@ -118,6 +118,11 @@ public class StubServer implements Server { return 0; } + @Override + public int getSimulationDistance() { + return 12; + } + @Override public @NotNull String getIp() { @@ -465,6 +470,11 @@ public class StubServer implements Server { } + @Override + public boolean getHideOnlinePlayers() { + return false; + } + @Override public boolean getOnlineMode() { return false; diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts index 3d73c711b..7e4ae09a7 100644 --- a/worldedit-core/build.gradle.kts +++ b/worldedit-core/build.gradle.kts @@ -12,7 +12,7 @@ applyPlatformAndCoreConfiguration() dependencies { constraints { implementation("org.yaml:snakeyaml") { - version { strictly("1.28") } + version { strictly("1.30") } because("Bukkit provides SnakeYaml") } } @@ -37,7 +37,6 @@ dependencies { // Plugins compileOnly(libs.redprotect) { isTransitive = false } - compileOnly(libs.plotsquaredV4) { isTransitive = false } compileOnly(libs.plotsquaredV6Core) { isTransitive = false } // ensure this is on the classpath for the AP 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 19b574108..f6cc83158 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 @@ -63,8 +63,6 @@ public class Settings extends Config { @Create public WEB WEB; @Create - public PLOTSQUARED_INTEGRATION PLOTSQUARED_INTEGRATION; - @Create public EXTENT EXTENT; @Create public EXPERIMENTAL EXPERIMENTAL; @@ -219,7 +217,7 @@ public class Settings extends Config { }) public List STRIP_NBT = new ArrayList<>(); @Comment({ - "If the disallowed blocks listed in config-legacy.yml should be disallowed in all edits,", + "If the disallowed blocks listed in worldedit-config.yml should be disallowed in all edits,", "not just where blocks patterns are used.", " - Can prevent blocks being pasted from clipboards, etc.", " - If fast-placement is disabled, this may cause edits to be slower." @@ -486,17 +484,6 @@ public class Settings extends Config { } - public static class PLOTSQUARED_INTEGRATION { - - @Comment({ - "Only disables/enables the components with PlotSquared v4.", - "For v6, see PlotSquared settings.yml" - }) - public boolean CLEAR = true; - public boolean COPY_AND_SWAP = true; - - } - public static class WEB { @Comment({ diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java index 6cc3eef7f..3af6fcf78 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java @@ -1,7 +1,6 @@ package com.fastasyncworldedit.core.function.generator; import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.world.block.BlockID; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.BlockVector2; @@ -237,11 +236,8 @@ public class CavesGen extends GenBase { BlockState material = chunk.getBlock(bx + local_x, local_y, bz + local_z); BlockState materialAbove = chunk.getBlock(bx + local_x, local_y + 1, bz + local_z); BlockType blockType = material.getBlockType(); - switch (blockType.getInternalId()) { - case BlockID.MYCELIUM: - case BlockID.GRASS: - grassFound = true; - + switch (blockType.getId()) { + case "minecraft:mycelium", "minecraft:grass_block" -> grassFound = true; } if (this.isSuitableBlock(material, materialAbove)) { if (local_y - 1 < 10) { @@ -281,13 +277,13 @@ public class CavesGen extends GenBase { } protected boolean isSuitableBlock(BlockStateHolder material, BlockStateHolder materialAbove) { - switch (material.getBlockType().getInternalId()) { - case BlockID.AIR: - case BlockID.CAVE_AIR: - case BlockID.VOID_AIR: - case BlockID.WATER: - case BlockID.LAVA: - case BlockID.BEDROCK: + switch (material.getBlockType().getId()) { + case "minecraft:air": + case "minecraft:cave_air": + case "minecraft:void_air": + case "minecraft:water": + case "minecraft:lava": + case "minecraft:bedrock": return false; default: return true; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java index 0e9413f8a..37fdcbf55 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java @@ -10,7 +10,6 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.util.MainUtil; import com.fastasyncworldedit.core.util.TaskManager; -import com.fastasyncworldedit.core.world.block.BlockID; import com.google.common.util.concurrent.Futures; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.EditSession; @@ -187,7 +186,7 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { int xx = bx + x; int from = blocksGet[index]; if (from == 0) { - from = BlockID.AIR; + from = 1; } final int combinedFrom = from; final int combinedTo = blocksSet[index]; @@ -199,22 +198,23 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { } } - BiomeType[] biomes = set.getBiomes(); + BiomeType[][] biomes = set.getBiomes(); if (biomes != null) { - int index = 0; for (int layer = get.getMinSectionPosition(); layer <= get.getMaxSectionPosition(); layer++) { if (!set.hasBiomes(layer)) { continue; } + BiomeType[] biomeSection = biomes[layer - set.getMinSectionPosition()]; + int index = 0; int yy = layer << 4; - for (int y = 0; y < 4; y++) { - for (int z = 0; z < 4; z++) { - for (int x = 0; x < 4; x++, index++) { - BiomeType newBiome = biomes[index]; + for (int y = 0; y < 16; y+= 4) { + for (int z = 0; z < 16; z+= 4) { + for (int x = 0; x < 16; x+= 4, index++) { + BiomeType newBiome = biomeSection[index]; if (newBiome != null) { - BiomeType oldBiome = get.getBiomeType(x, y, z); + BiomeType oldBiome = get.getBiomeType(x, yy + y, z); if (oldBiome != newBiome) { - addBiomeChange(bx + (x << 2), yy + (y << 2), bz + (z << 2), oldBiome, newBiome); + addBiomeChange(bx + x, yy + y, bz + z, oldBiome, newBiome); } } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBlocks.java index 2b4eb84f1..c57be1117 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBlocks.java @@ -3,7 +3,6 @@ package com.fastasyncworldedit.core.queue; import com.fastasyncworldedit.core.FaweCache; import com.fastasyncworldedit.core.internal.io.FastByteArrayOutputStream; import com.fastasyncworldedit.core.internal.io.FaweOutputStream; -import com.fastasyncworldedit.core.world.block.BlockID; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.platform.Capability; @@ -116,11 +115,11 @@ public interface IBlocks extends Trimable { for (int i = 0; i < ids.length; i++) { char ordinal = ids[i]; switch (ordinal) { - case BlockID.__RESERVED__: - case BlockID.CAVE_AIR: - case BlockID.VOID_AIR: - ids[i] = BlockID.AIR; - case BlockID.AIR: + case 0: + case 2: + case 3: + ids[i] = 1; + case 1: continue; default: nonEmpty++; @@ -140,10 +139,10 @@ public interface IBlocks extends Trimable { for (int i = 0; i < palette.paletteToBlockLength; i++) { int ordinal = palette.paletteToBlock[i]; switch (ordinal) { - case BlockID.__RESERVED__: - case BlockID.CAVE_AIR: - case BlockID.VOID_AIR: - case BlockID.AIR: + case 0: + case 2: + case 3: + case 1: sectionWriter.write(0); break; default: diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkSet.java index 318e8ebeb..79aed9f23 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkSet.java @@ -64,7 +64,7 @@ public interface IChunkSet extends IBlocks, OutputExtent { * * @return Array of biomes set */ - BiomeType[] getBiomes(); + BiomeType[][] getBiomes(); default boolean hasBiomes() { return getBiomes() != null; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/BitSetBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/BitSetBlocks.java index efa635626..0829ac710 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/BitSetBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/BitSetBlocks.java @@ -161,7 +161,7 @@ public class BitSetBlocks implements IChunkSet { } @Override - public BiomeType[] getBiomes() { + public BiomeType[][] getBiomes() { return null; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharSetBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharSetBlocks.java index 9b59a4915..64e3aa7ed 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharSetBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharSetBlocks.java @@ -33,7 +33,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { return POOL.poll(); } - public BiomeType[] biomes; + public BiomeType[][] biomes; public char[][] light; public char[][] skyLight; public BlockVector3ChunkMap tiles; @@ -54,17 +54,19 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { } @Override - public BiomeType[] getBiomes() { + public BiomeType[][] getBiomes() { return biomes; } @Override public BiomeType getBiomeType(int x, int y, int z) { + int layer; if (biomes == null || (y >> 4) < minSectionPosition || (y >> 4) > maxSectionPosition) { return null; + } else if (biomes[(layer = (y >> 4) - minSectionPosition)] == null) { + return null; } - y -= minSectionPosition << 4; - return biomes[(y >> 2) << 4 | (z >> 2) << 2 | x >> 2]; + return biomes[layer][(y & 15) >> 2 | (z >> 2) << 2 | x >> 2]; } @Override @@ -96,10 +98,14 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { public boolean setBiome(int x, int y, int z, BiomeType biome) { updateSectionIndexRange(y >> 4); y -= minSectionPosition << 4; + int layer = (y >> 4) - minSectionPosition; if (biomes == null) { - biomes = new BiomeType[64 * sectionCount]; + biomes = new BiomeType[sectionCount][]; + biomes[layer] = new BiomeType[64]; + } else if (biomes[layer] == null) { + biomes[layer] = new BiomeType[64]; } - biomes[(y >> 2) << 4 | (z >> 2) << 2 | x >> 2] = biome; + biomes[layer][(y & 12) << 2 | (z & 12) | (x & 12) >> 2] = biome; return true; } @@ -312,7 +318,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { if (layer < 0 || layer >= sections.length) { return false; } - return biomes != null; + return biomes != null && biomes[layer] != null; } @Override @@ -344,7 +350,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { sectionLocks = tmpSectionLocks; minSectionPosition = layer; if (biomes != null) { - BiomeType[] tmpBiomes = new BiomeType[sectionCount * 64]; + BiomeType[][] tmpBiomes = new BiomeType[sectionCount][64]; System.arraycopy(biomes, 0, tmpBiomes, 64 * diff, biomes.length); biomes = tmpBiomes; } @@ -376,7 +382,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet { sectionLocks = tmpSectionLocks; maxSectionPosition = layer; if (biomes != null) { - BiomeType[] tmpBiomes = new BiomeType[sectionCount * 64]; + BiomeType[][] tmpBiomes = new BiomeType[sectionCount][64]; System.arraycopy(biomes, 0, tmpBiomes, 0, biomes.length); biomes = tmpBiomes; } 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 7a7706f87..27fdf76ad 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 @@ -96,7 +96,7 @@ public class ChunkHolder> implements IQueueChunk { } @Override - public BiomeType[] getBiomes() { + public BiomeType[][] getBiomes() { // Uses set as this method is only used to retrieve biomes that have been set to the extent/chunk. return delegate.set(this).getBiomes(); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/NullChunk.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/NullChunk.java index 9b6d72b95..99757a513 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/NullChunk.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/NullChunk.java @@ -122,7 +122,7 @@ public final class NullChunk implements IQueueChunk { } @Nullable - public BiomeType[] getBiomes() { + public BiomeType[][] getBiomes() { return null; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/registry/state/PropertyKey.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/registry/state/PropertyKey.java index 8145c4514..5c7cdc34b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/registry/state/PropertyKey.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/registry/state/PropertyKey.java @@ -18,8 +18,13 @@ public class PropertyKey implements Comparable { // constants public static final PropertyKey AGE = getOrCreate("age"); public static final PropertyKey ATTACHED = getOrCreate("attached"); + public static final PropertyKey ATTACHMENT = getOrCreate("attachement"); public static final PropertyKey AXIS = getOrCreate("axis"); + public static final PropertyKey BERRIES = getOrCreate("berries"); public static final PropertyKey BITES = getOrCreate("bites"); + public static final PropertyKey BOTTOM = getOrCreate("bottom"); + public static final PropertyKey CANDLES = getOrCreate("candles"); + public static final PropertyKey CHARGES = getOrCreate("charges"); public static final PropertyKey CONDITIONAL = getOrCreate("conditional"); public static final PropertyKey DELAY = getOrCreate("delay"); public static final PropertyKey DISARMED = getOrCreate("disarmed"); @@ -33,17 +38,22 @@ public class PropertyKey implements Comparable { public static final PropertyKey EYE = getOrCreate("eye"); public static final PropertyKey FACE = getOrCreate("face"); public static final PropertyKey FACING = getOrCreate("facing"); + public static final PropertyKey FALLING = getOrCreate("falling"); public static final PropertyKey HALF = getOrCreate("half"); + public static final PropertyKey HANGING = getOrCreate("hanging"); + public static final PropertyKey HAS_BOOK = getOrCreate("has_book"); public static final PropertyKey HAS_BOTTLE_0 = getOrCreate("has_bottle_0"); public static final PropertyKey HAS_BOTTLE_1 = getOrCreate("has_bottle_1"); public static final PropertyKey HAS_BOTTLE_2 = getOrCreate("has_bottle_2"); public static final PropertyKey HAS_RECORD = getOrCreate("has_record"); public static final PropertyKey HATCH = getOrCreate("hatch"); public static final PropertyKey HINGE = getOrCreate("hinge"); - public static final PropertyKey IN_WALL = getOrCreate("in_wall"); + public static final PropertyKey HONEY_LEVEL = getOrCreate("honey_level"); public static final PropertyKey INSTRUMENT = getOrCreate("instrument"); public static final PropertyKey INVERTED = getOrCreate("inverted"); + public static final PropertyKey IN_WALL = getOrCreate("in_wall"); public static final PropertyKey LAYERS = getOrCreate("layers"); + public static final PropertyKey LEAVES = getOrCreate("leaves"); public static final PropertyKey LEVEL = getOrCreate("level"); public static final PropertyKey LIT = getOrCreate("lit"); public static final PropertyKey LOCKED = getOrCreate("locked"); @@ -53,29 +63,30 @@ public class PropertyKey implements Comparable { public static final PropertyKey NOTE = getOrCreate("note"); public static final PropertyKey OCCUPIED = getOrCreate("occupied"); public static final PropertyKey OPEN = getOrCreate("open"); + public static final PropertyKey ORIENTATION = getOrCreate("orientation"); public static final PropertyKey PART = getOrCreate("part"); public static final PropertyKey PERSISTENT = getOrCreate("persistent"); public static final PropertyKey PICKLES = getOrCreate("pickles"); public static final PropertyKey POWER = getOrCreate("power"); public static final PropertyKey POWERED = getOrCreate("powered"); public static final PropertyKey ROTATION = getOrCreate("rotation"); + public static final PropertyKey SCULK_SENSOR_PHASE = getOrCreate("sculk_sensor_phase"); public static final PropertyKey SHAPE = getOrCreate("shape"); public static final PropertyKey SHORT = getOrCreate("short"); + public static final PropertyKey SIGNAL_FIRE = getOrCreate("signal_fire"); public static final PropertyKey SNOWY = getOrCreate("snowy"); public static final PropertyKey SOUTH = getOrCreate("south"); public static final PropertyKey STAGE = getOrCreate("stage"); + public static final PropertyKey TILT = getOrCreate("tilt"); + public static final PropertyKey THICKNESS = getOrCreate("thickness"); public static final PropertyKey TRIGGERED = getOrCreate("triggered"); public static final PropertyKey TYPE = getOrCreate("type"); + public static final PropertyKey UNSTABLE = getOrCreate("unstable"); public static final PropertyKey UP = getOrCreate("up"); + public static final PropertyKey VERTICAL_DIRECTION = getOrCreate("vertical_direction"); + public static final PropertyKey VINE_END = getOrCreate("vine_end"); public static final PropertyKey WATERLOGGED = getOrCreate("waterlogged"); public static final PropertyKey WEST = getOrCreate("west"); - public static final PropertyKey UNSTABLE = getOrCreate("unstable"); - public static final PropertyKey LEAVES = getOrCreate("leaves"); - public static final PropertyKey ATTACHMENT = getOrCreate("attachement"); - public static final PropertyKey SIGNAL_FIRE = getOrCreate("signal_fire"); - public static final PropertyKey HANGING = getOrCreate("hanging"); - public static final PropertyKey HAS_BOOK = getOrCreate("has_book"); - public static final PropertyKey BOTTOM = getOrCreate("bottom"); private final String name; private final int id; @@ -90,10 +101,6 @@ public class PropertyKey implements Comparable { return keyList.size(); } - public final String getName() { - return this.name; - } - public static PropertyKey getByName(CharSequence name) { return keys.get(name); } @@ -116,6 +123,10 @@ public class PropertyKey implements Comparable { }); } + public final String getName() { + return this.name; + } + public int getId() { return id; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/world/block/BlockID.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/world/block/BlockID.java deleted file mode 100644 index c077c7f53..000000000 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/world/block/BlockID.java +++ /dev/null @@ -1,695 +0,0 @@ -package com.fastasyncworldedit.core.world.block; - -/** - * An internal FAWE class used for switch statements on blocks. - * Using IDs to register items is pre 1.13 days. This class is - * deprecated for removal with replacement of namespaced IDs. - */ -@Deprecated(forRemoval = true) -public class BlockID { - - public static final int __RESERVED__ = 0; - public static final int AIR = 1; - public static final int CAVE_AIR = 2; - public static final int VOID_AIR = 3; - public static final int ACACIA_BUTTON = 4; - public static final int ACACIA_DOOR = 5; - public static final int ACACIA_FENCE = 6; - public static final int ACACIA_FENCE_GATE = 7; - public static final int ACACIA_LEAVES = 8; - public static final int ACACIA_LOG = 9; - public static final int ACACIA_PLANKS = 10; - public static final int ACACIA_PRESSURE_PLATE = 11; - public static final int ACACIA_SAPLING = 12; - public static final int ACACIA_SIGN = 501; - public static final int ACACIA_SLAB = 13; - public static final int ACACIA_STAIRS = 14; - public static final int ACACIA_TRAPDOOR = 15; - public static final int ACACIA_WALL_SIGN = 565; - public static final int ACACIA_WOOD = 16; - public static final int ACTIVATOR_RAIL = 17; - public static final int ALLIUM = 18; - public static final int ANDESITE = 19; - public static final int ANDESITE_SLAB = 599; - public static final int ANDESITE_STAIRS = 600; - public static final int ANDESITE_WALL = 601; - public static final int ANVIL = 20; - public static final int ATTACHED_MELON_STEM = 21; - public static final int ATTACHED_PUMPKIN_STEM = 22; - public static final int AZURE_BLUET = 23; - public static final int BAMBOO = 602; - public static final int BAMBOO_SAPLING = 603; - public static final int BARREL = 604; - public static final int BARRIER = 24; - public static final int BEACON = 25; - public static final int BEDROCK = 26; - public static final int BEE_NEST = 677; - public static final int BEEHIVE = 678; // highest - public static final int BEETROOTS = 27; - public static final int BELL = 605; - public static final int BIRCH_BUTTON = 28; - public static final int BIRCH_DOOR = 29; - public static final int BIRCH_FENCE = 30; - public static final int BIRCH_FENCE_GATE = 31; - public static final int BIRCH_LEAVES = 32; - public static final int BIRCH_LOG = 33; - public static final int BIRCH_PLANKS = 34; - public static final int BIRCH_PRESSURE_PLATE = 35; - public static final int BIRCH_SAPLING = 36; - public static final int BIRCH_SIGN = 606; - public static final int BIRCH_SLAB = 37; - public static final int BIRCH_STAIRS = 38; - public static final int BIRCH_TRAPDOOR = 39; - public static final int BIRCH_WALL_SIGN = 607; - public static final int BIRCH_WOOD = 40; - public static final int BLACK_BANNER = 41; - public static final int BLACK_BED = 42; - public static final int BLACK_CARPET = 43; - public static final int BLACK_CONCRETE = 44; - public static final int BLACK_CONCRETE_POWDER = 45; - public static final int BLACK_GLAZED_TERRACOTTA = 46; - public static final int BLACK_SHULKER_BOX = 47; - public static final int BLACK_STAINED_GLASS = 48; - public static final int BLACK_STAINED_GLASS_PANE = 49; - public static final int BLACK_TERRACOTTA = 50; - public static final int BLACK_WALL_BANNER = 51; - public static final int BLACK_WOOL = 52; - public static final int BLAST_FURNACE = 608; - public static final int BLUE_BANNER = 53; - public static final int BLUE_BED = 54; - public static final int BLUE_CARPET = 55; - public static final int BLUE_CONCRETE = 56; - public static final int BLUE_CONCRETE_POWDER = 57; - public static final int BLUE_GLAZED_TERRACOTTA = 58; - public static final int BLUE_ICE = 59; - public static final int BLUE_ORCHID = 60; - public static final int BLUE_SHULKER_BOX = 61; - public static final int BLUE_STAINED_GLASS = 62; - public static final int BLUE_STAINED_GLASS_PANE = 63; - public static final int BLUE_TERRACOTTA = 64; - public static final int BLUE_WALL_BANNER = 65; - public static final int BLUE_WOOL = 66; - public static final int BONE_BLOCK = 67; - public static final int BOOKSHELF = 68; - public static final int BRAIN_CORAL = 69; - public static final int BRAIN_CORAL_BLOCK = 70; - public static final int BRAIN_CORAL_FAN = 71; - public static final int BRAIN_CORAL_WALL_FAN = 72; - public static final int BREWING_STAND = 73; - public static final int BRICK_SLAB = 74; - public static final int BRICK_STAIRS = 75; - public static final int BRICK_WALL = 609; - public static final int BRICKS = 76; - public static final int BROWN_BANNER = 77; - public static final int BROWN_BED = 78; - public static final int BROWN_CARPET = 79; - public static final int BROWN_CONCRETE = 80; - public static final int BROWN_CONCRETE_POWDER = 81; - public static final int BROWN_GLAZED_TERRACOTTA = 82; - public static final int BROWN_MUSHROOM = 83; - public static final int BROWN_MUSHROOM_BLOCK = 84; - public static final int BROWN_SHULKER_BOX = 85; - public static final int BROWN_STAINED_GLASS = 86; - public static final int BROWN_STAINED_GLASS_PANE = 87; - public static final int BROWN_TERRACOTTA = 88; - public static final int BROWN_WALL_BANNER = 89; - public static final int BROWN_WOOL = 90; - public static final int BUBBLE_COLUMN = 91; - public static final int BUBBLE_CORAL = 92; - public static final int BUBBLE_CORAL_BLOCK = 93; - public static final int BUBBLE_CORAL_FAN = 94; - public static final int BUBBLE_CORAL_WALL_FAN = 95; - public static final int CACTUS = 96; - public static final int CAKE = 97; - public static final int CAMPFIRE = 610; - public static final int CARROTS = 98; - public static final int CARTOGRAPHY_TABLE = 611; - public static final int CARVED_PUMPKIN = 99; - public static final int CAULDRON = 100; - public static final int CHAIN_COMMAND_BLOCK = 101; - public static final int CHEST = 102; - public static final int CHIPPED_ANVIL = 103; - public static final int CHISELED_QUARTZ_BLOCK = 104; - public static final int CHISELED_RED_SANDSTONE = 105; - public static final int CHISELED_SANDSTONE = 106; - public static final int CHISELED_STONE_BRICKS = 107; - public static final int CHORUS_FLOWER = 108; - public static final int CHORUS_PLANT = 109; - public static final int CLAY = 110; - public static final int COAL_BLOCK = 111; - public static final int COAL_ORE = 112; - public static final int COARSE_DIRT = 113; - public static final int COBBLESTONE = 114; - public static final int COBBLESTONE_SLAB = 115; - public static final int COBBLESTONE_STAIRS = 116; - public static final int COBBLESTONE_WALL = 117; - public static final int COBWEB = 118; - public static final int COCOA = 119; - public static final int COMMAND_BLOCK = 120; - public static final int COMPARATOR = 121; - public static final int COMPOSTER = 612; - public static final int CONDUIT = 122; - public static final int CORNFLOWER = 613; - public static final int CRACKED_STONE_BRICKS = 123; - public static final int CRAFTING_TABLE = 124; - public static final int CREEPER_HEAD = 125; - public static final int CREEPER_WALL_HEAD = 126; - public static final int CUT_RED_SANDSTONE = 127; - public static final int CUT_RED_SANDSTONE_SLAB = 614; - public static final int CUT_SANDSTONE = 128; - public static final int CUT_SANDSTONE_SLAB = 615; - public static final int CYAN_BANNER = 129; - public static final int CYAN_BED = 130; - public static final int CYAN_CARPET = 131; - public static final int CYAN_CONCRETE = 132; - public static final int CYAN_CONCRETE_POWDER = 133; - public static final int CYAN_GLAZED_TERRACOTTA = 134; - public static final int CYAN_SHULKER_BOX = 135; - public static final int CYAN_STAINED_GLASS = 136; - public static final int CYAN_STAINED_GLASS_PANE = 137; - public static final int CYAN_TERRACOTTA = 138; - public static final int CYAN_WALL_BANNER = 139; - public static final int CYAN_WOOL = 140; - public static final int DAMAGED_ANVIL = 141; - public static final int DANDELION = 142; - public static final int DARK_OAK_BUTTON = 143; - public static final int DARK_OAK_DOOR = 144; - public static final int DARK_OAK_FENCE = 145; - public static final int DARK_OAK_FENCE_GATE = 146; - public static final int DARK_OAK_LEAVES = 147; - public static final int DARK_OAK_LOG = 148; - public static final int DARK_OAK_PLANKS = 149; - public static final int DARK_OAK_PRESSURE_PLATE = 150; - public static final int DARK_OAK_SAPLING = 151; - public static final int DARK_OAK_SIGN = 616; - public static final int DARK_OAK_SLAB = 152; - public static final int DARK_OAK_STAIRS = 153; - public static final int DARK_OAK_TRAPDOOR = 154; - public static final int DARK_OAK_WALL_SIGN = 617; - public static final int DARK_OAK_WOOD = 155; - public static final int DARK_PRISMARINE = 156; - public static final int DARK_PRISMARINE_SLAB = 157; - public static final int DARK_PRISMARINE_STAIRS = 158; - public static final int DAYLIGHT_DETECTOR = 159; - public static final int DEAD_BRAIN_CORAL = 160; - public static final int DEAD_BRAIN_CORAL_BLOCK = 161; - public static final int DEAD_BRAIN_CORAL_FAN = 162; - public static final int DEAD_BRAIN_CORAL_WALL_FAN = 163; - public static final int DEAD_BUBBLE_CORAL = 164; - public static final int DEAD_BUBBLE_CORAL_BLOCK = 165; - public static final int DEAD_BUBBLE_CORAL_FAN = 166; - public static final int DEAD_BUBBLE_CORAL_WALL_FAN = 167; - public static final int DEAD_BUSH = 168; - public static final int DEAD_FIRE_CORAL = 169; - public static final int DEAD_FIRE_CORAL_BLOCK = 170; - public static final int DEAD_FIRE_CORAL_FAN = 171; - public static final int DEAD_FIRE_CORAL_WALL_FAN = 172; - public static final int DEAD_HORN_CORAL = 173; - public static final int DEAD_HORN_CORAL_BLOCK = 174; - public static final int DEAD_HORN_CORAL_FAN = 175; - public static final int DEAD_HORN_CORAL_WALL_FAN = 176; - public static final int DEAD_TUBE_CORAL = 177; - public static final int DEAD_TUBE_CORAL_BLOCK = 178; - public static final int DEAD_TUBE_CORAL_FAN = 179; - public static final int DEAD_TUBE_CORAL_WALL_FAN = 180; - public static final int DETECTOR_RAIL = 181; - public static final int DIAMOND_BLOCK = 182; - public static final int DIAMOND_ORE = 183; - public static final int DIORITE = 184; - public static final int DIORITE_SLAB = 618; - public static final int DIORITE_STAIRS = 619; - public static final int DIORITE_WALL = 620; - public static final int DIRT = 185; - public static final int DISPENSER = 186; - public static final int DRAGON_EGG = 187; - public static final int DRAGON_HEAD = 188; - public static final int DRAGON_WALL_HEAD = 189; - public static final int DRIED_KELP_BLOCK = 190; - public static final int DROPPER = 191; - public static final int EMERALD_BLOCK = 192; - public static final int EMERALD_ORE = 193; - public static final int ENCHANTING_TABLE = 194; - public static final int END_GATEWAY = 195; - public static final int END_PORTAL = 196; - public static final int END_PORTAL_FRAME = 197; - public static final int END_ROD = 198; - public static final int END_STONE = 199; - public static final int END_STONE_BRICK_SLAB = 621; - public static final int END_STONE_BRICK_STAIRS = 622; - public static final int END_STONE_BRICK_WALL = 623; - public static final int END_STONE_BRICKS = 200; - public static final int ENDER_CHEST = 201; - public static final int FARMLAND = 202; - public static final int FERN = 203; - public static final int FIRE = 204; - public static final int FIRE_CORAL = 205; - public static final int FIRE_CORAL_BLOCK = 206; - public static final int FIRE_CORAL_FAN = 207; - public static final int FIRE_CORAL_WALL_FAN = 208; - public static final int FLETCHING_TABLE = 624; - public static final int FLOWER_POT = 209; - public static final int FROSTED_ICE = 210; - public static final int FURNACE = 211; - public static final int GLASS = 212; - public static final int GLASS_PANE = 213; - public static final int GLOWSTONE = 214; - public static final int GOLD_BLOCK = 215; - public static final int GOLD_ORE = 216; - public static final int GRANITE = 217; - public static final int GRANITE_SLAB = 625; - public static final int GRANITE_STAIRS = 626; - public static final int GRANITE_WALL = 627; - public static final int GRASS = 218; - public static final int GRASS_BLOCK = 219; - public static final int GRASS_PATH = 220; - public static final int GRAVEL = 221; - public static final int GRAY_BANNER = 222; - public static final int GRAY_BED = 223; - public static final int GRAY_CARPET = 224; - public static final int GRAY_CONCRETE = 225; - public static final int GRAY_CONCRETE_POWDER = 226; - public static final int GRAY_GLAZED_TERRACOTTA = 227; - public static final int GRAY_SHULKER_BOX = 228; - public static final int GRAY_STAINED_GLASS = 229; - public static final int GRAY_STAINED_GLASS_PANE = 230; - public static final int GRAY_TERRACOTTA = 231; - public static final int GRAY_WALL_BANNER = 232; - public static final int GRAY_WOOL = 233; - public static final int GREEN_BANNER = 234; - public static final int GREEN_BED = 235; - public static final int GREEN_CARPET = 236; - public static final int GREEN_CONCRETE = 237; - public static final int GREEN_CONCRETE_POWDER = 238; - public static final int GREEN_GLAZED_TERRACOTTA = 239; - public static final int GREEN_SHULKER_BOX = 240; - public static final int GREEN_STAINED_GLASS = 241; - public static final int GREEN_STAINED_GLASS_PANE = 242; - public static final int GREEN_TERRACOTTA = 243; - public static final int GREEN_WALL_BANNER = 244; - public static final int GREEN_WOOL = 245; - public static final int GRINDSTONE = 628; - public static final int HAY_BLOCK = 246; - public static final int HEAVY_WEIGHTED_PRESSURE_PLATE = 247; - public static final int HOPPER = 248; - public static final int HORN_CORAL = 249; - public static final int HORN_CORAL_BLOCK = 250; - public static final int HORN_CORAL_FAN = 251; - public static final int HORN_CORAL_WALL_FAN = 252; - public static final int ICE = 253; - public static final int INFESTED_CHISELED_STONE_BRICKS = 254; - public static final int INFESTED_COBBLESTONE = 255; - public static final int INFESTED_CRACKED_STONE_BRICKS = 256; - public static final int INFESTED_MOSSY_STONE_BRICKS = 257; - public static final int INFESTED_STONE = 258; - public static final int INFESTED_STONE_BRICKS = 259; - public static final int IRON_BARS = 260; - public static final int IRON_BLOCK = 261; - public static final int IRON_DOOR = 262; - public static final int IRON_ORE = 263; - public static final int IRON_TRAPDOOR = 264; - public static final int JACK_O_LANTERN = 265; - public static final int JIGSAW = 629; - public static final int JUKEBOX = 266; - public static final int JUNGLE_BUTTON = 267; - public static final int JUNGLE_DOOR = 268; - public static final int JUNGLE_FENCE = 269; - public static final int JUNGLE_FENCE_GATE = 270; - public static final int JUNGLE_LEAVES = 271; - public static final int JUNGLE_LOG = 272; - public static final int JUNGLE_PLANKS = 273; - public static final int JUNGLE_PRESSURE_PLATE = 274; - public static final int JUNGLE_SAPLING = 275; - public static final int JUNGLE_SIGN = 630; - public static final int JUNGLE_SLAB = 276; - public static final int JUNGLE_STAIRS = 277; - public static final int JUNGLE_TRAPDOOR = 278; - public static final int JUNGLE_WALL_SIGN = 631; - public static final int JUNGLE_WOOD = 279; - public static final int KELP = 280; - public static final int KELP_PLANT = 281; - public static final int LADDER = 282; - public static final int LANTERN = 632; - public static final int LAPIS_BLOCK = 283; - public static final int LAPIS_ORE = 284; - public static final int LARGE_FERN = 285; - public static final int LAVA = 286; - public static final int LECTERN = 633; - public static final int LEVER = 287; - public static final int LIGHT_BLUE_BANNER = 288; - public static final int LIGHT_BLUE_BED = 289; - public static final int LIGHT_BLUE_CARPET = 290; - public static final int LIGHT_BLUE_CONCRETE = 291; - public static final int LIGHT_BLUE_CONCRETE_POWDER = 292; - public static final int LIGHT_BLUE_GLAZED_TERRACOTTA = 293; - public static final int LIGHT_BLUE_SHULKER_BOX = 294; - public static final int LIGHT_BLUE_STAINED_GLASS = 295; - public static final int LIGHT_BLUE_STAINED_GLASS_PANE = 296; - public static final int LIGHT_BLUE_TERRACOTTA = 297; - public static final int LIGHT_BLUE_WALL_BANNER = 298; - public static final int LIGHT_BLUE_WOOL = 299; - public static final int LIGHT_GRAY_BANNER = 300; - public static final int LIGHT_GRAY_BED = 301; - public static final int LIGHT_GRAY_CARPET = 302; - public static final int LIGHT_GRAY_CONCRETE = 303; - public static final int LIGHT_GRAY_CONCRETE_POWDER = 304; - public static final int LIGHT_GRAY_GLAZED_TERRACOTTA = 305; - public static final int LIGHT_GRAY_SHULKER_BOX = 306; - public static final int LIGHT_GRAY_STAINED_GLASS = 307; - public static final int LIGHT_GRAY_STAINED_GLASS_PANE = 308; - public static final int LIGHT_GRAY_TERRACOTTA = 309; - public static final int LIGHT_GRAY_WALL_BANNER = 310; - public static final int LIGHT_GRAY_WOOL = 311; - public static final int LIGHT_WEIGHTED_PRESSURE_PLATE = 312; - public static final int LILAC = 313; - public static final int LILY_OF_THE_VALLEY = 634; - public static final int LILY_PAD = 314; - public static final int LIME_BANNER = 315; - public static final int LIME_BED = 316; - public static final int LIME_CARPET = 317; - public static final int LIME_CONCRETE = 318; - public static final int LIME_CONCRETE_POWDER = 319; - public static final int LIME_GLAZED_TERRACOTTA = 320; - public static final int LIME_SHULKER_BOX = 321; - public static final int LIME_STAINED_GLASS = 322; - public static final int LIME_STAINED_GLASS_PANE = 323; - public static final int LIME_TERRACOTTA = 324; - public static final int LIME_WALL_BANNER = 325; - public static final int LIME_WOOL = 326; - public static final int LOOM = 635; - public static final int MAGENTA_BANNER = 327; - public static final int MAGENTA_BED = 328; - public static final int MAGENTA_CARPET = 329; - public static final int MAGENTA_CONCRETE = 330; - public static final int MAGENTA_CONCRETE_POWDER = 331; - public static final int MAGENTA_GLAZED_TERRACOTTA = 332; - public static final int MAGENTA_SHULKER_BOX = 333; - public static final int MAGENTA_STAINED_GLASS = 334; - public static final int MAGENTA_STAINED_GLASS_PANE = 335; - public static final int MAGENTA_TERRACOTTA = 336; - public static final int MAGENTA_WALL_BANNER = 337; - public static final int MAGENTA_WOOL = 338; - public static final int MAGMA_BLOCK = 339; - public static final int MELON = 340; - public static final int MELON_STEM = 341; - public static final int MOSSY_COBBLESTONE = 342; - public static final int MOSSY_COBBLESTONE_SLAB = 636; - public static final int MOSSY_COBBLESTONE_STAIRS = 637; - public static final int MOSSY_COBBLESTONE_WALL = 343; - public static final int MOSSY_STONE_BRICK_SLAB = 638; - public static final int MOSSY_STONE_BRICK_STAIRS = 639; - public static final int MOSSY_STONE_BRICK_WALL = 640; - public static final int MOSSY_STONE_BRICKS = 344; - public static final int MOVING_PISTON = 345; - public static final int MUSHROOM_STEM = 346; - public static final int MYCELIUM = 347; - public static final int NETHER_BRICK_FENCE = 348; - public static final int NETHER_BRICK_SLAB = 349; - public static final int NETHER_BRICK_STAIRS = 350; - public static final int NETHER_BRICK_WALL = 641; - public static final int NETHER_BRICKS = 351; - public static final int NETHER_PORTAL = 352; - public static final int NETHER_QUARTZ_ORE = 353; - public static final int NETHER_WART = 354; - public static final int NETHER_WART_BLOCK = 355; - public static final int NETHERRACK = 356; - public static final int NOTE_BLOCK = 357; - public static final int OAK_BUTTON = 358; - public static final int OAK_DOOR = 359; - public static final int OAK_FENCE = 360; - public static final int OAK_FENCE_GATE = 361; - public static final int OAK_LEAVES = 362; - public static final int OAK_LOG = 363; - public static final int OAK_PLANKS = 364; - public static final int OAK_PRESSURE_PLATE = 365; - public static final int OAK_SAPLING = 366; - public static final int OAK_SIGN = 642; - public static final int OAK_SLAB = 367; - public static final int OAK_STAIRS = 368; - public static final int OAK_TRAPDOOR = 369; - public static final int OAK_WALL_SIGN = 643; - public static final int OAK_WOOD = 370; - public static final int OBSERVER = 371; - public static final int OBSIDIAN = 372; - public static final int ORANGE_BANNER = 373; - public static final int ORANGE_BED = 374; - public static final int ORANGE_CARPET = 375; - public static final int ORANGE_CONCRETE = 376; - public static final int ORANGE_CONCRETE_POWDER = 377; - public static final int ORANGE_GLAZED_TERRACOTTA = 378; - public static final int ORANGE_SHULKER_BOX = 379; - public static final int ORANGE_STAINED_GLASS = 380; - public static final int ORANGE_STAINED_GLASS_PANE = 381; - public static final int ORANGE_TERRACOTTA = 382; - public static final int ORANGE_TULIP = 383; - public static final int ORANGE_WALL_BANNER = 384; - public static final int ORANGE_WOOL = 385; - public static final int OXEYE_DAISY = 386; - public static final int PACKED_ICE = 387; - public static final int PEONY = 388; - public static final int PETRIFIED_OAK_SLAB = 389; - public static final int PINK_BANNER = 390; - public static final int PINK_BED = 391; - public static final int PINK_CARPET = 392; - public static final int PINK_CONCRETE = 393; - public static final int PINK_CONCRETE_POWDER = 394; - public static final int PINK_GLAZED_TERRACOTTA = 395; - public static final int PINK_SHULKER_BOX = 396; - public static final int PINK_STAINED_GLASS = 397; - public static final int PINK_STAINED_GLASS_PANE = 398; - public static final int PINK_TERRACOTTA = 399; - public static final int PINK_TULIP = 400; - public static final int PINK_WALL_BANNER = 401; - public static final int PINK_WOOL = 402; - public static final int PISTON = 403; - public static final int PISTON_HEAD = 404; - public static final int PLAYER_HEAD = 405; - public static final int PLAYER_WALL_HEAD = 406; - public static final int PODZOL = 407; - public static final int POLISHED_ANDESITE = 408; - public static final int POLISHED_ANDESITE_SLAB = 644; - public static final int POLISHED_ANDESITE_STAIRS = 645; - public static final int POLISHED_DIORITE = 409; - public static final int POLISHED_DIORITE_SLAB = 646; - public static final int POLISHED_DIORITE_STAIRS = 647; - public static final int POLISHED_GRANITE = 410; - public static final int POLISHED_GRANITE_SLAB = 648; - public static final int POLISHED_GRANITE_STAIRS = 649; - public static final int POPPY = 411; - public static final int POTATOES = 412; - public static final int POTTED_ACACIA_SAPLING = 413; - public static final int POTTED_ALLIUM = 414; - public static final int POTTED_AZURE_BLUET = 415; - public static final int POTTED_BAMBOO = 650; - public static final int POTTED_BIRCH_SAPLING = 416; - public static final int POTTED_BLUE_ORCHID = 417; - public static final int POTTED_BROWN_MUSHROOM = 418; - public static final int POTTED_CACTUS = 419; - public static final int POTTED_CORNFLOWER = 651; - public static final int POTTED_DANDELION = 420; - public static final int POTTED_DARK_OAK_SAPLING = 421; - public static final int POTTED_DEAD_BUSH = 422; - public static final int POTTED_FERN = 423; - public static final int POTTED_JUNGLE_SAPLING = 424; - public static final int POTTED_LILY_OF_THE_VALLEY = 652; - public static final int POTTED_OAK_SAPLING = 425; - public static final int POTTED_ORANGE_TULIP = 426; - public static final int POTTED_OXEYE_DAISY = 427; - public static final int POTTED_PINK_TULIP = 428; - public static final int POTTED_POPPY = 429; - public static final int POTTED_RED_MUSHROOM = 430; - public static final int POTTED_RED_TULIP = 431; - public static final int POTTED_SPRUCE_SAPLING = 432; - public static final int POTTED_WHITE_TULIP = 433; - public static final int POTTED_WITHER_ROSE = 653; - public static final int POWERED_RAIL = 434; - public static final int PRISMARINE = 435; - public static final int PRISMARINE_BRICK_SLAB = 436; - public static final int PRISMARINE_BRICK_STAIRS = 437; - public static final int PRISMARINE_BRICKS = 438; - public static final int PRISMARINE_SLAB = 439; - public static final int PRISMARINE_STAIRS = 440; - public static final int PRISMARINE_WALL = 654; - public static final int PUMPKIN = 441; - public static final int PUMPKIN_STEM = 442; - public static final int PURPLE_BANNER = 443; - public static final int PURPLE_BED = 444; - public static final int PURPLE_CARPET = 445; - public static final int PURPLE_CONCRETE = 446; - public static final int PURPLE_CONCRETE_POWDER = 447; - public static final int PURPLE_GLAZED_TERRACOTTA = 448; - public static final int PURPLE_SHULKER_BOX = 449; - public static final int PURPLE_STAINED_GLASS = 450; - public static final int PURPLE_STAINED_GLASS_PANE = 451; - public static final int PURPLE_TERRACOTTA = 452; - public static final int PURPLE_WALL_BANNER = 453; - public static final int PURPLE_WOOL = 454; - public static final int PURPUR_BLOCK = 455; - public static final int PURPUR_PILLAR = 456; - public static final int PURPUR_SLAB = 457; - public static final int PURPUR_STAIRS = 458; - public static final int QUARTZ_BLOCK = 459; - public static final int QUARTZ_PILLAR = 460; - public static final int QUARTZ_SLAB = 461; - public static final int QUARTZ_STAIRS = 462; - public static final int RAIL = 463; - public static final int RED_BANNER = 464; - public static final int RED_BED = 465; - public static final int RED_CARPET = 466; - public static final int RED_CONCRETE = 467; - public static final int RED_CONCRETE_POWDER = 468; - public static final int RED_GLAZED_TERRACOTTA = 469; - public static final int RED_MUSHROOM = 470; - public static final int RED_MUSHROOM_BLOCK = 471; - public static final int RED_NETHER_BRICK_SLAB = 655; - public static final int RED_NETHER_BRICK_STAIRS = 656; - public static final int RED_NETHER_BRICK_WALL = 657; - public static final int RED_NETHER_BRICKS = 472; - public static final int RED_SAND = 473; - public static final int RED_SANDSTONE = 474; - public static final int RED_SANDSTONE_SLAB = 475; - public static final int RED_SANDSTONE_STAIRS = 476; - public static final int RED_SANDSTONE_WALL = 658; - public static final int RED_SHULKER_BOX = 477; - public static final int RED_STAINED_GLASS = 478; - public static final int RED_STAINED_GLASS_PANE = 479; - public static final int RED_TERRACOTTA = 480; - public static final int RED_TULIP = 481; - public static final int RED_WALL_BANNER = 482; - public static final int RED_WOOL = 483; - public static final int REDSTONE_BLOCK = 484; - public static final int REDSTONE_LAMP = 485; - public static final int REDSTONE_ORE = 486; - public static final int REDSTONE_TORCH = 487; - public static final int REDSTONE_WALL_TORCH = 488; - public static final int REDSTONE_WIRE = 489; - public static final int REPEATER = 490; - public static final int REPEATING_COMMAND_BLOCK = 491; - public static final int ROSE_BUSH = 492; - public static final int SAND = 493; - public static final int SANDSTONE = 494; - public static final int SANDSTONE_SLAB = 495; - public static final int SANDSTONE_STAIRS = 496; - public static final int SANDSTONE_WALL = 659; - public static final int SCAFFOLDING = 660; - public static final int SEA_LANTERN = 497; - public static final int SEA_PICKLE = 498; - public static final int SEAGRASS = 499; - public static final int SHULKER_BOX = 500; - public static final int SKELETON_SKULL = 502; - public static final int SKELETON_WALL_SKULL = 503; - public static final int SLIME_BLOCK = 504; - public static final int SMITHING_TABLE = 661; - public static final int SMOKER = 662; - public static final int SMOOTH_QUARTZ = 505; - public static final int SMOOTH_QUARTZ_SLAB = 663; - public static final int SMOOTH_QUARTZ_STAIRS = 664; - public static final int SMOOTH_RED_SANDSTONE = 506; - public static final int SMOOTH_RED_SANDSTONE_SLAB = 665; - public static final int SMOOTH_RED_SANDSTONE_STAIRS = 666; - public static final int SMOOTH_SANDSTONE = 507; - public static final int SMOOTH_SANDSTONE_SLAB = 667; - public static final int SMOOTH_SANDSTONE_STAIRS = 668; - public static final int SMOOTH_STONE = 508; - public static final int SMOOTH_STONE_SLAB = 669; - public static final int SNOW = 509; - public static final int SNOW_BLOCK = 510; - public static final int SOUL_SAND = 511; - public static final int SPAWNER = 512; - public static final int SPONGE = 513; - public static final int SPRUCE_BUTTON = 514; - public static final int SPRUCE_DOOR = 515; - public static final int SPRUCE_FENCE = 516; - public static final int SPRUCE_FENCE_GATE = 517; - public static final int SPRUCE_LEAVES = 518; - public static final int SPRUCE_LOG = 519; - public static final int SPRUCE_PLANKS = 520; - public static final int SPRUCE_PRESSURE_PLATE = 521; - public static final int SPRUCE_SAPLING = 522; - public static final int SPRUCE_SIGN = 670; - public static final int SPRUCE_SLAB = 523; - public static final int SPRUCE_STAIRS = 524; - public static final int SPRUCE_TRAPDOOR = 525; - public static final int SPRUCE_WALL_SIGN = 671; - public static final int SPRUCE_WOOD = 526; - public static final int STICKY_PISTON = 527; - public static final int STONE = 528; - public static final int STONE_BRICK_SLAB = 529; - public static final int STONE_BRICK_STAIRS = 530; - public static final int STONE_BRICK_WALL = 672; - public static final int STONE_BRICKS = 531; - public static final int STONE_BUTTON = 532; - public static final int STONE_PRESSURE_PLATE = 533; - public static final int STONE_SLAB = 534; - public static final int STONE_STAIRS = 673; - public static final int STONECUTTER = 674; - public static final int STRIPPED_ACACIA_LOG = 535; - public static final int STRIPPED_ACACIA_WOOD = 536; - public static final int STRIPPED_BIRCH_LOG = 537; - public static final int STRIPPED_BIRCH_WOOD = 538; - public static final int STRIPPED_DARK_OAK_LOG = 539; - public static final int STRIPPED_DARK_OAK_WOOD = 540; - public static final int STRIPPED_JUNGLE_LOG = 541; - public static final int STRIPPED_JUNGLE_WOOD = 542; - public static final int STRIPPED_OAK_LOG = 543; - public static final int STRIPPED_OAK_WOOD = 544; - public static final int STRIPPED_SPRUCE_LOG = 545; - public static final int STRIPPED_SPRUCE_WOOD = 546; - public static final int STRUCTURE_BLOCK = 547; - public static final int STRUCTURE_VOID = 548; - public static final int SUGAR_CANE = 549; - public static final int SUNFLOWER = 550; - public static final int SWEET_BERRY_BUSH = 675; - public static final int TALL_GRASS = 551; - public static final int TALL_SEAGRASS = 552; - public static final int TERRACOTTA = 553; - public static final int TNT = 554; - public static final int TORCH = 555; - public static final int TRAPPED_CHEST = 556; - public static final int TRIPWIRE = 557; - public static final int TRIPWIRE_HOOK = 558; - public static final int TUBE_CORAL = 559; - public static final int TUBE_CORAL_BLOCK = 560; - public static final int TUBE_CORAL_FAN = 561; - public static final int TUBE_CORAL_WALL_FAN = 562; - public static final int TURTLE_EGG = 563; - public static final int VINE = 564; - public static final int WALL_TORCH = 566; - public static final int WATER = 567; - public static final int WET_SPONGE = 568; - public static final int WHEAT = 569; - public static final int WHITE_BANNER = 570; - public static final int WHITE_BED = 571; - public static final int WHITE_CARPET = 572; - public static final int WHITE_CONCRETE = 573; - public static final int WHITE_CONCRETE_POWDER = 574; - public static final int WHITE_GLAZED_TERRACOTTA = 575; - public static final int WHITE_SHULKER_BOX = 576; - public static final int WHITE_STAINED_GLASS = 577; - public static final int WHITE_STAINED_GLASS_PANE = 578; - public static final int WHITE_TERRACOTTA = 579; - public static final int WHITE_TULIP = 580; - public static final int WHITE_WALL_BANNER = 581; - public static final int WHITE_WOOL = 582; - public static final int WITHER_ROSE = 676; - public static final int WITHER_SKELETON_SKULL = 583; - public static final int WITHER_SKELETON_WALL_SKULL = 584; - public static final int YELLOW_BANNER = 585; - public static final int YELLOW_BED = 586; - public static final int YELLOW_CARPET = 587; - public static final int YELLOW_CONCRETE = 588; - public static final int YELLOW_CONCRETE_POWDER = 589; - public static final int YELLOW_GLAZED_TERRACOTTA = 590; - public static final int YELLOW_SHULKER_BOX = 591; - public static final int YELLOW_STAINED_GLASS = 592; - public static final int YELLOW_STAINED_GLASS_PANE = 593; - public static final int YELLOW_TERRACOTTA = 594; - public static final int YELLOW_WALL_BANNER = 595; - public static final int YELLOW_WOOL = 596; - public static final int ZOMBIE_HEAD = 597; - public static final int ZOMBIE_WALL_HEAD = 598; - - // Deprecated - public static final int SIGN = OAK_SIGN; - public static final int WALL_SIGN = OAK_WALL_SIGN; - -} 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 5ac56564b..beb085a0d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -434,9 +434,8 @@ public class EditSession extends PassthroughExtent implements AutoCloseable { return output; } - // pkg private for TracedEditSession only, may later become public API - boolean commitRequired() { - //FAWE start + private boolean commitRequired() { + //FAWE start - false for us, returning true if the reorder extent != null for upstream return false; } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java index e2dba673b..6d178b363 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java @@ -54,7 +54,7 @@ public abstract class LocalConfiguration { private static final Logger LOGGER = LogManagerCompat.getLogger(); public boolean profile = false; - public boolean traceUnflushedSessions = false; + public boolean traceUnflushedSessions = true; public Set disallowedBlocks = new HashSet<>(); protected BlockMask disallowedBlocksMask; public int defaultChangeLimit = -1; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index f0a079e67..2fd81d469 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -1192,13 +1192,13 @@ public class LocalSession implements TextureHolder { /** * Get the brush tool assigned to the item. If there is no tool assigned - * or the tool is not assigned, the slot will be replaced with the + * or the tool is not a brush tool, the slot will be replaced with the * brush tool. * * @param item the item type * @return the tool, or {@code null} * @throws InvalidToolBindException if the item can't be bound to that item - * @deprecated FAWE binds to the item, not the type - this allows brushes to persist + * @deprecated FAWE binds to the item, not the type - this allows brushes to persist, also deprecated in upstream */ @Deprecated public BrushTool getBrushTool(ItemType item) throws InvalidToolBindException { @@ -1232,6 +1232,17 @@ public class LocalSession implements TextureHolder { } //FAWE end + /** + * Get the brush tool assigned to this item. + * + * @param item the item type + * @return the brush tool assigned to the item type + */ + @Nullable + public BrushTool getBrush(ItemType item) { + return getTool(item) instanceof BrushTool tool ? tool : null; + } + //FAWE start - see note of getBrushTool /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/TracedEditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/TracedEditSession.java index 586403847..4b4fb860b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/TracedEditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/TracedEditSession.java @@ -21,16 +21,22 @@ package com.sk89q.worldedit; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.internal.util.ErrorReporting; import com.sk89q.worldedit.util.eventbus.EventBus; import com.sk89q.worldedit.world.World; import javax.annotation.Nullable; +import java.lang.ref.Cleaner; /** * Internal use only. Unused for now, but present in case upstream make it API. */ class TracedEditSession extends EditSession { + private static final Cleaner cleaner = Cleaner.create(); + private final TraceRecord record; + private final Cleaner.Cleanable cleanable; + //FAWE start - does not work with FAWE's ways of doing things... @Deprecated //FAWE end @@ -45,22 +51,37 @@ class TracedEditSession extends EditSession { .blockBag(blockBag) .actor(actor) .tracing(tracing)); + this.record = new TraceRecord(actor); + this.cleanable = cleaner.register(this, record); } - TracedEditSession(EditSessionBuilder builder) { - super(builder); + public void close() { + try { + super.close(); + } finally { + this.record.committed = true; + cleanable.clean(); + } } - private final Throwable stacktrace = new Throwable("Creation trace."); + private static final class TraceRecord implements Runnable { + private final Throwable stacktrace = new Throwable("An EditSession was not closed."); + private final Actor actor; - @Override - protected void finalize() throws Throwable { - super.finalize(); + private volatile boolean committed = false; - if (commitRequired()) { - WorldEdit.logger.warn("####### LEFTOVER BUFFER BLOCKS DETECTED #######"); - WorldEdit.logger.warn("This means that some code did not flush their EditSession."); - WorldEdit.logger.warn("Here is a stacktrace from the creation of this EditSession:", stacktrace); + private TraceRecord(Actor actor) { + this.actor = actor; + } + + @Override + public void run() { + if (!committed) { + WorldEdit.logger.warn("####### EDIT SESSION NOT CLOSED #######"); + WorldEdit.logger.warn("This means that some code did not close their EditSession."); + WorldEdit.logger.warn("Here is a stacktrace from the creation of this EditSession:", stacktrace); + ErrorReporting.trigger(actor, stacktrace); + } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index fb38799a1..b115afbca 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -59,7 +59,6 @@ import com.fastasyncworldedit.core.util.MainUtil; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.StringMan; import com.fastasyncworldedit.core.util.image.ImageUtil; -import com.fastasyncworldedit.core.world.block.BlockID; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EmptyClipboardException; import com.sk89q.worldedit.LocalSession; @@ -1187,9 +1186,9 @@ public class BrushCommands { //FAWE start - Suggest different brush material if sand or gravel is used if (pattern instanceof BlockStateHolder) { BlockType type = ((BlockStateHolder) pattern).getBlockType(); - switch (type.getInternalId()) { - case BlockID.SAND: - case BlockID.GRAVEL: + switch (type.getId()) { + case "minecraft:sand": + case "minecraft:gravel": player.print( Caption.of("fawe.worldedit.brush.brush.try.other")); falling = true; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java index cad6775ac..c145fa61f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java @@ -113,7 +113,7 @@ public class WorldEditCommands { //FAWE start @Command( name = "debugpaste", - desc = "Writes a report of latest.log, config.yml, config-legacy.yml, strings.json to https://athion.net/ISPaster/paste" + desc = "Writes a report of latest.log, config.yml, worldedit-config.yml, strings.json to https://athion.net/ISPaster/paste" ) @CommandPermissions(value = {"worldedit.report", "worldedit.debugpaste"}, queued = false) public void report(Actor actor) throws WorldEditException { @@ -121,8 +121,8 @@ public class WorldEditCommands { try { final File logFile = new File("logs/latest.log"); final File config = new File(Fawe.imp().getDirectory(), "config.yml"); - final File legacyConfig = new File(Fawe.imp().getDirectory(), "config-legacy.yml"); - dest = IncendoPaster.debugPaste(logFile, Fawe.imp().getDebugInfo(), config, legacyConfig); + final File worldeditConfig = new File(Fawe.imp().getDirectory(), "worldedit-config.yml"); + dest = IncendoPaster.debugPaste(logFile, Fawe.imp().getDebugInfo(), config, worldeditConfig); } catch (IOException e) { actor.printInfo(TextComponent.of(e.getMessage())); return; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/QueryTool.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/QueryTool.java index d2a6fde14..23e570107 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/QueryTool.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/QueryTool.java @@ -20,7 +20,6 @@ package com.sk89q.worldedit.command.tool; import com.fastasyncworldedit.core.configuration.Caption; -import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.entity.Player; @@ -56,9 +55,8 @@ public class QueryTool implements BlockTool { ) { World world = (World) clicked.getExtent(); - EditSession editSession = session.createEditSession(player); BlockVector3 blockPoint = clicked.toVector().toBlockPoint(); - BaseBlock block = editSession.getFullBlock(blockPoint); + BaseBlock block = world.getFullBlock(blockPoint); TextComponent.Builder builder = TextComponent.builder(); builder.append(TextComponent.of("@" + clicked.toVector().toBlockPoint() + ": ", TextColor.BLUE)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java index d07b4d805..626703203 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformCommandManager.java @@ -120,6 +120,7 @@ import com.sk89q.worldedit.internal.command.CommandLoggingHandler; import com.sk89q.worldedit.internal.command.CommandRegistrationHandler; import com.sk89q.worldedit.internal.command.exception.ExceptionConverter; import com.sk89q.worldedit.internal.command.exception.WorldEditExceptionConverter; +import com.sk89q.worldedit.internal.util.ErrorReporting; import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.internal.util.Substring; import com.sk89q.worldedit.regions.Region; @@ -884,10 +885,9 @@ public final class PlatformCommandManager { } private void handleUnknownException(Actor actor, Throwable t) { - actor.print(Caption.of("worldedit.command.error.report")); - actor.print(TextComponent.of(t.getClass().getName() + ": " + t.getMessage())); //FAWE start - Exchange name LOGGER.error("An unexpected error while handling a FastAsyncWorldEdit command", t); + ErrorReporting.trigger(actor, t); //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java index c7dd577c1..7e5a4abf1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/mask/BlockMask.java @@ -210,9 +210,9 @@ public class BlockMask extends ABlockMask { @Override public boolean replacesAir() { - return ordinals[BlockTypes.AIR.getDefaultState().getOrdinal()] - || ordinals[BlockTypes.CAVE_AIR.getDefaultState().getOrdinal()] - || ordinals[BlockTypes.VOID_AIR.getDefaultState().getOrdinal()]; + return ordinals[1] + || ordinals[2] + || ordinals[3]; } @Override @@ -334,9 +334,9 @@ public class BlockMask extends ABlockMask { cloned[i] = !cloned[i]; } if (replacesAir()) { - cloned[BlockTypes.AIR.getDefaultState().getOrdinal()] = false; - cloned[BlockTypes.CAVE_AIR.getDefaultState().getOrdinal()] = false; - cloned[BlockTypes.VOID_AIR.getDefaultState().getOrdinal()] = false; + cloned[1] = false; + cloned[2] = false; + cloned[3] = false; cloned[0] = false; } return new BlockMask(getExtent(), cloned); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/Constants.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/Constants.java index a55b90f36..be9dabfc4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/Constants.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/Constants.java @@ -44,17 +44,23 @@ public final class Constants { /** * The DataVersion for Minecraft 1.13 + * @deprecated If Fawe drops interaction with 1.13, this method is subject to removal. */ + @Deprecated(forRemoval = true, since = "2.0.0") public static final int DATA_VERSION_MC_1_13 = 1519; /** * The DataVersion for Minecraft 1.13.2 + * @deprecated If Fawe drops interaction with 1.13, this method is subject to removal. */ + @Deprecated(forRemoval = true, since = "2.0.0") public static final int DATA_VERSION_MC_1_13_2 = 1631; /** * The DataVersion for Minecraft 1.14 + * @deprecated If Fawe drops interaction with 1.14, this method is subject to removal. */ + @Deprecated(forRemoval = true, since = "2.0.0") public static final int DATA_VERSION_MC_1_14 = 1952; /** @@ -72,11 +78,9 @@ public final class Constants { */ public static final int DATA_VERSION_MC_1_17 = 2724; - //FAWE start - add data version for 1.18 /** * The DataVersion for Minecraft 1.18 */ public static final int DATA_VERSION_MC_1_18 = 2860; - //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/ErrorReporting.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/ErrorReporting.java new file mode 100644 index 000000000..fa5b95868 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/util/ErrorReporting.java @@ -0,0 +1,43 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.internal.util; + +import com.fastasyncworldedit.core.configuration.Caption; +import com.google.common.base.Throwables; +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.event.HoverEvent; + +/** + * Simple class for handling error reporting to users. + */ +public class ErrorReporting { + private ErrorReporting() { + } + + public static void trigger(Actor actor, Throwable error) { + actor.printError(Caption.of("worldedit.command.error.report")); + actor.print( + TextComponent.builder(error.getClass().getName() + ": " + error.getMessage()) + .hoverEvent(HoverEvent.showText(TextComponent.of(Throwables.getStackTraceAsString(error)))) + .build() + ); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java index 14fb05834..9df060bf6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java @@ -121,12 +121,12 @@ public final class BlockTypes { @Nullable public static final BlockType BEDROCK = init(); @Nullable - public static final BlockType BEE_NEST = init(); - @Nullable public static final BlockType BEEHIVE = init(); @Nullable public static final BlockType BEETROOTS = init(); @Nullable + public static final BlockType BEE_NEST = init(); + @Nullable public static final BlockType BELL = init(); @Nullable public static final BlockType BIG_DRIPLEAF = init(); @@ -163,6 +163,14 @@ public final class BlockTypes { @Nullable public static final BlockType BIRCH_WOOD = init(); @Nullable + public static final BlockType BLACKSTONE = init(); + @Nullable + public static final BlockType BLACKSTONE_SLAB = init(); + @Nullable + public static final BlockType BLACKSTONE_STAIRS = init(); + @Nullable + public static final BlockType BLACKSTONE_WALL = init(); + @Nullable public static final BlockType BLACK_BANNER = init(); @Nullable public static final BlockType BLACK_BED = init(); @@ -191,14 +199,6 @@ public final class BlockTypes { @Nullable public static final BlockType BLACK_WOOL = init(); @Nullable - public static final BlockType BLACKSTONE = init(); - @Nullable - public static final BlockType BLACKSTONE_SLAB = init(); - @Nullable - public static final BlockType BLACKSTONE_STAIRS = init(); - @Nullable - public static final BlockType BLACKSTONE_WALL = init(); - @Nullable public static final BlockType BLAST_FURNACE = init(); @Nullable public static final BlockType BLUE_BANNER = init(); @@ -247,14 +247,14 @@ public final class BlockTypes { @Nullable public static final BlockType BREWING_STAND = init(); @Nullable + public static final BlockType BRICKS = init(); + @Nullable public static final BlockType BRICK_SLAB = init(); @Nullable public static final BlockType BRICK_STAIRS = init(); @Nullable public static final BlockType BRICK_WALL = init(); @Nullable - public static final BlockType BRICKS = init(); - @Nullable public static final BlockType BROWN_BANNER = init(); @Nullable public static final BlockType BROWN_BED = init(); @@ -389,8 +389,6 @@ public final class BlockTypes { @Nullable public static final BlockType COPPER_BLOCK = init(); @Nullable - public static final BlockType COPPER_ORE = init(); - @Nullable public static final BlockType CORNFLOWER = init(); @Nullable public static final BlockType CRACKED_DEEPSLATE_BRICKS = init(); @@ -571,14 +569,14 @@ public final class BlockTypes { @Nullable public static final BlockType DEEPSLATE = init(); @Nullable + public static final BlockType DEEPSLATE_BRICKS = init(); + @Nullable public static final BlockType DEEPSLATE_BRICK_SLAB = init(); @Nullable public static final BlockType DEEPSLATE_BRICK_STAIRS = init(); @Nullable public static final BlockType DEEPSLATE_BRICK_WALL = init(); @Nullable - public static final BlockType DEEPSLATE_BRICKS = init(); - @Nullable public static final BlockType DEEPSLATE_COAL_ORE = init(); @Nullable public static final BlockType DEEPSLATE_COPPER_ORE = init(); @@ -595,14 +593,14 @@ public final class BlockTypes { @Nullable public static final BlockType DEEPSLATE_REDSTONE_ORE = init(); @Nullable + public static final BlockType DEEPSLATE_TILES = init(); + @Nullable public static final BlockType DEEPSLATE_TILE_SLAB = init(); @Nullable public static final BlockType DEEPSLATE_TILE_STAIRS = init(); @Nullable public static final BlockType DEEPSLATE_TILE_WALL = init(); @Nullable - public static final BlockType DEEPSLATE_TILES = init(); - @Nullable public static final BlockType DETECTOR_RAIL = init(); @Nullable public static final BlockType DIAMOND_BLOCK = init(); @@ -641,6 +639,8 @@ public final class BlockTypes { @Nullable public static final BlockType ENCHANTING_TABLE = init(); @Nullable + public static final BlockType ENDER_CHEST = init(); + @Nullable public static final BlockType END_GATEWAY = init(); @Nullable public static final BlockType END_PORTAL = init(); @@ -651,18 +651,16 @@ public final class BlockTypes { @Nullable public static final BlockType END_STONE = init(); @Nullable + public static final BlockType END_STONE_BRICKS = init(); + @Nullable public static final BlockType END_STONE_BRICK_SLAB = init(); @Nullable public static final BlockType END_STONE_BRICK_STAIRS = init(); @Nullable public static final BlockType END_STONE_BRICK_WALL = init(); @Nullable - public static final BlockType END_STONE_BRICKS = init(); - @Nullable public static final BlockType EXPOSED_COPPER = init(); @Nullable - public static final BlockType ENDER_CHEST = init(); - @Nullable public static final BlockType EXPOSED_CUT_COPPER = init(); @Nullable public static final BlockType EXPOSED_CUT_COPPER_SLAB = init(); @@ -685,12 +683,12 @@ public final class BlockTypes { @Nullable public static final BlockType FLETCHING_TABLE = init(); @Nullable - public static final BlockType FLOWER_POT = init(); - @Nullable public static final BlockType FLOWERING_AZALEA = init(); @Nullable public static final BlockType FLOWERING_AZALEA_LEAVES = init(); @Nullable + public static final BlockType FLOWER_POT = init(); + @Nullable public static final BlockType FROSTED_ICE = init(); @Nullable public static final BlockType FURNACE = init(); @@ -701,10 +699,10 @@ public final class BlockTypes { @Nullable public static final BlockType GLASS_PANE = init(); @Nullable - public static final BlockType GLOW_LICHEN = init(); - @Nullable public static final BlockType GLOWSTONE = init(); @Nullable + public static final BlockType GLOW_LICHEN = init(); + @Nullable public static final BlockType GOLD_BLOCK = init(); @Nullable public static final BlockType GOLD_ORE = init(); @@ -720,9 +718,6 @@ public final class BlockTypes { public static final BlockType GRASS = init(); @Nullable public static final BlockType GRASS_BLOCK = init(); - @Deprecated - @Nullable - public static final BlockType GRASS_PATH = init(); @Nullable public static final BlockType GRAVEL = init(); @Nullable @@ -790,10 +785,10 @@ public final class BlockTypes { @Nullable public static final BlockType HEAVY_WEIGHTED_PRESSURE_PLATE = init(); @Nullable - public static final BlockType HONEY_BLOCK = init(); - @Nullable public static final BlockType HONEYCOMB_BLOCK = init(); @Nullable + public static final BlockType HONEY_BLOCK = init(); + @Nullable public static final BlockType HOPPER = init(); @Nullable public static final BlockType HORN_CORAL = init(); @@ -892,6 +887,8 @@ public final class BlockTypes { @Nullable public static final BlockType LIGHT = init(); @Nullable + public static final BlockType LIGHTNING_ROD = init(); + @Nullable public static final BlockType LIGHT_BLUE_BANNER = init(); @Nullable public static final BlockType LIGHT_BLUE_BED = init(); @@ -950,8 +947,6 @@ public final class BlockTypes { @Nullable public static final BlockType LIGHT_WEIGHTED_PRESSURE_PLATE = init(); @Nullable - public static final BlockType LIGHTNING_ROD = init(); - @Nullable public static final BlockType LILAC = init(); @Nullable public static final BlockType LILY_OF_THE_VALLEY = init(); @@ -1026,10 +1021,6 @@ public final class BlockTypes { @Nullable public static final BlockType MELON_STEM = init(); @Nullable - public static final BlockType MOSS_BLOCK = init(); - @Nullable - public static final BlockType MOSS_CARPET = init(); - @Nullable public static final BlockType MOSSY_COBBLESTONE = init(); @Nullable public static final BlockType MOSSY_COBBLESTONE_SLAB = init(); @@ -1038,13 +1029,17 @@ public final class BlockTypes { @Nullable public static final BlockType MOSSY_COBBLESTONE_WALL = init(); @Nullable + public static final BlockType MOSSY_STONE_BRICKS = init(); + @Nullable public static final BlockType MOSSY_STONE_BRICK_SLAB = init(); @Nullable public static final BlockType MOSSY_STONE_BRICK_STAIRS = init(); @Nullable public static final BlockType MOSSY_STONE_BRICK_WALL = init(); @Nullable - public static final BlockType MOSSY_STONE_BRICKS = init(); + public static final BlockType MOSS_BLOCK = init(); + @Nullable + public static final BlockType MOSS_CARPET = init(); @Nullable public static final BlockType MOVING_PISTON = init(); @Nullable @@ -1052,6 +1047,12 @@ public final class BlockTypes { @Nullable public static final BlockType MYCELIUM = init(); @Nullable + public static final BlockType NETHERITE_BLOCK = init(); + @Nullable + public static final BlockType NETHERRACK = init(); + @Nullable + public static final BlockType NETHER_BRICKS = init(); + @Nullable public static final BlockType NETHER_BRICK_FENCE = init(); @Nullable public static final BlockType NETHER_BRICK_SLAB = init(); @@ -1060,8 +1061,6 @@ public final class BlockTypes { @Nullable public static final BlockType NETHER_BRICK_WALL = init(); @Nullable - public static final BlockType NETHER_BRICKS = init(); - @Nullable public static final BlockType NETHER_GOLD_ORE = init(); @Nullable public static final BlockType NETHER_PORTAL = init(); @@ -1074,10 +1073,6 @@ public final class BlockTypes { @Nullable public static final BlockType NETHER_WART_BLOCK = init(); @Nullable - public static final BlockType NETHERITE_BLOCK = init(); - @Nullable - public static final BlockType NETHERRACK = init(); - @Nullable public static final BlockType NOTE_BLOCK = init(); @Nullable public static final BlockType OAK_BUTTON = init(); @@ -1212,14 +1207,14 @@ public final class BlockTypes { @Nullable public static final BlockType POLISHED_BLACKSTONE = init(); @Nullable + public static final BlockType POLISHED_BLACKSTONE_BRICKS = init(); + @Nullable public static final BlockType POLISHED_BLACKSTONE_BRICK_SLAB = init(); @Nullable public static final BlockType POLISHED_BLACKSTONE_BRICK_STAIRS = init(); @Nullable public static final BlockType POLISHED_BLACKSTONE_BRICK_WALL = init(); @Nullable - public static final BlockType POLISHED_BLACKSTONE_BRICKS = init(); - @Nullable public static final BlockType POLISHED_BLACKSTONE_BUTTON = init(); @Nullable public static final BlockType POLISHED_BLACKSTONE_PRESSURE_PLATE = init(); @@ -1257,9 +1252,12 @@ public final class BlockTypes { public static final BlockType POTTED_ACACIA_SAPLING = init(); @Nullable public static final BlockType POTTED_ALLIUM = init(); + @Deprecated //No longer has "bush" @Nullable public static final BlockType POTTED_AZALEA_BUSH = init(); @Nullable + public static final BlockType POTTED_AZALEA = init(); + @Nullable public static final BlockType POTTED_AZURE_BLUET = init(); @Nullable public static final BlockType POTTED_BAMBOO = init(); @@ -1285,9 +1283,12 @@ public final class BlockTypes { public static final BlockType POTTED_DEAD_BUSH = init(); @Nullable public static final BlockType POTTED_FERN = init(); + @Deprecated //No longer has "bush" @Nullable public static final BlockType POTTED_FLOWERING_AZALEA_BUSH = init(); @Nullable + public static final BlockType POTTED_FLOWERING_AZALEA = init(); + @Nullable public static final BlockType POTTED_JUNGLE_SAPLING = init(); @Nullable public static final BlockType POTTED_LILY_OF_THE_VALLEY = init(); @@ -1324,12 +1325,12 @@ public final class BlockTypes { @Nullable public static final BlockType PRISMARINE = init(); @Nullable + public static final BlockType PRISMARINE_BRICKS = init(); + @Nullable public static final BlockType PRISMARINE_BRICK_SLAB = init(); @Nullable public static final BlockType PRISMARINE_BRICK_STAIRS = init(); @Nullable - public static final BlockType PRISMARINE_BRICKS = init(); - @Nullable public static final BlockType PRISMARINE_SLAB = init(); @Nullable public static final BlockType PRISMARINE_STAIRS = init(); @@ -1394,6 +1395,18 @@ public final class BlockTypes { @Nullable public static final BlockType RAW_IRON_BLOCK = init(); @Nullable + public static final BlockType REDSTONE_BLOCK = init(); + @Nullable + public static final BlockType REDSTONE_LAMP = init(); + @Nullable + public static final BlockType REDSTONE_ORE = init(); + @Nullable + public static final BlockType REDSTONE_TORCH = init(); + @Nullable + public static final BlockType REDSTONE_WALL_TORCH = init(); + @Nullable + public static final BlockType REDSTONE_WIRE = init(); + @Nullable public static final BlockType RED_BANNER = init(); @Nullable public static final BlockType RED_BED = init(); @@ -1414,14 +1427,14 @@ public final class BlockTypes { @Nullable public static final BlockType RED_MUSHROOM_BLOCK = init(); @Nullable + public static final BlockType RED_NETHER_BRICKS = init(); + @Nullable public static final BlockType RED_NETHER_BRICK_SLAB = init(); @Nullable public static final BlockType RED_NETHER_BRICK_STAIRS = init(); @Nullable public static final BlockType RED_NETHER_BRICK_WALL = init(); @Nullable - public static final BlockType RED_NETHER_BRICKS = init(); - @Nullable public static final BlockType RED_SAND = init(); @Nullable public static final BlockType RED_SANDSTONE = init(); @@ -1446,18 +1459,6 @@ public final class BlockTypes { @Nullable public static final BlockType RED_WOOL = init(); @Nullable - public static final BlockType REDSTONE_BLOCK = init(); - @Nullable - public static final BlockType REDSTONE_LAMP = init(); - @Nullable - public static final BlockType REDSTONE_ORE = init(); - @Nullable - public static final BlockType REDSTONE_TORCH = init(); - @Nullable - public static final BlockType REDSTONE_WALL_TORCH = init(); - @Nullable - public static final BlockType REDSTONE_WIRE = init(); - @Nullable public static final BlockType REPEATER = init(); @Nullable public static final BlockType REPEATING_COMMAND_BLOCK = init(); @@ -1482,12 +1483,12 @@ public final class BlockTypes { @Nullable public static final BlockType SCULK_SENSOR = init(); @Nullable + public static final BlockType SEAGRASS = init(); + @Nullable public static final BlockType SEA_LANTERN = init(); @Nullable public static final BlockType SEA_PICKLE = init(); @Nullable - public static final BlockType SEAGRASS = init(); - @Nullable public static final BlockType SHROOMLIGHT = init(); @Nullable public static final BlockType SHULKER_BOX = init(); @@ -1591,14 +1592,16 @@ public final class BlockTypes { @Nullable public static final BlockType STONE = init(); @Nullable + public static final BlockType STONECUTTER = init(); + @Nullable + public static final BlockType STONE_BRICKS = init(); + @Nullable public static final BlockType STONE_BRICK_SLAB = init(); @Nullable public static final BlockType STONE_BRICK_STAIRS = init(); @Nullable public static final BlockType STONE_BRICK_WALL = init(); @Nullable - public static final BlockType STONE_BRICKS = init(); - @Nullable public static final BlockType STONE_BUTTON = init(); @Nullable public static final BlockType STONE_PRESSURE_PLATE = init(); @@ -1607,8 +1610,6 @@ public final class BlockTypes { @Nullable public static final BlockType STONE_STAIRS = init(); @Nullable - public static final BlockType STONECUTTER = init(); - @Nullable public static final BlockType STRIPPED_ACACIA_LOG = init(); @Nullable public static final BlockType STRIPPED_ACACIA_WOOD = init(); @@ -1772,10 +1773,10 @@ public final class BlockTypes { @Nullable public static final BlockType WEATHERED_CUT_COPPER_SLAB = init(); @Nullable - public static final BlockType WEEPING_VINES = init(); - @Nullable public static final BlockType WEATHERED_CUT_COPPER_STAIRS = init(); @Nullable + public static final BlockType WEEPING_VINES = init(); + @Nullable public static final BlockType WEEPING_VINES_PLANT = init(); @Nullable public static final BlockType WET_SPONGE = init(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypesCache.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypesCache.java index d476c092c..4485945fc 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypesCache.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypesCache.java @@ -2,7 +2,6 @@ package com.sk89q.worldedit.world.block; import com.fastasyncworldedit.core.registry.state.PropertyKey; import com.fastasyncworldedit.core.util.MathMan; -import com.fastasyncworldedit.core.world.block.BlockID; import com.google.common.primitives.Booleans; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.WorldEdit; @@ -14,7 +13,6 @@ import com.sk89q.worldedit.world.registry.BlockMaterial; import com.sk89q.worldedit.world.registry.BlockRegistry; import com.sk89q.worldedit.world.registry.Registries; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -218,14 +216,15 @@ public class BlockTypesCache { : item, item -> item)); int size = blockMap.size() + 1; - Field[] idFields = BlockID.class.getDeclaredFields(); - for (Field field : idFields) { - size = Math.max(field.getInt(null) + 1, size); - } BIT_OFFSET = MathMan.log2nlz(size); BIT_MASK = ((1 << BIT_OFFSET) - 1); values = new BlockType[size]; + /*Field[] idFields = BlockID.class.getDeclaredFields(); + for (Field field : idFields) { + size = Math.max(field.getInt(null) + 1, size); + } + // Register the statically declared ones first for (Field field : idFields) { if (field.getType() == int.class) { @@ -245,9 +244,30 @@ public class BlockTypesCache { // Note: Throws IndexOutOfBoundsError if nothing is registered and blocksMap is empty values[internalId] = type; } + }*/ + + // Register "Reserved". Ensure air/reserved and 0/1/2/3 + { + int internalId = 0; + for (String id : new String[]{"minecraft:__reserved__", "minecraft:air", "minecraft:cave_air", + "minecraft:void_air"}) { + String defaultState = blockMap.remove(id); + if (defaultState == null) { + defaultState = id; + } + if (values[internalId] != null) { + throw new IllegalStateException( + "Invalid duplicate id for __reserved__! Something has gone very wrong. Are " + + "any plugins shading FAWE?!"); + } + BlockType type = register(defaultState, internalId, stateList, tickList); + // Note: Throws IndexOutOfBoundsError if nothing is registered and blocksMap is empty + values[internalId] = type; + internalId++; + } } - { // Register new blocks + { // Register real blocks int internalId = 1; for (Map.Entry entry : blockMap.entrySet()) { String defaultState = entry.getValue(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk16.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk16.java index 1e507e58c..92f7f6caf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk16.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk16.java @@ -26,7 +26,7 @@ import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.storage.InvalidFormatException; /** - * The chunk format for Minecraft 1.16 and newer + * The chunk format for Minecraft 1.16 and 1.17 */ public class AnvilChunk16 extends AnvilChunk15 { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java new file mode 100644 index 000000000..6d8348d5e --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java @@ -0,0 +1,218 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.world.chunk; + +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.jnbt.IntTag; +import com.sk89q.jnbt.ListTag; +import com.sk89q.jnbt.LongArrayTag; +import com.sk89q.jnbt.NBTUtils; +import com.sk89q.jnbt.Tag; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.registry.state.Property; +import com.sk89q.worldedit.world.DataException; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockType; +import com.sk89q.worldedit.world.block.BlockTypes; +import com.sk89q.worldedit.world.storage.InvalidFormatException; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * The chunk format for Minecraft 1.18 and newer + */ +public class AnvilChunk18 implements Chunk { + + private final CompoundTag rootTag; + private final Int2ObjectOpenHashMap blocks; + private final int rootX; + private final int rootZ; + + private Map> tileEntities; + + /** + * Construct the chunk with a compound tag. + * + * @param tag the tag to read + * @throws DataException on a data error + */ + public AnvilChunk18(CompoundTag tag) throws DataException { + rootTag = tag; + + rootX = NBTUtils.getChildTag(rootTag.getValue(), "xPos", IntTag.class).getValue(); + rootZ = NBTUtils.getChildTag(rootTag.getValue(), "zPos", IntTag.class).getValue(); + + List sections = NBTUtils.getChildTag(rootTag.getValue(), "sections", ListTag.class).getValue(); + blocks = new Int2ObjectOpenHashMap<>(sections.size()); + + for (Tag rawSectionTag : sections) { + if (!(rawSectionTag instanceof CompoundTag sectionTag)) { + continue; + } + + Object yValue = sectionTag.getValue().get("Y").getValue(); // sometimes a byte, sometimes an int + if (!(yValue instanceof Number)) { + throw new InvalidFormatException("Y is not numeric: " + yValue); + } + int y = ((Number) yValue).intValue(); + + Tag rawBlockStatesTag = sectionTag.getValue().get("block_states"); // null for sections outside of the world limits + if (rawBlockStatesTag instanceof CompoundTag blockStatesTag) { + + // parse palette + List paletteEntries = blockStatesTag.getList("palette", CompoundTag.class); + int paletteSize = paletteEntries.size(); + if (paletteSize == 0) { + continue; + } + BlockState[] palette = new BlockState[paletteSize]; + for (int paletteEntryId = 0; paletteEntryId < paletteSize; paletteEntryId++) { + CompoundTag paletteEntry = paletteEntries.get(paletteEntryId); + BlockType type = BlockTypes.get(paletteEntry.getString("Name")); + if (type == null) { + throw new InvalidFormatException("Invalid block type: " + paletteEntry.getString("Name")); + } + BlockState blockState = type.getDefaultState(); + if (paletteEntry.containsKey("Properties")) { + CompoundTag properties = NBTUtils.getChildTag(paletteEntry.getValue(), "Properties", CompoundTag.class); + for (Property property : blockState.getStates().keySet()) { + if (properties.containsKey(property.getName())) { + String value = properties.getString(property.getName()); + try { + blockState = getBlockStateWith(blockState, property, value); + } catch (IllegalArgumentException e) { + throw new InvalidFormatException("Invalid block state for " + blockState.getBlockType().getId() + ", " + property.getName() + ": " + value); + } + } + } + } + palette[paletteEntryId] = blockState; + } + if (paletteSize == 1) { + // the same block everywhere + blocks.put(y, palette); + continue; + } + + // parse block states + long[] blockStatesSerialized = NBTUtils.getChildTag(blockStatesTag.getValue(), "data", LongArrayTag.class).getValue(); + + BlockState[] chunkSectionBlocks = new BlockState[16 * 16 * 16]; + blocks.put(y, chunkSectionBlocks); + + readBlockStates(palette, blockStatesSerialized, chunkSectionBlocks); + } + } + } + + protected void readBlockStates(BlockState[] palette, long[] blockStatesSerialized, BlockState[] chunkSectionBlocks) throws InvalidFormatException { + PackedIntArrayReader reader = new PackedIntArrayReader(blockStatesSerialized); + for (int blockPos = 0; blockPos < chunkSectionBlocks.length; blockPos++) { + int index = reader.get(blockPos); + if (index >= palette.length) { + throw new InvalidFormatException("Invalid block state table entry: " + index); + } + chunkSectionBlocks[blockPos] = palette[index]; + } + } + + private BlockState getBlockStateWith(BlockState source, Property property, String value) { + return source.with(property, property.getValueFor(value)); + } + + /** + * Used to load the tile entities. + */ + private void populateTileEntities() throws DataException { + tileEntities = new HashMap<>(); + if (!rootTag.getValue().containsKey("block_entities")) { + return; + } + List tags = NBTUtils.getChildTag(rootTag.getValue(), + "block_entities", ListTag.class).getValue(); + + for (Tag tag : tags) { + if (!(tag instanceof CompoundTag t)) { + throw new InvalidFormatException("CompoundTag expected in block_entities"); + } + + Map values = new HashMap<>(t.getValue()); + int x = ((IntTag) values.get("x")).getValue(); + int y = ((IntTag) values.get("y")).getValue(); + int z = ((IntTag) values.get("z")).getValue(); + + BlockVector3 vec = BlockVector3.at(x, y, z); + tileEntities.put(vec, values); + } + } + + /** + * Get the map of tags keyed to strings for a block's tile entity data. May + * return null if there is no tile entity data. Not public yet because + * what this function returns isn't ideal for usage. + * + * @param position the position + * @return the compound tag for that position, which may be null + * @throws DataException thrown if there is a data error + */ + @Nullable + private CompoundTag getBlockTileEntity(BlockVector3 position) throws DataException { + if (tileEntities == null) { + populateTileEntities(); + } + + Map values = tileEntities.get(position); + if (values == null) { + return null; + } + + return new CompoundTag(values); + } + + @Override + public BaseBlock getBlock(BlockVector3 position) throws DataException { + int x = position.getX() - rootX * 16; + int y = position.getY(); + int z = position.getZ() - rootZ * 16; + + int section = y >> 4; + int yIndex = y & 0x0F; + + BlockState[] sectionBlocks = blocks.get(section); + if (sectionBlocks == null) { + return BlockTypes.AIR.getDefaultState().toBaseBlock(); + } + BlockState state = sectionBlocks[sectionBlocks.length == 1 ? 0 : ((yIndex << 8) | (z << 4) | x)]; + + CompoundTag tileEntity = getBlockTileEntity(position); + + if (tileEntity != null) { + return state.toBaseBlock(tileEntity); + } + + return state.toBaseBlock(); + } + +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ChunkStoreHelper.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ChunkStoreHelper.java index 00970efd3..e6db601c3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ChunkStoreHelper.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ChunkStoreHelper.java @@ -34,6 +34,7 @@ import com.sk89q.worldedit.world.chunk.AnvilChunk13; import com.sk89q.worldedit.world.chunk.AnvilChunk15; import com.sk89q.worldedit.world.chunk.AnvilChunk16; import com.sk89q.worldedit.world.chunk.AnvilChunk17; +import com.sk89q.worldedit.world.chunk.AnvilChunk18; import com.sk89q.worldedit.world.chunk.Chunk; import com.sk89q.worldedit.world.chunk.OldChunk; @@ -72,8 +73,28 @@ public class ChunkStoreHelper { * @throws DataException if the rootTag is not valid chunk data */ public static Chunk getChunk(CompoundTag rootTag) throws DataException { + int dataVersion = rootTag.getInt("DataVersion"); + if (dataVersion == 0) { + dataVersion = -1; + } + + final Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING); + final int currentDataVersion = platform.getDataVersion(); + if ((dataVersion > 0 || hasLevelSections(rootTag)) && dataVersion < currentDataVersion) { // only fix up MCA format, DFU doesn't support MCR chunks + final DataFixer dataFixer = platform.getDataFixer(); + if (dataFixer != null) { + rootTag = (CompoundTag) AdventureNBTConverter.fromAdventure(dataFixer.fixUp(DataFixer.FixTypes.CHUNK, + rootTag.asBinaryTag(), dataVersion)); + dataVersion = currentDataVersion; + } + } + + if (dataVersion >= Constants.DATA_VERSION_MC_1_18) { + return new AnvilChunk18(rootTag); + } //FAWE start - biome and entity restore return getChunk(rootTag, () -> null); + //FAWE end } /** @@ -113,21 +134,6 @@ public class ChunkStoreHelper { if (dataVersion == 0) { dataVersion = -1; } - final Platform platform = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.WORLD_EDITING); - final int currentDataVersion = platform.getDataVersion(); - if (tag - .getValue() - .containsKey("Sections") && dataVersion < currentDataVersion) { // only fix up MCA format, DFU doesn't support MCR chunks - final DataFixer dataFixer = platform.getDataFixer(); - if (dataFixer != null) { - //FAWE start - BinaryTag - tag = (CompoundTag) AdventureNBTConverter.fromAdventure(dataFixer - .fixUp(DataFixer.FixTypes.CHUNK, rootTag.asBinaryTag(), dataVersion) - .get("Level")); - //FAWE end - dataVersion = currentDataVersion; - } - } //FAWE start - biome and entity restore if (dataVersion >= Constants.DATA_VERSION_MC_1_17) { return new AnvilChunk17(tag, entitiesTag); @@ -153,6 +159,15 @@ public class ChunkStoreHelper { return new OldChunk(tag); } + private static boolean hasLevelSections(CompoundTag rootTag) { + Map children = rootTag.getValue(); + Tag levelTag = children.get("Level"); + if (levelTag instanceof CompoundTag) { + return ((CompoundTag) levelTag).getValue().containsKey("Sections"); + } + return false; + } + private ChunkStoreHelper() { } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/TrueZipMcRegionChunkStore.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/TrueZipMcRegionChunkStore.java index f60df4510..76f9a5ba3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/TrueZipMcRegionChunkStore.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/TrueZipMcRegionChunkStore.java @@ -105,7 +105,7 @@ public class TrueZipMcRegionChunkStore extends McRegionChunkStore { endIndex = entryName.lastIndexOf('\\'); } folder = entryName.substring(0, endIndex); - if (folder.endsWith("poi")) { + if (folder.endsWith("poi") || folder.endsWith("entities")) { continue; } name = folder + "/" + name; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ZippedMcRegionChunkStore.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ZippedMcRegionChunkStore.java index a19aed26d..067515e13 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ZippedMcRegionChunkStore.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/storage/ZippedMcRegionChunkStore.java @@ -101,9 +101,7 @@ public class ZippedMcRegionChunkStore extends McRegionChunkStore { endIndex = entryName.lastIndexOf('\\'); } folder = entryName.substring(0, endIndex); - //FAWE start - biome and entity restore if (folder.endsWith("poi") || folder.endsWith("entities")) { - //FAWE end continue; } name = folder + "/" + name; diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index 54c0a9c44..dcd13d76e 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -238,8 +238,8 @@ "worldedit.error.unknown-block": "Block name '{0}' was not recognized.", "worldedit.error.disallowed-block": "Block '{0}' not allowed (see WorldEdit configuration).", "worldedit.error.max-changes": "Max blocks changed in an operation reached ({0}).", - "worldedit.error.max-brush-radius": "Maximum brush radius (in config-legacy.yml): {0}", - "worldedit.error.max-radius": "Maximum radius (in config-legacy.yml): {0}", + "worldedit.error.max-brush-radius": "Maximum brush radius (in worldedit-config.yml): {0}", + "worldedit.error.max-radius": "Maximum radius (in worldedit-config.yml): {0}", "worldedit.error.unknown-direction": "Unknown direction: {0}", "worldedit.error.empty-clipboard": "Your clipboard is empty. Use //copy first.", "worldedit.error.invalid-filename": "Filename '{0}' invalid: {1}",