3
0
Mirror von https://github.com/IntellectualSites/FastAsyncWorldEdit.git synchronisiert 2024-11-19 09:20:08 +01:00

Merge branch 'main' into v3

# Conflicts:
#	worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/TransformExtent.java
#	worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java
Dieser Commit ist enthalten in:
dordsor21 2024-06-07 16:19:50 +01:00
Commit 111eebe828
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 1E53E88969FFCF0B
363 geänderte Dateien mit 5426 neuen und 3648 gelöschten Zeilen

Datei anzeigen

@ -27,10 +27,9 @@ body:
description: Which server version version you using? If your server version is not listed, it is not supported. Update to a supported version first. 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 multiple: false
options: options:
- '1.20.4' - '1.20.5/6'
- '1.20' - '1.20'
- '1.19.4' - '1.19.4'
- '1.18.2'
validations: validations:
required: true required: true

Datei anzeigen

@ -2,7 +2,8 @@
"$schema" : "https://docs.renovatebot.com/renovate-schema.json", "$schema" : "https://docs.renovatebot.com/renovate-schema.json",
"extends" : [ "extends" : [
"config:recommended", "config:recommended",
":semanticCommitsDisabled" ":semanticCommitsDisabled",
"schedule:earlyMondays"
], ],
"automerge" : true, "automerge" : true,
"ignoreDeps" : [ "ignoreDeps" : [

Datei anzeigen

@ -11,13 +11,13 @@ jobs:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v2 uses: gradle/actions/wrapper-validation@v3
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
distribution: temurin distribution: temurin
cache: gradle cache: gradle
java-version: 17 java-version: 21
- name: Build on ${{ matrix.os }} - name: Build on ${{ matrix.os }}
run: ./gradlew build -s run: ./gradlew build -s
- name: Archive artifacts - name: Archive artifacts

Datei anzeigen

@ -11,13 +11,13 @@ jobs:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v2 uses: gradle/actions/wrapper-validation@v3
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
distribution: temurin distribution: temurin
cache: gradle cache: gradle
java-version: 17 java-version: 21
- name: Clean Build - name: Clean Build
run: ./gradlew clean build --no-daemon run: ./gradlew clean build --no-daemon
- name: Determine release status - name: Determine release status

Datei anzeigen

@ -25,7 +25,7 @@ jobs:
with: with:
distribution: temurin distribution: temurin
cache: gradle cache: gradle
java-version: 17 java-version: 21
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v3 uses: github/codeql-action/init@v3
with: with:

Datei anzeigen

@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Label conflicting PRs - name: Label conflicting PRs
uses: eps1lon/actions-label-merge-conflict@v3.0.0 uses: eps1lon/actions-label-merge-conflict@v3.0.2
with: with:
dirtyLabel: "unresolved-merge-conflict" dirtyLabel: "unresolved-merge-conflict"
repoToken: "${{ secrets.GITHUB_TOKEN }}" repoToken: "${{ secrets.GITHUB_TOKEN }}"

Datei anzeigen

@ -9,13 +9,13 @@ jobs:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v2 uses: gradle/actions/wrapper-validation@v3
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v4
with: with:
distribution: temurin distribution: temurin
cache: gradle cache: gradle
java-version: 17 java-version: 21
- name: Clean Build - name: Clean Build
run: ./gradlew clean build --no-daemon run: ./gradlew clean build --no-daemon
- name: Upload Release Assets - name: Upload Release Assets

Datei anzeigen

@ -3,12 +3,12 @@
= Compiling = Compiling
You can compile FastAsyncWorldEdit as long as you have some version of Java greater than or equal to 17 installed. Gradle will download JDK 17 specifically if needed, You can compile FastAsyncWorldEdit as long as you have some version of Java greater than or equal to 21 installed. Gradle will download JDK 21 specifically if needed,
but it needs some version of Java to bootstrap from. but it needs some version of Java to bootstrap from.
Note that if you have JRE 8 installed, Gradle will currently attempt to use that to compile, which will not work. It is easiest to uninstall JRE 8 and replace it with JDK 17. Note that if you have JRE 8 installed, Gradle will currently attempt to use that to compile, which will not work. It is easiest to uninstall JRE 8 and replace it with JDK 21.
You can get the JDK 17 link:https://adoptium.net/[here] from Adoptium. You can get the JDK 21 link:https://adoptium.net/[here] from Adoptium.
The build process uses Gradle, which you do *not* need to download. FastAsyncWorldEdit is a multi-module project with three active modules: The build process uses Gradle, which you do *not* need to download. FastAsyncWorldEdit is a multi-module project with three active modules:

2
Jenkinsfile vendored
Datei anzeigen

@ -7,7 +7,7 @@ pipeline {
stage('Build') { stage('Build') {
steps { steps {
withEnv([ withEnv([
"PATH+JAVA=${tool 'Temurin-17.0.7_7'}/bin" "PATH+JAVA=${tool 'Temurin-21.0.3_9'}/bin"
]) { ]) {
sh './gradlew clean build' sh './gradlew clean build'
} }

Datei anzeigen

@ -6,8 +6,8 @@ import java.time.format.DateTimeFormatter
import xyz.jpenilla.runpaper.task.RunServer import xyz.jpenilla.runpaper.task.RunServer
plugins { plugins {
id("io.github.gradle-nexus.publish-plugin") version "1.3.0" id("io.github.gradle-nexus.publish-plugin") version "2.0.0"
id("xyz.jpenilla.run-paper") version "2.2.3" id("xyz.jpenilla.run-paper") version "2.3.0"
} }
if (!File("$rootDir/.git").exists()) { if (!File("$rootDir/.git").exists()) {
@ -34,7 +34,7 @@ logger.lifecycle("""
******************************************* *******************************************
""") """)
var rootVersion by extra("2.9.2") var rootVersion by extra("2.10.1")
var snapshot by extra("SNAPSHOT") var snapshot by extra("SNAPSHOT")
var revision: String by extra("") var revision: String by extra("")
var buildNumber by extra("") var buildNumber by extra("")
@ -83,7 +83,7 @@ allprojects {
} }
applyCommonConfiguration() applyCommonConfiguration()
val supportedVersions = listOf("1.18.2", "1.19.4", "1.20", "1.20.4") val supportedVersions = listOf("1.19.4", "1.20", "1.20.4", "1.20.5", "1.20.6")
tasks { tasks {
supportedVersions.forEach { supportedVersions.forEach {

Datei anzeigen

@ -24,11 +24,23 @@ dependencies {
implementation(gradleApi()) implementation(gradleApi())
implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2") implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2")
implementation("com.github.johnrengelman:shadow:8.1.1") implementation("com.github.johnrengelman:shadow:8.1.1")
implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.11") implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.7.1")
constraints {
val asmVersion = "[9.7,)"
implementation("org.ow2.asm:asm:$asmVersion") {
because("Need Java 21 support in shadow")
}
implementation("org.ow2.asm:asm-commons:$asmVersion") {
because("Need Java 21 support in shadow")
}
implementation("org.vafer:jdependency:[2.10,)") {
because("Need Java 21 support in shadow")
}
}
} }
kotlin { kotlin {
jvmToolchain { jvmToolchain {
(this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(17)) (this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(21))
} }
} }

Datei anzeigen

@ -33,7 +33,7 @@ fun Project.applyCommonConfiguration() {
plugins.withId("java") { plugins.withId("java") {
the<JavaPluginExtension>().toolchain { the<JavaPluginExtension>().toolchain {
languageVersion.set(JavaLanguageVersion.of(17)) languageVersion.set(JavaLanguageVersion.of(21))
} }
} }

Datei anzeigen

@ -21,7 +21,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean
.matching { it.name == "compileJava" || it.name == "compileTestJava" } .matching { it.name == "compileJava" || it.name == "compileTestJava" }
.configureEach { .configureEach {
val disabledLint = listOf( val disabledLint = listOf(
"processing", "path", "fallthrough", "serial" "processing", "path", "fallthrough", "serial", "overloads", "this-escape",
) )
options.release.set(17) options.release.set(17)
options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" }) options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" })
@ -31,7 +31,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean
} }
configurations.all { configurations.all {
attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17) attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21)
} }
tasks.withType<Test>().configureEach { tasks.withType<Test>().configureEach {
@ -61,7 +61,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean
"https://jd.advntr.dev/api/latest/", "https://jd.advntr.dev/api/latest/",
"https://logging.apache.org/log4j/2.x/javadoc/log4j-api/", "https://logging.apache.org/log4j/2.x/javadoc/log4j-api/",
"https://www.antlr.org/api/Java/", "https://www.antlr.org/api/Java/",
"https://jd.papermc.io/paper/1.20/", "https://jd.papermc.io/paper/1.20.6/",
"https://intellectualsites.github.io/fastasyncworldedit-javadocs/worldedit-core/" "https://intellectualsites.github.io/fastasyncworldedit-javadocs/worldedit-core/"
) )
docTitle = "${rootProject.name}-${project.description}" + " " + "${rootProject.version}" docTitle = "${rootProject.name}-${project.description}" + " " + "${rootProject.version}"

Datei anzeigen

@ -122,7 +122,7 @@ fun Project.applyLibrariesConfiguration() {
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED)) attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR)) attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17) attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21)
} }
outgoing.artifact(tasks.named("jar")) outgoing.artifact(tasks.named("jar"))
} }
@ -137,7 +137,7 @@ fun Project.applyLibrariesConfiguration() {
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY)) attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED)) attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR)) attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17) attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21)
} }
outgoing.artifact(tasks.named("jar")) outgoing.artifact(tasks.named("jar"))
} }

Datei anzeigen

@ -1,6 +1,6 @@
[versions] [versions]
# Minecraft expectations # Minecraft expectations
paper = "1.20.4-R0.1-SNAPSHOT" paper = "1.20.6-R0.1-SNAPSHOT"
fastutil = "8.5.9" fastutil = "8.5.9"
guava = "31.1-jre" guava = "31.1-jre"
log4j = "2.19.0" log4j = "2.19.0"
@ -9,25 +9,25 @@ snakeyaml = "2.0"
# Plugins # Plugins
dummypermscompat = "1.10" dummypermscompat = "1.10"
worldguard-bukkit = "7.0.9" worldguard-bukkit = "7.0.10"
mapmanager = "1.8.0-SNAPSHOT" mapmanager = "1.8.0-SNAPSHOT"
griefprevention = "17.0.0" griefprevention = "17.0.0"
griefdefender = "2.1.0-SNAPSHOT" griefdefender = "2.1.0-SNAPSHOT"
residence = "4.5._13.1" residence = "4.5._13.1"
towny = "0.100.1.23" towny = "0.100.2.12"
plotsquared = "7.3.6" plotsquared = "7.3.8"
# Third party # Third party
bstats = "3.0.2" bstats = "3.0.2"
sparsebitset = "1.3" sparsebitset = "1.3"
parallelgzip = "1.0.5" parallelgzip = "1.0.5"
adventure = "4.16.0" adventure = "4.17.0"
adventure-bukkit = "4.3.2" adventure-bukkit = "4.3.3"
checkerqual = "3.42.0" checkerqual = "3.43.0"
truezip = "6.8.4" truezip = "6.8.4"
auto-value = "1.10.4" auto-value = "1.10.4"
findbugs = "3.0.2" findbugs = "3.0.2"
rhino-runtime = "1.7.14" rhino-runtime = "1.7.15"
zstd-jni = "1.4.8-1" # Not latest as it can be difficult to obtain latest ZSTD libs zstd-jni = "1.4.8-1" # Not latest as it can be difficult to obtain latest ZSTD libs
antlr4 = "4.13.1" antlr4 = "4.13.1"
json-simple = "1.1.1" json-simple = "1.1.1"
@ -35,18 +35,18 @@ jlibnoise = "1.0.0"
jchronic = "0.2.4a" jchronic = "0.2.4a"
lz4-java = "1.8.0" lz4-java = "1.8.0"
lz4-stream = "1.0.0" lz4-stream = "1.0.0"
commons-cli = "1.6.0" commons-cli = "1.8.0"
paperlib = "1.0.8" paperlib = "1.0.8"
paster = "1.1.5" paster = "1.1.6"
vault = "1.7.1" vault = "1.7.1"
serverlib = "2.3.4" serverlib = "2.3.6"
## Internal ## Internal
text-adapter = "3.0.6" text-adapter = "3.0.6"
text = "3.0.4" text = "3.0.4"
piston = "0.5.8" piston = "0.5.10"
# Tests # Tests
mockito = "5.11.0" mockito = "5.12.0"
# Gradle plugins # Gradle plugins
pluginyml = "0.6.0" pluginyml = "0.6.0"

Datei anzeigen

@ -2,7 +2,7 @@ rootProject.name = "FastAsyncWorldEdit"
include("worldedit-libs") include("worldedit-libs")
listOf("1_18_2", "1_19_4", "1_20", "1_20_2", "1_20_4").forEach { listOf("1_19_4", "1_20", "1_20_2", "1_20_4", "1_20_5").forEach {
include("worldedit-bukkit:adapters:adapter-$it") include("worldedit-bukkit:adapters:adapter-$it")
} }

Datei anzeigen

@ -27,7 +27,6 @@ import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.mojang.datafixers.util.Either; import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Lifecycle; import com.mojang.serialization.Lifecycle;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.NBTConstants; import com.sk89q.jnbt.NBTConstants;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItem;
@ -531,7 +530,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) { public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) {
((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create( ((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create(
new StructureBlockEntity( new StructureBlockEntity(
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()), new BlockPos(pos.x(), pos.y(), pos.z()),
Blocks.STRUCTURE_BLOCK.defaultBlockState() Blocks.STRUCTURE_BLOCK.defaultBlockState()
), ),
__ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) __ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData)
@ -581,10 +580,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
return false; return false;
} }
fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack); fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack);
fakePlayer.absMoveTo(position.getBlockX(), position.getBlockY(), position.getBlockZ(), fakePlayer.absMoveTo(position.x(), position.y(), position.z(),
(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 BlockPos blockPos = new BlockPos(position.x(), position.y(), position.z());
final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos); final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos);
final net.minecraft.core.Direction enumFacing = adapt(face); final net.minecraft.core.Direction enumFacing = adapt(face);
BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false); BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false);
@ -605,7 +604,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
public boolean canPlaceAt(org.bukkit.World world, BlockVector3 position, BlockState blockState) { public boolean canPlaceAt(org.bukkit.World world, BlockVector3 position, BlockState blockState) {
int internalId = BlockStateIdAccess.getBlockStateId(blockState); int internalId = BlockStateIdAccess.getBlockStateId(blockState);
net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId); 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.x(), position.y(), position.z()));
} }
@Override @Override
@ -725,7 +724,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
for (BlockVector3 vec : region) { for (BlockVector3 vec : region) {
BlockPos pos = new BlockPos(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ()); BlockPos pos = new BlockPos(vec.x(), vec.y(), vec.z());
ChunkAccess chunk = chunks.get(new ChunkPos(pos)); ChunkAccess chunk = chunks.get(new ChunkPos(pos));
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos); final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos);
int internalId = Block.getId(blockData); int internalId = Block.getId(blockData);
@ -738,7 +737,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
extent.setBlock(vec, state.toBaseBlock()); extent.setBlock(vec, state.toBaseBlock());
if (options.shouldRegenBiomes()) { if (options.shouldRegenBiomes()) {
Biome origBiome = chunk.getNoiseBiome(vec.getX(), vec.getY(), vec.getZ()).value(); Biome origBiome = chunk.getNoiseBiome(vec.x(), vec.y(), vec.z()).value();
BiomeType adaptedBiome = adapt(serverWorld, origBiome); BiomeType adaptedBiome = adapt(serverWorld, origBiome);
if (adaptedBiome != null) { if (adaptedBiome != null) {
extent.setBiome(vec, adaptedBiome); extent.setBiome(vec, adaptedBiome);
@ -757,7 +756,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
//noinspection unchecked //noinspection unchecked
chunkLoadings.add( chunkLoadings.add(
((CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>) ((CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>)
getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true)) getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true))
.thenApply(either -> either.left().orElse(null)) .thenApply(either -> either.left().orElse(null))
); );
} catch (IllegalAccessException | InvocationTargetException e) { } catch (IllegalAccessException | InvocationTargetException e) {
@ -797,7 +796,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) { public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) {
ServerLevel originalWorld = ((CraftWorld) world).getHandle(); ServerLevel originalWorld = ((CraftWorld) world).getHandle();
BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.x(), pt.y(), pt.z()));
if (entity instanceof Clearable) { if (entity instanceof Clearable) {
((Clearable) entity).clearContent(); ((Clearable) entity).clearContent();
return true; return true;

Datei anzeigen

@ -472,7 +472,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId); net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId);
return blockState1.hasPostProcess( return blockState1.hasPostProcess(
getServerLevel(world), getServerLevel(world),
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ()) new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z())
); );
} }

Datei anzeigen

@ -786,9 +786,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) { for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
final CompoundTag nativeTag = entry.getValue(); final CompoundTag nativeTag = entry.getValue();
final BlockVector3 blockHash = entry.getKey(); final BlockVector3 blockHash = entry.getKey();
final int x = blockHash.getX() + bx; final int x = blockHash.x() + bx;
final int y = blockHash.getY(); final int y = blockHash.y();
final int z = blockHash.getZ() + bz; final int z = blockHash.z() + bz;
final BlockPos pos = new BlockPos(x, y, z); final BlockPos pos = new BlockPos(x, y, z);
synchronized (nmsWorld) { synchronized (nmsWorld) {

Datei anzeigen

@ -570,7 +570,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) { public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) {
((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create( ((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create(
new StructureBlockEntity( new StructureBlockEntity(
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()), new BlockPos(pos.x(), pos.y(), pos.z()),
Blocks.STRUCTURE_BLOCK.defaultBlockState() Blocks.STRUCTURE_BLOCK.defaultBlockState()
), ),
__ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) __ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData)
@ -631,10 +631,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
return false; return false;
} }
fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack); fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack);
fakePlayer.absMoveTo(position.getBlockX(), position.getBlockY(), position.getBlockZ(), fakePlayer.absMoveTo(position.x(), position.y(), position.z(),
(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 BlockPos blockPos = new BlockPos(position.x(), position.y(), position.z());
final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos); final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos);
final net.minecraft.core.Direction enumFacing = adapt(face); final net.minecraft.core.Direction enumFacing = adapt(face);
BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false); BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false);
@ -655,7 +655,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
public boolean canPlaceAt(org.bukkit.World world, BlockVector3 position, BlockState blockState) { public boolean canPlaceAt(org.bukkit.World world, BlockVector3 position, BlockState blockState) {
int internalId = BlockStateIdAccess.getBlockStateId(blockState); int internalId = BlockStateIdAccess.getBlockStateId(blockState);
net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId); 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.x(), position.y(), position.z()));
} }
@Override @Override
@ -776,7 +776,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
for (BlockVector3 vec : region) { for (BlockVector3 vec : region) {
BlockPos pos = new BlockPos(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ()); BlockPos pos = new BlockPos(vec.x(), vec.y(), vec.z());
ChunkAccess chunk = chunks.get(new ChunkPos(pos)); ChunkAccess chunk = chunks.get(new ChunkPos(pos));
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos); final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos);
int internalId = Block.getId(blockData); int internalId = Block.getId(blockData);
@ -789,7 +789,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
extent.setBlock(vec, state.toBaseBlock()); extent.setBlock(vec, state.toBaseBlock());
if (options.shouldRegenBiomes()) { if (options.shouldRegenBiomes()) {
Biome origBiome = chunk.getNoiseBiome(vec.getX(), vec.getY(), vec.getZ()).value(); Biome origBiome = chunk.getNoiseBiome(vec.x(), vec.y(), vec.z()).value();
BiomeType adaptedBiome = adapt(serverWorld, origBiome); BiomeType adaptedBiome = adapt(serverWorld, origBiome);
if (adaptedBiome != null) { if (adaptedBiome != null) {
extent.setBiome(vec, adaptedBiome); extent.setBiome(vec, adaptedBiome);
@ -808,7 +808,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
//noinspection unchecked //noinspection unchecked
chunkLoadings.add( chunkLoadings.add(
((CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>) ((CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>)
getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true)) getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true))
.thenApply(either -> either.left().orElse(null)) .thenApply(either -> either.left().orElse(null))
); );
} catch (IllegalAccessException | InvocationTargetException e) { } catch (IllegalAccessException | InvocationTargetException e) {
@ -848,7 +848,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) { public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) {
ServerLevel originalWorld = ((CraftWorld) world).getHandle(); ServerLevel originalWorld = ((CraftWorld) world).getHandle();
BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.x(), pt.y(), pt.z()));
if (entity instanceof Clearable) { if (entity instanceof Clearable) {
((Clearable) entity).clearContent(); ((Clearable) entity).clearContent();
return true; return true;

Datei anzeigen

@ -472,7 +472,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId); net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId);
return blockState1.hasPostProcess( return blockState1.hasPostProcess(
getServerLevel(world), getServerLevel(world),
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ()) new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z())
); );
} }

Datei anzeigen

@ -784,9 +784,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) { for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
final CompoundTag nativeTag = entry.getValue(); final CompoundTag nativeTag = entry.getValue();
final BlockVector3 blockHash = entry.getKey(); final BlockVector3 blockHash = entry.getKey();
final int x = blockHash.getX() + bx; final int x = blockHash.x() + bx;
final int y = blockHash.getY(); final int y = blockHash.y();
final int z = blockHash.getZ() + bz; final int z = blockHash.z() + bz;
final BlockPos pos = new BlockPos(x, y, z); final BlockPos pos = new BlockPos(x, y, z);
synchronized (nmsWorld) { synchronized (nmsWorld) {

Datei anzeigen

@ -530,7 +530,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) { public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) {
((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create( ((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create(
new StructureBlockEntity( new StructureBlockEntity(
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()), new BlockPos(pos.x(), pos.y(), pos.z()),
Blocks.STRUCTURE_BLOCK.defaultBlockState() Blocks.STRUCTURE_BLOCK.defaultBlockState()
), ),
__ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) __ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData)
@ -580,10 +580,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
return false; return false;
} }
fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack); fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack);
fakePlayer.absMoveTo(position.getBlockX(), position.getBlockY(), position.getBlockZ(), fakePlayer.absMoveTo(position.x(), position.y(), position.z(),
(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 BlockPos blockPos = new BlockPos(position.x(), position.y(), position.z());
final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos); final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos);
final net.minecraft.core.Direction enumFacing = adapt(face); final net.minecraft.core.Direction enumFacing = adapt(face);
BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false); BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false);
@ -604,7 +604,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
public boolean canPlaceAt(org.bukkit.World world, BlockVector3 position, BlockState blockState) { public boolean canPlaceAt(org.bukkit.World world, BlockVector3 position, BlockState blockState) {
int internalId = BlockStateIdAccess.getBlockStateId(blockState); int internalId = BlockStateIdAccess.getBlockStateId(blockState);
net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId); 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.x(), position.y(), position.z()));
} }
@Override @Override
@ -725,7 +725,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
for (BlockVector3 vec : region) { for (BlockVector3 vec : region) {
BlockPos pos = new BlockPos(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ()); BlockPos pos = new BlockPos(vec.x(), vec.y(), vec.z());
ChunkAccess chunk = chunks.get(new ChunkPos(pos)); ChunkAccess chunk = chunks.get(new ChunkPos(pos));
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos); final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos);
int internalId = Block.getId(blockData); int internalId = Block.getId(blockData);
@ -738,7 +738,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
extent.setBlock(vec, state.toBaseBlock()); extent.setBlock(vec, state.toBaseBlock());
if (options.shouldRegenBiomes()) { if (options.shouldRegenBiomes()) {
Biome origBiome = chunk.getNoiseBiome(vec.getX(), vec.getY(), vec.getZ()).value(); Biome origBiome = chunk.getNoiseBiome(vec.x(), vec.y(), vec.z()).value();
BiomeType adaptedBiome = adapt(serverWorld, origBiome); BiomeType adaptedBiome = adapt(serverWorld, origBiome);
if (adaptedBiome != null) { if (adaptedBiome != null) {
extent.setBiome(vec, adaptedBiome); extent.setBiome(vec, adaptedBiome);
@ -757,7 +757,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
//noinspection unchecked //noinspection unchecked
chunkLoadings.add( chunkLoadings.add(
((CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>) ((CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>)
getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true)) getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true))
.thenApply(either -> either.left().orElse(null)) .thenApply(either -> either.left().orElse(null))
); );
} catch (IllegalAccessException | InvocationTargetException e) { } catch (IllegalAccessException | InvocationTargetException e) {
@ -797,7 +797,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) { public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) {
ServerLevel originalWorld = ((CraftWorld) world).getHandle(); ServerLevel originalWorld = ((CraftWorld) world).getHandle();
BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.x(), pt.y(), pt.z()));
if (entity instanceof Clearable) { if (entity instanceof Clearable) {
((Clearable) entity).clearContent(); ((Clearable) entity).clearContent();
return true; return true;

Datei anzeigen

@ -475,7 +475,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId); net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId);
return blockState1.hasPostProcess( return blockState1.hasPostProcess(
getServerLevel(world), getServerLevel(world),
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ()) new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z())
); );
} }

Datei anzeigen

@ -771,9 +771,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) { for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
final CompoundTag nativeTag = entry.getValue(); final CompoundTag nativeTag = entry.getValue();
final BlockVector3 blockHash = entry.getKey(); final BlockVector3 blockHash = entry.getKey();
final int x = blockHash.getX() + bx; final int x = blockHash.x() + bx;
final int y = blockHash.getY(); final int y = blockHash.y();
final int z = blockHash.getZ() + bz; final int z = blockHash.z() + bz;
final BlockPos pos = new BlockPos(x, y, z); final BlockPos pos = new BlockPos(x, y, z);
synchronized (nmsWorld) { synchronized (nmsWorld) {

Datei anzeigen

@ -12,6 +12,6 @@ repositories {
dependencies { dependencies {
// url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.4-R0.1-20240325.123556-143") the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.4-R0.1-20240528.102248-175")
compileOnly(libs.paperlib) compileOnly(libs.paperlib)
} }

Datei anzeigen

@ -530,7 +530,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) { public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) {
((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create( ((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create(
new StructureBlockEntity( new StructureBlockEntity(
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()), new BlockPos(pos.x(), pos.y(), pos.z()),
Blocks.STRUCTURE_BLOCK.defaultBlockState() Blocks.STRUCTURE_BLOCK.defaultBlockState()
), ),
__ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) __ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData)
@ -580,10 +580,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
return false; return false;
} }
fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack); fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack);
fakePlayer.absMoveTo(position.getBlockX(), position.getBlockY(), position.getBlockZ(), fakePlayer.absMoveTo(position.x(), position.y(), position.z(),
(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 BlockPos blockPos = new BlockPos(position.x(), position.y(), position.z());
final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos); final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos);
final net.minecraft.core.Direction enumFacing = adapt(face); final net.minecraft.core.Direction enumFacing = adapt(face);
BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false); BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false);
@ -604,7 +604,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
public boolean canPlaceAt(org.bukkit.World world, BlockVector3 position, BlockState blockState) { public boolean canPlaceAt(org.bukkit.World world, BlockVector3 position, BlockState blockState) {
int internalId = BlockStateIdAccess.getBlockStateId(blockState); int internalId = BlockStateIdAccess.getBlockStateId(blockState);
net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId); 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.x(), position.y(), position.z()));
} }
@Override @Override
@ -725,7 +725,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
for (BlockVector3 vec : region) { for (BlockVector3 vec : region) {
BlockPos pos = new BlockPos(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ()); BlockPos pos = new BlockPos(vec.x(), vec.y(), vec.z());
ChunkAccess chunk = chunks.get(new ChunkPos(pos)); ChunkAccess chunk = chunks.get(new ChunkPos(pos));
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos); final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos);
int internalId = Block.getId(blockData); int internalId = Block.getId(blockData);
@ -738,7 +738,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
extent.setBlock(vec, state.toBaseBlock()); extent.setBlock(vec, state.toBaseBlock());
if (options.shouldRegenBiomes()) { if (options.shouldRegenBiomes()) {
Biome origBiome = chunk.getNoiseBiome(vec.getX(), vec.getY(), vec.getZ()).value(); Biome origBiome = chunk.getNoiseBiome(vec.x(), vec.y(), vec.z()).value();
BiomeType adaptedBiome = adapt(serverWorld, origBiome); BiomeType adaptedBiome = adapt(serverWorld, origBiome);
if (adaptedBiome != null) { if (adaptedBiome != null) {
extent.setBiome(vec, adaptedBiome); extent.setBiome(vec, adaptedBiome);
@ -757,7 +757,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
//noinspection unchecked //noinspection unchecked
chunkLoadings.add( chunkLoadings.add(
((CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>) ((CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>)
getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true)) getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true))
.thenApply(either -> either.left().orElse(null)) .thenApply(either -> either.left().orElse(null))
); );
} catch (IllegalAccessException | InvocationTargetException e) { } catch (IllegalAccessException | InvocationTargetException e) {
@ -797,7 +797,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) { public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) {
ServerLevel originalWorld = ((CraftWorld) world).getHandle(); ServerLevel originalWorld = ((CraftWorld) world).getHandle();
BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.x(), pt.y(), pt.z()));
if (entity instanceof Clearable) { if (entity instanceof Clearable) {
((Clearable) entity).clearContent(); ((Clearable) entity).clearContent();
return true; return true;

Datei anzeigen

@ -475,7 +475,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId); net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId);
return blockState1.hasPostProcess( return blockState1.hasPostProcess(
getServerLevel(world), getServerLevel(world),
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ()) new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z())
); );
} }

Datei anzeigen

@ -771,9 +771,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) { for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
final CompoundTag nativeTag = entry.getValue(); final CompoundTag nativeTag = entry.getValue();
final BlockVector3 blockHash = entry.getKey(); final BlockVector3 blockHash = entry.getKey();
final int x = blockHash.getX() + bx; final int x = blockHash.x() + bx;
final int y = blockHash.getY(); final int y = blockHash.y();
final int z = blockHash.getZ() + bz; final int z = blockHash.z() + bz;
final BlockPos pos = new BlockPos(x, y, z); final BlockPos pos = new BlockPos(x, y, z);
synchronized (nmsWorld) { synchronized (nmsWorld) {

Datei anzeigen

@ -58,7 +58,6 @@ import net.minecraft.world.level.entity.PersistentEntitySectionManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R3.CraftChunk; import org.bukkit.craftbukkit.v1_20_R3.CraftChunk;
import sun.misc.Unsafe;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;

Datei anzeigen

@ -11,7 +11,7 @@ repositories {
} }
dependencies { dependencies {
// url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.18.2-R0.1-SNAPSHOT // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.18.2-R0.1-20220920.010157-167") the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.6-R0.1-20240602.222958-106")
compileOnly(libs.paperlib) compileOnly(libs.paperlib)
} }

Datei anzeigen

@ -17,24 +17,23 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2; package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Futures;
import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec;
import com.mojang.serialization.Lifecycle; import com.mojang.serialization.Lifecycle;
import com.sk89q.jnbt.NBTConstants;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.Refraction; import com.sk89q.worldedit.bukkit.adapter.Refraction;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.PaperweightPlatformAdapter;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extension.platform.Watchdog; import com.sk89q.worldedit.extension.platform.Watchdog;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
@ -81,14 +80,20 @@ import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemType;
import net.minecraft.Util; import net.minecraft.Util;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry; import net.minecraft.core.Holder;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.Tag;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ChunkResult;
import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.progress.ChunkProgressListener; import net.minecraft.server.level.progress.ChunkProgressListener;
@ -112,10 +117,10 @@ import net.minecraft.world.level.block.entity.StructureBlockEntity;
import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.DirectionProperty; import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.levelgen.WorldGenSettings; import net.minecraft.world.level.levelgen.WorldOptions;
import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.storage.PrimaryLevelData; import net.minecraft.world.level.storage.PrimaryLevelData;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
@ -124,13 +129,13 @@ import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World.Environment; import org.bukkit.World.Environment;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_18_R2.CraftServer; import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData; import org.bukkit.craftbukkit.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity; import org.bukkit.craftbukkit.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack; import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_18_R2.util.CraftMagicNumbers; import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
@ -155,7 +160,6 @@ import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -166,33 +170,28 @@ import static com.google.common.base.Preconditions.checkState;
public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft.nbt.Tag> { public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft.nbt.Tag> {
private static final Set<SideEffect> SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( private static final Codec<DataComponentPatch> COMPONENTS_CODEC = DataComponentPatch.CODEC.optionalFieldOf(
SideEffect.NEIGHBORS, "components", DataComponentPatch.EMPTY
SideEffect.LIGHTING, ).codec();
SideEffect.VALIDATION,
SideEffect.ENTITY_AI, private final Logger logger = Logger.getLogger(getClass().getCanonicalName());
SideEffect.EVENTS,
SideEffect.UPDATE
);
private final Field serverWorldsField; private final Field serverWorldsField;
private final Method getChunkFutureMethod; private final Method getChunkFutureMethod;
private final Field chunkProviderExecutorField; private final Field chunkProviderExecutorField;
private final Logger LOGGER = Logger.getLogger(getClass().getCanonicalName()); private final Watchdog watchdog;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Code that may break between versions of Minecraft // Code that may break between versions of Minecraft
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
private final Watchdog watchdog;
private final LoadingCache<ServerLevel, PaperweightFakePlayer> fakePlayers
= CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new));
public PaperweightAdapter() throws NoSuchFieldException, NoSuchMethodException { public PaperweightAdapter() throws NoSuchFieldException, NoSuchMethodException {
// A simple test // A simple test
CraftServer.class.cast(Bukkit.getServer()); CraftServer.class.cast(Bukkit.getServer());
int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion(); int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion();
if (dataVersion != 2975) { if (dataVersion != 3837 && dataVersion != 3839) {
throw new UnsupportedClassVersionError("Not 1.18.2!"); throw new UnsupportedClassVersionError("Not 1.20.(5/6)!");
} }
serverWorldsField = CraftServer.class.getDeclaredField("worlds"); serverWorldsField = CraftServer.class.getDeclaredField("worlds");
@ -209,7 +208,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
); );
chunkProviderExecutorField.setAccessible(true); chunkProviderExecutorField.setAccessible(true);
new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this).build(ForkJoinPool.commonPool()); new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this).buildUnoptimized();
Watchdog watchdog; Watchdog watchdog;
try { try {
@ -231,6 +230,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
} }
@Override
public DataFixer getDataFixer() {
return PaperweightDataConverters.INSTANCE;
}
/** /**
* Read the given NBT data into the given tile entity. * Read the given NBT data into the given tile entity.
* *
@ -238,7 +242,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
* @param tag the tag * @param tag the tag
*/ */
static void readTagIntoTileEntity(net.minecraft.nbt.CompoundTag tag, BlockEntity tileEntity) { static void readTagIntoTileEntity(net.minecraft.nbt.CompoundTag tag, BlockEntity tileEntity) {
tileEntity.load(tag); tileEntity.loadWithComponents(tag, MinecraftServer.getServer().registryAccess());
tileEntity.setChanged(); tileEntity.setChanged();
} }
@ -271,9 +275,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
* @param tag the tag * @param tag the tag
*/ */
private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) { private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) {
//FAWE start - avoid villager async catcher entity.load(tag);
PaperweightPlatformAdapter.readEntityIntoTag(entity, tag);
//FAWE end
} }
/** /**
@ -287,34 +289,14 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
private static Block getBlockFromType(BlockType blockType) { private static Block getBlockFromType(BlockType blockType) {
return Registry.BLOCK.get(ResourceLocation.tryParse(blockType.getId()));
return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK).get(ResourceLocation.tryParse(
blockType.getId()));
} }
private static Item getItemFromType(ItemType itemType) { private static Item getItemFromType(ItemType itemType) {
return Registry.ITEM.get(ResourceLocation.tryParse(itemType.getId())); return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(
} itemType.getId()));
private static net.minecraft.core.Direction adapt(Direction face) {
switch (face) {
case NORTH:
return net.minecraft.core.Direction.NORTH;
case SOUTH:
return net.minecraft.core.Direction.SOUTH;
case WEST:
return net.minecraft.core.Direction.WEST;
case EAST:
return net.minecraft.core.Direction.EAST;
case DOWN:
return net.minecraft.core.Direction.DOWN;
case UP:
default:
return net.minecraft.core.Direction.UP;
}
}
@Override
public DataFixer getDataFixer() {
return PaperweightDataConverters.INSTANCE;
} }
@Override @Override
@ -334,6 +316,25 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
return combinedId == 0 && state.getBlockType() != BlockTypes.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId); return combinedId == 0 && state.getBlockType() != BlockTypes.AIR ? OptionalInt.empty() : OptionalInt.of(combinedId);
} }
public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) {
int internalId = Block.getId(blockState);
BlockState state = BlockStateIdAccess.getBlockStateById(internalId);
if (state == null) {
state = BukkitAdapter.adapt(CraftBlockData.createData(blockState));
}
return state;
}
public BiomeType adapt(Biome biome) {
var mcBiome = ((CraftServer) Bukkit.getServer()).getServer().registryAccess().registryOrThrow(Registries.BIOME).getKey(
biome);
if (mcBiome == null) {
return null;
}
return BiomeType.REGISTRY.get(mcBiome.toString());
}
@Override @Override
public BlockState getBlock(Location location) { public BlockState getBlock(Location location) {
checkNotNull(location); checkNotNull(location);
@ -373,21 +374,37 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
// Read the NBT data // Read the NBT data
BlockEntity te = chunk.getBlockEntity(blockPos); BlockEntity te = chunk.getBlockEntity(blockPos);
if (te != null) { if (te != null) {
net.minecraft.nbt.CompoundTag tag = te.saveWithId(); net.minecraft.nbt.CompoundTag tag = te.saveWithId(MinecraftServer.getServer().registryAccess());
//FAWE start - BinaryTag
return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag)); return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag));
//FAWE end
} }
return state.toBaseBlock(); return state.toBaseBlock();
} }
private static final HashMap<BiomeType, Holder<Biome>> biomeTypeToNMSCache = new HashMap<>();
private static final HashMap<Holder<Biome>, BiomeType> biomeTypeFromNMSCache = new HashMap<>();
@Override @Override
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) { public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
return new PaperweightWorldNativeAccess( return new PaperweightWorldNativeAccess(this, new WeakReference<>(((CraftWorld) world).getHandle()));
this, }
new WeakReference<>(((CraftWorld) world).getHandle())
); private static net.minecraft.core.Direction adapt(Direction face) {
switch (face) {
case NORTH:
return net.minecraft.core.Direction.NORTH;
case SOUTH:
return net.minecraft.core.Direction.SOUTH;
case WEST:
return net.minecraft.core.Direction.WEST;
case EAST:
return net.minecraft.core.Direction.EAST;
case DOWN:
return net.minecraft.core.Direction.DOWN;
case UP:
default:
return net.minecraft.core.Direction.UP;
}
} }
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({"rawtypes", "unchecked"})
@ -429,16 +446,19 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
CraftEntity craftEntity = ((CraftEntity) entity); CraftEntity craftEntity = ((CraftEntity) entity);
Entity mcEntity = craftEntity.getHandle(); Entity mcEntity = craftEntity.getHandle();
// Do not allow creating of passenger entity snapshots, passengers are included in the vehicle entity
if (mcEntity.isPassenger()) {
return null;
}
String id = getEntityId(mcEntity); String id = getEntityId(mcEntity);
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
readEntityIntoTag(mcEntity, tag); readEntityIntoTag(mcEntity, tag);
//FAWE start - CompoundBinaryTag
return new BaseEntity( return new BaseEntity(
com.sk89q.worldedit.world.entity.EntityTypes.get(id), com.sk89q.worldedit.world.entity.EntityTypes.get(id),
LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag)) LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag))
); );
//FAWE end
} }
@Nullable @Nullable
@ -471,6 +491,22 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
} }
// This removes all unwanted tags from the main entity and all its passengers
private void removeUnwantedEntityTagsRecursively(net.minecraft.nbt.CompoundTag tag) {
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
tag.remove(name);
}
// Adapted from net.minecraft.world.entity.EntityType#loadEntityRecursive
if (tag.contains("Passengers", NBTConstants.TYPE_LIST)) {
net.minecraft.nbt.ListTag nbttaglist = tag.getList("Passengers", NBTConstants.TYPE_COMPOUND);
for (int i = 0; i < nbttaglist.size(); ++i) {
removeUnwantedEntityTagsRecursively(nbttaglist.getCompound(i));
}
}
}
@Override @Override
public Component getRichBlockName(BlockType blockType) { public Component getRichBlockName(BlockType blockType) {
return TranslatableComponent.of(getBlockFromType(blockType).getDescriptionId()); return TranslatableComponent.of(getBlockFromType(blockType).getDescriptionId());
@ -487,26 +523,44 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({"unchecked", "rawtypes"})
private static final LoadingCache<net.minecraft.world.level.block.state.properties.Property, Property<?>> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader<net.minecraft.world.level.block.state.properties.Property, Property<?>>() { private static final LoadingCache<net.minecraft.world.level.block.state.properties.Property, Property<?>> PROPERTY_CACHE = CacheBuilder
.newBuilder()
.build(new CacheLoader<net.minecraft.world.level.block.state.properties.Property, Property<?>>() {
@Override @Override
public Property<?> load(net.minecraft.world.level.block.state.properties.Property state) throws Exception { public Property<?> load(net.minecraft.world.level.block.state.properties.Property state) throws Exception {
if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) { if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) {
return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues()));
} else if (state instanceof DirectionProperty) { } else if (state instanceof DirectionProperty) {
return new DirectionalProperty(state.getName(), return new DirectionalProperty(
(List<Direction>) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).collect(Collectors.toList())); state.getName(),
(List<Direction>) 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) { } else if (state instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
return new EnumProperty(state.getName(), return new EnumProperty(
(List<String>) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).collect(Collectors.toList())); state.getName(),
(List<String>) state
.getPossibleValues()
.stream()
.map(e -> ((StringRepresentable) e).getSerializedName())
.collect(Collectors.toList())
);
} else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) { } else if (state instanceof net.minecraft.world.level.block.state.properties.IntegerProperty) {
return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues())); return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues()));
} else { } else {
throw new IllegalArgumentException("FastAsyncWorldEdit needs an update to support " + state.getClass().getSimpleName()); throw new IllegalArgumentException("WorldEdit needs an update to support " + state
.getClass()
.getSimpleName());
} }
} }
}); });
@SuppressWarnings({ "rawtypes" }) @SuppressWarnings({"rawtypes"})
@Override @Override
public Map<String, ? extends Property<?>> getProperties(BlockType blockType) { public Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
Map<String, Property<?>> properties = new TreeMap<>(); Map<String, Property<?>> properties = new TreeMap<>();
@ -520,50 +574,68 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
return properties; return properties;
} }
//FAWE start - CompoundBinaryTag > CompoundTag
@Override @Override
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) { public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) {
((CraftPlayer) player).getHandle().networkManager.send(ClientboundBlockEntityDataPacket.create( var structureBlock = new StructureBlockEntity(
new StructureBlockEntity( new BlockPos(pos.x(), pos.y(), pos.z()),
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()),
Blocks.STRUCTURE_BLOCK.defaultBlockState() Blocks.STRUCTURE_BLOCK.defaultBlockState()
), );
__ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData) structureBlock.setLevel(((CraftPlayer) player).getHandle().level());
((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create(
structureBlock,
(blockEntity, registryAccess) -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData)
)); ));
} }
//FAWE end
@Override @Override
public void sendFakeOP(Player player) { public void sendFakeOP(Player player) {
((CraftPlayer) player).getHandle().networkManager.send(new ClientboundEntityEventPacket( ((CraftPlayer) player).getHandle().connection.send(new ClientboundEntityEventPacket(
((CraftPlayer) player).getHandle(), (byte) 28 ((CraftPlayer) player).getHandle(), (byte) 28
)); ));
} }
@Override @Override
public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) { public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) {
ItemStack stack = new ItemStack(Registry.ITEM.get(ResourceLocation.tryParse(item.getType().getId())), item.getAmount()); final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess();
stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData()))); ItemStack stack = new ItemStack(
registryAccess.registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(item.getType().getId())),
item.getAmount()
);
final CompoundTag nbt = (net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData());
final DataComponentPatch patch = COMPONENTS_CODEC
.parse(registryAccess.createSerializationContext(NbtOps.INSTANCE), nbt)
.getOrThrow();
stack.applyComponents(patch);
return CraftItemStack.asCraftMirror(stack); return CraftItemStack.asCraftMirror(stack);
} }
@Override @Override
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess();
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); final Tag tag = COMPONENTS_CODEC.encodeStart(
//FAWE start - CBT > CT registryAccess.createSerializationContext(NbtOps.INSTANCE),
weStack.setNbt(((CompoundBinaryTag) toNativeBinary(nmsStack.getTag()))); nmsStack.getComponentsPatch()
//FAWE end ).getOrThrow();
return weStack; return new BaseItemStack(
BukkitAdapter.asItemType(itemStack.getType()),
LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag)),
itemStack.getAmount()
);
} }
private final LoadingCache<ServerLevel, PaperweightFakePlayer> fakePlayers
= CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new));
@Override @Override
public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) { public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) {
CraftWorld craftWorld = (CraftWorld) world; CraftWorld craftWorld = (CraftWorld) world;
ServerLevel worldServer = craftWorld.getHandle(); ServerLevel worldServer = craftWorld.getHandle();
ItemStack stack = CraftItemStack.asNMSCopy(BukkitAdapter.adapt(item instanceof BaseItemStack ItemStack stack = CraftItemStack.asNMSCopy(adapt(
? ((BaseItemStack) item) : new BaseItemStack(item.getType(), item.getNbtData(), 1))); item instanceof BaseItemStack
stack.setTag((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData())); ? ((BaseItemStack) item)
: new BaseItemStack(item.getType(), item.getNbtReference(), 1)
));
PaperweightFakePlayer fakePlayer; PaperweightFakePlayer fakePlayer;
try { try {
@ -572,20 +644,20 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
return false; return false;
} }
fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack); fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack);
fakePlayer.absMoveTo(position.getBlockX(), position.getBlockY(), position.getBlockZ(), fakePlayer.absMoveTo(position.x(), position.y(), position.z(),
(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 BlockPos blockPos = new BlockPos(position.x(), position.y(), position.z());
final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos); final Vec3 blockVec = Vec3.atLowerCornerOf(blockPos);
final net.minecraft.core.Direction enumFacing = adapt(face); final net.minecraft.core.Direction enumFacing = adapt(face);
BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false); BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false);
UseOnContext context = new UseOnContext(fakePlayer, InteractionHand.MAIN_HAND, rayTrace); UseOnContext context = new UseOnContext(fakePlayer, InteractionHand.MAIN_HAND, rayTrace);
InteractionResult result = stack.useOn(context, InteractionHand.MAIN_HAND); InteractionResult result = stack.useOn(context);
if (result != InteractionResult.SUCCESS) { if (result != InteractionResult.SUCCESS) {
if (worldServer if (worldServer
.getBlockState(blockPos) .getBlockState(blockPos)
.use(worldServer, fakePlayer, InteractionHand.MAIN_HAND, rayTrace) .useItemOn(stack, worldServer, fakePlayer, InteractionHand.MAIN_HAND, rayTrace)
.consumesAction()) { .consumesAction()) {
result = InteractionResult.SUCCESS; result = InteractionResult.SUCCESS;
} else { } else {
@ -602,7 +674,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId); net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId);
return blockData.canSurvive( return blockData.canSurvive(
((CraftWorld) world).getHandle(), ((CraftWorld) world).getHandle(),
new BlockPos(position.getX(), position.getY(), position.getZ()) new BlockPos(position.x(), position.y(), position.z())
); );
} }
@ -621,18 +693,18 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
Environment env = bukkitWorld.getEnvironment(); Environment env = bukkitWorld.getEnvironment();
ChunkGenerator gen = bukkitWorld.getGenerator(); ChunkGenerator gen = bukkitWorld.getGenerator();
Path tempDir = Files.createTempDirectory("FastAsyncWorldEditWorldGen"); Path tempDir = Files.createTempDirectory("WorldEditWorldGen");
LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir); LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir);
ResourceKey<LevelStem> worldDimKey = getWorldDimKey(env); ResourceKey<LevelStem> worldDimKey = getWorldDimKey(env);
try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("faweregentempworld", worldDimKey)) { try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("faweregentempworld", worldDimKey)) {
ServerLevel originalWorld = ((CraftWorld) bukkitWorld).getHandle(); ServerLevel originalWorld = ((CraftWorld) bukkitWorld).getHandle();
PrimaryLevelData levelProperties = (PrimaryLevelData) originalWorld.getServer() PrimaryLevelData levelProperties = (PrimaryLevelData) originalWorld.getServer()
.getWorldData().overworldData(); .getWorldData().overworldData();
WorldGenSettings originalOpts = levelProperties.worldGenSettings(); WorldOptions originalOpts = levelProperties.worldGenOptions();
long seed = options.getSeed().orElse(originalWorld.getSeed()); long seed = options.getSeed().orElse(originalWorld.getSeed());
WorldGenSettings newOpts = options.getSeed().isPresent() WorldOptions newOpts = options.getSeed().isPresent()
? originalOpts.withSeed(levelProperties.isHardcore(), OptionalLong.of(seed)) ? originalOpts.withSeed(OptionalLong.of(seed))
: originalOpts; : originalOpts;
LevelSettings newWorldSettings = new LevelSettings( LevelSettings newWorldSettings = new LevelSettings(
@ -642,23 +714,40 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
levelProperties.settings.difficulty(), levelProperties.settings.difficulty(),
levelProperties.settings.allowCommands(), levelProperties.settings.allowCommands(),
levelProperties.settings.gameRules(), levelProperties.settings.gameRules(),
levelProperties.settings.getDataPackConfig() levelProperties.settings.getDataConfiguration()
);
PrimaryLevelData.SpecialWorldProperty specialWorldProperty =
levelProperties.isFlatWorld()
? PrimaryLevelData.SpecialWorldProperty.FLAT
: levelProperties.isDebugWorld()
? PrimaryLevelData.SpecialWorldProperty.DEBUG
: PrimaryLevelData.SpecialWorldProperty.NONE;
PrimaryLevelData newWorldData = new PrimaryLevelData(
newWorldSettings,
newOpts,
specialWorldProperty,
Lifecycle.stable()
); );
PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, Lifecycle.stable());
ServerLevel freshWorld = new ServerLevel( ServerLevel freshWorld = new ServerLevel(
originalWorld.getServer(), originalWorld.getServer(),
originalWorld.getServer().executor, originalWorld.getServer().executor,
session, newWorldData, session, newWorldData,
originalWorld.dimension(), originalWorld.dimension(),
new LevelStem(
originalWorld.dimensionTypeRegistration(), originalWorld.dimensionTypeRegistration(),
originalWorld.getChunkSource().getGenerator()
),
new NoOpWorldLoadListener(), new NoOpWorldLoadListener(),
newOpts.dimensions().get(worldDimKey).generator(),
originalWorld.isDebug(), originalWorld.isDebug(),
seed, seed,
ImmutableList.of(), ImmutableList.of(),
false, false,
env, gen, originalWorld.getRandomSequences(),
env,
gen,
bukkitWorld.getBiomeProvider() bukkitWorld.getBiomeProvider()
); );
try { try {
@ -678,7 +767,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
private BiomeType adapt(ServerLevel serverWorld, Biome origBiome) { private BiomeType adapt(ServerLevel serverWorld, Biome origBiome) {
ResourceLocation key = serverWorld.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY).getKey(origBiome); ResourceLocation key = serverWorld.registryAccess().registryOrThrow(Registries.BIOME).getKey(origBiome);
if (key == null) { if (key == null) {
return null; return null;
} }
@ -713,7 +802,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
for (BlockVector3 vec : region) { for (BlockVector3 vec : region) {
BlockPos pos = new BlockPos(vec.getBlockX(), vec.getBlockY(), vec.getBlockZ()); BlockPos pos = new BlockPos(vec.x(), vec.y(), vec.z());
ChunkAccess chunk = chunks.get(new ChunkPos(pos)); ChunkAccess chunk = chunks.get(new ChunkPos(pos));
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos); final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos);
int internalId = Block.getId(blockData); int internalId = Block.getId(blockData);
@ -721,14 +810,12 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
Objects.requireNonNull(state); Objects.requireNonNull(state);
BlockEntity blockEntity = chunk.getBlockEntity(pos); BlockEntity blockEntity = chunk.getBlockEntity(pos);
if (blockEntity != null) { if (blockEntity != null) {
net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(serverWorld.registryAccess());
//FAWE start - BinaryTag
state = state.toBaseBlock(((CompoundBinaryTag) toNativeBinary(tag))); state = state.toBaseBlock(((CompoundBinaryTag) toNativeBinary(tag)));
//FAWE end
} }
extent.setBlock(vec, state.toBaseBlock()); extent.setBlock(vec, state.toBaseBlock());
if (options.shouldRegenBiomes()) { if (options.shouldRegenBiomes()) {
Biome origBiome = chunk.getNoiseBiome(vec.getX(), vec.getY(), vec.getZ()).value(); Biome origBiome = chunk.getNoiseBiome(vec.x(), vec.y(), vec.z()).value();
BiomeType adaptedBiome = adapt(serverWorld, origBiome); BiomeType adaptedBiome = adapt(serverWorld, origBiome);
if (adaptedBiome != null) { if (adaptedBiome != null) {
extent.setBiome(vec, adaptedBiome); extent.setBiome(vec, adaptedBiome);
@ -746,9 +833,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
try { try {
//noinspection unchecked //noinspection unchecked
chunkLoadings.add( chunkLoadings.add(
((CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>) ((CompletableFuture<ChunkResult<ChunkAccess>>)
getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true)) getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true))
.thenApply(either -> either.left().orElse(null)) .thenApply(either -> either.orElse(null))
); );
} catch (IllegalAccessException | InvocationTargetException e) { } catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException("Couldn't load chunk for regen.", e); throw new IllegalStateException("Couldn't load chunk for regen.", e);
@ -769,6 +856,15 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
} }
} }
private static final Set<SideEffect> SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
SideEffect.NEIGHBORS,
SideEffect.LIGHTING,
SideEffect.VALIDATION,
SideEffect.ENTITY_AI,
SideEffect.EVENTS,
SideEffect.UPDATE
);
@Override @Override
public Set<SideEffect> getSupportedSideEffects() { public Set<SideEffect> getSupportedSideEffects() {
return SUPPORTED_SIDE_EFFECTS; return SUPPORTED_SIDE_EFFECTS;
@ -778,7 +874,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) { public boolean clearContainerBlockContents(org.bukkit.World world, BlockVector3 pt) {
ServerLevel originalWorld = ((CraftWorld) world).getHandle(); ServerLevel originalWorld = ((CraftWorld) world).getHandle();
BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ())); BlockEntity entity = originalWorld.getBlockEntity(new BlockPos(pt.x(), pt.y(), pt.z()));
if (entity instanceof Clearable) { if (entity instanceof Clearable) {
((Clearable) entity).clearContent(); ((Clearable) entity).clearContent();
return true; return true;
@ -797,7 +893,6 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
* @param foreign non-native NMS NBT structure * @param foreign non-native NMS NBT structure
* @return native WorldEdit NBT structure * @return native WorldEdit NBT structure
*/ */
//FAWE start - BinaryTag
@Override @Override
public BinaryTag toNativeBinary(net.minecraft.nbt.Tag foreign) { public BinaryTag toNativeBinary(net.minecraft.nbt.Tag foreign) {
if (foreign == null) { if (foreign == null) {
@ -830,7 +925,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
try { try {
return toNativeList((net.minecraft.nbt.ListTag) foreign); return toNativeList((net.minecraft.nbt.ListTag) foreign);
} catch (Throwable e) { } catch (Throwable e) {
LOGGER.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e); logger.log(Level.WARNING, "Failed to convert net.minecraft.nbt.ListTag", e);
return ListBinaryTag.empty(); return ListBinaryTag.empty();
} }
} else if (foreign instanceof net.minecraft.nbt.LongTag) { } else if (foreign instanceof net.minecraft.nbt.LongTag) {
@ -855,7 +950,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
* @throws IllegalArgumentException on error * @throws IllegalArgumentException on error
*/ */
private ListBinaryTag toNativeList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException { private ListBinaryTag toNativeList(net.minecraft.nbt.ListTag foreign) throws SecurityException, IllegalArgumentException {
ListBinaryTag.Builder<BinaryTag> values = ListBinaryTag.builder(); ListBinaryTag.Builder values = ListBinaryTag.builder();
for (net.minecraft.nbt.Tag tag : foreign) { for (net.minecraft.nbt.Tag tag : foreign) {
values.add(toNativeBinary(tag)); values.add(toNativeBinary(tag));
@ -895,8 +990,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
return new net.minecraft.nbt.IntArrayTag(((IntArrayBinaryTag) foreign).value()); return new net.minecraft.nbt.IntArrayTag(((IntArrayBinaryTag) foreign).value());
} else if (foreign instanceof LongArrayBinaryTag) { } else if (foreign instanceof LongArrayBinaryTag) {
return new net.minecraft.nbt.LongArrayTag(((LongArrayBinaryTag) foreign).value()); return new net.minecraft.nbt.LongArrayTag(((LongArrayBinaryTag) foreign).value());
} else if (foreign instanceof ListBinaryTag foreignList) { } else if (foreign instanceof ListBinaryTag) {
net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag(); net.minecraft.nbt.ListTag tag = new net.minecraft.nbt.ListTag();
ListBinaryTag foreignList = (ListBinaryTag) foreign;
for (BinaryTag t : foreignList) { for (BinaryTag t : foreignList) {
tag.add(fromNativeBinary(t)); tag.add(fromNativeBinary(t));
} }
@ -913,7 +1009,6 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName()); throw new IllegalArgumentException("Don't know how to make NMS " + foreign.getClass().getCanonicalName());
} }
} }
//FAWE end
@Override @Override
public boolean supportsWatchdog() { public boolean supportsWatchdog() {
@ -925,54 +1020,6 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
watchdog.tick(); watchdog.tick();
} }
private static class MojangWatchdog implements Watchdog {
private final DedicatedServer server;
private final Field tickField;
MojangWatchdog(DedicatedServer server) throws NoSuchFieldException {
this.server = server;
Field tickField = MinecraftServer.class.getDeclaredField(
Refraction.pickName("nextTickTime", "ao")
);
tickField.setAccessible(true);
this.tickField = tickField;
}
@Override
public void tick() {
try {
tickField.set(server, Util.getMillis());
} catch (IllegalAccessException ignored) {
}
}
}
private static class NoOpWorldLoadListener implements ChunkProgressListener {
@Override
public void updateSpawnPos(ChunkPos spawnPos) {
}
@Override
public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) {
}
@Override
public void start() {
}
@Override
public void stop() {
}
@Override
public void setChunkRadius(int radius) {
}
}
private class SpigotWatchdog implements Watchdog { private class SpigotWatchdog implements Watchdog {
private final Field instanceField; private final Field instanceField;
@ -996,10 +1043,61 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
WatchdogThread.tick(); WatchdogThread.tick();
} }
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
LOGGER.log(Level.WARNING, "Failed to tick watchdog", e); logger.log(Level.WARNING, "Failed to tick watchdog", e);
} }
} }
} }
private static class MojangWatchdog implements Watchdog {
private final DedicatedServer server;
private final Field tickField;
MojangWatchdog(DedicatedServer server) throws NoSuchFieldException {
this.server = server;
Field tickField = MinecraftServer.class.getDeclaredField(
Refraction.pickName("nextTickTime", "ah")
);
if (tickField.getType() != long.class) {
throw new IllegalStateException("nextTickTime is not a long field, mapping is likely incorrect");
}
tickField.setAccessible(true);
this.tickField = tickField;
}
@Override
public void tick() {
try {
tickField.set(server, Util.getMillis());
} catch (IllegalAccessException ignored) {
}
}
}
private static class NoOpWorldLoadListener implements ChunkProgressListener {
@Override
public void updateSpawnPos(ChunkPos spawnPos) {
}
@Override
public void onStatusChange(
final ChunkPos pos,
@org.jetbrains.annotations.Nullable final net.minecraft.world.level.chunk.status.ChunkStatus status
) {
}
@Override
public void start() {
}
@Override
public void stop() {
}
}
} }

Datei anzeigen

@ -17,18 +17,19 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2; package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import net.minecraft.network.chat.ChatType;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ServerboundClientInformationPacket; import net.minecraft.server.level.ClientInformation;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.stats.Stat; import net.minecraft.stats.Stat;
import net.minecraft.world.MenuProvider; import net.minecraft.world.MenuProvider;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.entity.player.ChatVisiblity;
import net.minecraft.world.level.block.entity.SignBlockEntity; import net.minecraft.world.level.block.entity.SignBlockEntity;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
@ -37,15 +38,14 @@ import java.util.OptionalInt;
import java.util.UUID; import java.util.UUID;
class PaperweightFakePlayer extends ServerPlayer { class PaperweightFakePlayer extends ServerPlayer {
private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]");
private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(
UUID.nameUUIDFromBytes("worldedit".getBytes()),
"[WorldEdit]"
);
private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D); private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D);
private static final ClientInformation FAKE_CLIENT_INFO = new ClientInformation(
"en_US", 16, ChatVisiblity.FULL, true, 0, HumanoidArm.LEFT, false, false
);
PaperweightFakePlayer(ServerLevel world) { PaperweightFakePlayer(ServerLevel world) {
super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE); super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE, FAKE_CLIENT_INFO);
} }
@Override @Override
@ -72,17 +72,13 @@ class PaperweightFakePlayer extends ServerPlayer {
} }
@Override @Override
public void updateOptions(ServerboundClientInformationPacket packet) { public void updateOptions(ClientInformation clientOptions) {
} }
@Override @Override
public void displayClientMessage(Component message, boolean actionBar) { public void displayClientMessage(Component message, boolean actionBar) {
} }
@Override
public void sendMessage(Component message, ChatType type, UUID sender) {
}
@Override @Override
public void awardStat(Stat<?> stat, int amount) { public void awardStat(Stat<?> stat, int amount) {
} }
@ -97,7 +93,6 @@ class PaperweightFakePlayer extends ServerPlayer {
} }
@Override @Override
public void openTextEdit(SignBlockEntity sign) { public void openTextEdit(SignBlockEntity sign, boolean front) {
} }
} }

Datei anzeigen

@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2; package com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.internal.block.BlockStateIdAccess; import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
@ -27,21 +27,19 @@ import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.FullChunkStatus;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunk;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData; import org.bukkit.craftbukkit.block.data.CraftBlockData;
import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.event.block.BlockPhysicsEvent;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Objects; import java.util.Objects;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class PaperweightWorldNativeAccess implements public class PaperweightWorldNativeAccess implements WorldNativeAccess<LevelChunk, net.minecraft.world.level.block.state.BlockState, BlockPos> {
WorldNativeAccess<LevelChunk, net.minecraft.world.level.block.state.BlockState, BlockPos> {
private static final int UPDATE = 1; private static final int UPDATE = 1;
private static final int NOTIFY = 2; private static final int NOTIFY = 2;
@ -83,19 +81,12 @@ public class PaperweightWorldNativeAccess implements
@Nullable @Nullable
@Override @Override
public net.minecraft.world.level.block.state.BlockState setBlockState( public net.minecraft.world.level.block.state.BlockState setBlockState(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState state) {
LevelChunk chunk,
BlockPos position,
net.minecraft.world.level.block.state.BlockState state
) {
return chunk.setBlockState(position, state, false, this.sideEffectSet.shouldApply(SideEffect.UPDATE)); return chunk.setBlockState(position, state, false, this.sideEffectSet.shouldApply(SideEffect.UPDATE));
} }
@Override @Override
public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition( public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition(net.minecraft.world.level.block.state.BlockState block, BlockPos position) {
net.minecraft.world.level.block.state.BlockState block,
BlockPos position
) {
return Block.updateFromNeighbourShapes(block, getWorld(), position); return Block.updateFromNeighbourShapes(block, getWorld(), position);
} }
@ -115,12 +106,7 @@ public class PaperweightWorldNativeAccess implements
} }
@Override @Override
public void notifyBlockUpdate( public void notifyBlockUpdate(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) {
LevelChunk chunk,
BlockPos position,
net.minecraft.world.level.block.state.BlockState oldState,
net.minecraft.world.level.block.state.BlockState newState
) {
if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) { if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) {
getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY); getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY);
} }
@ -128,7 +114,7 @@ public class PaperweightWorldNativeAccess implements
@Override @Override
public boolean isChunkTicking(LevelChunk chunk) { public boolean isChunkTicking(LevelChunk chunk) {
return chunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING); return chunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING);
} }
@Override @Override
@ -139,11 +125,7 @@ public class PaperweightWorldNativeAccess implements
} }
@Override @Override
public void notifyNeighbors( public void notifyNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) {
BlockPos pos,
net.minecraft.world.level.block.state.BlockState oldState,
net.minecraft.world.level.block.state.BlockState newState
) {
ServerLevel world = getWorld(); ServerLevel world = getWorld();
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
world.updateNeighborsAt(pos, oldState.getBlock()); world.updateNeighborsAt(pos, oldState.getBlock());
@ -162,27 +144,20 @@ public class PaperweightWorldNativeAccess implements
} }
} }
// Not sure why neighborChanged is deprecated
private void fireNeighborChanged(BlockPos pos, ServerLevel world, Block block, BlockPos neighborPos) { private void fireNeighborChanged(BlockPos pos, ServerLevel world, Block block, BlockPos neighborPos) {
world.getBlockState(neighborPos).neighborChanged(world, neighborPos, block, pos, false); world.getBlockState(neighborPos).handleNeighborChanged(world, neighborPos, block, pos, false);
} }
@Override @Override
public void updateNeighbors( public void updateNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState, int recursionLimit) {
BlockPos pos,
net.minecraft.world.level.block.state.BlockState oldState,
net.minecraft.world.level.block.state.BlockState newState,
int recursionLimit
) {
ServerLevel world = getWorld(); ServerLevel world = getWorld();
// a == updateNeighbors // a == updateNeighbors
// b == updateDiagonalNeighbors // b == updateDiagonalNeighbors
oldState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit); oldState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit);
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) { if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
CraftWorld craftWorld = world.getWorld(); CraftWorld craftWorld = world.getWorld();
BlockPhysicsEvent event = new BlockPhysicsEvent( BlockPhysicsEvent event = new BlockPhysicsEvent(craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), CraftBlockData.fromData(newState));
craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()),
CraftBlockData.fromData(newState)
);
world.getCraftServer().getPluginManager().callEvent(event); world.getCraftServer().getPluginManager().callEvent(event);
if (event.isCancelled()) { if (event.isCancelled()) {
return; return;
@ -193,19 +168,13 @@ public class PaperweightWorldNativeAccess implements
} }
@Override @Override
public void onBlockStateChange( public void onBlockStateChange(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) {
BlockPos pos,
net.minecraft.world.level.block.state.BlockState oldState,
net.minecraft.world.level.block.state.BlockState newState
) {
getWorld().onBlockStateChange(pos, oldState, newState); getWorld().onBlockStateChange(pos, oldState, newState);
} }
//FAWE start
@Override @Override
public void flush() { public void flush() {
} }
//FAWE end
} }

Datei anzeigen

@ -1,28 +1,24 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.util.ReflectionUtil; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag;
import com.sk89q.worldedit.bukkit.adapter.Refraction;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag;
import com.sk89q.worldedit.world.registry.BlockMaterial; import com.sk89q.worldedit.world.registry.BlockMaterial;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.world.level.EmptyBlockGetter; import net.minecraft.world.level.EmptyBlockGetter;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Material; import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.level.material.PushReaction; import net.minecraft.world.level.material.PushReaction;
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData; import org.bukkit.craftbukkit.block.data.CraftBlockData;
public class PaperweightBlockMaterial implements BlockMaterial { public class PaperweightBlockMaterial implements BlockMaterial {
private final Block block; private final Block block;
private final BlockState blockState; private final BlockState blockState;
private final Material material;
private final boolean isTranslucent;
private final CraftBlockData craftBlockData; private final CraftBlockData craftBlockData;
private final org.bukkit.Material craftMaterial; private final org.bukkit.Material craftMaterial;
private final int opacity; private final int opacity;
@ -35,22 +31,16 @@ public class PaperweightBlockMaterial implements BlockMaterial {
public PaperweightBlockMaterial(Block block, BlockState blockState) { public PaperweightBlockMaterial(Block block, BlockState blockState) {
this.block = block; this.block = block;
this.blockState = blockState; this.blockState = blockState;
this.material = blockState.getMaterial();
this.craftBlockData = CraftBlockData.fromData(blockState); this.craftBlockData = CraftBlockData.fromData(blockState);
this.craftMaterial = craftBlockData.getMaterial(); this.craftMaterial = craftBlockData.getMaterial();
BlockBehaviour.Properties blockInfo = ReflectionUtil.getField(BlockBehaviour.class, block, Refraction.pickName(
"properties", "aO"));
this.isTranslucent = !(boolean) ReflectionUtil.getField(BlockBehaviour.Properties.class, blockInfo,
Refraction.pickName("canOcclude", "n")
);
opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO); opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity( BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity(
BlockPos.ZERO, BlockPos.ZERO,
blockState blockState
); );
tile = tileEntity == null tile = tileEntity == null ? null : new PaperweightLazyCompoundTag(
? null Suppliers.memoize(() -> tileEntity.saveWithId(DedicatedServer.getServer().registryAccess()))
: new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); );
} }
public Block getBlock() { public Block getBlock() {
@ -65,10 +55,6 @@ public class PaperweightBlockMaterial implements BlockMaterial {
return craftBlockData; return craftBlockData;
} }
public Material getMaterial() {
return material;
}
@Override @Override
public boolean isAir() { public boolean isAir() {
return blockState.isAir(); return blockState.isAir();
@ -81,7 +67,7 @@ public class PaperweightBlockMaterial implements BlockMaterial {
@Override @Override
public boolean isOpaque() { public boolean isOpaque() {
return material.isSolidBlocking(); return blockState.canOcclude();
} }
@Override @Override
@ -91,12 +77,13 @@ public class PaperweightBlockMaterial implements BlockMaterial {
@Override @Override
public boolean isLiquid() { public boolean isLiquid() {
return material.isLiquid(); return !blockState.getFluidState().is(Fluids.EMPTY);
} }
@Override @Override
public boolean isSolid() { public boolean isSolid() {
return material.isSolid(); // No access to world -> EmptyBlockGetter
return blockState.isSolidRender(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
} }
@Override @Override
@ -126,27 +113,27 @@ public class PaperweightBlockMaterial implements BlockMaterial {
@Override @Override
public boolean isFragileWhenPushed() { public boolean isFragileWhenPushed() {
return material.getPushReaction() == PushReaction.DESTROY; return blockState.getPistonPushReaction() == PushReaction.DESTROY;
} }
@Override @Override
public boolean isUnpushable() { public boolean isUnpushable() {
return material.getPushReaction() == PushReaction.BLOCK; return blockState.getPistonPushReaction() == PushReaction.BLOCK;
} }
@Override @Override
public boolean isTicksRandomly() { public boolean isTicksRandomly() {
return block.isRandomlyTicking(blockState); return blockState.isRandomlyTicking();
} }
@Override @Override
public boolean isMovementBlocker() { public boolean isMovementBlocker() {
return material.isSolid(); return craftMaterial.isSolid();
} }
@Override @Override
public boolean isBurnable() { public boolean isBurnable() {
return material.isFlammable(); return craftMaterial.isBurnable();
} }
@Override @Override
@ -157,12 +144,12 @@ public class PaperweightBlockMaterial implements BlockMaterial {
@Override @Override
public boolean isReplacedDuringPlacement() { public boolean isReplacedDuringPlacement() {
return material.isReplaceable(); return blockState.canBeReplaced();
} }
@Override @Override
public boolean isTranslucent() { public boolean isTranslucent() {
return isTranslucent; return !blockState.canOcclude();
} }
@Override @Override
@ -183,7 +170,7 @@ public class PaperweightBlockMaterial implements BlockMaterial {
@Override @Override
public int getMapColor() { public int getMapColor() {
// rgb field // rgb field
return material.getColor().col; return block.defaultMapColor().col;
} }
} }

Datei anzeigen

@ -1,4 +1,4 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
import com.fastasyncworldedit.bukkit.adapter.FaweAdapter; import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory; import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
@ -12,14 +12,13 @@ import com.fastasyncworldedit.core.util.NbtUtils;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.mojang.serialization.Codec;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.TileEntityBlock;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2.PaperweightAdapter; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.regen.PaperweightRegen;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.regen.PaperweightRegen;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.internal.block.BlockStateIdAccess; import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
@ -35,6 +34,7 @@ import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.SideEffectSet; import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.util.concurrency.LazyReference;
import com.sk89q.worldedit.util.formatting.text.Component; import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.nbt.BinaryTag; import com.sk89q.worldedit.util.nbt.BinaryTag;
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag; import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
@ -45,7 +45,6 @@ import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.block.BlockTypesCache;
import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemType;
@ -53,44 +52,48 @@ import com.sk89q.worldedit.world.registry.BlockMaterial;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.WritableRegistry; import net.minecraft.core.WritableRegistry;
import net.minecraft.nbt.IntTag; import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket; import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ChunkHolder;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.StringRepresentable; import net.minecraft.util.StringRepresentable;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty; import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LevelChunkSection;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.v1_18_R2.CraftChunk; import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.v1_18_R2.CraftServer; import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; import org.bukkit.craftbukkit.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData; import org.bukkit.craftbukkit.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity; import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack; import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.craftbukkit.v1_18_R2.util.CraftNamespacedKey;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -104,11 +107,24 @@ import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import static net.minecraft.core.registries.Registries.BIOME;
public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.Tag, ServerLevel> { public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.Tag, ServerLevel> {
private static final Logger LOGGER = LogManagerCompat.getLogger(); private static final Logger LOGGER = LogManagerCompat.getLogger();
private static Method CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE;
private static final Codec<DataComponentPatch> COMPONENTS_CODEC = DataComponentPatch.CODEC.optionalFieldOf(
"components", DataComponentPatch.EMPTY
).codec();
private final PaperweightAdapter parent; static {
try {
CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE = ChunkHolder.class.getDeclaredMethod("wasAccessibleSinceLastSave");
} catch (NoSuchMethodException ignored) { // may not be present in newer paper versions
}
}
private final com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4.PaperweightAdapter parent;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Code that may break between versions of Minecraft // Code that may break between versions of Minecraft
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -119,7 +135,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
private Map<String, List<Property<?>>> allBlockProperties = null; private Map<String, List<Property<?>>> allBlockProperties = null;
public PaperweightFaweAdapter() throws NoSuchFieldException, NoSuchMethodException { public PaperweightFaweAdapter() throws NoSuchFieldException, NoSuchMethodException {
this.parent = new PaperweightAdapter(); this.parent = new com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4.PaperweightAdapter();
} }
@Nullable @Nullable
@ -128,6 +144,10 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
return resourceLocation == null ? null : resourceLocation.toString(); return resourceLocation == null ? null : resourceLocation.toString();
} }
private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
entity.save(compoundTag);
}
@Override @Override
public BukkitImplAdapter<net.minecraft.nbt.Tag> getParent() { public BukkitImplAdapter<net.minecraft.nbt.Tag> getParent() {
return parent; return parent;
@ -219,7 +239,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
} }
public Block getBlock(BlockType blockType) { public Block getBlock(BlockType blockType) {
return Registry.BLOCK.get(new ResourceLocation(blockType.getNamespace(), blockType.getResource())); return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.BLOCK)
.get(new ResourceLocation(blockType.getNamespace(), blockType.getResource()));
} }
@Deprecated @Deprecated
@ -264,7 +285,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
// Read the NBT data // Read the NBT data
BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK); BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
if (blockEntity != null) { if (blockEntity != null) {
net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(); net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(DedicatedServer.getServer().registryAccess());
return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag)); return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag));
} }
} }
@ -277,54 +298,6 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
return SideEffectSet.defaults().getSideEffectsToApply(); return SideEffectSet.defaults().getSideEffectsToApply();
} }
public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) {
CraftChunk craftChunk = (CraftChunk) chunk;
LevelChunk levelChunk = craftChunk.getHandle();
Level level = levelChunk.getLevel();
BlockPos blockPos = new BlockPos(x, y, z);
net.minecraft.world.level.block.state.BlockState blockState = ((PaperweightBlockMaterial) state.getMaterial()).getState();
LevelChunkSection[] levelChunkSections = levelChunk.getSections();
int y4 = y >> 4;
LevelChunkSection section = levelChunkSections[y4];
net.minecraft.world.level.block.state.BlockState existing;
if (section == null) {
existing = ((PaperweightBlockMaterial) BlockTypes.AIR.getDefaultState().getMaterial()).getState();
} else {
existing = section.getBlockState(x & 15, y & 15, z & 15);
}
levelChunk.removeBlockEntity(blockPos); // Force delete the old tile entity
CompoundBinaryTag compoundTag = state instanceof BaseBlock ? state.getNbt() : null;
if (compoundTag != null || existing instanceof TileEntityBlock) {
level.setBlock(blockPos, blockState, 0);
// remove tile
if (compoundTag != null) {
// We will assume that the tile entity was created for us,
// though we do not do this on the Forge version
BlockEntity blockEntity = level.getBlockEntity(blockPos);
if (blockEntity != null) {
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeBinary(compoundTag);
tag.put("x", IntTag.valueOf(x));
tag.put("y", IntTag.valueOf(y));
tag.put("z", IntTag.valueOf(z));
blockEntity.load(tag); // readTagIntoTileEntity - load data
}
}
} else {
if (existing == blockState) {
return true;
}
levelChunk.setBlockState(blockPos, blockState, false);
}
if (update) {
level.getMinecraftWorld().sendBlockUpdated(blockPos, existing, blockState, 0);
}
return true;
}
@Override @Override
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) { public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
return new PaperweightFaweWorldNativeAccess(this, new WeakReference<>(getServerLevel(world))); return new PaperweightFaweWorldNativeAccess(this, new WeakReference<>(getServerLevel(world)));
@ -343,7 +316,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id); EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id);
Supplier<CompoundBinaryTag> saveTag = () -> { Supplier<CompoundBinaryTag> saveTag = () -> {
final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag(); final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag();
PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag); readEntityIntoTag(mcEntity, minecraftTag);
//add Id for AbstractChangeSet to work //add Id for AbstractChangeSet to work
final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag); final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag);
final Map<String, BinaryTag> tags = NbtUtils.getCompoundBinaryTagValues(tag); final Map<String, BinaryTag> tags = NbtUtils.getCompoundBinaryTagValues(tag);
@ -474,7 +447,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) { public void sendFakeChunk(org.bukkit.World world, Player player, ChunkPacket chunkPacket) {
ServerLevel nmsWorld = getServerLevel(world); ServerLevel nmsWorld = getServerLevel(world);
ChunkHolder map = PaperweightPlatformAdapter.getPlayerChunk(nmsWorld, chunkPacket.getChunkX(), chunkPacket.getChunkZ()); ChunkHolder map = PaperweightPlatformAdapter.getPlayerChunk(nmsWorld, chunkPacket.getChunkX(), chunkPacket.getChunkZ());
if (map != null && map.wasAccessibleSinceLastSave()) { if (map != null && wasAccessibleSinceLastSave(map)) {
boolean flag = false;
// PlayerChunk.d players = map.players; // PlayerChunk.d players = map.players;
Stream<ServerPlayer> stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag) Stream<ServerPlayer> stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag)
*/ Stream.empty(); */ Stream.empty();
@ -510,17 +484,24 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId); net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId);
return blockState1.hasPostProcess( return blockState1.hasPostProcess(
getServerLevel(world), getServerLevel(world),
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ()) new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z())
); );
} }
@Override @Override
public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) { public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) {
final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess();
ItemStack stack = new ItemStack( ItemStack stack = new ItemStack(
Registry.ITEM.get(ResourceLocation.tryParse(baseItemStack.getType().getId())), registryAccess.registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(baseItemStack.getType().getId())),
baseItemStack.getAmount() baseItemStack.getAmount()
); );
stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(baseItemStack.getNbtData()))); final CompoundTag nbt = (net.minecraft.nbt.CompoundTag) fromNative(baseItemStack.getNbtData());
if (nbt != null) {
final DataComponentPatch patch = COMPONENTS_CODEC
.parse(registryAccess.createSerializationContext(NbtOps.INSTANCE), nbt)
.getOrThrow();
stack.applyComponents(patch);
}
return CraftItemStack.asCraftMirror(stack); return CraftItemStack.asCraftMirror(stack);
} }
@ -547,29 +528,19 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
return ((CraftWorld) world).getHandle(); return ((CraftWorld) world).getHandle();
} }
@Override
public List<org.bukkit.entity.Entity> getEntities(org.bukkit.World world) {
// Quickly add each entity to a list copy.
List<Entity> mcEntities = new ArrayList<>();
getServerLevel(world).entityManager.getEntityGetter().getAll().forEach(mcEntities::add);
List<org.bukkit.entity.Entity> list = new ArrayList<>();
mcEntities.forEach((mcEnt) -> {
org.bukkit.entity.Entity bukkitEntity = mcEnt.getBukkitEntity();
if (bukkitEntity.isValid()) {
list.add(bukkitEntity);
}
});
return list;
}
@Override @Override
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) { public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess();
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack); final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount()); final net.minecraft.nbt.Tag tag = COMPONENTS_CODEC.encodeStart(
weStack.setNbt(((CompoundBinaryTag) toNativeBinary(nmsStack.getTag()))); registryAccess.createSerializationContext(NbtOps.INSTANCE),
return weStack; nmsStack.getComponentsPatch()
).getOrThrow();
return new BaseItemStack(
BukkitAdapter.asItemType(itemStack.getType()),
LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag)),
itemStack.getAmount()
);
} }
@Override @Override
@ -577,17 +548,12 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
return parent.toNative(foreign); return parent.toNative(foreign);
} }
@Override
public BinaryTag toNativeBinary(final net.minecraft.nbt.Tag foreign) {
return parent.toNativeBinary(foreign);
}
@Override @Override
public net.minecraft.nbt.Tag fromNative(Tag foreign) { public net.minecraft.nbt.Tag fromNative(Tag foreign) {
if (foreign instanceof PaperweightLazyCompoundTag) { if (foreign instanceof PaperweightLazyCompoundTag) {
return ((PaperweightLazyCompoundTag) foreign).get(); return ((PaperweightLazyCompoundTag) foreign).get();
} }
return (net.minecraft.nbt.Tag) parent.fromNative(foreign); return parent.fromNative(foreign);
} }
@Override @Override
@ -605,7 +571,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
final Registry<Biome> registry = MinecraftServer final Registry<Biome> registry = MinecraftServer
.getServer() .getServer()
.registryAccess() .registryAccess()
.ownedRegistryOrThrow(Registry.BIOME_REGISTRY); .registryOrThrow(BIOME);
ResourceLocation resourceLocation = ResourceLocation.tryParse(biomeType.getId()); ResourceLocation resourceLocation = ResourceLocation.tryParse(biomeType.getId());
Biome biome = registry.get(resourceLocation); Biome biome = registry.get(resourceLocation);
return registry.getId(biome); return registry.getId(biome);
@ -616,8 +582,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) ((CraftServer) Bukkit.getServer()) WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) ((CraftServer) Bukkit.getServer())
.getServer() .getServer()
.registryAccess() .registryAccess()
.ownedRegistryOrThrow( .registryOrThrow(BIOME);
Registry.BIOME_REGISTRY);
List<ResourceLocation> keys = biomeRegistry.stream() List<ResourceLocation> keys = biomeRegistry.stream()
.map(biomeRegistry::getKey).filter(Objects::nonNull).toList(); .map(biomeRegistry::getKey).filter(Objects::nonNull).toList();
List<NamespacedKey> namespacedKeys = new ArrayList<>(); List<NamespacedKey> namespacedKeys = new ArrayList<>();
@ -659,4 +624,16 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
return new PaperweightPostProcessor(); return new PaperweightPostProcessor();
} }
private boolean wasAccessibleSinceLastSave(ChunkHolder holder) {
if (!PaperLib.isPaper() || !PaperweightPlatformAdapter.POST_CHUNK_REWRITE) {
try {
return (boolean) CHUNK_HOLDER_WAS_ACCESSIBLE_SINCE_LAST_SAVE.invoke(holder);
} catch (IllegalAccessException | InvocationTargetException ignored) {
// fall-through
}
}
// Papers new chunk system has no related replacement - therefor we assume true.
return true;
}
} }

Datei anzeigen

@ -1,4 +1,4 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
import com.fastasyncworldedit.core.Fawe; import com.fastasyncworldedit.core.Fawe;
import com.fastasyncworldedit.core.math.IntPair; import com.fastasyncworldedit.core.math.IntPair;
@ -15,14 +15,15 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.FullChunkStatus;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunk;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData; import org.bukkit.craftbukkit.block.data.CraftBlockData;
import org.bukkit.event.block.BlockPhysicsEvent; import org.bukkit.event.block.BlockPhysicsEvent;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -102,7 +103,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
} }
// Since FAWE is.. Async we need to do it on the main thread (wooooo.. :( ) // Since FAWE is.. Async we need to do it on the main thread (wooooo.. :( )
cachedChanges.add(new CachedChange(levelChunk, blockPos, blockState)); cachedChanges.add(new CachedChange(levelChunk, blockPos, blockState));
cachedChunksToSend.add(new IntPair(levelChunk.bukkitChunk.getX(), levelChunk.bukkitChunk.getZ())); cachedChunksToSend.add(new IntPair(levelChunk.locX, levelChunk.locZ));
boolean nextTick = lastTick.get() > currentTick; boolean nextTick = lastTick.get() > currentTick;
if (nextTick || cachedChanges.size() >= 1024) { if (nextTick || cachedChanges.size() >= 1024) {
if (nextTick) { if (nextTick) {
@ -140,7 +141,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
return false; return false;
} }
net.minecraft.nbt.Tag nativeTag = paperweightFaweAdapter.fromNativeBinary(tag); net.minecraft.nbt.Tag nativeTag = paperweightFaweAdapter.fromNativeBinary(tag);
blockEntity.load((CompoundTag) nativeTag); blockEntity.loadWithComponents((CompoundTag) nativeTag, DedicatedServer.getServer().registryAccess());
return true; return true;
} }
@ -157,7 +158,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
@Override @Override
public boolean isChunkTicking(LevelChunk levelChunk) { public boolean isChunkTicking(LevelChunk levelChunk) {
return levelChunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING); return levelChunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING);
} }
@Override @Override
@ -181,7 +182,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
// Un-nest neighbour updating // Un-nest neighbour updating
for (Direction direction : NEIGHBOUR_ORDER) { for (Direction direction : NEIGHBOUR_ORDER) {
BlockPos shifted = blockPos.relative(direction); BlockPos shifted = blockPos.relative(direction);
level.getBlockState(shifted).neighborChanged(level, shifted, oldState.getBlock(), blockPos, false); level.getBlockState(shifted).handleNeighborChanged(level, shifted, oldState.getBlock(), blockPos, false);
} }
} }
if (newState.hasAnalogOutputSignal()) { if (newState.hasAnalogOutputSignal()) {

Datei anzeigen

@ -1,4 +1,4 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
import com.fastasyncworldedit.bukkit.adapter.BukkitGetBlocks; import com.fastasyncworldedit.bukkit.adapter.BukkitGetBlocks;
import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore;
@ -20,7 +20,7 @@ import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag;
import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.internal.Constants;
import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
@ -29,12 +29,9 @@ import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.block.BlockTypesCache;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import io.papermc.paper.event.block.BeaconDeactivatedEvent; import io.papermc.paper.event.block.BeaconDeactivatedEvent;
import net.minecraft.core.BlockPos; import net.minecraft.core.*;
import net.minecraft.core.Holder;
import net.minecraft.core.IdMap;
import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.nbt.IntTag; import net.minecraft.nbt.IntTag;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundEvents;
import net.minecraft.util.BitStorage; import net.minecraft.util.BitStorage;
@ -46,33 +43,17 @@ import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.entity.BeaconBlockEntity; import net.minecraft.world.level.block.entity.BeaconBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.DataLayer; import net.minecraft.world.level.chunk.*;
import net.minecraft.world.level.chunk.HashMapPalette;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.LinearPalette;
import net.minecraft.world.level.chunk.Palette;
import net.minecraft.world.level.chunk.PalettedContainer;
import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.lighting.LevelLightEngine; import net.minecraft.world.level.lighting.LevelLightEngine;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.v1_18_R2.block.CraftBlock; import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.AbstractSet; import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -83,13 +64,16 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static net.minecraft.core.registries.Registries.BIOME;
public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks { public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks {
private static final Logger LOGGER = LogManagerCompat.getLogger(); private static final Logger LOGGER = LogManagerCompat.getLogger();
private static final Function<BlockPos, BlockVector3> posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ()); private static final Function<BlockPos, BlockVector3> posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ());
private static final Function<BlockEntity, CompoundTag> nmsTile2We = private static final Function<BlockEntity, CompoundTag> nmsTile2We = tileEntity -> new PaperweightLazyCompoundTag(
tileEntity -> new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId)); Suppliers.memoize(() -> tileEntity.saveWithId(DedicatedServer.getServer().registryAccess()))
);
private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin
.getInstance() .getInstance()
.getBukkitImplAdapter()); .getBukkitImplAdapter());
@ -130,7 +114,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
this.maxSectionPosition = maxHeight >> 4; this.maxSectionPosition = maxHeight >> 4;
this.skyLight = new DataLayer[getSectionCount()]; this.skyLight = new DataLayer[getSectionCount()];
this.blockLight = new DataLayer[getSectionCount()]; this.blockLight = new DataLayer[getSectionCount()];
this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY); this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(BIOME);
this.biomeHolderIdMap = biomeRegistry.asHolderIdMap(); this.biomeHolderIdMap = biomeRegistry.asHolderIdMap();
} }
@ -260,7 +244,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
if (blockEntity == null) { if (blockEntity == null) {
return null; return null;
} }
return new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)); return new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.saveWithId(DedicatedServer.getServer().registryAccess())));
} }
@Override @Override
@ -289,8 +273,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(
LightLayer.BLOCK, LightLayer.BLOCK,
sectionPos, sectionPos,
dataLayer, dataLayer
true
); );
} }
skyLight[alayer] = dataLayer; skyLight[alayer] = dataLayer;
@ -317,7 +300,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
Arrays.fill(LAYER_COUNT, (byte) 15); Arrays.fill(LAYER_COUNT, (byte) 15);
dataLayer = new DataLayer(LAYER_COUNT); dataLayer = new DataLayer(LAYER_COUNT);
((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(LightLayer.BLOCK, sectionPos, ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(LightLayer.BLOCK, sectionPos,
dataLayer, true dataLayer
); );
} }
blockLight[alayer] = dataLayer; blockLight[alayer] = dataLayer;
@ -334,7 +317,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
@Override @Override
public CompoundTag getEntity(UUID uuid) { public CompoundTag getEntity(UUID uuid) {
Entity entity = serverLevel.getEntity(uuid); ensureLoaded(serverLevel, chunkX, chunkZ);
List<Entity> entities = PaperweightPlatformAdapter.getEntities(getChunk());
Entity entity = null;
for (Entity e : entities) {
if (e.getUUID().equals(uuid)) {
entity = e;
break;
}
}
if (entity != null) { if (entity != null) {
org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity(); org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity();
return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData(); return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData();
@ -349,6 +340,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
@Override @Override
public Set<CompoundTag> getEntities() { public Set<CompoundTag> getEntities() {
ensureLoaded(serverLevel, chunkX, chunkZ);
List<Entity> entities = PaperweightPlatformAdapter.getEntities(getChunk()); List<Entity> entities = PaperweightPlatformAdapter.getEntities(getChunk());
if (entities.isEmpty()) { if (entities.isEmpty()) {
return Collections.emptySet(); return Collections.emptySet();
@ -385,7 +377,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
public Iterator<CompoundTag> iterator() { public Iterator<CompoundTag> iterator() {
Iterable<CompoundTag> result = entities.stream().map(input -> { Iterable<CompoundTag> result = entities.stream().map(input -> {
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag(); net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
PaperweightPlatformAdapter.readEntityIntoTag(input, tag); input.save(tag);
return (CompoundTag) adapter.toNative(tag); return (CompoundTag) adapter.toNative(tag);
}).collect(Collectors.toList()); }).collect(Collectors.toList());
return result.iterator(); return result.iterator();
@ -474,7 +466,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
synchronized (super.sectionLocks[getSectionIndex]) { synchronized (super.sectionLocks[getSectionIndex]) {
LevelChunkSection existingSection = levelChunkSections[getSectionIndex]; LevelChunkSection existingSection = levelChunkSections[getSectionIndex];
if (createCopy && existingSection != null) { if (createCopy && existingSection != null) {
copy.storeBiomes(getSectionIndex, existingSection.getBiomes().copy()); copy.storeBiomes(getSectionIndex, existingSection.getBiomes());
} }
if (existingSection == null) { if (existingSection == null) {
@ -507,8 +499,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
} }
} else { } else {
PalettedContainer<Holder<Biome>> biomeData = existingSection.getBiomes(); setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes());
setBiomesToPalettedContainer(biomes[setSectionIndex], biomeData);
} }
} }
} }
@ -543,7 +534,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); System.arraycopy(tmpLoad, 0, copyArr, 0, 4096);
copy.storeSection(getSectionIndex, copyArr); copy.storeSection(getSectionIndex, copyArr);
if (biomes != null && existingSection != null) { if (biomes != null && existingSection != null) {
copy.storeBiomes(getSectionIndex, existingSection.getBiomes().copy()); copy.storeBiomes(getSectionIndex, existingSection.getBiomes());
} }
} }
@ -555,8 +546,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
.getBukkitImplAdapter() .getBukkitImplAdapter()
.getInternalBiomeId( .getInternalBiomeId(
BiomeTypes.PLAINS)), BiomeTypes.PLAINS)),
PalettedContainer.Strategy.SECTION_BIOMES, PalettedContainer.Strategy.SECTION_BIOMES
null
) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap);
newSection = PaperweightPlatformAdapter.newChunkSection( newSection = PaperweightPlatformAdapter.newChunkSection(
layerNo, layerNo,
@ -616,11 +606,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
sectionLock.writeLock().unlock(); sectionLock.writeLock().unlock();
} }
PalettedContainer<Holder<Biome>> biomeData = existingSection.getBiomes(); PalettedContainer<Holder<Biome>> biomeData = setBiomesToPalettedContainer(
biomes,
if (biomes != null && biomes[setSectionIndex] != null) { setSectionIndex,
setBiomesToPalettedContainer(biomes[setSectionIndex], biomeData); existingSection.getBiomes()
} );
newSection = newSection =
PaperweightPlatformAdapter.newChunkSection( PaperweightPlatformAdapter.newChunkSection(
@ -705,7 +695,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) { if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) {
for (UUID uuid : entityRemoves) { for (UUID uuid : entityRemoves) {
Entity entity = nmsWorld.entityManager.getEntityGetter().get(uuid); Entity entity = nmsWorld.getEntities().get(uuid);
if (entity != null) { if (entity != null) {
removeEntity(entity); removeEntity(entity);
} }
@ -783,9 +773,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) { for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
final CompoundTag nativeTag = entry.getValue(); final CompoundTag nativeTag = entry.getValue();
final BlockVector3 blockHash = entry.getKey(); final BlockVector3 blockHash = entry.getKey();
final int x = blockHash.getX() + bx; final int x = blockHash.x() + bx;
final int y = blockHash.getY(); final int y = blockHash.y();
final int z = blockHash.getZ() + bz; final int z = blockHash.z() + bz;
final BlockPos pos = new BlockPos(x, y, z); final BlockPos pos = new BlockPos(x, y, z);
synchronized (nmsWorld) { synchronized (nmsWorld) {
@ -800,7 +790,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
tag.put("x", IntTag.valueOf(x)); tag.put("x", IntTag.valueOf(x));
tag.put("y", IntTag.valueOf(y)); tag.put("y", IntTag.valueOf(y));
tag.put("z", IntTag.valueOf(z)); tag.put("z", IntTag.valueOf(z));
tileEntity.load(tag); tileEntity.loadWithComponents(tag, DedicatedServer.getServer().registryAccess());
} }
} }
} }
@ -1076,8 +1066,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData( ((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(
lightLayer, lightLayer,
sectionPos, sectionPos,
dataLayer, dataLayer
true
); );
} }
synchronized (dataLayer) { synchronized (dataLayer) {
@ -1095,22 +1084,35 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
} }
private void setBiomesToPalettedContainer( private PalettedContainer<Holder<Biome>> setBiomesToPalettedContainer(
final BiomeType[] biomes, final BiomeType[][] biomes,
PalettedContainer<Holder<Biome>> data final int sectionIndex,
final PalettedContainerRO<Holder<Biome>> data
) { ) {
int index = 0; PalettedContainer<Holder<Biome>> biomeData;
if (biomes == null) { if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
return; biomeData = palettedContainer;
} else {
LOGGER.warn(
"Cannot correctly set biomes to world, existing biomes may be lost. Expected class " +
"type {} but got {}",
PalettedContainer.class.getSimpleName(),
data.getClass().getSimpleName()
);
biomeData = data.recreate();
} }
for (int y = 0; y < 4; y++) { BiomeType[] sectionBiomes;
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return biomeData;
}
for (int y = 0, index = 0; y < 4; y++) {
for (int z = 0; z < 4; z++) { for (int z = 0; z < 4; z++) {
for (int x = 0; x < 4; x++, index++) { for (int x = 0; x < 4; x++, index++) {
BiomeType biomeType = biomes[index]; BiomeType biomeType = sectionBiomes[index];
if (biomeType == null) { if (biomeType == null) {
continue; continue;
} }
data.set( biomeData.set(
x, x,
y, y,
z, z,
@ -1122,6 +1124,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
} }
} }
return biomeData;
} }
@Override @Override

Datei anzeigen

@ -1,4 +1,4 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
import com.fastasyncworldedit.core.queue.IBlocks; import com.fastasyncworldedit.core.queue.IBlocks;
@ -8,19 +8,23 @@ import com.google.common.base.Suppliers;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.block.BlockTypesCache;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.PalettedContainer; import net.minecraft.world.level.chunk.PalettedContainer;
import net.minecraft.world.level.chunk.PalettedContainerRO;
import org.apache.logging.log4j.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Arrays; import java.util.Arrays;
@ -33,6 +37,8 @@ import java.util.concurrent.Future;
public class PaperweightGetBlocks_Copy implements IChunkGet { public class PaperweightGetBlocks_Copy implements IChunkGet {
private static final Logger LOGGER = LogManagerCompat.getLogger();
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>(); private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
private final Set<CompoundTag> entities = new HashSet<>(); private final Set<CompoundTag> entities = new HashSet<>();
private final char[][] blocks; private final char[][] blocks;
@ -57,7 +63,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
blockEntity.getBlockPos().getY(), blockEntity.getBlockPos().getY(),
blockEntity.getBlockPos().getZ() blockEntity.getBlockPos().getZ()
), ),
new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId)) new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.saveWithId(DedicatedServer.getServer().registryAccess())))
); );
} }
@ -76,7 +82,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
protected void storeEntity(Entity entity) { protected void storeEntity(Entity entity) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag(); net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag();
PaperweightPlatformAdapter.readEntityIntoTag(entity, compoundTag); entity.save(compoundTag);
entities.add((CompoundTag) adapter.toNative(compoundTag)); entities.add((CompoundTag) adapter.toNative(compoundTag));
} }
@ -166,11 +172,19 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
blocks[layer] = data; blocks[layer] = data;
} }
protected void storeBiomes(int layer, PalettedContainer<Holder<Biome>> biomeData) { protected void storeBiomes(int layer, PalettedContainerRO<Holder<Biome>> biomeData) {
if (biomes == null) { if (biomes == null) {
biomes = new PalettedContainer[getSectionCount()]; biomes = new PalettedContainer[getSectionCount()];
} }
biomes[layer] = biomeData; if (biomeData instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomes[layer] = palettedContainer.copy();
} else {
LOGGER.error(
"Cannot correctly save biomes to history. Expected class type {} but got {}",
PalettedContainer.class.getSimpleName(),
biomeData.getClass().getSimpleName()
);
}
} }
@Override @Override

Datei anzeigen

@ -1,4 +1,4 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil; import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil;
import com.sk89q.worldedit.bukkit.adapter.Refraction; import com.sk89q.worldedit.bukkit.adapter.Refraction;
@ -10,10 +10,10 @@ public class PaperweightMapChunkUtil extends MapChunkUtil<ClientboundLevelChunkW
public PaperweightMapChunkUtil() throws NoSuchFieldException { public PaperweightMapChunkUtil() throws NoSuchFieldException {
fieldX = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("TWO_MEGABYTES", "a")); fieldX = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("TWO_MEGABYTES", "a"));
fieldZ = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("x", "a")); fieldZ = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("x", "b"));
fieldBitMask = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("z", "b")); fieldBitMask = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("z", "c"));
fieldHeightMap = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("heightmaps", "b")); fieldHeightMap = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("heightmaps", "b"));
fieldChunkData = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("chunkData", "c")); fieldChunkData = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("chunkData", "d"));
fieldBlockEntities = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("buffer", "c")); fieldBlockEntities = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("buffer", "c"));
fieldFull = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("blockEntitiesData", "d")); fieldFull = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("blockEntitiesData", "d"));
fieldX.setAccessible(true); fieldX.setAccessible(true);

Datei anzeigen

@ -1,5 +1,6 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
import com.destroystokyo.paper.util.maplist.EntityList;
import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter; import com.fastasyncworldedit.bukkit.adapter.CachedBukkitAdapter;
import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore; import com.fastasyncworldedit.bukkit.adapter.DelegateSemaphore;
import com.fastasyncworldedit.bukkit.adapter.NMSAdapter; import com.fastasyncworldedit.bukkit.adapter.NMSAdapter;
@ -19,6 +20,7 @@ import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.block.BlockTypesCache;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import io.papermc.paper.world.ChunkEntitySlices;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.core.IdMap; import net.minecraft.core.IdMap;
@ -30,19 +32,19 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.level.TicketType; import net.minecraft.server.level.TicketType;
import net.minecraft.util.BitStorage; import net.minecraft.util.BitStorage;
import net.minecraft.util.ExceptionCollector;
import net.minecraft.util.SimpleBitStorage; import net.minecraft.util.SimpleBitStorage;
import net.minecraft.util.ThreadingDetector; import net.minecraft.util.ThreadingDetector;
import net.minecraft.util.Unit; import net.minecraft.util.Unit;
import net.minecraft.util.ZeroBitStorage; import net.minecraft.util.ZeroBitStorage;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.npc.AbstractVillager;
import net.minecraft.world.item.trading.MerchantOffers;
import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.GlobalPalette; import net.minecraft.world.level.chunk.GlobalPalette;
import net.minecraft.world.level.chunk.HashMapPalette; import net.minecraft.world.level.chunk.HashMapPalette;
import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunk;
@ -51,15 +53,17 @@ import net.minecraft.world.level.chunk.LinearPalette;
import net.minecraft.world.level.chunk.Palette; import net.minecraft.world.level.chunk.Palette;
import net.minecraft.world.level.chunk.PalettedContainer; import net.minecraft.world.level.chunk.PalettedContainer;
import net.minecraft.world.level.chunk.SingleValuePalette; import net.minecraft.world.level.chunk.SingleValuePalette;
import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_18_R2.CraftChunk; import org.bukkit.craftbukkit.CraftChunk;
import sun.misc.Unsafe;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
@ -79,6 +83,9 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
import java.util.function.Function; import java.util.function.Function;
import static java.lang.invoke.MethodType.methodType;
import static net.minecraft.core.registries.Registries.BIOME;
public final class PaperweightPlatformAdapter extends NMSAdapter { public final class PaperweightPlatformAdapter extends NMSAdapter {
public static final Field fieldData; public static final Field fieldData;
@ -100,14 +107,23 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final MethodHandle methodRemoveGameEventListener; private static final MethodHandle methodRemoveGameEventListener;
private static final MethodHandle methodremoveTickingBlockEntity; private static final MethodHandle methodremoveTickingBlockEntity;
private static final Field fieldOffers; /*
private static final MerchantOffers OFFERS = new MerchantOffers(); * This is a workaround for the changes from https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/1fddefce1cdce44010927b888432bf70c0e88cde#src/main/java/org/bukkit/craftbukkit/CraftChunk.java
* and is only needed to support 1.19.4 versions before *and* after this change.
*/
private static final MethodHandle CRAFT_CHUNK_GET_HANDLE;
private static final Field fieldRemove; private static final Field fieldRemove;
private static final Logger LOGGER = LogManagerCompat.getLogger(); private static final Logger LOGGER = LogManagerCompat.getLogger();
static final boolean POST_CHUNK_REWRITE;
private static Method PAPER_CHUNK_GEN_ALL_ENTITIES;
private static Field LEVEL_CHUNK_ENTITIES;
private static Field SERVER_LEVEL_ENTITY_MANAGER;
static { static {
final MethodHandles.Lookup lookup = MethodHandles.lookup();
try { try {
fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d")); fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d"));
fieldData.setAccessible(true); fieldData.setAccessible(true);
@ -121,11 +137,11 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
fieldPalette = dataClazz.getDeclaredField(Refraction.pickName("palette", "c")); fieldPalette = dataClazz.getDeclaredField(Refraction.pickName("palette", "c"));
fieldPalette.setAccessible(true); fieldPalette.setAccessible(true);
fieldTickingFluidCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "h")); fieldTickingFluidCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "g"));
fieldTickingFluidCount.setAccessible(true); fieldTickingFluidCount.setAccessible(true);
fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "g")); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f"));
fieldTickingBlockCount.setAccessible(true); fieldTickingBlockCount.setAccessible(true);
fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "f")); fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e"));
fieldNonEmptyBlockCount.setAccessible(true); fieldNonEmptyBlockCount.setAccessible(true);
Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName(
@ -133,7 +149,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
"b" "b"
), long.class); ), long.class);
getVisibleChunkIfPresent.setAccessible(true); getVisibleChunkIfPresent.setAccessible(true);
methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent); methodGetVisibleChunk = lookup.unreflect(getVisibleChunkIfPresent);
if (!PaperLib.isPaper()) { if (!PaperLib.isPaper()) {
fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f")); fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f"));
@ -147,31 +163,66 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
} }
Method removeGameEventListener = LevelChunk.class.getDeclaredMethod( Method removeGameEventListener = LevelChunk.class.getDeclaredMethod(
Refraction.pickName("removeGameEventListener", "d"), Refraction.pickName("removeGameEventListener", "a"),
BlockEntity.class BlockEntity.class,
ServerLevel.class
); );
removeGameEventListener.setAccessible(true); removeGameEventListener.setAccessible(true);
methodRemoveGameEventListener = MethodHandles.lookup().unreflect(removeGameEventListener); methodRemoveGameEventListener = lookup.unreflect(removeGameEventListener);
Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod( Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod(
Refraction.pickName( Refraction.pickName(
"removeBlockEntityTicker", "removeBlockEntityTicker",
"l" "k"
), BlockPos.class ), BlockPos.class
); );
removeBlockEntityTicker.setAccessible(true); removeBlockEntityTicker.setAccessible(true);
methodremoveTickingBlockEntity = MethodHandles.lookup().unreflect(removeBlockEntityTicker); methodremoveTickingBlockEntity = lookup.unreflect(removeBlockEntityTicker);
fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p")); fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p"));
fieldRemove.setAccessible(true); fieldRemove.setAccessible(true);
fieldOffers = AbstractVillager.class.getDeclaredField(Refraction.pickName("offers", "bW")); boolean chunkRewrite;
fieldOffers.setAccessible(true); try {
} catch (RuntimeException e) { ServerLevel.class.getDeclaredMethod("getEntityLookup");
throw e; chunkRewrite = true;
} catch (Throwable rethrow) { PAPER_CHUNK_GEN_ALL_ENTITIES = ChunkEntitySlices.class.getDeclaredMethod("getAllEntities");
rethrow.printStackTrace(); PAPER_CHUNK_GEN_ALL_ENTITIES.setAccessible(true);
throw new RuntimeException(rethrow); } catch (NoSuchMethodException ignored) {
chunkRewrite = false;
} }
try {
// Paper - Pre-Chunk-Update
LEVEL_CHUNK_ENTITIES = LevelChunk.class.getDeclaredField("entities");
LEVEL_CHUNK_ENTITIES.setAccessible(true);
} catch (NoSuchFieldException ignored) {
}
try {
// Non-Paper
SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField(Refraction.pickName("entityManager", "N"));
SERVER_LEVEL_ENTITY_MANAGER.setAccessible(true);
} catch (NoSuchFieldException ignored) {
}
POST_CHUNK_REWRITE = chunkRewrite;
} catch (RuntimeException | Error e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
MethodHandle craftChunkGetHandle;
final MethodType type = methodType(LevelChunk.class);
try {
craftChunkGetHandle = lookup.findVirtual(CraftChunk.class, "getHandle", type);
} catch (NoSuchMethodException | IllegalAccessException e) {
try {
final MethodType newType = methodType(ChunkAccess.class, ChunkStatus.class);
craftChunkGetHandle = lookup.findVirtual(CraftChunk.class, "getHandle", newType);
craftChunkGetHandle = MethodHandles.insertArguments(craftChunkGetHandle, 1, ChunkStatus.FULL);
} catch (NoSuchMethodException | IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
CRAFT_CHUNK_GET_HANDLE = craftChunkGetHandle;
} }
static boolean setSectionAtomic( static boolean setSectionAtomic(
@ -255,7 +306,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
throw new UnsupportedOperationException("Cannot load chunk from unloaded world " + world + "!"); throw new UnsupportedOperationException("Cannot load chunk from unloaded world " + world + "!");
} }
} }
return chunk.getHandle(); addTicket(serverLevel, chunkX, chunkZ);
return (LevelChunk) CRAFT_CHUNK_GET_HANDLE.invoke(chunk);
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -265,9 +317,9 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static void addTicket(ServerLevel serverLevel, int chunkX, int chunkZ) { private static void addTicket(ServerLevel serverLevel, int chunkX, int chunkZ) {
// Ensure chunk is definitely loaded before applying a ticket // Ensure chunk is definitely loaded before applying a ticket
net.minecraft.server.MCUtil.MAIN_EXECUTOR.execute(() -> serverLevel io.papermc.paper.util.MCUtil.MAIN_EXECUTOR.execute(() -> serverLevel
.getChunkSource() .getChunkSource()
.addRegionTicket(TicketType.PLUGIN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE)); .addRegionTicket(TicketType.UNLOAD_COOLDOWN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE));
} }
public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) { public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) {
@ -286,20 +338,19 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
return; return;
} }
ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ); ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ);
// UNLOADED_CHUNK LevelChunk levelChunk;
Optional<LevelChunk> optional = ((Either) chunkHolder
.getTickingChunkFuture()
.getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left();
if (PaperLib.isPaper()) { if (PaperLib.isPaper()) {
// getChunkAtIfLoadedImmediately is paper only // getChunkAtIfLoadedImmediately is paper only
optional = optional.or(() -> Optional.ofNullable(nmsWorld levelChunk = nmsWorld
.getChunkSource() .getChunkSource()
.getChunkAtIfLoadedImmediately(chunkX, chunkZ))); .getChunkAtIfLoadedImmediately(chunkX, chunkZ);
} else {
levelChunk = chunkHolder.getTickingChunkFuture()
.getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK).orElse(null);
} }
if (optional.isEmpty()) { if (levelChunk == null) {
return; return;
} }
LevelChunk levelChunk = optional.get();
TaskManager.taskManager().task(() -> { TaskManager.taskManager().task(() -> {
ClientboundLevelChunkWithLightPacket packet; ClientboundLevelChunkWithLightPacket packet;
if (PaperLib.isPaper()) { if (PaperLib.isPaper()) {
@ -307,9 +358,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
levelChunk, levelChunk,
nmsWorld.getChunkSource().getLightEngine(), nmsWorld.getChunkSource().getLightEngine(),
null, null,
null, null
true, // last false is to not bother with x-ray
false // last false is to not bother with x-ray
); );
} else { } else {
// deprecated on paper - deprecation suppressed // deprecated on paper - deprecation suppressed
@ -317,8 +367,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
levelChunk, levelChunk,
nmsWorld.getChunkSource().getLightEngine(), nmsWorld.getChunkSource().getLightEngine(),
null, null,
null, null
true
); );
} }
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet)); nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
@ -424,12 +473,11 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
.getBukkitImplAdapter() .getBukkitImplAdapter()
.getInternalBiomeId( .getInternalBiomeId(
BiomeTypes.PLAINS)), BiomeTypes.PLAINS)),
PalettedContainer.Strategy.SECTION_BIOMES, PalettedContainer.Strategy.SECTION_BIOMES
null
); );
} }
return new LevelChunkSection(layer, blockStatePalettedContainer, biomes); return new LevelChunkSection(blockStatePalettedContainer, biomes);
} catch (final Throwable e) { } catch (final Throwable e) {
throw e; throw e;
} finally { } finally {
@ -447,15 +495,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
@Nullable PalettedContainer<Holder<Biome>> biomes @Nullable PalettedContainer<Holder<Biome>> biomes
) { ) {
if (biomes == null) { if (biomes == null) {
return new LevelChunkSection(layer, biomeRegistry); return new LevelChunkSection(biomeRegistry);
} }
PalettedContainer<net.minecraft.world.level.block.state.BlockState> dataPaletteBlocks = new PalettedContainer<>( PalettedContainer<net.minecraft.world.level.block.state.BlockState> dataPaletteBlocks = new PalettedContainer<>(
Block.BLOCK_STATE_REGISTRY, Block.BLOCK_STATE_REGISTRY,
Blocks.AIR.defaultBlockState(), Blocks.AIR.defaultBlockState(),
PalettedContainer.Strategy.SECTION_STATES, PalettedContainer.Strategy.SECTION_STATES
null
); );
return new LevelChunkSection(layer, dataPaletteBlocks, biomes); return new LevelChunkSection(dataPaletteBlocks, biomes);
} }
/** /**
@ -492,8 +539,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
PalettedContainer<Holder<Biome>> biomePalettedContainer = new PalettedContainer<>( PalettedContainer<Holder<Biome>> biomePalettedContainer = new PalettedContainer<>(
biomeRegistry, biomeRegistry,
biomeRegistry.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), biomeRegistry.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)),
PalettedContainer.Strategy.SECTION_BIOMES, PalettedContainer.Strategy.SECTION_BIOMES
null
); );
final Palette<Holder<Biome>> biomePalette; final Palette<Holder<Biome>> biomePalette;
@ -571,7 +617,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
} }
public static BiomeType adapt(Holder<Biome> biome, LevelAccessor levelAccessor) { public static BiomeType adapt(Holder<Biome> biome, LevelAccessor levelAccessor) {
final Registry<Biome> biomeRegistry = levelAccessor.registryAccess().ownedRegistryOrThrow(Registry.BIOME_REGISTRY); final Registry<Biome> biomeRegistry = levelAccessor.registryAccess().registryOrThrow(BIOME);
if (biomeRegistry.getKey(biome.value()) == null) { if (biomeRegistry.getKey(biome.value()) == null) {
return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN
: null; : null;
@ -581,13 +627,11 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) { static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) {
try { try {
// Do the method ourselves to avoid trying to reflect generic method parameters
// similar to removeGameEventListener
if (levelChunk.loaded || levelChunk.level.isClientSide()) { if (levelChunk.loaded || levelChunk.level.isClientSide()) {
BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos()); BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos());
if (blockEntity != null) { if (blockEntity != null) {
if (!levelChunk.level.isClientSide) { if (!levelChunk.level.isClientSide) {
methodRemoveGameEventListener.invoke(levelChunk, beacon); methodRemoveGameEventListener.invoke(levelChunk, beacon, levelChunk.level);
} }
fieldRemove.set(beacon, true); fieldRemove.set(beacon, true);
} }
@ -599,30 +643,32 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
} }
static List<Entity> getEntities(LevelChunk chunk) { static List<Entity> getEntities(LevelChunk chunk) {
return chunk.level.entityManager.getEntities(chunk.getPos()); ExceptionCollector<RuntimeException> collector = new ExceptionCollector<>();
} if (PaperLib.isPaper()) {
if (POST_CHUNK_REWRITE) {
public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
boolean isVillager = entity instanceof AbstractVillager && !Fawe.isMainThread();
boolean unset = false;
if (isVillager) {
try { try {
if (fieldOffers.get(entity) != null) { //noinspection unchecked
fieldOffers.set(entity, OFFERS); return (List<Entity>) PAPER_CHUNK_GEN_ALL_ENTITIES.invoke(chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ));
unset = true; } catch (IllegalAccessException | InvocationTargetException e) {
} throw new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=true]", e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to set offers field to villager to avoid async catcher.", e);
} }
} }
entity.save(compoundTag);
if (unset) {
try { try {
fieldOffers.set(entity, null); EntityList entityList = (EntityList) LEVEL_CHUNK_ENTITIES.get(chunk);
return List.of(entityList.getRawData());
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new RuntimeException("Failed to set offers field to null again on villager.", e); collector.add(new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=false]", e));
// fall through
} }
} }
try {
//noinspection unchecked
return ((PersistentEntitySectionManager<Entity>) (SERVER_LEVEL_ENTITY_MANAGER.get(chunk.level))).getEntities(chunk.getPos());
} catch (IllegalAccessException e) {
collector.add(new RuntimeException("Failed to lookup entities [PAPER=false]", e));
}
collector.throwIfPresent();
return List.of();
} }
record FakeIdMapBlock(int size) implements IdMap<net.minecraft.world.level.block.state.BlockState> { record FakeIdMapBlock(int size) implements IdMap<net.minecraft.world.level.block.state.BlockState> {

Datei anzeigen

@ -1,4 +1,4 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.configuration.Settings;
import com.fastasyncworldedit.core.extent.processor.ProcessorScope; import com.fastasyncworldedit.core.extent.processor.ProcessorScope;

Datei anzeigen

@ -1,14 +1,14 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter; import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter;
import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.configuration.Settings;
import com.fastasyncworldedit.core.queue.IQueueExtent; import com.fastasyncworldedit.core.queue.IQueueExtent;
import net.minecraft.server.MCUtil; import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.TicketType; import net.minecraft.server.level.TicketType;
import net.minecraft.util.Unit; import net.minecraft.util.Unit;
import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.status.ChunkStatus;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -18,7 +18,7 @@ import java.util.function.IntConsumer;
public class PaperweightStarlightRelighter extends StarlightRelighter<ServerLevel, ChunkPos> { public class PaperweightStarlightRelighter extends StarlightRelighter<ServerLevel, ChunkPos> {
private static final TicketType<Unit> FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0); private static final TicketType<Unit> FAWE_TICKET = TicketType.create("fawe_ticket", (a, b) -> 0);
private static final int LIGHT_LEVEL = MCUtil.getTicketLevelFor(ChunkStatus.LIGHT); private static final int LIGHT_LEVEL = ChunkMap.MAX_VIEW_DISTANCE + ChunkStatus.getDistance(ChunkStatus.LIGHT);
public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent<?> queue) { public PaperweightStarlightRelighter(ServerLevel serverLevel, IQueueExtent<?> queue) {
super(serverLevel, queue); super(serverLevel, queue);

Datei anzeigen

@ -1,4 +1,4 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2; package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter; import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter;
import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode; import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode;
@ -7,7 +7,7 @@ import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
import com.fastasyncworldedit.core.queue.IQueueExtent; import com.fastasyncworldedit.core.queue.IQueueExtent;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; import org.bukkit.craftbukkit.CraftWorld;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;

Datei anzeigen

@ -1,4 +1,4 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt; package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.LazyCompoundTag; import com.sk89q.jnbt.LazyCompoundTag;

Datei anzeigen

@ -1,17 +1,15 @@
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.regen; package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.regen;
import com.fastasyncworldedit.bukkit.adapter.Regenerator; import com.fastasyncworldedit.bukkit.adapter.Regenerator;
import com.fastasyncworldedit.core.Fawe; import com.fastasyncworldedit.core.Fawe;
import com.fastasyncworldedit.core.queue.IChunkCache; import com.fastasyncworldedit.core.queue.IChunkCache;
import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkGet;
import com.fastasyncworldedit.core.util.ReflectionUtils;
import com.fastasyncworldedit.core.util.TaskManager; import com.fastasyncworldedit.core.util.TaskManager;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Lifecycle; import com.mojang.serialization.Lifecycle;
import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.Refraction; import com.sk89q.worldedit.bukkit.adapter.Refraction;
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.PaperweightGetBlocks; import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.PaperweightGetBlocks;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
@ -20,14 +18,19 @@ import com.sk89q.worldedit.world.RegenOptions;
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.data.BuiltinRegistries; import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ChunkTaskPriorityQueueSorter.Message;
import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ThreadedLevelLightEngine; import net.minecraft.server.level.ThreadedLevelLightEngine;
import net.minecraft.server.level.progress.ChunkProgressListener; import net.minecraft.server.level.progress.ChunkProgressListener;
import net.minecraft.util.thread.ProcessorHandle;
import net.minecraft.util.thread.ProcessorMailbox;
import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelHeightAccessor; import net.minecraft.world.level.LevelHeightAccessor;
@ -37,31 +40,34 @@ import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.biome.FixedBiomeSource; import net.minecraft.world.level.biome.FixedBiomeSource;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator; import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.ChunkGeneratorStructureState;
import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.ProtoChunk; import net.minecraft.world.level.chunk.ProtoChunk;
import net.minecraft.world.level.chunk.UpgradeData; import net.minecraft.world.level.chunk.UpgradeData;
import net.minecraft.world.level.chunk.status.ChunkStatus;
import net.minecraft.world.level.chunk.status.WorldGenContext;
import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.dimension.LevelStem;
import net.minecraft.world.level.levelgen.FlatLevelSource; import net.minecraft.world.level.levelgen.FlatLevelSource;
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator; import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings; import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
import net.minecraft.world.level.levelgen.WorldGenSettings; import net.minecraft.world.level.levelgen.WorldOptions;
import net.minecraft.world.level.levelgen.blending.BlendingData; import net.minecraft.world.level.levelgen.blending.BlendingData;
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings; import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement; import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.storage.PrimaryLevelData; import net.minecraft.world.level.storage.PrimaryLevelData;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_18_R2.CraftServer; import org.bukkit.Chunk;
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.v1_18_R2.generator.CustomChunkGenerator; import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.generator.CustomChunkGenerator;
import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.BlockPopulator;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Collections; import java.util.Collections;
@ -74,6 +80,8 @@ import java.util.concurrent.CompletableFuture;
import java.util.function.BooleanSupplier; import java.util.function.BooleanSupplier;
import java.util.function.Supplier; import java.util.function.Supplier;
import static net.minecraft.core.registries.Registries.BIOME;
public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, LevelChunk, PaperweightRegen.ChunkStatusWrap> { public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, LevelChunk, PaperweightRegen.ChunkStatusWrap> {
private static final Logger LOGGER = LogManagerCompat.getLogger(); private static final Logger LOGGER = LogManagerCompat.getLogger();
@ -85,6 +93,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
private static final Field generatorSettingBaseSupplierField; private static final Field generatorSettingBaseSupplierField;
private static final Field delegateField; private static final Field delegateField;
private static final Field chunkSourceField; private static final Field chunkSourceField;
private static final Field generatorStructureStateField;
private static final Field ringPositionsField; private static final Field ringPositionsField;
private static final Field hasGeneratedPositionsField; private static final Field hasGeneratedPositionsField;
@ -96,23 +105,22 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
chunkStati.put(ChunkStatus.STRUCTURE_STARTS, Concurrency.NONE); // structure starts: uses unsynchronized maps chunkStati.put(ChunkStatus.STRUCTURE_STARTS, Concurrency.NONE); // structure starts: uses unsynchronized maps
chunkStati.put( chunkStati.put(
ChunkStatus.STRUCTURE_REFERENCES, ChunkStatus.STRUCTURE_REFERENCES,
Concurrency.FULL Concurrency.NONE
); // structure refs: radius 8, but only writes to current chunk ); // structure refs: radius 8, but only writes to current chunk
chunkStati.put(ChunkStatus.BIOMES, Concurrency.FULL); // biomes: radius 0 chunkStati.put(ChunkStatus.BIOMES, Concurrency.NONE); // biomes: radius 0
chunkStati.put(ChunkStatus.NOISE, Concurrency.RADIUS); // noise: radius 8 chunkStati.put(ChunkStatus.NOISE, Concurrency.RADIUS); // noise: radius 8
chunkStati.put(ChunkStatus.SURFACE, Concurrency.NONE); // surface: radius 0, requires NONE 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.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.FEATURES, Concurrency.NONE); // features: uses unsynchronized maps
chunkStati.put(
ChunkStatus.INITIALIZE_LIGHT,
Concurrency.FULL
); // initialize_light: radius 0
chunkStati.put( chunkStati.put(
ChunkStatus.LIGHT, ChunkStatus.LIGHT,
Concurrency.FULL Concurrency.FULL
); // light: radius 1, but no writes to other chunks, only current chunk ); // light: radius 1, but no writes to other chunks, only current chunk
chunkStati.put(ChunkStatus.SPAWN, Concurrency.FULL); // spawn: radius 0 chunkStati.put(ChunkStatus.SPAWN, Concurrency.NONE); // spawn: radius 0
chunkStati.put(ChunkStatus.HEIGHTMAPS, Concurrency.FULL); // heightmaps: radius 0
try { try {
serverWorldsField = CraftServer.class.getDeclaredField("worlds"); serverWorldsField = CraftServer.class.getDeclaredField("worlds");
@ -134,22 +142,27 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
flatBedrockField = tmpFlatBedrockField; flatBedrockField = tmpFlatBedrockField;
generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName( generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName(
"settings", "h")); "settings", "e"));
generatorSettingBaseSupplierField.setAccessible(true); generatorSettingBaseSupplierField.setAccessible(true);
generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "g")); generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "d"));
generatorSettingFlatField.setAccessible(true); generatorSettingFlatField.setAccessible(true);
delegateField = CustomChunkGenerator.class.getDeclaredField("delegate"); delegateField = CustomChunkGenerator.class.getDeclaredField("delegate");
delegateField.setAccessible(true); delegateField.setAccessible(true);
chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "K")); chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "I"));
chunkSourceField.setAccessible(true); chunkSourceField.setAccessible(true);
ringPositionsField = ChunkGenerator.class.getDeclaredField(Refraction.pickName("ringPositions", "h")); generatorStructureStateField = ChunkMap.class.getDeclaredField(Refraction.pickName("chunkGeneratorState", "v"));
generatorStructureStateField.setAccessible(true);
ringPositionsField = ChunkGeneratorStructureState.class.getDeclaredField(Refraction.pickName("ringPositions", "g"));
ringPositionsField.setAccessible(true); ringPositionsField.setAccessible(true);
hasGeneratedPositionsField = ChunkGenerator.class.getDeclaredField(Refraction.pickName("hasGeneratedPositions", "i")); hasGeneratedPositionsField = ChunkGeneratorStructureState.class.getDeclaredField(
Refraction.pickName("hasGeneratedPositions", "h")
);
hasGeneratedPositionsField.setAccessible(true); hasGeneratedPositionsField.setAccessible(true);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -162,9 +175,10 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
private ServerLevel freshWorld; private ServerLevel freshWorld;
private ServerChunkCache freshChunkProvider; private ServerChunkCache freshChunkProvider;
private LevelStorageSource.LevelStorageAccess session; private LevelStorageSource.LevelStorageAccess session;
private StructureManager structureManager; private StructureTemplateManager structureTemplateManager;
private ThreadedLevelLightEngine threadedLevelLightEngine; private ThreadedLevelLightEngine threadedLevelLightEngine;
private ChunkGenerator chunkGenerator; private ChunkGenerator chunkGenerator;
private WorldGenContext worldGenContext;
private Path tempDir; private Path tempDir;
@ -207,12 +221,10 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey); session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey);
PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData; PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData;
BiomeProvider biomeProvider = getBiomeProvider();
MinecraftServer server = originalServerWorld.getCraftServer().getServer(); MinecraftServer server = originalServerWorld.getCraftServer().getServer();
WorldGenSettings originalOpts = originalWorldData.worldGenSettings(); WorldOptions originalOpts = originalWorldData.worldGenOptions();
WorldGenSettings newOpts = options.getSeed().isPresent() WorldOptions newOpts = options.getSeed().isPresent()
? originalOpts.withSeed(originalWorldData.isHardcore(), OptionalLong.of(seed)) ? originalOpts.withSeed(OptionalLong.of(seed))
: originalOpts; : originalOpts;
LevelSettings newWorldSettings = new LevelSettings( LevelSettings newWorldSettings = new LevelSettings(
"faweregentempworld", "faweregentempworld",
@ -221,9 +233,19 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
originalWorldData.settings.difficulty(), originalWorldData.settings.difficulty(),
originalWorldData.settings.allowCommands(), originalWorldData.settings.allowCommands(),
originalWorldData.settings.gameRules(), originalWorldData.settings.gameRules(),
originalWorldData.settings.getDataPackConfig() originalWorldData.settings.getDataConfiguration()
); );
PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, Lifecycle.stable());
PrimaryLevelData.SpecialWorldProperty specialWorldProperty =
originalWorldData.isFlatWorld()
? PrimaryLevelData.SpecialWorldProperty.FLAT
: originalWorldData.isDebugWorld()
? PrimaryLevelData.SpecialWorldProperty.DEBUG
: PrimaryLevelData.SpecialWorldProperty.NONE;
PrimaryLevelData newWorldData = new PrimaryLevelData(newWorldSettings, newOpts, specialWorldProperty, Lifecycle.stable());
BiomeProvider biomeProvider = getBiomeProvider();
//init world //init world
freshWorld = Fawe.instance().getQueueHandler().sync((Supplier<ServerLevel>) () -> new ServerLevel( freshWorld = Fawe.instance().getQueueHandler().sync((Supplier<ServerLevel>) () -> new ServerLevel(
@ -232,66 +254,70 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
session, session,
newWorldData, newWorldData,
originalServerWorld.dimension(), originalServerWorld.dimension(),
originalServerWorld.dimensionTypeRegistration(), DedicatedServer.getServer().registryAccess().registry(Registries.LEVEL_STEM).orElseThrow()
.getOrThrow(levelStemResourceKey),
new RegenNoOpWorldLoadListener(), new RegenNoOpWorldLoadListener(),
// placeholder. Required for new ChunkProviderServer, but we create and then set it later
newOpts.dimensions().getOrThrow(levelStemResourceKey).generator(),
originalServerWorld.isDebug(), originalServerWorld.isDebug(),
seed, seed,
ImmutableList.of(), ImmutableList.of(),
false, false,
originalServerWorld.getRandomSequences(),
environment, environment,
generator, generator,
biomeProvider biomeProvider
) { ) {
private final Holder<Biome> singleBiome = options.hasBiomeType() ? BuiltinRegistries.BIOME.asHolderIdMap().byId(
private final Holder<Biome> singleBiome = options.hasBiomeType() ? DedicatedServer.getServer().registryAccess()
.registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow(
WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()) WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())
) : null; ) : null;
@Override @Override
public void tick(BooleanSupplier shouldKeepTicking) { //no ticking public void tick(@NotNull BooleanSupplier shouldKeepTicking) { //no ticking
} }
@Override @Override
public Holder<Biome> getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) { public @NotNull Holder<Biome> getUncachedNoiseBiome(int biomeX, int biomeY, int biomeZ) {
if (options.hasBiomeType()) { if (options.hasBiomeType()) {
return singleBiome; return singleBiome;
} }
return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome(biomeX, biomeY, biomeZ, return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome(
PaperweightRegen.this.chunkGenerator.climateSampler() biomeX, biomeY, biomeZ, getChunkSource().randomState().sampler()
); );
} }
}).get(); }).get();
freshWorld.noSave = true; freshWorld.noSave = true;
removeWorldFromWorldsMap(); removeWorldFromWorldsMap();
newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name
if (paperConfigField != null) { if (paperConfigField != null) {
paperConfigField.set(freshWorld, originalServerWorld.paperConfig); paperConfigField.set(freshWorld, originalServerWorld.paperConfig());
} }
//generator
ChunkGenerator originalGenerator = originalChunkProvider.getGenerator(); ChunkGenerator originalGenerator = originalChunkProvider.getGenerator();
if (originalGenerator instanceof FlatLevelSource flatLevelSource) { if (originalGenerator instanceof FlatLevelSource flatLevelSource) {
FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings(); FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings();
chunkGenerator = new FlatLevelSource(originalGenerator.structureSets, generatorSettingFlat); chunkGenerator = new FlatLevelSource(generatorSettingFlat);
} else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) { } else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
Holder<NoiseGeneratorSettings> generatorSettingBaseSupplier = Holder<NoiseGeneratorSettings> generatorSettingBaseSupplier = (Holder<NoiseGeneratorSettings>)
(Holder<NoiseGeneratorSettings>) generatorSettingBaseSupplierField generatorSettingBaseSupplierField.get(noiseBasedChunkGenerator);
.get(originalGenerator);
BiomeSource biomeSource; BiomeSource biomeSource;
if (options.hasBiomeType()) { if (options.hasBiomeType()) {
biomeSource = new FixedBiomeSource(BuiltinRegistries.BIOME biomeSource = new FixedBiomeSource(
.asHolderIdMap() DedicatedServer.getServer().registryAccess()
.byId(WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType()))); .registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow(
WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())
)
);
} else { } else {
biomeSource = originalGenerator.getBiomeSource(); biomeSource = originalGenerator.getBiomeSource();
} }
chunkGenerator = new NoiseBasedChunkGenerator(originalGenerator.structureSets, noiseBasedChunkGenerator.noises, chunkGenerator = new NoiseBasedChunkGenerator(
biomeSource, seed, biomeSource,
generatorSettingBaseSupplier generatorSettingBaseSupplier
); );
} else if (originalGenerator instanceof CustomChunkGenerator customChunkGenerator) { } else if (originalGenerator instanceof CustomChunkGenerator customChunkGenerator) {
chunkGenerator = customChunkGenerator.delegate; chunkGenerator = customChunkGenerator.getDelegate();
} else { } else {
LOGGER.error("Unsupported generator type {}", originalGenerator.getClass().getName()); LOGGER.error("Unsupported generator type {}", originalGenerator.getClass().getName());
return false; return false;
@ -300,22 +326,8 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator); chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator);
generateConcurrent = generator.isParallelCapable(); generateConcurrent = generator.isParallelCapable();
} }
// chunkGenerator.conf = freshWorld.spigotConfig; - Does not exist anymore, may need to be re-addressed
if (seed == originalOpts.seed() && !options.hasBiomeType()) {
// Optimisation for needless ring position calculation when the seed and biome is the same.
boolean hasGeneratedPositions = hasGeneratedPositionsField.getBoolean(originalGenerator);
if (hasGeneratedPositions) {
Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> ringPositions =
(Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>>) ringPositionsField.get(
originalGenerator);
Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> copy = new Object2ObjectArrayMap<>(ringPositions);
ringPositionsField.set(chunkGenerator, copy);
hasGeneratedPositionsField.setBoolean(chunkGenerator, true);
}
}
chunkGenerator.conf = originalServerWorld.spigotConfig;
freshChunkProvider = new ServerChunkCache( freshChunkProvider = new ServerChunkCache(
freshWorld, freshWorld,
session, session,
@ -333,7 +345,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
) { ) {
// redirect to LevelChunks created in #createChunks // redirect to LevelChunks created in #createChunks
@Override @Override
public ChunkAccess getChunk(int x, int z, ChunkStatus chunkstatus, boolean create) { public ChunkAccess getChunk(int x, int z, @NotNull ChunkStatus chunkstatus, boolean create) {
ChunkAccess chunkAccess = getChunkAt(x, z); ChunkAccess chunkAccess = getChunkAt(x, z);
if (chunkAccess == null && create) { if (chunkAccess == null && create) {
chunkAccess = createChunk(getProtoChunkAt(x, z)); chunkAccess = createChunk(getProtoChunkAt(x, z));
@ -342,11 +354,32 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
} }
}; };
if (seed == originalOpts.seed() && !options.hasBiomeType()) {
// Optimisation for needless ring position calculation when the seed and biome is the same.
ChunkGeneratorStructureState state = (ChunkGeneratorStructureState) generatorStructureStateField.get(
originalChunkProvider.chunkMap);
boolean hasGeneratedPositions = hasGeneratedPositionsField.getBoolean(state);
if (hasGeneratedPositions) {
Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> origPositions =
(Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>>) ringPositionsField.get(state);
Map<ConcentricRingsStructurePlacement, CompletableFuture<List<ChunkPos>>> copy = new Object2ObjectArrayMap<>(
origPositions);
ChunkGeneratorStructureState newState = (ChunkGeneratorStructureState) generatorStructureStateField.get(
freshChunkProvider.chunkMap);
ringPositionsField.set(newState, copy);
hasGeneratedPositionsField.setBoolean(newState, true);
}
}
chunkSourceField.set(freshWorld, freshChunkProvider); chunkSourceField.set(freshWorld, freshChunkProvider);
//let's start then //let's start then
structureManager = server.getStructureManager(); structureTemplateManager = server.getStructureManager();
threadedLevelLightEngine = freshChunkProvider.getLightEngine(); threadedLevelLightEngine = new NoOpLightEngine(freshChunkProvider);
this.worldGenContext = new WorldGenContext(freshWorld, chunkGenerator, structureTemplateManager,
threadedLevelLightEngine
);
return true; return true;
} }
@ -362,7 +395,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
Fawe.instance().getQueueHandler().sync(() -> { Fawe.instance().getQueueHandler().sync(() -> {
try { try {
freshChunkProvider.close(false); freshChunkProvider.close(false);
} catch (IOException e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
}); });
@ -385,7 +418,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
@Override @Override
protected ProtoChunk createProtoChunk(int x, int z) { protected ProtoChunk createProtoChunk(int x, int z) {
return new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld, return new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld,
this.freshWorld.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), null this.freshWorld.registryAccess().registryOrThrow(BIOME), null
); );
} }
@ -411,7 +444,11 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
@Override @Override
protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) { protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) {
// BlockPopulator#populate has to be called synchronously for TileEntity access // BlockPopulator#populate has to be called synchronously for TileEntity access
TaskManager.taskManager().task(() -> blockPopulator.populate(freshWorld.getWorld(), random, levelChunk.getBukkitChunk())); TaskManager.taskManager().task(() -> {
final CraftWorld world = freshWorld.getWorld();
final Chunk chunk = world.getChunkAt(levelChunk.locX, levelChunk.locZ);
blockPopulator.populate(world, random, chunk);
});
} }
@Override @Override
@ -427,14 +464,12 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
//util //util
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void removeWorldFromWorldsMap() { private void removeWorldFromWorldsMap() {
Fawe.instance().getQueueHandler().sync(() -> {
try { try {
Map<String, org.bukkit.World> map = (Map<String, org.bukkit.World>) serverWorldsField.get(Bukkit.getServer()); Map<String, org.bukkit.World> map = (Map<String, org.bukkit.World>) serverWorldsField.get(Bukkit.getServer());
map.remove("faweregentempworld"); map.remove("faweregentempworld");
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
});
} }
private ResourceKey<LevelStem> getWorldDimKey(org.bukkit.World.Environment env) { private ResourceKey<LevelStem> getWorldDimKey(org.bukkit.World.Environment env) {
@ -451,11 +486,15 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
} }
@Override @Override
public void updateSpawnPos(ChunkPos spawnPos) { public void updateSpawnPos(@NotNull ChunkPos spawnPos) {
} }
@Override @Override
public void onStatusChange(ChunkPos pos, @Nullable ChunkStatus status) { public void onStatusChange(
final @NotNull ChunkPos pos,
@org.jetbrains.annotations.Nullable final net.minecraft.world.level.chunk.status.ChunkStatus status
) {
} }
@Override @Override
@ -487,15 +526,14 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
// avoid warning on paper // avoid warning on paper
// compatibility with spigot @SuppressWarnings("unused") // compatibility with spigot
public boolean generateFlatBedrock() { public boolean generateFlatBedrock() {
return generateFlatBedrock; return generateFlatBedrock;
} }
// no one will ever see the entities! // no one will ever see the entities!
@Override @Override
public List<CompoundTag> getEntities() { public @NotNull List<CompoundTag> getEntities() {
return Collections.emptyList(); return Collections.emptyList();
} }
@ -516,23 +554,41 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
@Override @Override
public String name() { public String name() {
return chunkStatus.getName(); return chunkStatus.toString();
} }
@Override @Override
public CompletableFuture<?> processChunk(List<ChunkAccess> accessibleChunks) { public CompletableFuture<?> processChunk(List<ChunkAccess> accessibleChunks) {
return chunkStatus.generate( return chunkStatus.generate(
Runnable::run, // TODO revisit, we might profit from this somehow? worldGenContext,
freshWorld, Runnable::run,
chunkGenerator, CompletableFuture::completedFuture,
structureManager, accessibleChunks
threadedLevelLightEngine,
c -> CompletableFuture.completedFuture(Either.left(c)),
accessibleChunks,
true
); );
} }
} }
/**
* A light engine that does nothing. As light is calculated after pasting anyway, we can avoid
* work this way.
*/
static class NoOpLightEngine extends ThreadedLevelLightEngine {
private static final ProcessorMailbox<Runnable> MAILBOX = ProcessorMailbox.create(task -> {
}, "fawe-no-op");
private static final ProcessorHandle<Message<Runnable>> HANDLE = ProcessorHandle.of("fawe-no-op", m -> {
});
public NoOpLightEngine(final ServerChunkCache chunkProvider) {
super(chunkProvider, chunkProvider.chunkMap, false, MAILBOX, HANDLE);
}
@Override
public @NotNull CompletableFuture<ChunkAccess> lightChunk(final @NotNull ChunkAccess chunk, final boolean excludeBlocks) {
return CompletableFuture.completedFuture(chunk);
}
}
} }

Datei anzeigen

@ -36,6 +36,7 @@ repositories {
name = "Glaremasters" name = "Glaremasters"
url = uri("https://repo.glaremasters.me/repository/towny/") url = uri("https://repo.glaremasters.me/repository/towny/")
} }
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") // TODO Remove when 4.17.0 is released
flatDir { dir(File("src/main/resources")) } flatDir { dir(File("src/main/resources")) }
} }
@ -169,7 +170,7 @@ tasks.named<ShadowJar>("shadowJar") {
include(dependency("it.unimi.dsi:fastutil")) include(dependency("it.unimi.dsi:fastutil"))
} }
relocate("org.incendo.serverlib", "com.fastasyncworldedit.serverlib") { relocate("org.incendo.serverlib", "com.fastasyncworldedit.serverlib") {
include(dependency("dev.notmyfault.serverlib:ServerLib:2.3.4")) include(dependency("dev.notmyfault.serverlib:ServerLib:2.3.6"))
} }
relocate("com.intellectualsites.paster", "com.fastasyncworldedit.paster") { relocate("com.intellectualsites.paster", "com.fastasyncworldedit.paster") {
include(dependency("com.intellectualsites.paster:Paster")) include(dependency("com.intellectualsites.paster:Paster"))
@ -178,7 +179,7 @@ tasks.named<ShadowJar>("shadowJar") {
include(dependency("org.lz4:lz4-java:1.8.0")) include(dependency("org.lz4:lz4-java:1.8.0"))
} }
relocate("net.kyori", "com.fastasyncworldedit.core.adventure") { relocate("net.kyori", "com.fastasyncworldedit.core.adventure") {
include(dependency("net.kyori:adventure-nbt:4.16.0")) include(dependency("net.kyori:adventure-nbt:4.17.0"))
} }
relocate("com.zaxxer", "com.fastasyncworldedit.core.math") { relocate("com.zaxxer", "com.fastasyncworldedit.core.math") {
include(dependency("com.zaxxer:SparseBitSet:1.3")) include(dependency("com.zaxxer:SparseBitSet:1.3"))
@ -210,7 +211,7 @@ tasks {
versionNumber.set("${project.version}") versionNumber.set("${project.version}")
versionType.set("release") versionType.set("release")
uploadFile.set(file("build/libs/${rootProject.name}-Bukkit-${project.version}.jar")) uploadFile.set(file("build/libs/${rootProject.name}-Bukkit-${project.version}.jar"))
gameVersions.addAll(listOf("1.20.4", "1.20.3", "1.20.2", "1.20.1", "1.20", "1.19.4", "1.18.2")) gameVersions.addAll(listOf("1.20.6", "1.20.5", "1.20.3", "1.20.2", "1.20.1", "1.20", "1.19.4"))
loaders.addAll(listOf("paper", "spigot")) loaders.addAll(listOf("paper", "spigot"))
changelog.set("The changelog is available on GitHub: https://github.com/IntellectualSites/" + changelog.set("The changelog is available on GitHub: https://github.com/IntellectualSites/" +
"FastAsyncWorldEdit/releases/tag/${project.version}") "FastAsyncWorldEdit/releases/tag/${project.version}")

Datei anzeigen

@ -31,6 +31,8 @@ import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes; import com.sk89q.worldedit.world.item.ItemTypes;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.TreeType; import org.bukkit.TreeType;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
@ -97,7 +99,7 @@ public interface IBukkitAdapter {
checkNotNull(position); checkNotNull(position);
return new org.bukkit.Location( return new org.bukkit.Location(
world, world,
position.getX(), position.getY(), position.getZ() position.x(), position.y(), position.z()
); );
} }
@ -117,7 +119,7 @@ public interface IBukkitAdapter {
checkNotNull(location); checkNotNull(location);
return new org.bukkit.Location( return new org.bukkit.Location(
world, world,
location.getX(), location.getY(), location.getZ(), location.x(), location.y(), location.z(),
location.getYaw(), location.getYaw(),
location.getPitch() location.getPitch()
); );
@ -186,10 +188,12 @@ public interface IBukkitAdapter {
} }
default org.bukkit.entity.EntityType adapt(EntityType entityType) { default org.bukkit.entity.EntityType adapt(EntityType entityType) {
if (!entityType.getId().startsWith("minecraft:")) { NamespacedKey entityKey = NamespacedKey.fromString(entityType.toString());
throw new IllegalArgumentException("Bukkit only supports vanilla entities"); if (entityKey == null) {
throw new IllegalArgumentException("Entity key '" + entityType + "' does not map to Bukkit");
} }
return org.bukkit.entity.EntityType.fromName(entityType.getId().substring(10).toLowerCase(Locale.ROOT));
return Registry.ENTITY_TYPE.get(entityKey);
} }
/** /**
@ -343,7 +347,7 @@ public interface IBukkitAdapter {
* @return WorldEdit EntityType * @return WorldEdit EntityType
*/ */
default EntityType adapt(org.bukkit.entity.EntityType entityType) { default EntityType adapt(org.bukkit.entity.EntityType entityType) {
return EntityTypes.get(entityType.getName().toLowerCase(Locale.ROOT)); return EntityTypes.get(entityType.getKey().toString());
} }
/** /**

Datei anzeigen

@ -5,6 +5,7 @@ import com.fastasyncworldedit.core.queue.IChunkCache;
import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkGet;
import com.fastasyncworldedit.core.queue.implementation.SingleThreadQueueExtent; import com.fastasyncworldedit.core.queue.implementation.SingleThreadQueueExtent;
import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.MathMan;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
@ -24,11 +25,16 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongArrayList; import it.unimi.dsi.fastutil.longs.LongArrayList;
import it.unimi.dsi.fastutil.longs.LongList; import it.unimi.dsi.fastutil.longs.LongList;
import jdk.jfr.Category;
import jdk.jfr.Event;
import jdk.jfr.Label;
import jdk.jfr.Name;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.WorldInfo; import org.bukkit.generator.WorldInfo;
import java.util.AbstractList;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -36,6 +42,7 @@ import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Random; import java.util.Random;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@ -62,7 +69,7 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
protected final RegenOptions options; protected final RegenOptions options;
//runtime //runtime
protected final Map<ChunkStatus, Concurrency> chunkStatuses = new LinkedHashMap<>(); protected final LinkedHashMap<ChunkStatus, Concurrency> chunkStatuses = new LinkedHashMap<>(); // TODO (j21): use SequencedMap
private final Long2ObjectLinkedOpenHashMap<ProtoChunk> protoChunks = new Long2ObjectLinkedOpenHashMap<>(); private final Long2ObjectLinkedOpenHashMap<ProtoChunk> protoChunks = new Long2ObjectLinkedOpenHashMap<>();
private final Long2ObjectOpenHashMap<Chunk> chunks = new Long2ObjectOpenHashMap<>(); private final Long2ObjectOpenHashMap<Chunk> chunks = new Long2ObjectOpenHashMap<>();
protected boolean generateConcurrent = true; protected boolean generateConcurrent = true;
@ -172,51 +179,70 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
//TODO: can we get that required radius down without affecting chunk generation (e.g. strucures, features, ...)? //TODO: can we get that required radius down without affecting chunk generation (e.g. strucures, features, ...)?
//for now it is working well and fast, if we are bored in the future we could do the research (a lot of it) to reduce the border radius //for now it is working well and fast, if we are bored in the future we could do the research (a lot of it) to reduce the border radius
//generate chunk coords lists with a certain radius // to get the chunks we need to generate in the nth chunk status, we need to know how many chunks
Int2ObjectOpenHashMap<long[]> chunkCoordsForRadius = new Int2ObjectOpenHashMap<>(); // we need to generate in the n + 1 th chunk status. Summing up the margin solves that
chunkStatuses.keySet().stream().mapToInt(ChunkStatusWrapper::requiredNeighborChunkRadius0).distinct().forEach(radius -> { LinkedHashMap<ChunkStatus, long[]> chunkCoordsForChunkStatus = new LinkedHashMap<>();
if (radius == -1) { //ignore ChunkStatus.EMPTY int borderSum = 1;
return; // TODO (j21): use SequencedMap#sequencedKeySet().reversed()
final List<ChunkStatus> reversedKeys = Lists.reverse(new ArrayList<>(chunkStatuses.keySet()));
for (final ChunkStatus status : reversedKeys) {
chunkCoordsForChunkStatus.put(status, getChunkCoordsRegen(region, borderSum));
borderSum += status.requiredNeighborChunkRadius();
} }
int border = 10 - radius; //9 = 8 + 1, 8: max border radius used in chunk stages, 1: need 1 extra chunk for chunk
// features to generate at the border of the region
chunkCoordsForRadius.put(radius, getChunkCoordsRegen(region, border));
});
//create chunks //create chunks
for (long xz : chunkCoordsForRadius.get(0)) { // TODO (j21): use SequencedMap#firstEntry().getKey()
for (long xz : chunkCoordsForChunkStatus.get(chunkStatuses.keySet().iterator().next())) {
ProtoChunk chunk = createProtoChunk(MathMan.unpairIntX(xz), MathMan.unpairIntY(xz)); ProtoChunk chunk = createProtoChunk(MathMan.unpairIntX(xz), MathMan.unpairIntY(xz));
protoChunks.put(xz, chunk); protoChunks.put(xz, chunk);
} }
//generate lists for RegionLimitedWorldAccess, need to be square with odd length (e.g. 17x17), 17 = 1 middle chunk + 8 border chunks * 2 // a memory-efficient, lightweight "list" that calculates index -> ChunkAccess
Int2ObjectOpenHashMap<Long2ObjectOpenHashMap<List<IChunkAccess>>> worldLimits = new Int2ObjectOpenHashMap<>(); // as needed when accessed
chunkStatuses.keySet().stream().mapToInt(ChunkStatusWrapper::requiredNeighborChunkRadius0).distinct().forEach(radius -> { class LazyChunkList extends AbstractList<IChunkAccess> {
if (radius == -1) { //ignore ChunkStatus.EMPTY private final int size;
return; private final int minX;
private final int minZ;
private final int sizeSqrt;
LazyChunkList(int radius, int centerX, int centerZ) {
this.sizeSqrt = radius + 1 + radius; // length of one side
this.size = this.sizeSqrt * this.sizeSqrt;
this.minX = centerX - radius;
this.minZ = centerZ - radius;
} }
Long2ObjectOpenHashMap<List<IChunkAccess>> map = new Long2ObjectOpenHashMap<>(); @Override
for (long xz : chunkCoordsForRadius.get(radius)) { public IChunkAccess get(final int index) {
int x = MathMan.unpairIntX(xz); Objects.checkIndex(index, size);
int z = MathMan.unpairIntY(xz); int absX = (index % sizeSqrt) + minX;
List<IChunkAccess> l = new ArrayList<>((radius + 1 + radius) * (radius + 1 + radius)); int absZ = (index / sizeSqrt) + minZ;
for (int zz = z - radius; zz <= z + radius; zz++) { //order is important, first z then x return protoChunks.get(MathMan.pairInt(absX, absZ));
for (int xx = x - radius; xx <= x + radius; xx++) {
l.add(protoChunks.get(MathMan.pairInt(xx, zz)));
} }
@Override
public int size() {
return size;
} }
map.put(xz, l);
}
@Label("Regeneration")
@Category("FAWE")
@Name("fawe.regen")
class RegenerationEvent extends Event {
private String chunkStatus;
private int chunksToProcess;
} }
worldLimits.put(radius, map);
});
//run generation tasks excluding FULL chunk status //run generation tasks excluding FULL chunk status
for (Map.Entry<ChunkStatus, Concurrency> entry : chunkStatuses.entrySet()) { for (Map.Entry<ChunkStatus, Concurrency> entry : chunkStatuses.entrySet()) {
ChunkStatus chunkStatus = entry.getKey(); ChunkStatus chunkStatus = entry.getKey();
int radius = chunkStatus.requiredNeighborChunkRadius0(); final RegenerationEvent event = new RegenerationEvent();
event.begin();
event.chunkStatus = chunkStatus.name();
int radius = Math.max(1, chunkStatus.requiredNeighborChunkRadius0());
long[] coords = chunkCoordsForRadius.get(radius); long[] coords = chunkCoordsForChunkStatus.get(chunkStatus);
Long2ObjectOpenHashMap<List<IChunkAccess>> limitsForRadius = worldLimits.get(radius); event.chunksToProcess = coords.length;
if (this.generateConcurrent && entry.getValue() == Concurrency.RADIUS) { if (this.generateConcurrent && entry.getValue() == Concurrency.RADIUS) {
SequentialTasks<ConcurrentTasks<LongList>> tasks = getChunkStatusTaskRows(coords, radius); SequentialTasks<ConcurrentTasks<LongList>> tasks = getChunkStatusTaskRows(coords, radius);
for (ConcurrentTasks<LongList> para : tasks) { for (ConcurrentTasks<LongList> para : tasks) {
@ -224,7 +250,8 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
for (LongList row : para) { for (LongList row : para) {
scheduled.add(() -> { scheduled.add(() -> {
for (long xz : row) { for (long xz : row) {
chunkStatus.processChunkSave(xz, limitsForRadius.get(xz)); chunkStatus.processChunkSave(xz, new LazyChunkList(radius, MathMan.unpairIntX(xz),
MathMan.unpairIntY(xz)));
} }
}); });
} }
@ -234,7 +261,8 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
// every chunk can be processed individually // every chunk can be processed individually
List<Runnable> scheduled = new ArrayList<>(coords.length); List<Runnable> scheduled = new ArrayList<>(coords.length);
for (long xz : coords) { for (long xz : coords) {
scheduled.add(() -> chunkStatus.processChunkSave(xz, limitsForRadius.get(xz))); scheduled.add(() -> chunkStatus.processChunkSave(xz, new LazyChunkList(radius, MathMan.unpairIntX(xz),
MathMan.unpairIntY(xz))));
} }
runAndWait(scheduled); runAndWait(scheduled);
} else { // Concurrency.NONE or generateConcurrent == false } else { // Concurrency.NONE or generateConcurrent == false
@ -242,28 +270,33 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
// running regen on the main thread otherwise triggers async-only events on the main thread // running regen on the main thread otherwise triggers async-only events on the main thread
executor.submit(() -> { executor.submit(() -> {
for (long xz : coords) { for (long xz : coords) {
chunkStatus.processChunkSave(xz, limitsForRadius.get(xz)); chunkStatus.processChunkSave(xz, new LazyChunkList(radius, MathMan.unpairIntX(xz),
MathMan.unpairIntY(xz)));
} }
}).get(); // wait until finished this step }).get(); // wait until finished this step
} }
event.commit();
} }
//convert to proper chunks //convert to proper chunks
for (long xz : chunkCoordsForRadius.get(0)) { // TODO (j21): use SequencedMap#firstEntry().getValue()
for (long xz : chunkCoordsForChunkStatus.values().iterator().next()) {
ProtoChunk proto = protoChunks.get(xz); ProtoChunk proto = protoChunks.get(xz);
chunks.put(xz, createChunk(proto)); chunks.put(xz, createChunk(proto));
} }
//final chunkstatus //final chunkstatus
ChunkStatus FULL = getFullChunkStatus(); ChunkStatus FULL = getFullChunkStatus();
for (long xz : chunkCoordsForRadius.get(0)) { //FULL.requiredNeighbourChunkRadius() == 0! // TODO (j21): use SequencedMap#firstEntry().getValue()
for (long xz : chunkCoordsForChunkStatus.values().iterator().next()) { //FULL.requiredNeighbourChunkRadius() == 0!
Chunk chunk = chunks.get(xz); Chunk chunk = chunks.get(xz);
FULL.processChunkSave(xz, List.of(chunk)); FULL.processChunkSave(xz, List.of(chunk));
} }
//populate //populate
List<BlockPopulator> populators = getBlockPopulators(); List<BlockPopulator> populators = getBlockPopulators();
for (long xz : chunkCoordsForRadius.get(0)) { // TODO (j21): use SequencedMap#firstEntry().getValue()
for (long xz : chunkCoordsForChunkStatus.values().iterator().next()) {
int x = MathMan.unpairIntX(xz); int x = MathMan.unpairIntX(xz);
int z = MathMan.unpairIntY(xz); int z = MathMan.unpairIntY(xz);
@ -277,8 +310,10 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
}); });
} }
source = new SingleThreadQueueExtent(BukkitWorld.HAS_MIN_Y ? originalBukkitWorld.getMinHeight() : 0, source = new SingleThreadQueueExtent(
BukkitWorld.HAS_MIN_Y ? originalBukkitWorld.getMaxHeight() : 256); BukkitWorld.HAS_MIN_Y ? originalBukkitWorld.getMinHeight() : 0,
BukkitWorld.HAS_MIN_Y ? originalBukkitWorld.getMaxHeight() : 256
);
source.init(target, initSourceQueueCache(), null); source.init(target, initSourceQueueCache(), null);
return true; return true;
} }
@ -319,7 +354,7 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
@Override @Override
public boolean apply(final Extent extent, final BlockVector3 get, final BlockVector3 set) throws WorldEditException { public boolean apply(final Extent extent, final BlockVector3 get, final BlockVector3 set) throws WorldEditException {
return extent.setBlock(set.getX(), set.getY(), set.getZ(), source.getFullBlock(get.getX(), get.getY(), get.getZ())); return extent.setBlock(set.x(), set.y(), set.z(), source.getFullBlock(get.x(), get.y(), get.z()));
} }
} }
@ -339,8 +374,8 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
@Override @Override
public boolean apply(final Extent extent, final BlockVector3 get, final BlockVector3 set) throws WorldEditException { public boolean apply(final Extent extent, final BlockVector3 get, final BlockVector3 set) throws WorldEditException {
return extent.setBlock(set.getX(), set.getY(), set.getZ(), source.getFullBlock(get.getX(), get.getY(), get.getZ())) return extent.setBlock(set.x(), set.y(), set.z(), source.getFullBlock(get.x(), get.y(), get.z()))
&& extent.setBiome(set.getX(), set.getY(), set.getZ(), biomeGetter.apply(get)); && extent.setBiome(set.x(), set.y(), set.z(), biomeGetter.apply(get));
} }
} }
@ -433,22 +468,22 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
private long[] getChunkCoordsRegen(Region region, int border) { //needs to be square num of chunks private long[] getChunkCoordsRegen(Region region, int border) { //needs to be square num of chunks
BlockVector3 oldMin = region.getMinimumPoint(); BlockVector3 oldMin = region.getMinimumPoint();
BlockVector3 newMin = BlockVector3.at( BlockVector3 newMin = BlockVector3.at(
(oldMin.getX() >> 4 << 4) - border * 16, (oldMin.x() >> 4 << 4) - border * 16,
oldMin.getY(), oldMin.y(),
(oldMin.getZ() >> 4 << 4) - border * 16 (oldMin.z() >> 4 << 4) - border * 16
); );
BlockVector3 oldMax = region.getMaximumPoint(); BlockVector3 oldMax = region.getMaximumPoint();
BlockVector3 newMax = BlockVector3.at( BlockVector3 newMax = BlockVector3.at(
(oldMax.getX() >> 4 << 4) + (border + 1) * 16 - 1, (oldMax.x() >> 4 << 4) + (border + 1) * 16 - 1,
oldMax.getY(), oldMax.y(),
(oldMax.getZ() >> 4 << 4) + (border + 1) * 16 - 1 (oldMax.z() >> 4 << 4) + (border + 1) * 16 - 1
); );
Region adjustedRegion = new CuboidRegion(newMin, newMax); Region adjustedRegion = new CuboidRegion(newMin, newMax);
return adjustedRegion.getChunks().stream() return adjustedRegion.getChunks().stream()
.sorted(Comparator .sorted(Comparator
.comparingInt(BlockVector2::getZ) .comparingInt(BlockVector2::z)
.thenComparingInt(BlockVector2::getX)) //needed for RegionLimitedWorldAccess .thenComparingInt(BlockVector2::x)) //needed for RegionLimitedWorldAccess
.mapToLong(c -> MathMan.pairInt(c.getX(), c.getZ())) .mapToLong(c -> MathMan.pairInt(c.x(), c.z()))
.toArray(); .toArray();
} }
@ -503,7 +538,7 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
int numlists = Math.min(requiredNeighbors * 2 + 1, maxZ - minZ + 1); int numlists = Math.min(requiredNeighbors * 2 + 1, maxZ - minZ + 1);
Int2ObjectOpenHashMap<LongList> byZ = new Int2ObjectOpenHashMap<>(); Int2ObjectOpenHashMap<LongList> byZ = new Int2ObjectOpenHashMap<>();
int expectedListLength = (coordsCount + 1) / (maxZ - minZ); int expectedListLength = (coordsCount + 1) / (maxZ - minZ + 2);
//init lists //init lists
for (int i = minZ; i <= maxZ; i++) { for (int i = minZ; i <= maxZ; i++) {
@ -581,13 +616,16 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
try { try {
processChunk(accessibleChunks).get(); processChunk(accessibleChunks).get();
} catch (Exception e) { } catch (Exception e) {
LOGGER.error( LOGGER.error("Error while running {} on chunk {}/{}",
"Error while running " + name() + " on chunk " + MathMan.unpairIntX(xz) + "/" + MathMan.unpairIntY(xz), name(), MathMan.unpairIntX(xz), MathMan.unpairIntY(xz), e);
e
);
} }
} }
@Override
public String toString() {
return name();
}
} }
public static class SequentialTasks<T> extends Tasks<T> { public static class SequentialTasks<T> extends Tasks<T> {

Datei anzeigen

@ -135,7 +135,7 @@ public abstract class ChunkListener implements Listener {
@Deprecated(since = "2.0.0") @Deprecated(since = "2.0.0")
public void cleanup(Chunk chunk) { public void cleanup(Chunk chunk) {
for (Entity entity : chunk.getEntities()) { for (Entity entity : chunk.getEntities()) {
if (entity.getType() == EntityType.DROPPED_ITEM) { if (entity.getType() == EntityType.ITEM) {
entity.remove(); entity.remove();
} }
} }

Datei anzeigen

@ -56,7 +56,7 @@ public class WorldGuardFeature extends BukkitMaskManager implements Listener {
if (region instanceof ProtectedPolygonalRegion casted) { if (region instanceof ProtectedPolygonalRegion casted) {
BlockVector3 max = region.getMaximumPoint(); BlockVector3 max = region.getMaximumPoint();
BlockVector3 min = region.getMinimumPoint(); BlockVector3 min = region.getMinimumPoint();
return new Polygonal2DRegion(null, casted.getPoints(), min.getBlockY(), max.getBlockY()); return new Polygonal2DRegion(null, casted.getPoints(), min.y(), max.y());
} }
return new AdaptedRegion(region); return new AdaptedRegion(region);
} }

Datei anzeigen

@ -94,15 +94,15 @@ public class FaweDelegateSchematicHandler {
return; return;
} }
BlockVector3 dimension = schematic.getClipboard().getDimensions(); BlockVector3 dimension = schematic.getClipboard().getDimensions();
final int WIDTH = dimension.getX(); final int WIDTH = dimension.x();
final int LENGTH = dimension.getZ(); final int LENGTH = dimension.z();
final int HEIGHT = dimension.getY(); final int HEIGHT = dimension.y();
final int worldHeight = plot.getArea().getMaxGenHeight() - plot.getArea().getMinGenHeight() + 1; final int worldHeight = plot.getArea().getMaxGenHeight() - plot.getArea().getMinGenHeight() + 1;
// Validate dimensions // Validate dimensions
CuboidRegion region = plot.getLargestRegion(); CuboidRegion region = plot.getLargestRegion();
boolean sizeMismatch = boolean sizeMismatch =
((region.getMaximumPoint().getX() - region.getMinimumPoint().getX() + xOffset + 1) < WIDTH) || ( ((region.getMaximumPoint().x() - region.getMinimumPoint().x() + xOffset + 1) < WIDTH) || (
(region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ() + zOffset + 1) < LENGTH) || (HEIGHT (region.getMaximumPoint().z() - region.getMinimumPoint().z() + zOffset + 1) < LENGTH) || (HEIGHT
> worldHeight); > worldHeight);
if (!Settings.Schematics.PASTE_MISMATCHES && sizeMismatch) { if (!Settings.Schematics.PASTE_MISMATCHES && sizeMismatch) {
if (actor != null) { if (actor != null) {
@ -111,8 +111,8 @@ public class FaweDelegateSchematicHandler {
TaskManager.runTask(whenDone); TaskManager.runTask(whenDone);
return; return;
} }
if (((region.getMaximumPoint().getX() - region.getMinimumPoint().getX() + xOffset + 1) < WIDTH) || ( if (((region.getMaximumPoint().x() - region.getMinimumPoint().x() + xOffset + 1) < WIDTH) || (
(region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ() + zOffset + 1) < LENGTH) || (HEIGHT (region.getMaximumPoint().z() - region.getMinimumPoint().z() + zOffset + 1) < LENGTH) || (HEIGHT
> worldHeight)) { > worldHeight)) {
if (whenDone != null) { if (whenDone != null) {
TaskManager.runTask(whenDone); TaskManager.runTask(whenDone);
@ -141,7 +141,7 @@ public class FaweDelegateSchematicHandler {
} else { } else {
y_offset_actual = yOffset + pw.getMinBuildHeight() + editSession.getHighestTerrainBlock(region y_offset_actual = yOffset + pw.getMinBuildHeight() + editSession.getHighestTerrainBlock(region
.getMinimumPoint() .getMinimumPoint()
.getX() + 1, region.getMinimumPoint().getZ() + 1, pw.getMinGenHeight(), pw.getMaxGenHeight() .x() + 1, region.getMinimumPoint().z() + 1, pw.getMinGenHeight(), pw.getMaxGenHeight()
); );
} }
} }
@ -150,7 +150,7 @@ public class FaweDelegateSchematicHandler {
} }
final BlockVector3 to = BlockVector3 final BlockVector3 to = BlockVector3
.at(region.getMinimumPoint().getX() + xOffset, y_offset_actual, region.getMinimumPoint().getZ() + zOffset); .at(region.getMinimumPoint().x() + xOffset, y_offset_actual, region.getMinimumPoint().z() + zOffset);
final Clipboard clipboard = schematic.getClipboard(); final Clipboard clipboard = schematic.getClipboard();
clipboard.setOrigin(clipboard.getRegion().getMinimumPoint()); clipboard.setOrigin(clipboard.getRegion().getMinimumPoint());
clipboard.paste(editSession, to, true, false, true); clipboard.paste(editSession, to, true, false, true);

Datei anzeigen

@ -1,6 +1,5 @@
package com.fastasyncworldedit.bukkit.regions.plotsquared; package com.fastasyncworldedit.bukkit.regions.plotsquared;
import com.fastasyncworldedit.core.FaweAPI;
import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.regions.FaweMask; import com.fastasyncworldedit.core.regions.FaweMask;
import com.fastasyncworldedit.core.regions.FaweMaskManager; import com.fastasyncworldedit.core.regions.FaweMaskManager;
@ -159,8 +158,8 @@ public class PlotSquaredFeature extends FaweMaskManager {
regions = WEManager.getMask(pp); regions = WEManager.getMask(pp);
if (regions.size() == 1) { if (regions.size() == 1) {
CuboidRegion region = regions.iterator().next(); CuboidRegion region = regions.iterator().next();
if (region.getMinimumPoint().getX() == Integer.MIN_VALUE if (region.getMinimumPoint().x() == Integer.MIN_VALUE
&& region.getMaximumPoint().getX() == Integer.MAX_VALUE) { && region.getMaximumPoint().x() == Integer.MAX_VALUE) {
regions.clear(); regions.clear();
} }
} }
@ -174,22 +173,21 @@ public class PlotSquaredFeature extends FaweMaskManager {
return null; return null;
} }
Region maskedRegion;
if (regions.size() == 1) {
final World world = player.getWorld(); final World world = player.getWorld();
int min = area != null ? area.getMinBuildHeight() : world.getMinY(); int min = area != null ? area.getMinBuildHeight() : world.getMinY();
// PlotSquared uses exclusive max height, WorldEdit uses inclusive max height -> subtract 1 // PlotSquared uses exclusive max height, WorldEdit uses inclusive max height -> subtract 1
int max = area != null ? Math.min(world.getMaxY(), area.getMaxBuildHeight() - 1) : world.getMaxY(); int max = area != null ? Math.min(world.getMaxY(), area.getMaxBuildHeight() - 1) : world.getMaxY();
Region maskedRegion;
if (regions.size() == 1) {
final CuboidRegion region = regions.iterator().next(); final CuboidRegion region = regions.iterator().next();
final BlockVector3 pos1 = BlockVector3.at(region.getMinimumX(), min, region.getMinimumZ()); final BlockVector3 pos1 = BlockVector3.at(region.getMinimumX(), min, region.getMinimumZ());
final BlockVector3 pos2 = BlockVector3.at(region.getMaximumX(), max, region.getMaximumZ()); final BlockVector3 pos2 = BlockVector3.at(region.getMaximumX(), max, region.getMaximumZ());
maskedRegion = new CuboidRegion(pos1, pos2); maskedRegion = new CuboidRegion(pos1, pos2);
} else { } else {
World world = FaweAPI.getWorld(area.getWorldName());
List<Region> weRegions = regions.stream().map( List<Region> weRegions = regions.stream().map(
r -> new CuboidRegion(world, BlockVector3.at(r.getMinimumX(), r.getMinimumY(), r.getMinimumZ()), r -> new CuboidRegion(world, BlockVector3.at(r.getMinimumX(), min, r.getMinimumZ()),
BlockVector3.at(r.getMaximumX(), r.getMaximumY(), r.getMaximumZ()) BlockVector3.at(r.getMaximumX(), max, r.getMaximumZ())
)).collect(Collectors.toList()); )).collect(Collectors.toList());
maskedRegion = new RegionIntersection(world, weRegions); maskedRegion = new RegionIntersection(world, weRegions);
} }

Datei anzeigen

@ -20,6 +20,7 @@
package com.sk89q.bukkit.util; package com.sk89q.bukkit.util;
import com.sk89q.util.ReflectionUtil; import com.sk89q.util.ReflectionUtil;
import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
@ -96,12 +97,11 @@ public class CommandRegistration {
return fallbackCommands; return fallbackCommands;
} }
CommandMap commandMap = ReflectionUtil.getField(plugin.getServer().getPluginManager(), "commandMap"); CommandMap commandMap = PaperLib.isPaper() ? Bukkit.getCommandMap() : ReflectionUtil.getField(plugin.getServer().getPluginManager(), "commandMap");
if (commandMap == null) { if (commandMap == null) {
Bukkit.getServer().getLogger().severe(plugin.getDescription().getName() Bukkit.getServer().getLogger().severe(plugin.getDescription().getName()
+ ": Could not retrieve server CommandMap, using fallback instead!"); + ": Could not retrieve server CommandMap");
fallbackCommands = commandMap = new SimpleCommandMap(Bukkit.getServer()); throw new IllegalStateException("Failed to retrieve command map, make sure you are running supported server software");
Bukkit.getServer().getPluginManager().registerEvents(new FallbackRegistrationListener(fallbackCommands), plugin);
} else { } else {
serverCommandMap = commandMap; serverCommandMap = commandMap;
} }

Datei anzeigen

@ -240,7 +240,7 @@ public enum BukkitAdapter {
Vector3 position = location; Vector3 position = location;
return new org.bukkit.Location( return new org.bukkit.Location(
adapt((World) location.getExtent()), adapt((World) location.getExtent()),
position.getX(), position.getY(), position.getZ(), position.x(), position.y(), position.z(),
location.getYaw(), location.getYaw(),
location.getPitch() location.getPitch()
); );
@ -258,7 +258,7 @@ public enum BukkitAdapter {
checkNotNull(position); checkNotNull(position);
return new org.bukkit.Location( return new org.bukkit.Location(
world, world,
position.getX(), position.getY(), position.getZ() position.x(), position.y(), position.z()
); );
} }
@ -274,7 +274,7 @@ public enum BukkitAdapter {
checkNotNull(position); checkNotNull(position);
return new org.bukkit.Location( return new org.bukkit.Location(
world, world,
position.getX(), position.getY(), position.getZ() position.x(), position.y(), position.z()
); );
} }
@ -290,7 +290,7 @@ public enum BukkitAdapter {
checkNotNull(location); checkNotNull(location);
return new org.bukkit.Location( return new org.bukkit.Location(
world, world,
location.getX(), location.getY(), location.getZ(), location.x(), location.y(), location.z(),
location.getYaw(), location.getYaw(),
location.getPitch() location.getPitch()
); );

Datei anzeigen

@ -242,9 +242,9 @@ public class BukkitPlayer extends AbstractPlayerActor {
//FAWE end //FAWE end
return TaskManager.taskManager().sync(() -> player.teleport(new Location( return TaskManager.taskManager().sync(() -> player.teleport(new Location(
finalWorld, finalWorld,
pos.getX(), pos.x(),
pos.getY(), pos.y(),
pos.getZ(), pos.z(),
yaw, yaw,
pitch pitch
))); )));
@ -422,7 +422,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
@Override @Override
public <B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, B block) { public <B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, B block) {
Location loc = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ()); Location loc = new Location(player.getWorld(), pos.x(), pos.y(), pos.z());
if (block == null) { if (block == null) {
player.sendBlockChange(loc, player.getWorld().getBlockAt(loc).getBlockData()); player.sendBlockChange(loc, player.getWorld().getBlockAt(loc).getBlockData());
} else { } else {

Datei anzeigen

@ -247,7 +247,7 @@ public class BukkitWorld extends AbstractWorld {
//FAWE start - safe edit region //FAWE start - safe edit region
testCoords(pt); testCoords(pt);
//FAWE end //FAWE end
return getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).getLightLevel(); return getWorld().getBlockAt(pt.x(), pt.y(), pt.z()).getLightLevel();
} }
@Override @Override
@ -284,7 +284,7 @@ public class BukkitWorld extends AbstractWorld {
return false; return false;
} }
Block block = getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); Block block = getWorld().getBlockAt(pt.x(), pt.y(), pt.z());
BlockState state = PaperLib.getBlockState(block, false).getState(); BlockState state = PaperLib.getBlockState(block, false).getState();
if (!(state instanceof InventoryHolder)) { if (!(state instanceof InventoryHolder)) {
return false; return false;
@ -363,8 +363,8 @@ public class BukkitWorld extends AbstractWorld {
//FAWE end //FAWE end
World world = getWorld(); World world = getWorld();
//FAWE start //FAWE start
int X = pt.getBlockX() >> 4; int X = pt.x() >> 4;
int Z = pt.getBlockZ() >> 4; int Z = pt.z() >> 4;
if (Fawe.isMainThread()) { if (Fawe.isMainThread()) {
world.getChunkAt(X, Z); world.getChunkAt(X, Z);
} else if (PaperLib.isPaper()) { } else if (PaperLib.isPaper()) {
@ -413,7 +413,7 @@ public class BukkitWorld extends AbstractWorld {
public void fixAfterFastMode(Iterable<BlockVector2> chunks) { public void fixAfterFastMode(Iterable<BlockVector2> chunks) {
World world = getWorld(); World world = getWorld();
for (BlockVector2 chunkPos : chunks) { for (BlockVector2 chunkPos : chunks) {
world.refreshChunk(chunkPos.getBlockX(), chunkPos.getBlockZ()); world.refreshChunk(chunkPos.x(), chunkPos.z());
} }
} }
@ -495,13 +495,13 @@ public class BukkitWorld extends AbstractWorld {
//FAWE start - safe edit region //FAWE start - safe edit region
testCoords(pt); testCoords(pt);
//FAWE end //FAWE end
getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).breakNaturally(); getWorld().getBlockAt(pt.x(), pt.y(), pt.z()).breakNaturally();
} }
//FAWE start //FAWE start
@Override @Override
public Collection<BaseItemStack> getBlockDrops(BlockVector3 position) { public Collection<BaseItemStack> getBlockDrops(BlockVector3 position) {
return getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()).getDrops().stream() return getWorld().getBlockAt(position.x(), position.y(), position.z()).getDrops().stream()
.map(BukkitAdapter::adapt).collect(Collectors.toList()); .map(BukkitAdapter::adapt).collect(Collectors.toList());
} }
//FAWE end //FAWE end
@ -538,7 +538,7 @@ public class BukkitWorld extends AbstractWorld {
} }
} }
if (WorldEditPlugin.getInstance().getLocalConfiguration().unsupportedVersionEditing) { if (WorldEditPlugin.getInstance().getLocalConfiguration().unsupportedVersionEditing) {
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); Block bukkitBlock = getWorld().getBlockAt(position.x(), position.y(), position.z());
return BukkitAdapter.adapt(bukkitBlock.getBlockData()); return BukkitAdapter.adapt(bukkitBlock.getBlockData());
} else { } else {
throw new RuntimeException(new UnsupportedVersionEditException()); throw new RuntimeException(new UnsupportedVersionEditException());
@ -562,7 +562,7 @@ public class BukkitWorld extends AbstractWorld {
} }
} }
} }
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ()); Block bukkitBlock = getWorld().getBlockAt(position.x(), position.y(), position.z());
bukkitBlock.setBlockData(BukkitAdapter.adapt(block), sideEffects.doesApplyAny()); bukkitBlock.setBlockData(BukkitAdapter.adapt(block), sideEffects.doesApplyAny());
return true; return true;
} }
@ -584,8 +584,8 @@ public class BukkitWorld extends AbstractWorld {
if (!Settings.settings().REGION_RESTRICTIONS_OPTIONS.RESTRICT_TO_SAFE_RANGE) { if (!Settings.settings().REGION_RESTRICTIONS_OPTIONS.RESTRICT_TO_SAFE_RANGE) {
return; return;
} }
int x = position.getX(); int x = position.x();
int z = position.getZ(); int z = position.z();
if (x > 30000000 || z > 30000000 || x < -30000000 || z < -30000000) { if (x > 30000000 || z > 30000000 || x < -30000000 || z < -30000000) {
throw FaweCache.OUTSIDE_SAFE_REGION; throw FaweCache.OUTSIDE_SAFE_REGION;
} }
@ -636,9 +636,9 @@ public class BukkitWorld extends AbstractWorld {
testCoords(position); testCoords(position);
//FAWE end //FAWE end
if (HAS_3D_BIOMES) { if (HAS_3D_BIOMES) {
return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ())); return BukkitAdapter.adapt(getWorld().getBiome(position.x(), position.y(), position.z()));
} else { } else {
return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockZ())); return BukkitAdapter.adapt(getWorld().getBiome(position.x(), position.z()));
} }
} }
@ -649,9 +649,9 @@ public class BukkitWorld extends AbstractWorld {
testCoords(position); testCoords(position);
//FAWE end //FAWE end
if (HAS_3D_BIOMES) { if (HAS_3D_BIOMES) {
getWorld().setBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ(), BukkitAdapter.adapt(biome)); getWorld().setBiome(position.x(), position.y(), position.z(), BukkitAdapter.adapt(biome));
} else { } else {
getWorld().setBiome(position.getBlockX(), position.getBlockZ(), BukkitAdapter.adapt(biome)); getWorld().setBiome(position.x(), position.z(), BukkitAdapter.adapt(biome));
} }
return true; return true;
} }

Datei anzeigen

@ -120,7 +120,6 @@ public class WorldEditPlugin extends JavaPlugin {
public void onLoad() { public void onLoad() {
//FAWE start //FAWE start
this.bukkitConsoleCommandSender = new BukkitCommandSender(this, Bukkit.getConsoleSender());
// This is already covered by Spigot, however, a more pesky warning with a proper explanation over "Ambiguous plugin name..." can't hurt. // This is already covered by Spigot, however, a more pesky warning with a proper explanation over "Ambiguous plugin name..." can't hurt.
Plugin[] plugins = Bukkit.getServer().getPluginManager().getPlugins(); Plugin[] plugins = Bukkit.getServer().getPluginManager().getPlugins();
for (Plugin p : plugins) { for (Plugin p : plugins) {
@ -138,6 +137,14 @@ public class WorldEditPlugin extends JavaPlugin {
//noinspection ResultOfMethodCallIgnored //noinspection ResultOfMethodCallIgnored
getDataFolder().mkdirs(); getDataFolder().mkdirs();
//FAWE start - Modify WorldEdit config name
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "worldedit-config.yml"), true), this);
// Load config before we say we've loaded platforms as it is used in listeners of the event
// Load config in onLoad to ensure it is loaded before FAWE settings to allow (inelegant) copying of values across
// where needed
config.load();
//FAWE end
WorldEdit worldEdit = WorldEdit.getInstance(); WorldEdit worldEdit = WorldEdit.getInstance();
// Setup platform // Setup platform
@ -148,14 +155,14 @@ public class WorldEditPlugin extends JavaPlugin {
migrateLegacyConfig(); migrateLegacyConfig();
//FAWE end //FAWE end
//FAWE start - Modify WorldEdit config name
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "worldedit-config.yml"), true), this);
//FAWE end
//FAWE start - Setup permission attachments //FAWE start - Setup permission attachments
permissionAttachmentManager = new BukkitPermissionAttachmentManager(this); permissionAttachmentManager = new BukkitPermissionAttachmentManager(this);
//FAWE end //FAWE end
//FAWE start - initialise bukkitConsoleCommandSender later
this.bukkitConsoleCommandSender = new BukkitCommandSender(this, Bukkit.getConsoleSender());
//FAWE end
Path delChunks = Paths.get(getDataFolder().getPath(), DELCHUNKS_FILE_NAME); Path delChunks = Paths.get(getDataFolder().getPath(), DELCHUNKS_FILE_NAME);
if (Files.exists(delChunks)) { if (Files.exists(delChunks)) {
ChunkDeleter.runFromFile(delChunks, true); ChunkDeleter.runFromFile(delChunks, true);
@ -189,8 +196,6 @@ public class WorldEditPlugin extends JavaPlugin {
new FaweBukkit(this); new FaweBukkit(this);
//FAWE end //FAWE end
config.load(); // Load config before we say we've loaded platforms as it is used in listeners of the event
WorldEdit.getInstance().getEventBus().post(new PlatformsRegisteredEvent()); WorldEdit.getInstance().getEventBus().post(new PlatformsRegisteredEvent());
PermissionsResolverManager.initialize(this); // Setup permission resolver PermissionsResolverManager.initialize(this); // Setup permission resolver

Datei anzeigen

@ -24,11 +24,13 @@ limits:
max-polygonal-points: max-polygonal-points:
default: -1 default: -1
maximum: 20 maximum: 20
# radius, superpickaxe, brush radius are ignored, use FAWE config limits
max-radius: -1 max-radius: -1
max-super-pickaxe-size: 5 max-super-pickaxe-size: 5
max-brush-radius: 100 max-brush-radius: 100
butcher-radius: butcher-radius:
default: -1 default: -1
# Ignored, use FAWE config limits
maximum: -1 maximum: -1
disallowed-blocks: disallowed-blocks:
- "minecraft:wheat" - "minecraft:wheat"

Datei anzeigen

@ -1,6 +1,6 @@
/** /**
* The following classes are FAWE additions: * The following classes are FAWE additions:
* *
* @see com.sk89q.worldedit.cli.AccessPoint * {@link com.sk89q.worldedit.cli.AccessPoint}
*/ */
package com.sk89q.worldedit.cli; package com.sk89q.worldedit.cli;

Datei anzeigen

@ -1,16 +1,12 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
kotlin("jvm") version "1.8.20" kotlin("jvm") version "1.9.23"
application application
} }
applyCommonConfiguration() applyCommonConfiguration()
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "17"
}
application.mainClass.set("com.sk89q.worldedit.internal.util.DocumentationPrinter") application.mainClass.set("com.sk89q.worldedit.internal.util.DocumentationPrinter")
tasks.named<JavaExec>("run") { tasks.named<JavaExec>("run") {
workingDir = rootProject.projectDir workingDir = rootProject.projectDir

Datei anzeigen

@ -339,11 +339,11 @@ public class FaweAPI {
final BlockVector3 bot = selection.getMinimumPoint(); final BlockVector3 bot = selection.getMinimumPoint();
final BlockVector3 top = selection.getMaximumPoint(); final BlockVector3 top = selection.getMaximumPoint();
final int minX = bot.getBlockX() >> 4; final int minX = bot.x() >> 4;
final int minZ = bot.getBlockZ() >> 4; final int minZ = bot.z() >> 4;
final int maxX = top.getBlockX() >> 4; final int maxX = top.x() >> 4;
final int maxZ = top.getBlockZ() >> 4; final int maxZ = top.z() >> 4;
int count = 0; int count = 0;

Datei anzeigen

@ -50,9 +50,9 @@ public class BlendBall implements Brush {
final int outsetSize = (int) (size + 1); final int outsetSize = (int) (size + 1);
double brushSizeSquared = size * size; double brushSizeSquared = size * size;
int tx = position.getBlockX(); int tx = position.x();
int ty = position.getBlockY(); int ty = position.y();
int tz = position.getBlockZ(); int tz = position.z();
int[] frequency = new int[BlockTypes.size()]; int[] frequency = new int[BlockTypes.size()];

Datei anzeigen

@ -81,9 +81,9 @@ public class CatenaryBrush implements Brush, ResettableTool {
return pos1.add(pos2).divide(2).toBlockPoint(); return pos1.add(pos2).divide(2).toBlockPoint();
} }
double curveLen = pos1.distance(pos2) * lenPercent; double curveLen = pos1.distance(pos2) * lenPercent;
double dy = pos2.getY() - pos1.getY(); double dy = pos2.y() - pos1.y();
double dx = pos2.getX() - pos1.getX(); double dx = pos2.x() - pos1.x();
double dz = pos2.getZ() - pos1.getZ(); double dz = pos2.z() - pos1.z();
double dh = Math.sqrt(dx * dx + dz * dz); double dh = Math.sqrt(dx * dx + dz * dz);
double g = Math.sqrt(curveLen * curveLen - dy * dy) / 2; double g = Math.sqrt(curveLen * curveLen - dy * dy) / 2;
double a = 0.00001; double a = 0.00001;

Datei anzeigen

@ -54,9 +54,9 @@ public class CommandBrush implements Brush {
position.subtract(radius, radius, radius), position.subtract(radius, radius, radius),
position.add(radius, radius, radius) position.add(radius, radius, radius)
); );
String replaced = command.replace("{x}", Integer.toString(position.getBlockX())) String replaced = command.replace("{x}", Integer.toString(position.x()))
.replace("{y}", Integer.toString(position.getBlockY())) .replace("{y}", Integer.toString(position.y()))
.replace("{z}", Integer.toString(position.getBlockZ())) .replace("{z}", Integer.toString(position.z()))
.replace("{world}", editSession.getWorld().getName()) .replace("{world}", editSession.getWorld().getName())
.replace("{size}", Integer.toString(radius)); .replace("{size}", Integer.toString(radius));

Datei anzeigen

@ -65,11 +65,11 @@ public class CopyPastaBrush implements Brush, ResettableTool {
mask = Masks.alwaysTrue(); mask = Masks.alwaysTrue();
} }
final ResizableClipboardBuilder builder = new ResizableClipboardBuilder(editSession.getWorld()); final ResizableClipboardBuilder builder = new ResizableClipboardBuilder(editSession.getWorld());
final int minY = position.getBlockY(); final int minY = position.y();
mask = new AbstractDelegateMask(mask) { mask = new AbstractDelegateMask(mask) {
@Override @Override
public boolean test(BlockVector3 vector) { public boolean test(BlockVector3 vector) {
if (super.test(vector) && vector.getBlockY() >= minY) { if (super.test(vector) && vector.y() >= minY) {
BaseBlock block = editSession.getFullBlock(vector); BaseBlock block = editSession.getFullBlock(vector);
if (!block.getBlockType().getMaterial().isAir()) { if (!block.getBlockType().getMaterial().isAir()) {
builder.add(vector, BlockTypes.AIR.getDefaultState().toBaseBlock(), block); builder.add(vector, BlockTypes.AIR.getDefaultState().toBaseBlock(), block);

Datei anzeigen

@ -63,9 +63,9 @@ public class ErodeBrush implements Brush {
Clipboard buffer1 = new CPUOptimizedClipboard(region); Clipboard buffer1 = new CPUOptimizedClipboard(region);
Clipboard buffer2 = new CPUOptimizedClipboard(region); Clipboard buffer2 = new CPUOptimizedClipboard(region);
final int bx = target.getBlockX(); final int bx = target.x();
final int by = target.getBlockY(); final int by = target.y();
final int bz = target.getBlockZ(); final int bz = target.z();
for (int x = -brushSize, relx = 0; x <= brushSize && relx < buffer1.getWidth(); x++, relx++) { for (int x = -brushSize, relx = 0; x <= brushSize && relx < buffer1.getWidth(); x++, relx++) {
int x0 = x + bx; int x0 = x + bx;
@ -106,7 +106,7 @@ public class ErodeBrush implements Brush {
for (BlockVector3 pos : finalBuffer) { for (BlockVector3 pos : finalBuffer) {
BlockState block = pos.getBlock(finalBuffer); BlockState block = pos.getBlock(finalBuffer);
es.setBlock(pos.getX() + bx - brushSize, pos.getY() + by - brushSize, pos.getZ() + bz - brushSize, block); es.setBlock(pos.x() + bx - brushSize, pos.y() + by - brushSize, pos.z() + bz - brushSize, block);
} }
} }
@ -139,9 +139,9 @@ public class ErodeBrush implements Brush {
int highest = 1; int highest = 1;
for (BlockVector3 offs : FACES_TO_CHECK) { for (BlockVector3 offs : FACES_TO_CHECK) {
BaseBlock next = current.getFullBlock( BaseBlock next = current.getFullBlock(
relx + offs.getBlockX(), relx + offs.x(),
rely + offs.getBlockY(), rely + offs.y(),
relz + offs.getBlockZ() relz + offs.z()
); );
if (!next.getBlockType().getMaterial().isMovementBlocker()) { if (!next.getBlockType().getMaterial().isMovementBlocker()) {
continue; continue;
@ -190,9 +190,9 @@ public class ErodeBrush implements Brush {
int total = 0; int total = 0;
for (BlockVector3 offs : FACES_TO_CHECK) { for (BlockVector3 offs : FACES_TO_CHECK) {
BaseBlock next = current.getFullBlock( BaseBlock next = current.getFullBlock(
relx + offs.getBlockX(), relx + offs.x(),
rely + offs.getBlockY(), rely + offs.y(),
relz + offs.getBlockZ() relz + offs.z()
); );
if (next.getMaterial().isMovementBlocker()) { if (next.getMaterial().isMovementBlocker()) {
continue; continue;

Datei anzeigen

@ -12,9 +12,9 @@ public class FallingSphere implements Brush {
@Override @Override
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws
MaxChangedBlocksException { MaxChangedBlocksException {
int px = position.getBlockX(); int px = position.x();
int py = position.getBlockY(); int py = position.y();
int pz = position.getBlockZ(); int pz = position.z();
int maxY = editSession.getMaxY(); int maxY = editSession.getMaxY();
int minY = editSession.getMinY(); int minY = editSession.getMinY();

Datei anzeigen

@ -14,7 +14,6 @@ import com.sk89q.worldedit.command.tool.BrushTool;
import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
@ -25,7 +24,6 @@ import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
import com.sk89q.worldedit.util.formatting.text.format.TextColor; import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import org.apache.logging.log4j.Logger;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
@ -80,9 +78,9 @@ public class InspectBrush extends BrushTool {
return true; return true;
} }
BlockVector3 target = targetVector.toBlockPoint(); BlockVector3 target = targetVector.toBlockPoint();
final int x = target.getBlockX(); final int x = target.x();
final int y = target.getBlockY(); final int y = target.y();
final int z = target.getBlockZ(); final int z = target.z();
World world = player.getWorld(); World world = player.getWorld();
RollbackDatabase db = DBHandler.dbHandler().getDatabase(world); RollbackDatabase db = DBHandler.dbHandler().getDatabase(world);
int count = 0; int count = 0;

Datei anzeigen

@ -35,7 +35,7 @@ public record RecurseBrush(boolean dfs) implements Brush {
DFSRecursiveVisitor visitor = new DFSRecursiveVisitor(mask, replace, Integer.MAX_VALUE, Integer.MAX_VALUE) { DFSRecursiveVisitor visitor = new DFSRecursiveVisitor(mask, replace, Integer.MAX_VALUE, Integer.MAX_VALUE) {
@Override @Override
public boolean isVisitable(BlockVector3 from, BlockVector3 to) { public boolean isVisitable(BlockVector3 from, BlockVector3 to) {
int y = to.getBlockY(); int y = to.y();
return y < maxY && radMask.test(to) && super.isVisitable(from, to); return y < maxY && radMask.test(to) && super.isVisitable(from, to);
} }
}; };
@ -45,7 +45,7 @@ public record RecurseBrush(boolean dfs) implements Brush {
RecursiveVisitor visitor = new RecursiveVisitor(mask, replace, radius, editSession.getMinY(), editSession.getMaxY()) { RecursiveVisitor visitor = new RecursiveVisitor(mask, replace, radius, editSession.getMinY(), editSession.getMaxY()) {
@Override @Override
public boolean isVisitable(BlockVector3 from, BlockVector3 to) { public boolean isVisitable(BlockVector3 from, BlockVector3 to) {
int y = to.getBlockY(); int y = to.y();
return y < maxY && super.isVisitable(from, to); return y < maxY && super.isVisitable(from, to);
} }
}; };

Datei anzeigen

@ -19,15 +19,15 @@ public record RockBrush(double amplitude, double frequency, Vector3 radius) impl
double seedY = ThreadLocalRandom.current().nextDouble(); double seedY = ThreadLocalRandom.current().nextDouble();
double seedZ = ThreadLocalRandom.current().nextDouble(); double seedZ = ThreadLocalRandom.current().nextDouble();
int px = position.getBlockX(); int px = position.x();
int py = position.getBlockY(); int py = position.y();
int pz = position.getBlockZ(); int pz = position.z();
double distort = this.frequency / size; double distort = this.frequency / size;
double modX = 1D / radius.getX(); double modX = 1D / radius.x();
double modY = 1D / radius.getY(); double modY = 1D / radius.y();
double modZ = 1D / radius.getZ(); double modZ = 1D / radius.z();
int radiusSqr = (int) (size * size); int radiusSqr = (int) (size * size);
int sizeInt = (int) size * 2; int sizeInt = (int) size * 2;

Datei anzeigen

@ -5,6 +5,7 @@ import com.fastasyncworldedit.core.function.mask.RadiusMask;
import com.fastasyncworldedit.core.function.mask.SurfaceMask; import com.fastasyncworldedit.core.function.mask.SurfaceMask;
import com.fastasyncworldedit.core.math.BlockVectorSet; import com.fastasyncworldedit.core.math.BlockVectorSet;
import com.fastasyncworldedit.core.math.LocalBlockVectorSet; import com.fastasyncworldedit.core.math.LocalBlockVectorSet;
import com.fastasyncworldedit.core.util.collection.BlockVector3Set;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.command.tool.brush.Brush; import com.sk89q.worldedit.command.tool.brush.Brush;
@ -64,16 +65,17 @@ public class ScatterBrush implements Brush {
length = 1; length = 1;
visited.add(position); visited.add(position);
} }
LocalBlockVectorSet placed = new LocalBlockVectorSet(); BlockVector3 patternSize = pattern.size();
placed.setOffset(position.getX(), position.getZ()); BlockVector3Set placed = BlockVector3Set.getAppropriateVectorSet(patternSize.add(distance, distance, distance));
placed.setOffset(position.x(), position.y(), position.z());
int maxFails = 1000; int maxFails = 1000;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
int index = ThreadLocalRandom.current().nextInt(length); int index = ThreadLocalRandom.current().nextInt(length);
BlockVector3 pos = visited.get(index); BlockVector3 pos = visited.get(index);
if (pos != null && canApply(pos)) { if (pos != null && canApply(pos)) {
int x = pos.getBlockX(); int x = pos.x();
int y = pos.getBlockY(); int y = pos.y();
int z = pos.getBlockZ(); int z = pos.z();
if (placed.containsRadius(x, y, z, distance)) { if (placed.containsRadius(x, y, z, distance)) {
if (maxFails-- <= 0) { if (maxFails-- <= 0) {
break; break;
@ -88,7 +90,20 @@ public class ScatterBrush implements Brush {
finish(editSession, placed, position, pattern, size); finish(editSession, placed, position, pattern, size);
} }
/**
* @deprecated Use {@link ScatterBrush#finish(EditSession, BlockVector3Set, BlockVector3, Pattern, double)}
*/
@Deprecated(forRemoval = true, since = "2.9.2")
public void finish(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pos, Pattern pattern, double size) { public void finish(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pos, Pattern pattern, double size) {
finish(editSession, (BlockVector3Set) placed, pos, pattern, size);
}
/**
* Complete the scatter brush process.
*
* @since 2.9.2
*/
public void finish(EditSession editSession, BlockVector3Set placed, BlockVector3 pos, Pattern pattern, double size) {
} }
public boolean canApply(BlockVector3 pos) { public boolean canApply(BlockVector3 pos) {
@ -99,8 +114,23 @@ public class ScatterBrush implements Brush {
return surface.direction(pt); return surface.direction(pt);
} }
/**
* @deprecated Use {@link ScatterBrush#apply(EditSession, BlockVector3Set, BlockVector3, Pattern, double)}
*/
@Deprecated(forRemoval = true, since = "2.9.2")
public void apply(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pt, Pattern p, double size) throws public void apply(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pt, Pattern p, double size) throws
MaxChangedBlocksException { MaxChangedBlocksException {
apply(editSession, (BlockVector3Set) placed, pt, p, size);
}
/**
* Apply the scatter brush to a given position
*
* @since 2.9.2
*/
public void apply(EditSession editSession, BlockVector3Set placed, BlockVector3 pt, Pattern p, double size) throws
MaxChangedBlocksException {
editSession.setBlock(pt, p); editSession.setBlock(pt, p);
} }

Datei anzeigen

@ -45,9 +45,9 @@ public class ScatterCommand extends ScatterBrush {
position.subtract(radius, radius, radius), position.subtract(radius, radius, radius),
position.add(radius, radius, radius) position.add(radius, radius, radius)
); );
String replaced = command.replace("{x}", Integer.toString(position.getBlockX())) String replaced = command.replace("{x}", Integer.toString(position.x()))
.replace("{y}", Integer.toString(position.getBlockY())) .replace("{y}", Integer.toString(position.y()))
.replace("{z}", Integer.toString(position.getBlockZ())) .replace("{z}", Integer.toString(position.z()))
.replace("{world}", editSession.getWorld().getName()) .replace("{world}", editSession.getWorld().getName())
.replace("{size}", Integer.toString(radius)); .replace("{size}", Integer.toString(radius));

Datei anzeigen

@ -16,9 +16,9 @@ public class ScatterOverlayBrush extends ScatterBrush {
@Override @Override
public void apply(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pt, Pattern p, double size) throws public void apply(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pt, Pattern p, double size) throws
MaxChangedBlocksException { MaxChangedBlocksException {
final int x = pt.getBlockX(); final int x = pt.x();
final int y = pt.getBlockY(); final int y = pt.y();
final int z = pt.getBlockZ(); final int z = pt.z();
BlockVector3 dir = getDirection(pt); BlockVector3 dir = getDirection(pt);
if (dir == null) { if (dir == null) {
getDir: getDir:
@ -37,7 +37,7 @@ public class ScatterOverlayBrush extends ScatterBrush {
return; return;
} }
} }
editSession.setBlock(x + dir.getBlockX(), y + dir.getBlockY(), z + dir.getBlockZ(), p); editSession.setBlock(x + dir.x(), y + dir.y(), z + dir.z(), p);
} }
} }

Datei anzeigen

@ -3,6 +3,7 @@ package com.fastasyncworldedit.core.command.tool.brush;
import com.fastasyncworldedit.core.function.mask.SurfaceMask; import com.fastasyncworldedit.core.function.mask.SurfaceMask;
import com.fastasyncworldedit.core.math.LocalBlockVectorSet; import com.fastasyncworldedit.core.math.LocalBlockVectorSet;
import com.fastasyncworldedit.core.math.MutableBlockVector3; import com.fastasyncworldedit.core.math.MutableBlockVector3;
import com.fastasyncworldedit.core.util.collection.BlockVector3Set;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
@ -24,7 +25,7 @@ public class ShatterBrush extends ScatterBrush {
@Override @Override
public void apply( public void apply(
final EditSession editSession, final EditSession editSession,
final LocalBlockVectorSet placed, final BlockVector3Set placed,
final BlockVector3 position, final BlockVector3 position,
Pattern p, Pattern p,
double size double size
@ -34,7 +35,7 @@ public class ShatterBrush extends ScatterBrush {
@Override @Override
public void finish( public void finish(
EditSession editSession, EditSession editSession,
LocalBlockVectorSet placed, BlockVector3Set placed,
final BlockVector3 position, final BlockVector3 position,
Pattern pattern, Pattern pattern,
double size double size
@ -79,13 +80,13 @@ public class ShatterBrush extends ScatterBrush {
} }
for (int i1 = 0; i1 < BreadthFirstSearch.DIAGONAL_DIRECTIONS.length; i1++) { for (int i1 = 0; i1 < BreadthFirstSearch.DIAGONAL_DIRECTIONS.length; i1++) {
BlockVector3 direction = BreadthFirstSearch.DIAGONAL_DIRECTIONS[i1]; BlockVector3 direction = BreadthFirstSearch.DIAGONAL_DIRECTIONS[i1];
int x2 = x + direction.getBlockX(); int x2 = x + direction.x();
int y2 = y + direction.getBlockY(); int y2 = y + direction.y();
int z2 = z + direction.getBlockZ(); int z2 = z + direction.z();
// Check boundary // Check boundary
int dx = position.getBlockX() - x2; int dx = position.x() - x2;
int dy = position.getBlockY() - y2; int dy = position.y() - y2;
int dz = position.getBlockZ() - z2; int dz = position.z() - z2;
int dSqr = (dx * dx) + (dy * dy) + (dz * dz); int dSqr = (dx * dx) + (dy * dy) + (dz * dz);
if (dSqr <= radius2) { if (dSqr <= radius2) {
BlockVector3 bv = mutable.setComponents(x2, y2, z2); BlockVector3 bv = mutable.setComponents(x2, y2, z2);

Datei anzeigen

@ -130,9 +130,9 @@ public class SplineBrush implements Brush, ResettableTool {
private Vector3 getCentroid(Collection<BlockVector3> points) { private Vector3 getCentroid(Collection<BlockVector3> points) {
MutableVector3 sum = new MutableVector3(); MutableVector3 sum = new MutableVector3();
for (BlockVector3 p : points) { for (BlockVector3 p : points) {
sum.mutX(sum.getX() + p.getX()); sum.mutX(sum.x() + p.x());
sum.mutY(sum.getY() + p.getY()); sum.mutY(sum.y() + p.y());
sum.mutZ(sum.getZ() + p.getZ()); sum.mutZ(sum.z() + p.z());
} }
return sum.multiply(1.0 / points.size()); return sum.multiply(1.0 / points.size());
} }

Datei anzeigen

@ -38,16 +38,16 @@ public class SurfaceSpline implements Brush {
int minY = editSession.getMinY(); int minY = editSession.getMinY();
if (path.isEmpty() || !pos.equals(path.get(path.size() - 1))) { if (path.isEmpty() || !pos.equals(path.get(path.size() - 1))) {
int max = editSession.getNearestSurfaceTerrainBlock( int max = editSession.getNearestSurfaceTerrainBlock(
pos.getBlockX(), pos.x(),
pos.getBlockZ(), pos.z(),
pos.getBlockY(), pos.y(),
minY, minY,
maxY maxY
); );
if (max == -1) { if (max == -1) {
return; return;
} }
path.add(BlockVector3.at(pos.getBlockX(), max, pos.getBlockZ())); path.add(BlockVector3.at(pos.x(), max, pos.z()));
if (editSession.getActor() != null) { if (editSession.getActor() != null) {
editSession.getActor().print(Caption.of("fawe.worldedit.brush.spline.primary.2")); editSession.getActor().print(Caption.of("fawe.worldedit.brush.spline.primary.2"));
} }
@ -69,9 +69,9 @@ public class SurfaceSpline implements Brush {
LocalBlockVectorSet vset = new LocalBlockVectorSet(); LocalBlockVectorSet vset = new LocalBlockVectorSet();
for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) { for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) {
final Vector3 tipv = interpol.getPosition(loop); final Vector3 tipv = interpol.getPosition(loop);
final int tipx = MathMan.roundInt(tipv.getX()); final int tipx = MathMan.roundInt(tipv.x());
final int tipz = (int) tipv.getZ(); final int tipz = (int) tipv.z();
int tipy = MathMan.roundInt(tipv.getY()); int tipy = MathMan.roundInt(tipv.y());
tipy = editSession.getNearestSurfaceTerrainBlock(tipx, tipz, tipy, minY, maxY, Integer.MIN_VALUE, Integer.MAX_VALUE); tipy = editSession.getNearestSurfaceTerrainBlock(tipx, tipz, tipy, minY, maxY, Integer.MIN_VALUE, Integer.MAX_VALUE);
if (tipy == Integer.MIN_VALUE || tipy == Integer.MAX_VALUE) { if (tipy == Integer.MIN_VALUE || tipy == Integer.MAX_VALUE) {
continue; continue;
@ -88,15 +88,15 @@ public class SurfaceSpline implements Brush {
LocalBlockVectorSet newSet = new LocalBlockVectorSet(); LocalBlockVectorSet newSet = new LocalBlockVectorSet();
final int ceilrad = (int) Math.ceil(radius); final int ceilrad = (int) Math.ceil(radius);
for (BlockVector3 v : vset) { for (BlockVector3 v : vset) {
final int tipx = v.getBlockX(); final int tipx = v.x();
final int tipz = v.getBlockZ(); final int tipz = v.z();
for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) { for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) {
for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) { for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) {
if (MathMan.hypot2(loopx - tipx, 0, loopz - tipz) <= radius2) { if (MathMan.hypot2(loopx - tipx, 0, loopz - tipz) <= radius2) {
int y = editSession.getNearestSurfaceTerrainBlock( int y = editSession.getNearestSurfaceTerrainBlock(
loopx, loopx,
loopz, loopz,
v.getBlockY(), v.y(),
minY, minY,
maxY, maxY,
Integer.MIN_VALUE, Integer.MIN_VALUE,

Datei anzeigen

@ -13,7 +13,7 @@ public class ScrollRange extends Scroll {
@Override @Override
public boolean increment(Player player, int amount) { public boolean increment(Player player, int amount) {
int max = WorldEdit.getInstance().getConfiguration().maxBrushRadius; int max = player.getLimit().MAX_BRUSH_RADIUS;
int newSize = MathMan.wrap(getTool().getRange() + amount, (int) (getTool().getSize() + 1), max); int newSize = MathMan.wrap(getTool().getRange() + amount, (int) (getTool().getSize() + 1), max);
getTool().setRange(newSize); getTool().setRange(newSize);
return true; return true;

Datei anzeigen

@ -12,7 +12,7 @@ public class ScrollSize extends Scroll {
@Override @Override
public boolean increment(Player player, int amount) { public boolean increment(Player player, int amount) {
int max = WorldEdit.getInstance().getConfiguration().maxRadius; int max = player.getLimit().MAX_RADIUS;
double newSize = Math.max(0, Math.min(max == -1 ? 4095 : max, getTool().getSize() + amount)); double newSize = Math.max(0, Math.min(max == -1 ? 4095 : max, getTool().getSize() + amount));
getTool().setSize(newSize); getTool().setSize(newSize);
return true; return true;

Datei anzeigen

@ -83,7 +83,7 @@ public class ClipboardSpline extends Spline {
Region region = clipboard.getRegion(); Region region = clipboard.getRegion();
BlockVector3 origin = clipboard.getOrigin(); BlockVector3 origin = clipboard.getOrigin();
// center = region.getCenter().setY(origin.getY() - 1); // center = region.getCenter().setY(origin.getY() - 1);
center = region.getCenter().withY(origin.getY() - 1).toBlockPoint(); center = region.getCenter().withY(origin.y() - 1).toBlockPoint();
this.centerOffset = center.subtract(center.round()); this.centerOffset = center.subtract(center.round());
this.center = center.subtract(centerOffset); this.center = center.subtract(centerOffset);
this.transform = transform; this.transform = transform;
@ -108,15 +108,15 @@ public class ClipboardSpline extends Spline {
clipboardHolder.setTransform(transform); clipboardHolder.setTransform(transform);
BlockVector3 functionOffset = target.subtract(clipboard.getOrigin()); BlockVector3 functionOffset = target.subtract(clipboard.getOrigin());
final int offX = functionOffset.getBlockX(); final int offX = functionOffset.x();
final int offY = functionOffset.getBlockY(); final int offY = functionOffset.y();
final int offZ = functionOffset.getBlockZ(); final int offZ = functionOffset.z();
Operation operation = clipboardHolder Operation operation = clipboardHolder
.createPaste(editSession) .createPaste(editSession)
.to(target) .to(target)
.ignoreAirBlocks(true) .ignoreAirBlocks(true)
.filter(v -> buffer.add(v.getBlockX() + offX, v.getBlockY() + offY, v.getBlockZ() + offZ)) .filter(v -> buffer.add(v.x() + offX, v.y() + offY, v.z() + offZ))
.build(); .build();
Operations.completeLegacy(operation); Operations.completeLegacy(operation);

Datei anzeigen

@ -121,7 +121,7 @@ public abstract class Spline {
* 2 dimensional "cross" product. cross2D(v1, v2) = |v1|*|v2|*sin(theta) or v1 X v2 taking Y to be 0 * 2 dimensional "cross" product. cross2D(v1, v2) = |v1|*|v2|*sin(theta) or v1 X v2 taking Y to be 0
*/ */
private double cross2D(Vector2 v1, Vector2 v2) { private double cross2D(Vector2 v1, Vector2 v2) {
return v1.getX() * v2.getZ() - v2.getX() * v1.getZ(); return v1.x() * v2.z() - v2.x() * v1.z();
} }
/** /**
@ -144,7 +144,7 @@ public abstract class Spline {
// Calculate rotation from spline // Calculate rotation from spline
Vector3 deriv = interpolation.get1stDerivative(position); Vector3 deriv = interpolation.get1stDerivative(position);
Vector2 deriv2D = Vector2.at(deriv.getX(), deriv.getZ()).normalize(); Vector2 deriv2D = Vector2.at(deriv.x(), deriv.z()).normalize();
double angle = Math.toDegrees( double angle = Math.toDegrees(
-Math.atan2(cross2D(direction, deriv2D), direction.dot(deriv2D)) -Math.atan2(cross2D(direction, deriv2D), direction.dot(deriv2D))
); );

Datei anzeigen

@ -79,13 +79,13 @@ public class SweepBrush implements Brush, ResettableTool {
Clipboard clipboard = holder.getClipboard(); Clipboard clipboard = holder.getClipboard();
BlockVector3 dimensions = clipboard.getDimensions(); BlockVector3 dimensions = clipboard.getDimensions();
double quality = Math.max(dimensions.getBlockX(), dimensions.getBlockZ()); double quality = Math.max(dimensions.x(), dimensions.z());
AffineTransform transform = new AffineTransform(); AffineTransform transform = new AffineTransform();
ClipboardSpline spline = new ClipboardSpline(editSession, holder, interpol, transform, nodes.size()); ClipboardSpline spline = new ClipboardSpline(editSession, holder, interpol, transform, nodes.size());
if (dimensions.getBlockX() > dimensions.getBlockZ()) { if (dimensions.x() > dimensions.z()) {
spline.setDirection(Vector2.at(0, 1)); spline.setDirection(Vector2.at(0, 1));
} }

Datei anzeigen

@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.configuration;
import com.fastasyncworldedit.core.configuration.file.YamlConfiguration; import com.fastasyncworldedit.core.configuration.file.YamlConfiguration;
import com.fastasyncworldedit.core.util.StringMan; import com.fastasyncworldedit.core.util.StringMan;
import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.internal.util.LogManagerCompat;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -14,8 +15,10 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
@ -27,6 +30,9 @@ public class Config {
private static final Logger LOGGER = LogManagerCompat.getLogger(); private static final Logger LOGGER = LogManagerCompat.getLogger();
private final Map<String, Object> removedKeyVals = new HashMap<>();
private List<String> existingMigrateNodes = null;
public Config() { public Config() {
save(new PrintWriter(new ByteArrayOutputStream(0)), getClass(), this, 0); save(new PrintWriter(new ByteArrayOutputStream(0)), getClass(), this, 0);
} }
@ -43,7 +49,8 @@ public class Config {
try { try {
return (T) field.get(instance); return (T) field.get(instance);
} catch (IllegalAccessException e) { } catch (IllegalAccessException e) {
e.printStackTrace(); LOGGER.error("Failed to get config option: {}", key, e);
return null;
} }
} }
} }
@ -67,6 +74,10 @@ public class Config {
if (field.getAnnotation(Final.class) != null) { if (field.getAnnotation(Final.class) != null) {
return; return;
} }
Migrate migrate = field.getAnnotation(Migrate.class);
if (existingMigrateNodes != null && migrate != null) {
existingMigrateNodes.add(migrate.value());
}
if (field.getType() == String.class && !(value instanceof String)) { if (field.getType() == String.class && !(value instanceof String)) {
value = value + ""; value = value + "";
} }
@ -74,17 +85,22 @@ public class Config {
field.set(instance, value); field.set(instance, value);
return; return;
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); LOGGER.error("Failed to set config option: {}", key);
} }
} }
} }
LOGGER.error("Failed to set config option: {}: {} | {} | {}.yml", key, value, instance, root.getSimpleName()); removedKeyVals.put(key, value);
LOGGER.error(
"Failed to set config option: {}: {} | {} | {}.yml. This is likely because it was removed.",
key,
value,
instance,
root.getSimpleName()
);
} }
public boolean load(File file) { public boolean load(File file) {
if (!file.exists()) { existingMigrateNodes = new ArrayList<>();
return false;
}
YamlConfiguration yml = YamlConfiguration.loadConfiguration(file); YamlConfiguration yml = YamlConfiguration.loadConfiguration(file);
for (String key : yml.getKeys(true)) { for (String key : yml.getKeys(true)) {
Object value = yml.get(key); Object value = yml.get(key);
@ -93,6 +109,10 @@ public class Config {
} }
set(key, value, getClass()); set(key, value, getClass());
} }
for (String node : existingMigrateNodes) {
removedKeyVals.remove(node);
}
existingMigrateNodes = null;
return true; return true;
} }
@ -113,7 +133,7 @@ public class Config {
save(writer, getClass(), instance, 0); save(writer, getClass(), instance, 0);
writer.close(); writer.close();
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); LOGGER.error("Failed to save config file: {}", file, e);
} }
} }
@ -166,6 +186,19 @@ public class Config {
} }
/**
* Indicates that a field should be instantiated / created.
*
* @since 2.10.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Migrate {
String value();
}
@Ignore // This is not part of the config @Ignore // This is not part of the config
public static class ConfigBlock<T> { public static class ConfigBlock<T> {
@ -222,7 +255,6 @@ public class Config {
try { try {
String CTRF = System.lineSeparator(); String CTRF = System.lineSeparator();
String spacing = StringMan.repeat(" ", indent); String spacing = StringMan.repeat(" ", indent);
HashMap<Class<?>, Object> instances = new HashMap<>();
for (Field field : clazz.getFields()) { for (Field field : clazz.getFields()) {
if (field.getAnnotation(Ignore.class) != null) { if (field.getAnnotation(Ignore.class) != null) {
continue; continue;
@ -239,31 +271,14 @@ public class Config {
} }
if (current == ConfigBlock.class) { if (current == ConfigBlock.class) {
current = (Class<?>) ((ParameterizedType) (field.getGenericType())).getActualTypeArguments()[0]; current = (Class<?>) ((ParameterizedType) (field.getGenericType())).getActualTypeArguments()[0];
comment = current.getAnnotation(Comment.class); handleConfigBlockSave(writer, instance, indent, field, spacing, CTRF, current);
if (comment != null) {
for (String commentLine : comment.value()) {
writer.write(spacing + "# " + commentLine + CTRF);
}
}
BlockName blockNames = current.getAnnotation(BlockName.class);
if (blockNames != null) {
writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF);
ConfigBlock configBlock = (ConfigBlock) field.get(instance);
if (configBlock == null || configBlock.getInstances().isEmpty()) {
configBlock = new ConfigBlock();
field.set(instance, configBlock);
for (String blockName : blockNames.value()) {
configBlock.put(blockName, current.getDeclaredConstructor().newInstance());
}
}
// Save each instance
for (Map.Entry<String, Object> entry : ((Map<String, Object>) configBlock.getRaw()).entrySet()) {
String key = entry.getKey();
writer.write(spacing + " " + toNodeName(key) + ":" + CTRF);
save(writer, current, entry.getValue(), indent + 4);
}
}
continue; continue;
} else if (!removedKeyVals.isEmpty()) {
Migrate migrate = field.getAnnotation(Migrate.class);
Object value;
if (migrate != null && (value = removedKeyVals.remove(migrate.value())) != null) {
field.set(instance, value);
}
} }
Create create = field.getAnnotation(Create.class); Create create = field.getAnnotation(Create.class);
if (create != null) { if (create != null) {
@ -281,7 +296,6 @@ public class Config {
writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF); writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF);
if (value == null) { if (value == null) {
field.set(instance, value = current.getDeclaredConstructor().newInstance()); field.set(instance, value = current.getDeclaredConstructor().newInstance());
instances.put(current, value);
} }
save(writer, current, value, indent + 2); save(writer, current, value, indent + 2);
} else { } else {
@ -292,7 +306,42 @@ public class Config {
} }
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); LOGGER.error("Failed to save config file", e);
}
}
private <T> void handleConfigBlockSave(
PrintWriter writer,
Object instance,
int indent,
Field field,
String spacing,
String CTRF,
Class<T> current
) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
Comment comment = current.getAnnotation(Comment.class);
if (comment != null) {
for (String commentLine : comment.value()) {
writer.write(spacing + "# " + commentLine + CTRF);
}
}
BlockName blockNames = current.getAnnotation(BlockName.class);
if (blockNames != null) {
writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF);
ConfigBlock<T> configBlock = (ConfigBlock<T>) field.get(instance);
if (configBlock == null || configBlock.getInstances().isEmpty()) {
configBlock = new ConfigBlock<>();
field.set(instance, configBlock);
for (String blockName : blockNames.value()) {
configBlock.put(blockName, current.getDeclaredConstructor().newInstance());
}
}
// Save each instance
for (Map.Entry<String, T> entry : configBlock.getRaw().entrySet()) {
String key = entry.getKey();
writer.write(spacing + " " + toNodeName(key) + ":" + CTRF);
save(writer, current, entry.getValue(), indent + 4);
}
} }
} }
@ -311,7 +360,7 @@ public class Config {
return field; return field;
} catch (Throwable ignored) { } catch (Throwable ignored) {
LOGGER.warn( LOGGER.warn(
"Invalid config field: {} for {}", "Invalid config field: {} for {}. It is possible this is because it has been removed.",
StringMan.join(split, "."), StringMan.join(split, "."),
toNodeName(instance.getClass().getSimpleName()) toNodeName(instance.getClass().getSimpleName())
); );
@ -379,7 +428,7 @@ public class Config {
return null; return null;
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); LOGGER.error("Failed retrieving instance for config node: {}", StringUtil.joinString(split, "."), e);
} }
return null; return null;
} }

Datei anzeigen

@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.configuration;
import com.fastasyncworldedit.core.limit.FaweLimit; import com.fastasyncworldedit.core.limit.FaweLimit;
import com.fastasyncworldedit.core.limit.PropertyRemap; import com.fastasyncworldedit.core.limit.PropertyRemap;
import com.sk89q.worldedit.LocalConfiguration;
import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.block.BlockTypesCache;
@ -79,6 +80,8 @@ public class Settings extends Config {
@Create @Create
public REGION_RESTRICTIONS_OPTIONS REGION_RESTRICTIONS_OPTIONS; public REGION_RESTRICTIONS_OPTIONS REGION_RESTRICTIONS_OPTIONS;
@Create @Create
public GENERAL GENERAL;
@Create
public ConfigBlock<LIMITS> LIMITS; public ConfigBlock<LIMITS> LIMITS;
private Settings() { private Settings() {
@ -138,13 +141,35 @@ public class Settings extends Config {
); );
limit.MAX_FAILS = Math.max(limit.MAX_FAILS, newLimit.MAX_FAILS != -1 ? newLimit.MAX_FAILS : Integer.MAX_VALUE); limit.MAX_FAILS = Math.max(limit.MAX_FAILS, newLimit.MAX_FAILS != -1 ? newLimit.MAX_FAILS : Integer.MAX_VALUE);
limit.MAX_ITERATIONS = Math.max( limit.MAX_ITERATIONS = Math.max(
limit.MAX_ITERATIONS, limit.MAX_ITERATIONS, newLimit.MAX_ITERATIONS != -1 ? newLimit.MAX_ITERATIONS : Integer.MAX_VALUE);
newLimit.MAX_ITERATIONS != -1 ? newLimit.MAX_ITERATIONS : Integer.MAX_VALUE limit.MAX_RADIUS = Math.max(
limit.MAX_RADIUS,
newLimit.MAX_RADIUS != -1 ? newLimit.MAX_RADIUS : Integer.MAX_VALUE
);
limit.MAX_SUPER_PICKAXE_SIZE = Math.max(
limit.MAX_SUPER_PICKAXE_SIZE,
newLimit.MAX_SUPER_PICKAXE_SIZE != -1 ? newLimit.MAX_SUPER_PICKAXE_SIZE : Integer.MAX_VALUE
);
limit.MAX_BRUSH_RADIUS = Math.max(
limit.MAX_BRUSH_RADIUS,
newLimit.MAX_BRUSH_RADIUS != -1 ? newLimit.MAX_BRUSH_RADIUS : Integer.MAX_VALUE
);
limit.MAX_BUTCHER_RADIUS = Math.max(
limit.MAX_BUTCHER_RADIUS,
newLimit.MAX_BUTCHER_RADIUS != -1 ? newLimit.MAX_BUTCHER_RADIUS : Integer.MAX_VALUE
); );
limit.MAX_HISTORY = Math.max( limit.MAX_HISTORY = Math.max(
limit.MAX_HISTORY, limit.MAX_HISTORY,
newLimit.MAX_HISTORY_MB != -1 ? newLimit.MAX_HISTORY_MB : Integer.MAX_VALUE newLimit.MAX_HISTORY_MB != -1 ? newLimit.MAX_HISTORY_MB : Integer.MAX_VALUE
); );
limit.SCHEM_FILE_NUM_LIMIT = Math.max(
limit.SCHEM_FILE_NUM_LIMIT,
newLimit.SCHEM_FILE_NUM_LIMIT != -1 ? newLimit.SCHEM_FILE_NUM_LIMIT : Integer.MAX_VALUE
);
limit.SCHEM_FILE_SIZE_LIMIT = Math.max(
limit.SCHEM_FILE_SIZE_LIMIT,
newLimit.SCHEM_FILE_SIZE_LIMIT != -1 ? newLimit.SCHEM_FILE_SIZE_LIMIT : Integer.MAX_VALUE
);
limit.MAX_EXPRESSION_MS = Math.max( limit.MAX_EXPRESSION_MS = Math.max(
limit.MAX_EXPRESSION_MS, limit.MAX_EXPRESSION_MS,
newLimit.MAX_EXPRESSION_MS != -1 ? newLimit.MAX_EXPRESSION_MS : Integer.MAX_VALUE newLimit.MAX_EXPRESSION_MS != -1 ? newLimit.MAX_EXPRESSION_MS : Integer.MAX_VALUE
@ -342,6 +367,14 @@ public class Settings extends Config {
public int MAX_ITERATIONS = 1000; public int MAX_ITERATIONS = 1000;
@Comment("Max allowed entities (e.g. cows)") @Comment("Max allowed entities (e.g. cows)")
public int MAX_ENTITIES = 1337; public int MAX_ENTITIES = 1337;
@Comment("Max allowed radius (e.g. for //sphere)")
public int MAX_RADIUS = LocalConfiguration.MAX_RADIUS;
@Comment("Max allowed superpickaxe size")
public int MAX_SUPER_PICKAXE_SIZE = LocalConfiguration.MAX_SUPER_RADIUS;
@Comment("Max allowed brush radius")
public int MAX_BRUSH_RADIUS = LocalConfiguration.MAX_BRUSH_RADIUS;
@Comment("Max allowed butcher radius")
public int MAX_BUTCHER_RADIUS = LocalConfiguration.MAX_BUTCHER_RADIUS;
@Comment({ @Comment({
"Blockstates include Banner, Beacon, BrewingStand, Chest, CommandBlock, ", "Blockstates include Banner, Beacon, BrewingStand, Chest, CommandBlock, ",
"CreatureSpawner, Dispenser, Dropper, EndGateway, Furnace, Hopper, Jukebox, ", "CreatureSpawner, Dispenser, Dropper, EndGateway, Furnace, Hopper, Jukebox, ",
@ -353,6 +386,18 @@ public class Settings extends Config {
" - History on disk or memory will be deleted", " - History on disk or memory will be deleted",
}) })
public int MAX_HISTORY_MB = -1; public int MAX_HISTORY_MB = -1;
@Comment({
"Sets a maximum limit (in kb) for the size of a player's schematics directory (per-player mode only)",
"Set to -1 to disable"
})
@Migrate("experimental.per-player-file-size-limit")
public int SCHEM_FILE_SIZE_LIMIT = -1;
@Comment({
"Sets a maximum limit for the amount of schematics in a player's schematics directory (per-player mode only)",
"Set to -1 to disable"
})
@Migrate("experimental.per-player-file-num-limit")
public int SCHEM_FILE_NUM_LIMIT = -1;
@Comment("Maximum time in milliseconds //calc can execute") @Comment("Maximum time in milliseconds //calc can execute")
public int MAX_EXPRESSION_MS = 50; public int MAX_EXPRESSION_MS = 50;
@Comment({ @Comment({
@ -615,18 +660,6 @@ public class Settings extends Config {
}) })
public boolean ALLOW_TICK_FLUIDS = false; public boolean ALLOW_TICK_FLUIDS = false;
@Comment({
"Sets a maximum limit (in kb) for the size of a player's schematics directory (per-player mode only)",
"Set to -1 to disable"
})
public int PER_PLAYER_FILE_SIZE_LIMIT = -1;
@Comment({
"Sets a maximum limit for the amount of schematics in a player's schematics directory (per-player mode only)",
"Set to -1 to disable"
})
public int PER_PLAYER_FILE_NUM_LIMIT = -1;
} }
@Comment({"Web/HTTP connection related settings"}) @Comment({"Web/HTTP connection related settings"})
@ -635,6 +668,13 @@ public class Settings extends Config {
@Comment({"The web interface for clipboards", " - All schematics are anonymous and private", " - Downloads can be deleted by the user", " - Supports clipboard uploads, downloads and saves",}) @Comment({"The web interface for clipboards", " - All schematics are anonymous and private", " - Downloads can be deleted by the user", " - Supports clipboard uploads, downloads and saves",})
public String URL = "https://schem.intellectualsites.com/fawe/"; public String URL = "https://schem.intellectualsites.com/fawe/";
@Comment({"The url of the backend server (Arkitektonika)"})
public String ARKITEKTONIKA_BACKEND_URL = "https://api.schematic.cloud/";
@Comment({"The url used to generate a download link from.", "{key} will be replaced with the generated key"})
public String ARKITEKTONIKA_DOWNLOAD_URL = "https://schematic.cloud/download/{key}";
@Comment({"The url used to generate a deletion link from.", "{key} will be replaced with the generated key"})
public String ARKITEKTONIKA_DELETE_URL = "https://schematic.cloud/delete/{key}";
@Comment("The maximum amount of time in seconds the plugin can attempt to load images for.") @Comment("The maximum amount of time in seconds the plugin can attempt to load images for.")
public int MAX_IMAGE_LOAD_TIME = 5; public int MAX_IMAGE_LOAD_TIME = 5;
@ -744,4 +784,13 @@ public class Settings extends Config {
} }
public static class GENERAL {
@Comment({
"If the player should be relocated/unstuck when a generation command would bury them",
})
public boolean UNSTUCK_ON_GENERATE = true;
}
} }

Datei anzeigen

@ -179,13 +179,13 @@ public class RollbackDatabase extends AsyncNotifyQueue {
} }
try (PreparedStatement stmt = connection.prepareStatement(stmtStr.formatted(this.prefix))) { try (PreparedStatement stmt = connection.prepareStatement(stmtStr.formatted(this.prefix))) {
stmt.setInt(1, (int) (minTime / 1000)); stmt.setInt(1, (int) (minTime / 1000));
stmt.setInt(2, pos1.getBlockX()); stmt.setInt(2, pos1.x());
stmt.setInt(3, pos2.getBlockX()); stmt.setInt(3, pos2.x());
stmt.setInt(4, pos1.getBlockZ()); stmt.setInt(4, pos1.z());
stmt.setInt(5, pos2.getBlockZ()); stmt.setInt(5, pos2.z());
// Keep 128 offset for backwards-compatibility // Keep 128 offset for backwards-compatibility
stmt.setInt(6, pos1.getBlockY() - 128); stmt.setInt(6, pos1.y() - 128);
stmt.setInt(7, pos2.getBlockY() - 128); stmt.setInt(7, pos2.y() - 128);
if (uuid != null) { if (uuid != null) {
byte[] uuidBytes = toBytes(uuid); byte[] uuidBytes = toBytes(uuid);
stmt.setBytes(8, uuidBytes); stmt.setBytes(8, uuidBytes);
@ -210,13 +210,13 @@ public class RollbackDatabase extends AsyncNotifyQueue {
.array(); .array();
stmt.setBytes(1, uuidBytes); stmt.setBytes(1, uuidBytes);
stmt.setInt(2, (int) (minTime / 1000)); stmt.setInt(2, (int) (minTime / 1000));
stmt.setInt(3, pos1.getBlockX()); stmt.setInt(3, pos1.x());
stmt.setInt(4, pos2.getBlockX()); stmt.setInt(4, pos2.x());
stmt.setInt(5, pos1.getBlockZ()); stmt.setInt(5, pos1.z());
stmt.setInt(6, pos2.getBlockZ()); stmt.setInt(6, pos2.z());
// Keep 128 offset for backwards-compatibility // Keep 128 offset for backwards-compatibility
stmt.setInt(7, pos1.getBlockY() - 128); stmt.setInt(7, pos1.y() - 128);
stmt.setInt(8, pos2.getBlockY() - 128); stmt.setInt(8, pos2.y() - 128);
} }
} }
return count; return count;
@ -262,13 +262,13 @@ public class RollbackDatabase extends AsyncNotifyQueue {
BlockVector3 pos1 = change.getMinimumPoint(); BlockVector3 pos1 = change.getMinimumPoint();
BlockVector3 pos2 = change.getMaximumPoint(); BlockVector3 pos2 = change.getMaximumPoint();
stmt.setInt(4, pos1.getX()); stmt.setInt(4, pos1.x());
stmt.setInt(5, pos2.getX()); stmt.setInt(5, pos2.x());
stmt.setInt(6, pos1.getZ()); stmt.setInt(6, pos1.z());
stmt.setInt(7, pos2.getZ()); stmt.setInt(7, pos2.z());
// Keep 128 offset for backwards-compatibility // Keep 128 offset for backwards-compatibility
stmt.setInt(8, pos1.getY() - 128); stmt.setInt(8, pos1.y() - 128);
stmt.setInt(9, pos2.getY() - 128); stmt.setInt(9, pos2.y() - 128);
stmt.setString(10, change.getCommand()); stmt.setString(10, change.getCommand());
stmt.setInt(11, change.size()); stmt.setInt(11, change.size());
stmt.executeUpdate(); stmt.executeUpdate();

Datei anzeigen

@ -0,0 +1,30 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <https://www.gnu.org/licenses/>.
*/
package com.fastasyncworldedit.core.exception;
/**
* Thrown when a maximum radius for a brush is reached.
*/
public class BrushRadiusLimitException extends RadiusLimitException {
public BrushRadiusLimitException(int maxBrushRadius) {
super(maxBrushRadius);
}
}

Datei anzeigen

@ -0,0 +1,41 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* 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 <https://www.gnu.org/licenses/>.
*/
package com.fastasyncworldedit.core.exception;
import com.sk89q.worldedit.WorldEditException;
/**
* Thrown when a maximum radius is reached, such as, for example,
* in the case of a sphere command.
*/
public class RadiusLimitException extends WorldEditException {
private final int maxRadius;
public RadiusLimitException(int maxRadius) {
this.maxRadius = maxRadius;
}
public int getMaxRadius() {
return maxRadius;
}
//FAWE end
}

Datei anzeigen

@ -24,7 +24,7 @@ public final class BlockTranslateExtent extends AbstractDelegateExtent {
@Override @Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block) throws WorldEditException { public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block) throws WorldEditException {
return getExtent().setBlock(location.getX() + dx, location.getY() + dy, location.getZ() + dz, block); return getExtent().setBlock(location.x() + dx, location.y() + dy, location.z() + dz, block);
} }
@Override @Override
@ -49,7 +49,7 @@ public final class BlockTranslateExtent extends AbstractDelegateExtent {
@Override @Override
public BlockState getBlock(BlockVector3 location) { public BlockState getBlock(BlockVector3 location) {
return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ()); return getBlock(location.x(), location.y(), location.z());
} }
@Override @Override

Datei anzeigen

@ -64,11 +64,11 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc
@Override @Override
public final boolean contains(BlockVector3 p) { public final boolean contains(BlockVector3 p) {
return contains(p.getBlockX(), p.getBlockY(), p.getBlockZ()); return contains(p.x(), p.y(), p.z());
} }
public final boolean contains(BlockVector2 p) { public final boolean contains(BlockVector2 p) {
return contains(p.getBlockX(), p.getBlockZ()); return contains(p.x(), p.z());
} }
@Override @Override
@ -96,7 +96,7 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc
@Override @Override
public BiomeType getBiome(BlockVector3 position) { public BiomeType getBiome(BlockVector3 position) {
return getBiomeType(position.getX(), position.getY(), position.getZ()); return getBiomeType(position.x(), position.y(), position.z());
} }
@Override @Override
@ -112,7 +112,7 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc
@Override @Override
public BaseBlock getFullBlock(BlockVector3 position) { public BaseBlock getFullBlock(BlockVector3 position) {
return getFullBlock(position.getX(), position.getY(), position.getZ()); return getFullBlock(position.x(), position.y(), position.z());
} }
@Override @Override
@ -128,7 +128,7 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc
@Override @Override
public BlockState getBlock(BlockVector3 position) { public BlockState getBlock(BlockVector3 position) {
return getBlock(position.getX(), position.getY(), position.getZ()); return getBlock(position.x(), position.y(), position.z());
} }
@Override @Override

Datei anzeigen

@ -66,7 +66,7 @@ public final class HistoryExtent extends AbstractDelegateExtent {
@Override @Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException { public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
return setBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ(), block); return setBlock(location.x(), location.y(), location.z(), block);
} }
@Nullable @Nullable
@ -111,7 +111,7 @@ public final class HistoryExtent extends AbstractDelegateExtent {
public boolean setBiome(BlockVector3 position, BiomeType newBiome) { public boolean setBiome(BlockVector3 position, BiomeType newBiome) {
BiomeType oldBiome = this.getBiome(position); BiomeType oldBiome = this.getBiome(position);
if (!oldBiome.getId().equals(newBiome.getId())) { if (!oldBiome.getId().equals(newBiome.getId())) {
this.changeSet.addBiomeChange(position.getBlockX(), position.getBlockY(), position.getBlockZ(), oldBiome, newBiome); this.changeSet.addBiomeChange(position.x(), position.y(), position.z(), oldBiome, newBiome);
return getExtent().setBiome(position, newBiome); return getExtent().setBiome(position, newBiome);
} else { } else {
return false; return false;

Datei anzeigen

@ -373,12 +373,12 @@ public final class LimitExtent extends AbstractDelegateExtent {
size = ((Collection<BlockVector3>) positions).size(); size = ((Collection<BlockVector3>) positions).size();
} else if (positions instanceof Region) { } else if (positions instanceof Region) {
BlockVector3 dim = ((Region) positions).getDimensions(); BlockVector3 dim = ((Region) positions).getDimensions();
size = dim.getX() * dim.getY() * dim.getZ(); size = dim.x() * dim.y() * dim.z();
} else if (positions instanceof Extent) { } else if (positions instanceof Extent) {
BlockVector3 min = ((Extent) positions).getMinimumPoint(); BlockVector3 min = ((Extent) positions).getMinimumPoint();
BlockVector3 max = ((Extent) positions).getMinimumPoint(); BlockVector3 max = ((Extent) positions).getMinimumPoint();
BlockVector3 dim = max.subtract(min).add(BlockVector3.ONE); BlockVector3 dim = max.subtract(min).add(BlockVector3.ONE);
size = dim.getX() * dim.getY() * dim.getZ(); size = dim.x() * dim.y() * dim.z();
} else { } else {
ExtentFilterBlock block = new ExtentFilterBlock(this); ExtentFilterBlock block = new ExtentFilterBlock(this);
for (BlockVector3 pos : positions) { for (BlockVector3 pos : positions) {

Datei anzeigen

@ -38,9 +38,9 @@ public final class PositionTransformExtent extends ResettableExtent {
if (min == null) { if (min == null) {
min = pos; min = pos;
} }
mutable.mutX(pos.getX() - min.getX()); mutable.mutX(pos.x() - min.x());
mutable.mutY(pos.getY() - min.getY()); mutable.mutY(pos.y() - min.y());
mutable.mutZ(pos.getZ() - min.getZ()); mutable.mutZ(pos.z() - min.z());
MutableVector3 tmp = new MutableVector3(transform.apply(mutable.toVector3())); MutableVector3 tmp = new MutableVector3(transform.apply(mutable.toVector3()));
return min.add(tmp.roundHalfUp().toBlockPoint()); return min.add(tmp.roundHalfUp().toBlockPoint());
} }
@ -49,9 +49,9 @@ public final class PositionTransformExtent extends ResettableExtent {
if (min == null) { if (min == null) {
min = BlockVector3.at(x, y, z); min = BlockVector3.at(x, y, z);
} }
mutable.mutX(x - min.getX()); mutable.mutX(x - min.x());
mutable.mutY(y - min.getY()); mutable.mutY(y - min.y());
mutable.mutZ(z - min.getZ()); mutable.mutZ(z - min.z());
MutableVector3 tmp = new MutableVector3(transform.apply(mutable.toVector3())); MutableVector3 tmp = new MutableVector3(transform.apply(mutable.toVector3()));
return min.add(tmp.roundHalfUp().toBlockPoint()); return min.add(tmp.roundHalfUp().toBlockPoint());
} }
@ -73,10 +73,10 @@ public final class PositionTransformExtent extends ResettableExtent {
@Override @Override
public BiomeType getBiome(BlockVector3 position) { public BiomeType getBiome(BlockVector3 position) {
mutable.mutX(position.getBlockX()); mutable.mutX(position.x());
mutable.mutZ(position.getBlockZ()); mutable.mutZ(position.z());
mutable.mutY(position.getBlockY()); mutable.mutY(position.y());
return super.getBiome(getPos(mutable.getX(), mutable.getY(), mutable.getZ())); return super.getBiome(getPos(mutable.x(), mutable.y(), mutable.z()));
} }
@Override @Override
@ -92,10 +92,10 @@ public final class PositionTransformExtent extends ResettableExtent {
@Override @Override
public boolean setBiome(BlockVector3 position, BiomeType biome) { public boolean setBiome(BlockVector3 position, BiomeType biome) {
mutable.mutX(position.getBlockX()); mutable.mutX(position.x());
mutable.mutZ(position.getBlockZ()); mutable.mutZ(position.z());
mutable.mutY(position.getBlockY()); mutable.mutY(position.y());
return super.setBiome(getPos(mutable.getX(), mutable.getY(), mutable.getZ()), biome); return super.setBiome(getPos(mutable.x(), mutable.y(), mutable.z()), biome);
} }
public void setTransform(Transform transform) { public void setTransform(Transform transform) {

Datei anzeigen

@ -80,12 +80,12 @@ public final class ProcessedWEExtent extends AbstractDelegateExtent {
@Override @Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block)
throws WorldEditException { throws WorldEditException {
return setBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ(), block); return setBlock(location.x(), location.y(), location.z(), block);
} }
@Override @Override
public BlockState getBlock(BlockVector3 location) { public BlockState getBlock(BlockVector3 location) {
return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ()); return getBlock(location.x(), location.y(), location.z());
} }
@Override @Override

Datei anzeigen

@ -41,8 +41,8 @@ public final class SourceMaskExtent extends TemporalExtent {
@Override @Override
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block) throws WorldEditException { public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block) throws WorldEditException {
set(location.getBlockX(), location.getBlockY(), location.getBlockZ(), block); set(location.x(), location.y(), location.z(), block);
return mask.test(location) && super.setBlock(location.getX(), location.getY(), location.getZ(), block); return mask.test(location) && super.setBlock(location.x(), location.y(), location.z(), block);
} }
@Override @Override

Datei anzeigen

@ -44,7 +44,7 @@ public abstract class TemporalExtent extends PassthroughExtent {
@Override @Override
public BlockState getBlock(BlockVector3 position) { public BlockState getBlock(BlockVector3 position) {
if (position.getX() == x && position.getY() == y && position.getZ() == z) { if (position.x() == x && position.y() == y && position.z() == z) {
return block.toImmutableState(); return block.toImmutableState();
} }
return super.getBlock(position); return super.getBlock(position);
@ -60,7 +60,7 @@ public abstract class TemporalExtent extends PassthroughExtent {
@Override @Override
public BaseBlock getFullBlock(BlockVector3 position) { public BaseBlock getFullBlock(BlockVector3 position) {
if (position.getX() == x && position.getY() == y && position.getZ() == z) { if (position.x() == x && position.y() == y && position.z() == z) {
if (block instanceof BaseBlock) { if (block instanceof BaseBlock) {
return (BaseBlock) block; return (BaseBlock) block;
} else { } else {
@ -72,7 +72,7 @@ public abstract class TemporalExtent extends PassthroughExtent {
@Override @Override
public BiomeType getBiome(BlockVector3 position) { public BiomeType getBiome(BlockVector3 position) {
if (position.getX() == bx && position.getZ() == bz) { if (position.x() == bx && position.z() == bz) {
return biome; return biome;
} }
return super.getBiome(position); return super.getBiome(position);

Datei anzeigen

@ -41,7 +41,7 @@ public class CPUOptimizedClipboard extends LinearClipboard {
@Override @Override
public boolean setBiome(BlockVector3 position, BiomeType biome) { public boolean setBiome(BlockVector3 position, BiomeType biome) {
return setBiome(position.getX(), position.getY(), position.getZ(), biome); return setBiome(position.x(), position.y(), position.z(), biome);
} }
@Override @Override
@ -92,7 +92,7 @@ public class CPUOptimizedClipboard extends LinearClipboard {
@Override @Override
public BiomeType getBiome(BlockVector3 position) { public BiomeType getBiome(BlockVector3 position) {
return getBiome(getBiomeIndex(position.getX(), position.getY(), position.getZ())); return getBiome(getBiomeIndex(position.x(), position.y(), position.z()));
} }
public void convertTilesToIndex() { public void convertTilesToIndex() {

Datei anzeigen

@ -359,7 +359,7 @@ public class DiskOptimizedClipboard extends LinearClipboard {
@Override @Override
public boolean setBiome(BlockVector3 position, BiomeType biome) { public boolean setBiome(BlockVector3 position, BiomeType biome) {
return setBiome(position.getX(), position.getY(), position.getZ(), biome); return setBiome(position.x(), position.y(), position.z(), biome);
} }
@Override @Override
@ -417,7 +417,7 @@ public class DiskOptimizedClipboard extends LinearClipboard {
@Override @Override
public BiomeType getBiome(BlockVector3 position) { public BiomeType getBiome(BlockVector3 position) {
return getBiome(getBiomeIndex(position.getX(), position.getY(), position.getZ())); return getBiome(getBiomeIndex(position.x(), position.y(), position.z()));
} }
public BlockArrayClipboard toClipboard() { public BlockArrayClipboard toClipboard() {
@ -438,9 +438,9 @@ public class DiskOptimizedClipboard extends LinearClipboard {
super.setOrigin(origin); super.setOrigin(origin);
origin = origin.subtract(offset); origin = origin.subtract(offset);
try { try {
byteBuffer.putShort(10, (short) origin.getBlockX()); byteBuffer.putShort(10, (short) origin.x());
byteBuffer.putShort(12, (short) origin.getBlockY()); byteBuffer.putShort(12, (short) origin.y());
byteBuffer.putShort(14, (short) origin.getBlockZ()); byteBuffer.putShort(14, (short) origin.z());
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -450,9 +450,9 @@ public class DiskOptimizedClipboard extends LinearClipboard {
protected void setOffset(BlockVector3 offset) { protected void setOffset(BlockVector3 offset) {
super.setOffset(offset); super.setOffset(offset);
try { try {
byteBuffer.putShort(16, (short) offset.getBlockX()); byteBuffer.putShort(16, (short) offset.x());
byteBuffer.putShort(18, (short) offset.getBlockY()); byteBuffer.putShort(18, (short) offset.y());
byteBuffer.putShort(20, (short) offset.getBlockZ()); byteBuffer.putShort(20, (short) offset.z());
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -588,9 +588,9 @@ public class DiskOptimizedClipboard extends LinearClipboard {
CompoundTag data = entity.getState().getNbtData(); CompoundTag data = entity.getState().getNbtData();
HashMap<String, Tag> value = new HashMap<>(data.getValue()); HashMap<String, Tag> value = new HashMap<>(data.getValue());
List<DoubleTag> pos = new ArrayList<>(3); List<DoubleTag> pos = new ArrayList<>(3);
pos.add(new DoubleTag(entity.getLocation().getX())); pos.add(new DoubleTag(entity.getLocation().x()));
pos.add(new DoubleTag(entity.getLocation().getX())); pos.add(new DoubleTag(entity.getLocation().x()));
pos.add(new DoubleTag(entity.getLocation().getX())); pos.add(new DoubleTag(entity.getLocation().x()));
value.put("Pos", new ListTag(DoubleTag.class, pos)); value.put("Pos", new ListTag(DoubleTag.class, pos));
nbtOS.writeTag(new CompoundTag(value)); nbtOS.writeTag(new CompoundTag(value));
} }

Datei anzeigen

@ -64,7 +64,7 @@ public class MemoryOptimizedClipboard extends LinearClipboard {
@Override @Override
public boolean setBiome(BlockVector3 position, BiomeType biome) { public boolean setBiome(BlockVector3 position, BiomeType biome) {
return setBiome(position.getX(), position.getY(), position.getZ(), biome); return setBiome(position.x(), position.y(), position.z(), biome);
} }
@Override @Override
@ -115,7 +115,7 @@ public class MemoryOptimizedClipboard extends LinearClipboard {
@Override @Override
public BiomeType getBiome(BlockVector3 position) { public BiomeType getBiome(BlockVector3 position) {
return getBiome(getBiomeIndex(position.getX(), position.getY(), position.getZ())); return getBiome(getBiomeIndex(position.x(), position.y(), position.z()));
} }
private int getOrdinal(int index) { private int getOrdinal(int index) {

Datei anzeigen

@ -70,17 +70,17 @@ public abstract class SimpleClipboard implements Clipboard {
@Override @Override
public final int getWidth() { public final int getWidth() {
return size.getBlockX(); return size.x();
} }
@Override @Override
public final int getHeight() { public final int getHeight() {
return size.getBlockY(); return size.y();
} }
@Override @Override
public final int getLength() { public final int getLength() {
return size.getBlockZ(); return size.z();
} }
@Override @Override

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen