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:
Commit
111eebe828
3
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
3
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -27,10 +27,9 @@ body:
|
||||
description: Which server version version you using? If your server version is not listed, it is not supported. Update to a supported version first.
|
||||
multiple: false
|
||||
options:
|
||||
- '1.20.4'
|
||||
- '1.20.5/6'
|
||||
- '1.20'
|
||||
- '1.19.4'
|
||||
- '1.18.2'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
3
.github/renovate.json
vendored
3
.github/renovate.json
vendored
@ -2,7 +2,8 @@
|
||||
"$schema" : "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends" : [
|
||||
"config:recommended",
|
||||
":semanticCommitsDisabled"
|
||||
":semanticCommitsDisabled",
|
||||
"schedule:earlyMondays"
|
||||
],
|
||||
"automerge" : true,
|
||||
"ignoreDeps" : [
|
||||
|
4
.github/workflows/build-pr.yml
vendored
4
.github/workflows/build-pr.yml
vendored
@ -11,13 +11,13 @@ jobs:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/wrapper-validation-action@v2
|
||||
uses: gradle/actions/wrapper-validation@v3
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
cache: gradle
|
||||
java-version: 17
|
||||
java-version: 21
|
||||
- name: Build on ${{ matrix.os }}
|
||||
run: ./gradlew build -s
|
||||
- name: Archive artifacts
|
||||
|
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@ -11,13 +11,13 @@ jobs:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/wrapper-validation-action@v2
|
||||
uses: gradle/actions/wrapper-validation@v3
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
cache: gradle
|
||||
java-version: 17
|
||||
java-version: 21
|
||||
- name: Clean Build
|
||||
run: ./gradlew clean build --no-daemon
|
||||
- name: Determine release status
|
||||
|
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
||||
with:
|
||||
distribution: temurin
|
||||
cache: gradle
|
||||
java-version: 17
|
||||
java-version: 21
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
|
2
.github/workflows/label-merge-conflicts.yaml
vendored
2
.github/workflows/label-merge-conflicts.yaml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Label conflicting PRs
|
||||
uses: eps1lon/actions-label-merge-conflict@v3.0.0
|
||||
uses: eps1lon/actions-label-merge-conflict@v3.0.2
|
||||
with:
|
||||
dirtyLabel: "unresolved-merge-conflict"
|
||||
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
4
.github/workflows/upload-release-assets.yml
vendored
4
.github/workflows/upload-release-assets.yml
vendored
@ -9,13 +9,13 @@ jobs:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/wrapper-validation-action@v2
|
||||
uses: gradle/actions/wrapper-validation@v3
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
cache: gradle
|
||||
java-version: 17
|
||||
java-version: 21
|
||||
- name: Clean Build
|
||||
run: ./gradlew clean build --no-daemon
|
||||
- name: Upload Release Assets
|
||||
|
@ -3,12 +3,12 @@
|
||||
|
||||
= Compiling
|
||||
|
||||
You can compile FastAsyncWorldEdit as long as you have some version of Java greater than or equal to 17 installed. Gradle will download JDK 17 specifically if needed,
|
||||
You can compile FastAsyncWorldEdit as long as you have some version of Java greater than or equal to 21 installed. Gradle will download JDK 21 specifically if needed,
|
||||
but it needs some version of Java to bootstrap from.
|
||||
|
||||
Note that if you have JRE 8 installed, Gradle will currently attempt to use that to compile, which will not work. It is easiest to uninstall JRE 8 and replace it with JDK 17.
|
||||
Note that if you have JRE 8 installed, Gradle will currently attempt to use that to compile, which will not work. It is easiest to uninstall JRE 8 and replace it with JDK 21.
|
||||
|
||||
You can get the JDK 17 link:https://adoptium.net/[here] from Adoptium.
|
||||
You can get the JDK 21 link:https://adoptium.net/[here] from Adoptium.
|
||||
|
||||
The build process uses Gradle, which you do *not* need to download. FastAsyncWorldEdit is a multi-module project with three active modules:
|
||||
|
||||
|
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -7,7 +7,7 @@ pipeline {
|
||||
stage('Build') {
|
||||
steps {
|
||||
withEnv([
|
||||
"PATH+JAVA=${tool 'Temurin-17.0.7_7'}/bin"
|
||||
"PATH+JAVA=${tool 'Temurin-21.0.3_9'}/bin"
|
||||
]) {
|
||||
sh './gradlew clean build'
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ import java.time.format.DateTimeFormatter
|
||||
import xyz.jpenilla.runpaper.task.RunServer
|
||||
|
||||
plugins {
|
||||
id("io.github.gradle-nexus.publish-plugin") version "1.3.0"
|
||||
id("xyz.jpenilla.run-paper") version "2.2.3"
|
||||
id("io.github.gradle-nexus.publish-plugin") version "2.0.0"
|
||||
id("xyz.jpenilla.run-paper") version "2.3.0"
|
||||
}
|
||||
|
||||
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 revision: String by extra("")
|
||||
var buildNumber by extra("")
|
||||
@ -83,7 +83,7 @@ allprojects {
|
||||
}
|
||||
|
||||
applyCommonConfiguration()
|
||||
val supportedVersions = listOf("1.18.2", "1.19.4", "1.20", "1.20.4")
|
||||
val supportedVersions = listOf("1.19.4", "1.20", "1.20.4", "1.20.5", "1.20.6")
|
||||
|
||||
tasks {
|
||||
supportedVersions.forEach {
|
||||
|
@ -24,11 +24,23 @@ dependencies {
|
||||
implementation(gradleApi())
|
||||
implementation("org.ajoberstar.grgit:grgit-gradle:5.2.2")
|
||||
implementation("com.github.johnrengelman:shadow:8.1.1")
|
||||
implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.5.11")
|
||||
implementation("io.papermc.paperweight.userdev:io.papermc.paperweight.userdev.gradle.plugin:1.7.1")
|
||||
constraints {
|
||||
val asmVersion = "[9.7,)"
|
||||
implementation("org.ow2.asm:asm:$asmVersion") {
|
||||
because("Need Java 21 support in shadow")
|
||||
}
|
||||
implementation("org.ow2.asm:asm-commons:$asmVersion") {
|
||||
because("Need Java 21 support in shadow")
|
||||
}
|
||||
implementation("org.vafer:jdependency:[2.10,)") {
|
||||
because("Need Java 21 support in shadow")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain {
|
||||
(this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(17))
|
||||
(this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ fun Project.applyCommonConfiguration() {
|
||||
|
||||
plugins.withId("java") {
|
||||
the<JavaPluginExtension>().toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(17))
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean
|
||||
.matching { it.name == "compileJava" || it.name == "compileTestJava" }
|
||||
.configureEach {
|
||||
val disabledLint = listOf(
|
||||
"processing", "path", "fallthrough", "serial"
|
||||
"processing", "path", "fallthrough", "serial", "overloads", "this-escape",
|
||||
)
|
||||
options.release.set(17)
|
||||
options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" })
|
||||
@ -31,7 +31,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17)
|
||||
attributes.attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21)
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
@ -61,7 +61,7 @@ fun Project.applyCommonJavaConfiguration(sourcesJar: Boolean, banSlf4j: Boolean
|
||||
"https://jd.advntr.dev/api/latest/",
|
||||
"https://logging.apache.org/log4j/2.x/javadoc/log4j-api/",
|
||||
"https://www.antlr.org/api/Java/",
|
||||
"https://jd.papermc.io/paper/1.20/",
|
||||
"https://jd.papermc.io/paper/1.20.6/",
|
||||
"https://intellectualsites.github.io/fastasyncworldedit-javadocs/worldedit-core/"
|
||||
)
|
||||
docTitle = "${rootProject.name}-${project.description}" + " " + "${rootProject.version}"
|
||||
|
@ -122,7 +122,7 @@ fun Project.applyLibrariesConfiguration() {
|
||||
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
||||
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17)
|
||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21)
|
||||
}
|
||||
outgoing.artifact(tasks.named("jar"))
|
||||
}
|
||||
@ -137,7 +137,7 @@ fun Project.applyLibrariesConfiguration() {
|
||||
attribute(Category.CATEGORY_ATTRIBUTE, project.objects.named(Category.LIBRARY))
|
||||
attribute(Bundling.BUNDLING_ATTRIBUTE, project.objects.named(Bundling.SHADOWED))
|
||||
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(LibraryElements.JAR))
|
||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17)
|
||||
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 21)
|
||||
}
|
||||
outgoing.artifact(tasks.named("jar"))
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
[versions]
|
||||
# Minecraft expectations
|
||||
paper = "1.20.4-R0.1-SNAPSHOT"
|
||||
paper = "1.20.6-R0.1-SNAPSHOT"
|
||||
fastutil = "8.5.9"
|
||||
guava = "31.1-jre"
|
||||
log4j = "2.19.0"
|
||||
@ -9,25 +9,25 @@ snakeyaml = "2.0"
|
||||
|
||||
# Plugins
|
||||
dummypermscompat = "1.10"
|
||||
worldguard-bukkit = "7.0.9"
|
||||
worldguard-bukkit = "7.0.10"
|
||||
mapmanager = "1.8.0-SNAPSHOT"
|
||||
griefprevention = "17.0.0"
|
||||
griefdefender = "2.1.0-SNAPSHOT"
|
||||
residence = "4.5._13.1"
|
||||
towny = "0.100.1.23"
|
||||
plotsquared = "7.3.6"
|
||||
towny = "0.100.2.12"
|
||||
plotsquared = "7.3.8"
|
||||
|
||||
# Third party
|
||||
bstats = "3.0.2"
|
||||
sparsebitset = "1.3"
|
||||
parallelgzip = "1.0.5"
|
||||
adventure = "4.16.0"
|
||||
adventure-bukkit = "4.3.2"
|
||||
checkerqual = "3.42.0"
|
||||
adventure = "4.17.0"
|
||||
adventure-bukkit = "4.3.3"
|
||||
checkerqual = "3.43.0"
|
||||
truezip = "6.8.4"
|
||||
auto-value = "1.10.4"
|
||||
findbugs = "3.0.2"
|
||||
rhino-runtime = "1.7.14"
|
||||
rhino-runtime = "1.7.15"
|
||||
zstd-jni = "1.4.8-1" # Not latest as it can be difficult to obtain latest ZSTD libs
|
||||
antlr4 = "4.13.1"
|
||||
json-simple = "1.1.1"
|
||||
@ -35,18 +35,18 @@ jlibnoise = "1.0.0"
|
||||
jchronic = "0.2.4a"
|
||||
lz4-java = "1.8.0"
|
||||
lz4-stream = "1.0.0"
|
||||
commons-cli = "1.6.0"
|
||||
commons-cli = "1.8.0"
|
||||
paperlib = "1.0.8"
|
||||
paster = "1.1.5"
|
||||
paster = "1.1.6"
|
||||
vault = "1.7.1"
|
||||
serverlib = "2.3.4"
|
||||
serverlib = "2.3.6"
|
||||
## Internal
|
||||
text-adapter = "3.0.6"
|
||||
text = "3.0.4"
|
||||
piston = "0.5.8"
|
||||
piston = "0.5.10"
|
||||
|
||||
# Tests
|
||||
mockito = "5.11.0"
|
||||
mockito = "5.12.0"
|
||||
|
||||
# Gradle plugins
|
||||
pluginyml = "0.6.0"
|
||||
|
@ -2,7 +2,7 @@ rootProject.name = "FastAsyncWorldEdit"
|
||||
|
||||
include("worldedit-libs")
|
||||
|
||||
listOf("1_18_2", "1_19_4", "1_20", "1_20_2", "1_20_4").forEach {
|
||||
listOf("1_19_4", "1_20", "1_20_2", "1_20_4", "1_20_5").forEach {
|
||||
include("worldedit-bukkit:adapters:adapter-$it")
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@ import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.NBTConstants;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
@ -531,7 +530,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) {
|
||||
((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create(
|
||||
new StructureBlockEntity(
|
||||
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()),
|
||||
new BlockPos(pos.x(), pos.y(), pos.z()),
|
||||
Blocks.STRUCTURE_BLOCK.defaultBlockState()
|
||||
),
|
||||
__ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData)
|
||||
@ -581,10 +580,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
return false;
|
||||
}
|
||||
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());
|
||||
|
||||
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 net.minecraft.core.Direction enumFacing = adapt(face);
|
||||
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) {
|
||||
int internalId = BlockStateIdAccess.getBlockStateId(blockState);
|
||||
net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId);
|
||||
return blockData.canSurvive(((CraftWorld) world).getHandle(), new BlockPos(position.getX(), position.getY(), position.getZ()));
|
||||
return blockData.canSurvive(((CraftWorld) world).getHandle(), new BlockPos(position.x(), position.y(), position.z()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -725,7 +724,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
}
|
||||
|
||||
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));
|
||||
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos);
|
||||
int internalId = Block.getId(blockData);
|
||||
@ -738,7 +737,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
}
|
||||
extent.setBlock(vec, state.toBaseBlock());
|
||||
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);
|
||||
if (adaptedBiome != null) {
|
||||
extent.setBiome(vec, adaptedBiome);
|
||||
@ -757,7 +756,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
//noinspection unchecked
|
||||
chunkLoadings.add(
|
||||
((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))
|
||||
);
|
||||
} 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) {
|
||||
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) {
|
||||
((Clearable) entity).clearContent();
|
||||
return true;
|
||||
|
@ -472,7 +472,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId);
|
||||
return blockState1.hasPostProcess(
|
||||
getServerLevel(world),
|
||||
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ())
|
||||
new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z())
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -786,9 +786,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
|
||||
final CompoundTag nativeTag = entry.getValue();
|
||||
final BlockVector3 blockHash = entry.getKey();
|
||||
final int x = blockHash.getX() + bx;
|
||||
final int y = blockHash.getY();
|
||||
final int z = blockHash.getZ() + bz;
|
||||
final int x = blockHash.x() + bx;
|
||||
final int y = blockHash.y();
|
||||
final int z = blockHash.z() + bz;
|
||||
final BlockPos pos = new BlockPos(x, y, z);
|
||||
|
||||
synchronized (nmsWorld) {
|
||||
|
@ -570,7 +570,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) {
|
||||
((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create(
|
||||
new StructureBlockEntity(
|
||||
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()),
|
||||
new BlockPos(pos.x(), pos.y(), pos.z()),
|
||||
Blocks.STRUCTURE_BLOCK.defaultBlockState()
|
||||
),
|
||||
__ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData)
|
||||
@ -631,10 +631,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
return false;
|
||||
}
|
||||
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());
|
||||
|
||||
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 net.minecraft.core.Direction enumFacing = adapt(face);
|
||||
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) {
|
||||
int internalId = BlockStateIdAccess.getBlockStateId(blockState);
|
||||
net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId);
|
||||
return blockData.canSurvive(((CraftWorld) world).getHandle(), new BlockPos(position.getX(), position.getY(), position.getZ()));
|
||||
return blockData.canSurvive(((CraftWorld) world).getHandle(), new BlockPos(position.x(), position.y(), position.z()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -776,7 +776,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
}
|
||||
|
||||
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));
|
||||
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos);
|
||||
int internalId = Block.getId(blockData);
|
||||
@ -789,7 +789,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
}
|
||||
extent.setBlock(vec, state.toBaseBlock());
|
||||
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);
|
||||
if (adaptedBiome != null) {
|
||||
extent.setBiome(vec, adaptedBiome);
|
||||
@ -808,7 +808,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
//noinspection unchecked
|
||||
chunkLoadings.add(
|
||||
((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))
|
||||
);
|
||||
} 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) {
|
||||
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) {
|
||||
((Clearable) entity).clearContent();
|
||||
return true;
|
||||
|
@ -472,7 +472,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId);
|
||||
return blockState1.hasPostProcess(
|
||||
getServerLevel(world),
|
||||
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ())
|
||||
new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z())
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -784,9 +784,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
|
||||
final CompoundTag nativeTag = entry.getValue();
|
||||
final BlockVector3 blockHash = entry.getKey();
|
||||
final int x = blockHash.getX() + bx;
|
||||
final int y = blockHash.getY();
|
||||
final int z = blockHash.getZ() + bz;
|
||||
final int x = blockHash.x() + bx;
|
||||
final int y = blockHash.y();
|
||||
final int z = blockHash.z() + bz;
|
||||
final BlockPos pos = new BlockPos(x, y, z);
|
||||
|
||||
synchronized (nmsWorld) {
|
||||
|
@ -530,7 +530,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) {
|
||||
((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create(
|
||||
new StructureBlockEntity(
|
||||
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()),
|
||||
new BlockPos(pos.x(), pos.y(), pos.z()),
|
||||
Blocks.STRUCTURE_BLOCK.defaultBlockState()
|
||||
),
|
||||
__ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData)
|
||||
@ -580,10 +580,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
return false;
|
||||
}
|
||||
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());
|
||||
|
||||
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 net.minecraft.core.Direction enumFacing = adapt(face);
|
||||
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) {
|
||||
int internalId = BlockStateIdAccess.getBlockStateId(blockState);
|
||||
net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId);
|
||||
return blockData.canSurvive(((CraftWorld) world).getHandle(), new BlockPos(position.getX(), position.getY(), position.getZ()));
|
||||
return blockData.canSurvive(((CraftWorld) world).getHandle(), new BlockPos(position.x(), position.y(), position.z()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -725,7 +725,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
}
|
||||
|
||||
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));
|
||||
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos);
|
||||
int internalId = Block.getId(blockData);
|
||||
@ -738,7 +738,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
}
|
||||
extent.setBlock(vec, state.toBaseBlock());
|
||||
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);
|
||||
if (adaptedBiome != null) {
|
||||
extent.setBiome(vec, adaptedBiome);
|
||||
@ -757,7 +757,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
//noinspection unchecked
|
||||
chunkLoadings.add(
|
||||
((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))
|
||||
);
|
||||
} 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) {
|
||||
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) {
|
||||
((Clearable) entity).clearContent();
|
||||
return true;
|
||||
|
@ -475,7 +475,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId);
|
||||
return blockState1.hasPostProcess(
|
||||
getServerLevel(world),
|
||||
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ())
|
||||
new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z())
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -771,9 +771,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
|
||||
final CompoundTag nativeTag = entry.getValue();
|
||||
final BlockVector3 blockHash = entry.getKey();
|
||||
final int x = blockHash.getX() + bx;
|
||||
final int y = blockHash.getY();
|
||||
final int z = blockHash.getZ() + bz;
|
||||
final int x = blockHash.x() + bx;
|
||||
final int y = blockHash.y();
|
||||
final int z = blockHash.z() + bz;
|
||||
final BlockPos pos = new BlockPos(x, y, z);
|
||||
|
||||
synchronized (nmsWorld) {
|
||||
|
@ -12,6 +12,6 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
// url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.4-R0.1-SNAPSHOT
|
||||
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.4-R0.1-20240325.123556-143")
|
||||
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.4-R0.1-20240528.102248-175")
|
||||
compileOnly(libs.paperlib)
|
||||
}
|
||||
|
@ -530,7 +530,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) {
|
||||
((CraftPlayer) player).getHandle().connection.send(ClientboundBlockEntityDataPacket.create(
|
||||
new StructureBlockEntity(
|
||||
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()),
|
||||
new BlockPos(pos.x(), pos.y(), pos.z()),
|
||||
Blocks.STRUCTURE_BLOCK.defaultBlockState()
|
||||
),
|
||||
__ -> (net.minecraft.nbt.CompoundTag) fromNativeBinary(nbtData)
|
||||
@ -580,10 +580,10 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
return false;
|
||||
}
|
||||
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());
|
||||
|
||||
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 net.minecraft.core.Direction enumFacing = adapt(face);
|
||||
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) {
|
||||
int internalId = BlockStateIdAccess.getBlockStateId(blockState);
|
||||
net.minecraft.world.level.block.state.BlockState blockData = Block.stateById(internalId);
|
||||
return blockData.canSurvive(((CraftWorld) world).getHandle(), new BlockPos(position.getX(), position.getY(), position.getZ()));
|
||||
return blockData.canSurvive(((CraftWorld) world).getHandle(), new BlockPos(position.x(), position.y(), position.z()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -725,7 +725,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
}
|
||||
|
||||
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));
|
||||
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos);
|
||||
int internalId = Block.getId(blockData);
|
||||
@ -738,7 +738,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
}
|
||||
extent.setBlock(vec, state.toBaseBlock());
|
||||
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);
|
||||
if (adaptedBiome != null) {
|
||||
extent.setBiome(vec, adaptedBiome);
|
||||
@ -757,7 +757,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
//noinspection unchecked
|
||||
chunkLoadings.add(
|
||||
((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))
|
||||
);
|
||||
} 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) {
|
||||
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) {
|
||||
((Clearable) entity).clearContent();
|
||||
return true;
|
||||
|
@ -475,7 +475,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
net.minecraft.world.level.block.state.BlockState blockState1 = Block.stateById(internalId);
|
||||
return blockState1.hasPostProcess(
|
||||
getServerLevel(world),
|
||||
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ())
|
||||
new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z())
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -771,9 +771,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
|
||||
final CompoundTag nativeTag = entry.getValue();
|
||||
final BlockVector3 blockHash = entry.getKey();
|
||||
final int x = blockHash.getX() + bx;
|
||||
final int y = blockHash.getY();
|
||||
final int z = blockHash.getZ() + bz;
|
||||
final int x = blockHash.x() + bx;
|
||||
final int y = blockHash.y();
|
||||
final int z = blockHash.z() + bz;
|
||||
final BlockPos pos = new BlockPos(x, y, z);
|
||||
|
||||
synchronized (nmsWorld) {
|
||||
|
@ -58,7 +58,6 @@ import net.minecraft.world.level.entity.PersistentEntitySectionManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_20_R3.CraftChunk;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -11,7 +11,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.18.2-R0.1-SNAPSHOT
|
||||
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.18.2-R0.1-20220920.010157-167")
|
||||
// url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/
|
||||
the<PaperweightUserDependenciesExtension>().paperDevBundle("1.20.6-R0.1-20240602.222958-106")
|
||||
compileOnly(libs.paperlib)
|
||||
}
|
@ -17,24 +17,23 @@
|
||||
* 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.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import com.sk89q.jnbt.NBTConstants;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.PaperweightPlatformAdapter;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extension.platform.Watchdog;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
@ -81,14 +80,20 @@ import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.component.DataComponentPatch;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.ChunkResult;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
@ -112,10 +117,10 @@ import net.minecraft.world.level.block.entity.StructureBlockEntity;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||
import net.minecraft.world.level.levelgen.WorldOptions;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.PrimaryLevelData;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
@ -124,13 +129,13 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.util.CraftMagicNumbers;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||
import org.bukkit.craftbukkit.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
@ -155,7 +160,6 @@ import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
@ -166,33 +170,28 @@ import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft.nbt.Tag> {
|
||||
|
||||
private static final Set<SideEffect> SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
|
||||
SideEffect.NEIGHBORS,
|
||||
SideEffect.LIGHTING,
|
||||
SideEffect.VALIDATION,
|
||||
SideEffect.ENTITY_AI,
|
||||
SideEffect.EVENTS,
|
||||
SideEffect.UPDATE
|
||||
);
|
||||
private static final Codec<DataComponentPatch> COMPONENTS_CODEC = DataComponentPatch.CODEC.optionalFieldOf(
|
||||
"components", DataComponentPatch.EMPTY
|
||||
).codec();
|
||||
|
||||
private final Logger logger = Logger.getLogger(getClass().getCanonicalName());
|
||||
|
||||
private final Field serverWorldsField;
|
||||
private final Method getChunkFutureMethod;
|
||||
private final Field chunkProviderExecutorField;
|
||||
private final Logger LOGGER = Logger.getLogger(getClass().getCanonicalName());
|
||||
private final Watchdog watchdog;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Code that may break between versions of Minecraft
|
||||
// ------------------------------------------------------------------------
|
||||
private final Watchdog watchdog;
|
||||
private final LoadingCache<ServerLevel, PaperweightFakePlayer> fakePlayers
|
||||
= CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new));
|
||||
|
||||
public PaperweightAdapter() throws NoSuchFieldException, NoSuchMethodException {
|
||||
// A simple test
|
||||
CraftServer.class.cast(Bukkit.getServer());
|
||||
|
||||
int dataVersion = CraftMagicNumbers.INSTANCE.getDataVersion();
|
||||
if (dataVersion != 2975) {
|
||||
throw new UnsupportedClassVersionError("Not 1.18.2!");
|
||||
if (dataVersion != 3837 && dataVersion != 3839) {
|
||||
throw new UnsupportedClassVersionError("Not 1.20.(5/6)!");
|
||||
}
|
||||
|
||||
serverWorldsField = CraftServer.class.getDeclaredField("worlds");
|
||||
@ -209,7 +208,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
);
|
||||
chunkProviderExecutorField.setAccessible(true);
|
||||
|
||||
new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this).build(ForkJoinPool.commonPool());
|
||||
new PaperweightDataConverters(CraftMagicNumbers.INSTANCE.getDataVersion(), this).buildUnoptimized();
|
||||
|
||||
Watchdog watchdog;
|
||||
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.
|
||||
*
|
||||
@ -238,7 +242,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
* @param tag the tag
|
||||
*/
|
||||
static void readTagIntoTileEntity(net.minecraft.nbt.CompoundTag tag, BlockEntity tileEntity) {
|
||||
tileEntity.load(tag);
|
||||
tileEntity.loadWithComponents(tag, MinecraftServer.getServer().registryAccess());
|
||||
tileEntity.setChanged();
|
||||
}
|
||||
|
||||
@ -271,9 +275,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
* @param tag the tag
|
||||
*/
|
||||
private static void readTagIntoEntity(net.minecraft.nbt.CompoundTag tag, Entity entity) {
|
||||
//FAWE start - avoid villager async catcher
|
||||
PaperweightPlatformAdapter.readEntityIntoTag(entity, tag);
|
||||
//FAWE end
|
||||
entity.load(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -287,34 +289,14 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
}
|
||||
|
||||
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) {
|
||||
return Registry.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;
|
||||
return DedicatedServer.getServer().registryAccess().registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(
|
||||
itemType.getId()));
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
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
|
||||
public BlockState getBlock(Location location) {
|
||||
checkNotNull(location);
|
||||
@ -373,21 +374,37 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
// Read the NBT data
|
||||
BlockEntity te = chunk.getBlockEntity(blockPos);
|
||||
if (te != null) {
|
||||
net.minecraft.nbt.CompoundTag tag = te.saveWithId();
|
||||
//FAWE start - BinaryTag
|
||||
net.minecraft.nbt.CompoundTag tag = te.saveWithId(MinecraftServer.getServer().registryAccess());
|
||||
return state.toBaseBlock((CompoundBinaryTag) toNativeBinary(tag));
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
return state.toBaseBlock();
|
||||
}
|
||||
|
||||
private static final HashMap<BiomeType, Holder<Biome>> biomeTypeToNMSCache = new HashMap<>();
|
||||
private static final HashMap<Holder<Biome>, BiomeType> biomeTypeFromNMSCache = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
|
||||
return new PaperweightWorldNativeAccess(
|
||||
this,
|
||||
new WeakReference<>(((CraftWorld) world).getHandle())
|
||||
);
|
||||
return new PaperweightWorldNativeAccess(this, new WeakReference<>(((CraftWorld) world).getHandle()));
|
||||
}
|
||||
|
||||
private static net.minecraft.core.Direction adapt(Direction face) {
|
||||
switch (face) {
|
||||
case NORTH:
|
||||
return net.minecraft.core.Direction.NORTH;
|
||||
case SOUTH:
|
||||
return net.minecraft.core.Direction.SOUTH;
|
||||
case WEST:
|
||||
return net.minecraft.core.Direction.WEST;
|
||||
case EAST:
|
||||
return net.minecraft.core.Direction.EAST;
|
||||
case DOWN:
|
||||
return net.minecraft.core.Direction.DOWN;
|
||||
case UP:
|
||||
default:
|
||||
return net.minecraft.core.Direction.UP;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@ -429,16 +446,19 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
CraftEntity craftEntity = ((CraftEntity) entity);
|
||||
Entity mcEntity = craftEntity.getHandle();
|
||||
|
||||
// Do not allow creating of passenger entity snapshots, passengers are included in the vehicle entity
|
||||
if (mcEntity.isPassenger()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String id = getEntityId(mcEntity);
|
||||
|
||||
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
||||
readEntityIntoTag(mcEntity, tag);
|
||||
//FAWE start - CompoundBinaryTag
|
||||
return new BaseEntity(
|
||||
com.sk89q.worldedit.world.entity.EntityTypes.get(id),
|
||||
LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag))
|
||||
);
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
@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
|
||||
public Component getRichBlockName(BlockType blockType) {
|
||||
return TranslatableComponent.of(getBlockFromType(blockType).getDescriptionId());
|
||||
@ -487,26 +523,44 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
}
|
||||
|
||||
@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
|
||||
public Property<?> load(net.minecraft.world.level.block.state.properties.Property state) throws Exception {
|
||||
if (state instanceof net.minecraft.world.level.block.state.properties.BooleanProperty) {
|
||||
return new BooleanProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues()));
|
||||
} else if (state instanceof DirectionProperty) {
|
||||
return new DirectionalProperty(state.getName(),
|
||||
(List<Direction>) state.getPossibleValues().stream().map(e -> Direction.valueOf(((StringRepresentable) e).getSerializedName().toUpperCase(Locale.ROOT))).collect(Collectors.toList()));
|
||||
return new DirectionalProperty(
|
||||
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) {
|
||||
return new EnumProperty(state.getName(),
|
||||
(List<String>) state.getPossibleValues().stream().map(e -> ((StringRepresentable) e).getSerializedName()).collect(Collectors.toList()));
|
||||
return new EnumProperty(
|
||||
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) {
|
||||
return new IntegerProperty(state.getName(), ImmutableList.copyOf(state.getPossibleValues()));
|
||||
} 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
|
||||
public Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
|
||||
Map<String, Property<?>> properties = new TreeMap<>();
|
||||
@ -520,50 +574,68 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
return properties;
|
||||
}
|
||||
|
||||
//FAWE start - CompoundBinaryTag > CompoundTag
|
||||
@Override
|
||||
public void sendFakeNBT(Player player, BlockVector3 pos, CompoundBinaryTag nbtData) {
|
||||
((CraftPlayer) player).getHandle().networkManager.send(ClientboundBlockEntityDataPacket.create(
|
||||
new StructureBlockEntity(
|
||||
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()),
|
||||
var structureBlock = new StructureBlockEntity(
|
||||
new BlockPos(pos.x(), pos.y(), pos.z()),
|
||||
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
|
||||
public void sendFakeOP(Player player) {
|
||||
((CraftPlayer) player).getHandle().networkManager.send(new ClientboundEntityEventPacket(
|
||||
((CraftPlayer) player).getHandle().connection.send(new ClientboundEntityEventPacket(
|
||||
((CraftPlayer) player).getHandle(), (byte) 28
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.inventory.ItemStack adapt(BaseItemStack item) {
|
||||
ItemStack stack = new ItemStack(Registry.ITEM.get(ResourceLocation.tryParse(item.getType().getId())), item.getAmount());
|
||||
stack.setTag(((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData())));
|
||||
final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess();
|
||||
ItemStack stack = new ItemStack(
|
||||
registryAccess.registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(item.getType().getId())),
|
||||
item.getAmount()
|
||||
);
|
||||
final CompoundTag nbt = (net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData());
|
||||
final DataComponentPatch patch = COMPONENTS_CODEC
|
||||
.parse(registryAccess.createSerializationContext(NbtOps.INSTANCE), nbt)
|
||||
.getOrThrow();
|
||||
stack.applyComponents(patch);
|
||||
return CraftItemStack.asCraftMirror(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
|
||||
final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess();
|
||||
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||
final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount());
|
||||
//FAWE start - CBT > CT
|
||||
weStack.setNbt(((CompoundBinaryTag) toNativeBinary(nmsStack.getTag())));
|
||||
//FAWE end
|
||||
return weStack;
|
||||
final Tag tag = COMPONENTS_CODEC.encodeStart(
|
||||
registryAccess.createSerializationContext(NbtOps.INSTANCE),
|
||||
nmsStack.getComponentsPatch()
|
||||
).getOrThrow();
|
||||
return new BaseItemStack(
|
||||
BukkitAdapter.asItemType(itemStack.getType()),
|
||||
LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag)),
|
||||
itemStack.getAmount()
|
||||
);
|
||||
}
|
||||
|
||||
private final LoadingCache<ServerLevel, PaperweightFakePlayer> fakePlayers
|
||||
= CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(PaperweightFakePlayer::new));
|
||||
|
||||
@Override
|
||||
public boolean simulateItemUse(org.bukkit.World world, BlockVector3 position, BaseItem item, Direction face) {
|
||||
CraftWorld craftWorld = (CraftWorld) world;
|
||||
ServerLevel worldServer = craftWorld.getHandle();
|
||||
ItemStack stack = CraftItemStack.asNMSCopy(BukkitAdapter.adapt(item instanceof BaseItemStack
|
||||
? ((BaseItemStack) item) : new BaseItemStack(item.getType(), item.getNbtData(), 1)));
|
||||
stack.setTag((net.minecraft.nbt.CompoundTag) fromNative(item.getNbtData()));
|
||||
ItemStack stack = CraftItemStack.asNMSCopy(adapt(
|
||||
item instanceof BaseItemStack
|
||||
? ((BaseItemStack) item)
|
||||
: new BaseItemStack(item.getType(), item.getNbtReference(), 1)
|
||||
));
|
||||
|
||||
PaperweightFakePlayer fakePlayer;
|
||||
try {
|
||||
@ -572,20 +644,20 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
return false;
|
||||
}
|
||||
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()
|
||||
);
|
||||
|
||||
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 net.minecraft.core.Direction enumFacing = adapt(face);
|
||||
BlockHitResult rayTrace = new BlockHitResult(blockVec, enumFacing, blockPos, false);
|
||||
UseOnContext context = new UseOnContext(fakePlayer, InteractionHand.MAIN_HAND, rayTrace);
|
||||
InteractionResult result = stack.useOn(context, InteractionHand.MAIN_HAND);
|
||||
InteractionResult result = stack.useOn(context);
|
||||
if (result != InteractionResult.SUCCESS) {
|
||||
if (worldServer
|
||||
.getBlockState(blockPos)
|
||||
.use(worldServer, fakePlayer, InteractionHand.MAIN_HAND, rayTrace)
|
||||
.useItemOn(stack, worldServer, fakePlayer, InteractionHand.MAIN_HAND, rayTrace)
|
||||
.consumesAction()) {
|
||||
result = InteractionResult.SUCCESS;
|
||||
} else {
|
||||
@ -602,7 +674,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
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())
|
||||
new BlockPos(position.x(), position.y(), position.z())
|
||||
);
|
||||
}
|
||||
|
||||
@ -621,18 +693,18 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
Environment env = bukkitWorld.getEnvironment();
|
||||
ChunkGenerator gen = bukkitWorld.getGenerator();
|
||||
|
||||
Path tempDir = Files.createTempDirectory("FastAsyncWorldEditWorldGen");
|
||||
Path tempDir = Files.createTempDirectory("WorldEditWorldGen");
|
||||
LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir);
|
||||
ResourceKey<LevelStem> worldDimKey = getWorldDimKey(env);
|
||||
try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("faweregentempworld", worldDimKey)) {
|
||||
ServerLevel originalWorld = ((CraftWorld) bukkitWorld).getHandle();
|
||||
PrimaryLevelData levelProperties = (PrimaryLevelData) originalWorld.getServer()
|
||||
.getWorldData().overworldData();
|
||||
WorldGenSettings originalOpts = levelProperties.worldGenSettings();
|
||||
WorldOptions originalOpts = levelProperties.worldGenOptions();
|
||||
|
||||
long seed = options.getSeed().orElse(originalWorld.getSeed());
|
||||
WorldGenSettings newOpts = options.getSeed().isPresent()
|
||||
? originalOpts.withSeed(levelProperties.isHardcore(), OptionalLong.of(seed))
|
||||
WorldOptions newOpts = options.getSeed().isPresent()
|
||||
? originalOpts.withSeed(OptionalLong.of(seed))
|
||||
: originalOpts;
|
||||
|
||||
LevelSettings newWorldSettings = new LevelSettings(
|
||||
@ -642,23 +714,40 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
levelProperties.settings.difficulty(),
|
||||
levelProperties.settings.allowCommands(),
|
||||
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(
|
||||
originalWorld.getServer(),
|
||||
originalWorld.getServer().executor,
|
||||
session, newWorldData,
|
||||
originalWorld.dimension(),
|
||||
new LevelStem(
|
||||
originalWorld.dimensionTypeRegistration(),
|
||||
originalWorld.getChunkSource().getGenerator()
|
||||
),
|
||||
new NoOpWorldLoadListener(),
|
||||
newOpts.dimensions().get(worldDimKey).generator(),
|
||||
originalWorld.isDebug(),
|
||||
seed,
|
||||
ImmutableList.of(),
|
||||
false,
|
||||
env, gen,
|
||||
originalWorld.getRandomSequences(),
|
||||
env,
|
||||
gen,
|
||||
bukkitWorld.getBiomeProvider()
|
||||
);
|
||||
try {
|
||||
@ -678,7 +767,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
}
|
||||
|
||||
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) {
|
||||
return null;
|
||||
}
|
||||
@ -713,7 +802,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
}
|
||||
|
||||
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));
|
||||
final net.minecraft.world.level.block.state.BlockState blockData = chunk.getBlockState(pos);
|
||||
int internalId = Block.getId(blockData);
|
||||
@ -721,14 +810,12 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
Objects.requireNonNull(state);
|
||||
BlockEntity blockEntity = chunk.getBlockEntity(pos);
|
||||
if (blockEntity != null) {
|
||||
net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId();
|
||||
//FAWE start - BinaryTag
|
||||
net.minecraft.nbt.CompoundTag tag = blockEntity.saveWithId(serverWorld.registryAccess());
|
||||
state = state.toBaseBlock(((CompoundBinaryTag) toNativeBinary(tag)));
|
||||
//FAWE end
|
||||
}
|
||||
extent.setBlock(vec, state.toBaseBlock());
|
||||
if (options.shouldRegenBiomes()) {
|
||||
Biome origBiome = chunk.getNoiseBiome(vec.getX(), vec.getY(), vec.getZ()).value();
|
||||
Biome origBiome = chunk.getNoiseBiome(vec.x(), vec.y(), vec.z()).value();
|
||||
BiomeType adaptedBiome = adapt(serverWorld, origBiome);
|
||||
if (adaptedBiome != null) {
|
||||
extent.setBiome(vec, adaptedBiome);
|
||||
@ -746,9 +833,9 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
try {
|
||||
//noinspection unchecked
|
||||
chunkLoadings.add(
|
||||
((CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>)
|
||||
getChunkFutureMethod.invoke(chunkManager, chunk.getX(), chunk.getZ(), ChunkStatus.FEATURES, true))
|
||||
.thenApply(either -> either.left().orElse(null))
|
||||
((CompletableFuture<ChunkResult<ChunkAccess>>)
|
||||
getChunkFutureMethod.invoke(chunkManager, chunk.x(), chunk.z(), ChunkStatus.FEATURES, true))
|
||||
.thenApply(either -> either.orElse(null))
|
||||
);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new IllegalStateException("Couldn't load chunk for regen.", e);
|
||||
@ -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
|
||||
public Set<SideEffect> getSupportedSideEffects() {
|
||||
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) {
|
||||
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) {
|
||||
((Clearable) entity).clearContent();
|
||||
return true;
|
||||
@ -797,7 +893,6 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
* @param foreign non-native NMS NBT structure
|
||||
* @return native WorldEdit NBT structure
|
||||
*/
|
||||
//FAWE start - BinaryTag
|
||||
@Override
|
||||
public BinaryTag toNativeBinary(net.minecraft.nbt.Tag foreign) {
|
||||
if (foreign == null) {
|
||||
@ -830,7 +925,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
try {
|
||||
return toNativeList((net.minecraft.nbt.ListTag) foreign);
|
||||
} 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();
|
||||
}
|
||||
} else if (foreign instanceof net.minecraft.nbt.LongTag) {
|
||||
@ -855,7 +950,7 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
* @throws IllegalArgumentException on error
|
||||
*/
|
||||
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) {
|
||||
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());
|
||||
} else if (foreign instanceof LongArrayBinaryTag) {
|
||||
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();
|
||||
ListBinaryTag foreignList = (ListBinaryTag) foreign;
|
||||
for (BinaryTag t : foreignList) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
@Override
|
||||
public boolean supportsWatchdog() {
|
||||
@ -925,54 +1020,6 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
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 final Field instanceField;
|
||||
@ -996,10 +1043,61 @@ public final class PaperweightAdapter implements BukkitImplAdapter<net.minecraft
|
||||
WatchdogThread.tick();
|
||||
}
|
||||
} 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-Diff unterdrückt, da er zu groß ist
Diff laden
@ -17,18 +17,19 @@
|
||||
* 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 net.minecraft.network.chat.ChatType;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.game.ServerboundClientInformationPacket;
|
||||
import net.minecraft.server.level.ClientInformation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.stats.Stat;
|
||||
import net.minecraft.world.MenuProvider;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.HumanoidArm;
|
||||
import net.minecraft.world.entity.player.ChatVisiblity;
|
||||
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||
@ -37,15 +38,14 @@ import java.util.OptionalInt;
|
||||
import java.util.UUID;
|
||||
|
||||
class PaperweightFakePlayer extends ServerPlayer {
|
||||
|
||||
private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(
|
||||
UUID.nameUUIDFromBytes("worldedit".getBytes()),
|
||||
"[WorldEdit]"
|
||||
);
|
||||
private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]");
|
||||
private static final Vec3 ORIGIN = new Vec3(0.0D, 0.0D, 0.0D);
|
||||
private static final ClientInformation FAKE_CLIENT_INFO = new ClientInformation(
|
||||
"en_US", 16, ChatVisiblity.FULL, true, 0, HumanoidArm.LEFT, false, false
|
||||
);
|
||||
|
||||
PaperweightFakePlayer(ServerLevel world) {
|
||||
super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE);
|
||||
super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE, FAKE_CLIENT_INFO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -72,17 +72,13 @@ class PaperweightFakePlayer extends ServerPlayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateOptions(ServerboundClientInformationPacket packet) {
|
||||
public void updateOptions(ClientInformation clientOptions) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayClientMessage(Component message, boolean actionBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(Component message, ChatType type, UUID sender) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void awardStat(Stat<?> stat, int amount) {
|
||||
}
|
||||
@ -97,7 +93,6 @@ class PaperweightFakePlayer extends ServerPlayer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openTextEdit(SignBlockEntity sign) {
|
||||
public void openTextEdit(SignBlockEntity sign, boolean front) {
|
||||
}
|
||||
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
* 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.internal.block.BlockStateIdAccess;
|
||||
@ -27,21 +27,19 @@ import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.FullChunkStatus;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Objects;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class PaperweightWorldNativeAccess implements
|
||||
WorldNativeAccess<LevelChunk, net.minecraft.world.level.block.state.BlockState, BlockPos> {
|
||||
|
||||
public class PaperweightWorldNativeAccess implements WorldNativeAccess<LevelChunk, net.minecraft.world.level.block.state.BlockState, BlockPos> {
|
||||
private static final int UPDATE = 1;
|
||||
private static final int NOTIFY = 2;
|
||||
|
||||
@ -83,19 +81,12 @@ public class PaperweightWorldNativeAccess implements
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public net.minecraft.world.level.block.state.BlockState setBlockState(
|
||||
LevelChunk chunk,
|
||||
BlockPos position,
|
||||
net.minecraft.world.level.block.state.BlockState state
|
||||
) {
|
||||
public net.minecraft.world.level.block.state.BlockState setBlockState(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState state) {
|
||||
return chunk.setBlockState(position, state, false, this.sideEffectSet.shouldApply(SideEffect.UPDATE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition(
|
||||
net.minecraft.world.level.block.state.BlockState block,
|
||||
BlockPos position
|
||||
) {
|
||||
public net.minecraft.world.level.block.state.BlockState getValidBlockForPosition(net.minecraft.world.level.block.state.BlockState block, BlockPos position) {
|
||||
return Block.updateFromNeighbourShapes(block, getWorld(), position);
|
||||
}
|
||||
|
||||
@ -115,12 +106,7 @@ public class PaperweightWorldNativeAccess implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyBlockUpdate(
|
||||
LevelChunk chunk,
|
||||
BlockPos position,
|
||||
net.minecraft.world.level.block.state.BlockState oldState,
|
||||
net.minecraft.world.level.block.state.BlockState newState
|
||||
) {
|
||||
public void notifyBlockUpdate(LevelChunk chunk, BlockPos position, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) {
|
||||
if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) {
|
||||
getWorld().sendBlockUpdated(position, oldState, newState, UPDATE | NOTIFY);
|
||||
}
|
||||
@ -128,7 +114,7 @@ public class PaperweightWorldNativeAccess implements
|
||||
|
||||
@Override
|
||||
public boolean isChunkTicking(LevelChunk chunk) {
|
||||
return chunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING);
|
||||
return chunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -139,11 +125,7 @@ public class PaperweightWorldNativeAccess implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyNeighbors(
|
||||
BlockPos pos,
|
||||
net.minecraft.world.level.block.state.BlockState oldState,
|
||||
net.minecraft.world.level.block.state.BlockState newState
|
||||
) {
|
||||
public void notifyNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) {
|
||||
ServerLevel world = getWorld();
|
||||
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
|
||||
world.updateNeighborsAt(pos, oldState.getBlock());
|
||||
@ -162,27 +144,20 @@ public class PaperweightWorldNativeAccess implements
|
||||
}
|
||||
}
|
||||
|
||||
// Not sure why neighborChanged is deprecated
|
||||
private void fireNeighborChanged(BlockPos pos, ServerLevel world, Block block, BlockPos neighborPos) {
|
||||
world.getBlockState(neighborPos).neighborChanged(world, neighborPos, block, pos, false);
|
||||
world.getBlockState(neighborPos).handleNeighborChanged(world, neighborPos, block, pos, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNeighbors(
|
||||
BlockPos pos,
|
||||
net.minecraft.world.level.block.state.BlockState oldState,
|
||||
net.minecraft.world.level.block.state.BlockState newState,
|
||||
int recursionLimit
|
||||
) {
|
||||
public void updateNeighbors(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState, int recursionLimit) {
|
||||
ServerLevel world = getWorld();
|
||||
// a == updateNeighbors
|
||||
// b == updateDiagonalNeighbors
|
||||
oldState.updateIndirectNeighbourShapes(world, pos, NOTIFY, recursionLimit);
|
||||
if (sideEffectSet.shouldApply(SideEffect.EVENTS)) {
|
||||
CraftWorld craftWorld = world.getWorld();
|
||||
BlockPhysicsEvent event = new BlockPhysicsEvent(
|
||||
craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()),
|
||||
CraftBlockData.fromData(newState)
|
||||
);
|
||||
BlockPhysicsEvent event = new BlockPhysicsEvent(craftWorld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), CraftBlockData.fromData(newState));
|
||||
world.getCraftServer().getPluginManager().callEvent(event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
@ -193,19 +168,13 @@ public class PaperweightWorldNativeAccess implements
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockStateChange(
|
||||
BlockPos pos,
|
||||
net.minecraft.world.level.block.state.BlockState oldState,
|
||||
net.minecraft.world.level.block.state.BlockState newState
|
||||
) {
|
||||
public void onBlockStateChange(BlockPos pos, net.minecraft.world.level.block.state.BlockState oldState, net.minecraft.world.level.block.state.BlockState newState) {
|
||||
getWorld().onBlockStateChange(pos, oldState, newState);
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
@Override
|
||||
public void flush() {
|
||||
|
||||
}
|
||||
//FAWE end
|
||||
|
||||
}
|
@ -1,28 +1,24 @@
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.util.ReflectionUtil;
|
||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag;
|
||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.world.level.EmptyBlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData;
|
||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||
|
||||
public class PaperweightBlockMaterial implements BlockMaterial {
|
||||
|
||||
private final Block block;
|
||||
private final BlockState blockState;
|
||||
private final Material material;
|
||||
private final boolean isTranslucent;
|
||||
private final CraftBlockData craftBlockData;
|
||||
private final org.bukkit.Material craftMaterial;
|
||||
private final int opacity;
|
||||
@ -35,22 +31,16 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
||||
public PaperweightBlockMaterial(Block block, BlockState blockState) {
|
||||
this.block = block;
|
||||
this.blockState = blockState;
|
||||
this.material = blockState.getMaterial();
|
||||
this.craftBlockData = CraftBlockData.fromData(blockState);
|
||||
this.craftMaterial = craftBlockData.getMaterial();
|
||||
BlockBehaviour.Properties blockInfo = ReflectionUtil.getField(BlockBehaviour.class, block, Refraction.pickName(
|
||||
"properties", "aO"));
|
||||
this.isTranslucent = !(boolean) ReflectionUtil.getField(BlockBehaviour.Properties.class, blockInfo,
|
||||
Refraction.pickName("canOcclude", "n")
|
||||
);
|
||||
opacity = blockState.getLightBlock(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
|
||||
BlockEntity tileEntity = !(block instanceof EntityBlock) ? null : ((EntityBlock) block).newBlockEntity(
|
||||
BlockPos.ZERO,
|
||||
blockState
|
||||
);
|
||||
tile = tileEntity == null
|
||||
? null
|
||||
: new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId));
|
||||
tile = tileEntity == null ? null : new PaperweightLazyCompoundTag(
|
||||
Suppliers.memoize(() -> tileEntity.saveWithId(DedicatedServer.getServer().registryAccess()))
|
||||
);
|
||||
}
|
||||
|
||||
public Block getBlock() {
|
||||
@ -65,10 +55,6 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
||||
return craftBlockData;
|
||||
}
|
||||
|
||||
public Material getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAir() {
|
||||
return blockState.isAir();
|
||||
@ -81,7 +67,7 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
||||
|
||||
@Override
|
||||
public boolean isOpaque() {
|
||||
return material.isSolidBlocking();
|
||||
return blockState.canOcclude();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -91,12 +77,13 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
||||
|
||||
@Override
|
||||
public boolean isLiquid() {
|
||||
return material.isLiquid();
|
||||
return !blockState.getFluidState().is(Fluids.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSolid() {
|
||||
return material.isSolid();
|
||||
// No access to world -> EmptyBlockGetter
|
||||
return blockState.isSolidRender(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -126,27 +113,27 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
||||
|
||||
@Override
|
||||
public boolean isFragileWhenPushed() {
|
||||
return material.getPushReaction() == PushReaction.DESTROY;
|
||||
return blockState.getPistonPushReaction() == PushReaction.DESTROY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnpushable() {
|
||||
return material.getPushReaction() == PushReaction.BLOCK;
|
||||
return blockState.getPistonPushReaction() == PushReaction.BLOCK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTicksRandomly() {
|
||||
return block.isRandomlyTicking(blockState);
|
||||
return blockState.isRandomlyTicking();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMovementBlocker() {
|
||||
return material.isSolid();
|
||||
return craftMaterial.isSolid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBurnable() {
|
||||
return material.isFlammable();
|
||||
return craftMaterial.isBurnable();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -157,12 +144,12 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
||||
|
||||
@Override
|
||||
public boolean isReplacedDuringPlacement() {
|
||||
return material.isReplaceable();
|
||||
return blockState.canBeReplaced();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTranslucent() {
|
||||
return isTranslucent;
|
||||
return !blockState.canOcclude();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -183,7 +170,7 @@ public class PaperweightBlockMaterial implements BlockMaterial {
|
||||
@Override
|
||||
public int getMapColor() {
|
||||
// rgb field
|
||||
return material.getColor().col;
|
||||
return block.defaultMapColor().col;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||
|
||||
import com.fastasyncworldedit.bukkit.adapter.FaweAdapter;
|
||||
import com.fastasyncworldedit.bukkit.adapter.NMSRelighterFactory;
|
||||
@ -12,14 +12,13 @@ import com.fastasyncworldedit.core.util.NbtUtils;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.blocks.TileEntityBlock;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||
import com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_18_R2.PaperweightAdapter;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.regen.PaperweightRegen;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.regen.PaperweightRegen;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
|
||||
@ -35,6 +34,7 @@ import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.concurrency.LazyReference;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.nbt.BinaryTag;
|
||||
import com.sk89q.worldedit.util.nbt.CompoundBinaryTag;
|
||||
@ -45,7 +45,6 @@ import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
import com.sk89q.worldedit.world.entity.EntityType;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
@ -53,44 +52,48 @@ import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.WritableRegistry;
|
||||
import net.minecraft.nbt.IntTag;
|
||||
import net.minecraft.core.component.DataComponentPatch;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.StringRepresentable;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftChunk;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.util.CraftNamespacedKey;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||
import org.bukkit.craftbukkit.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
@ -104,11 +107,24 @@ import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static net.minecraft.core.registries.Registries.BIOME;
|
||||
|
||||
public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.Tag, ServerLevel> {
|
||||
|
||||
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
|
||||
// ------------------------------------------------------------------------
|
||||
@ -119,7 +135,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
private Map<String, List<Property<?>>> allBlockProperties = null;
|
||||
|
||||
public PaperweightFaweAdapter() throws NoSuchFieldException, NoSuchMethodException {
|
||||
this.parent = new PaperweightAdapter();
|
||||
this.parent = new com.sk89q.worldedit.bukkit.adapter.ext.fawe.v1_20_R4.PaperweightAdapter();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@ -128,6 +144,10 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
return resourceLocation == null ? null : resourceLocation.toString();
|
||||
}
|
||||
|
||||
private static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
|
||||
entity.save(compoundTag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BukkitImplAdapter<net.minecraft.nbt.Tag> getParent() {
|
||||
return parent;
|
||||
@ -219,7 +239,8 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
}
|
||||
|
||||
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
|
||||
@ -264,7 +285,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
// Read the NBT data
|
||||
BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
||||
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));
|
||||
}
|
||||
}
|
||||
@ -277,54 +298,6 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
return SideEffectSet.defaults().getSideEffectsToApply();
|
||||
}
|
||||
|
||||
public boolean setBlock(org.bukkit.Chunk chunk, int x, int y, int z, BlockStateHolder state, boolean update) {
|
||||
CraftChunk craftChunk = (CraftChunk) chunk;
|
||||
LevelChunk levelChunk = craftChunk.getHandle();
|
||||
Level level = levelChunk.getLevel();
|
||||
|
||||
BlockPos blockPos = new BlockPos(x, y, z);
|
||||
net.minecraft.world.level.block.state.BlockState blockState = ((PaperweightBlockMaterial) state.getMaterial()).getState();
|
||||
LevelChunkSection[] levelChunkSections = levelChunk.getSections();
|
||||
int y4 = y >> 4;
|
||||
LevelChunkSection section = levelChunkSections[y4];
|
||||
|
||||
net.minecraft.world.level.block.state.BlockState existing;
|
||||
if (section == null) {
|
||||
existing = ((PaperweightBlockMaterial) BlockTypes.AIR.getDefaultState().getMaterial()).getState();
|
||||
} else {
|
||||
existing = section.getBlockState(x & 15, y & 15, z & 15);
|
||||
}
|
||||
|
||||
levelChunk.removeBlockEntity(blockPos); // Force delete the old tile entity
|
||||
|
||||
CompoundBinaryTag compoundTag = state instanceof BaseBlock ? state.getNbt() : null;
|
||||
if (compoundTag != null || existing instanceof TileEntityBlock) {
|
||||
level.setBlock(blockPos, blockState, 0);
|
||||
// remove tile
|
||||
if (compoundTag != null) {
|
||||
// We will assume that the tile entity was created for us,
|
||||
// though we do not do this on the Forge version
|
||||
BlockEntity blockEntity = level.getBlockEntity(blockPos);
|
||||
if (blockEntity != null) {
|
||||
net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) fromNativeBinary(compoundTag);
|
||||
tag.put("x", IntTag.valueOf(x));
|
||||
tag.put("y", IntTag.valueOf(y));
|
||||
tag.put("z", IntTag.valueOf(z));
|
||||
blockEntity.load(tag); // readTagIntoTileEntity - load data
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (existing == blockState) {
|
||||
return true;
|
||||
}
|
||||
levelChunk.setBlockState(blockPos, blockState, false);
|
||||
}
|
||||
if (update) {
|
||||
level.getMinecraftWorld().sendBlockUpdated(blockPos, existing, blockState, 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldNativeAccess<?, ?, ?> createWorldNativeAccess(org.bukkit.World world) {
|
||||
return new PaperweightFaweWorldNativeAccess(this, new WeakReference<>(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);
|
||||
Supplier<CompoundBinaryTag> saveTag = () -> {
|
||||
final net.minecraft.nbt.CompoundTag minecraftTag = new net.minecraft.nbt.CompoundTag();
|
||||
PaperweightPlatformAdapter.readEntityIntoTag(mcEntity, minecraftTag);
|
||||
readEntityIntoTag(mcEntity, minecraftTag);
|
||||
//add Id for AbstractChangeSet to work
|
||||
final CompoundBinaryTag tag = (CompoundBinaryTag) toNativeBinary(minecraftTag);
|
||||
final Map<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) {
|
||||
ServerLevel nmsWorld = getServerLevel(world);
|
||||
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;
|
||||
Stream<ServerPlayer> stream = /*players.a(new ChunkCoordIntPair(packet.getChunkX(), packet.getChunkZ()), flag)
|
||||
*/ 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);
|
||||
return blockState1.hasPostProcess(
|
||||
getServerLevel(world),
|
||||
new BlockPos(blockVector3.getX(), blockVector3.getY(), blockVector3.getZ())
|
||||
new BlockPos(blockVector3.x(), blockVector3.y(), blockVector3.z())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public org.bukkit.inventory.ItemStack adapt(BaseItemStack baseItemStack) {
|
||||
final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess();
|
||||
ItemStack stack = new ItemStack(
|
||||
Registry.ITEM.get(ResourceLocation.tryParse(baseItemStack.getType().getId())),
|
||||
registryAccess.registryOrThrow(Registries.ITEM).get(ResourceLocation.tryParse(baseItemStack.getType().getId())),
|
||||
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);
|
||||
}
|
||||
|
||||
@ -547,29 +528,19 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
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
|
||||
public BaseItemStack adapt(org.bukkit.inventory.ItemStack itemStack) {
|
||||
final RegistryAccess.Frozen registryAccess = DedicatedServer.getServer().registryAccess();
|
||||
final ItemStack nmsStack = CraftItemStack.asNMSCopy(itemStack);
|
||||
final BaseItemStack weStack = new BaseItemStack(BukkitAdapter.asItemType(itemStack.getType()), itemStack.getAmount());
|
||||
weStack.setNbt(((CompoundBinaryTag) toNativeBinary(nmsStack.getTag())));
|
||||
return weStack;
|
||||
final net.minecraft.nbt.Tag tag = COMPONENTS_CODEC.encodeStart(
|
||||
registryAccess.createSerializationContext(NbtOps.INSTANCE),
|
||||
nmsStack.getComponentsPatch()
|
||||
).getOrThrow();
|
||||
return new BaseItemStack(
|
||||
BukkitAdapter.asItemType(itemStack.getType()),
|
||||
LazyReference.from(() -> (CompoundBinaryTag) toNativeBinary(tag)),
|
||||
itemStack.getAmount()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -577,17 +548,12 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
return parent.toNative(foreign);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryTag toNativeBinary(final net.minecraft.nbt.Tag foreign) {
|
||||
return parent.toNativeBinary(foreign);
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.nbt.Tag fromNative(Tag foreign) {
|
||||
if (foreign instanceof PaperweightLazyCompoundTag) {
|
||||
return ((PaperweightLazyCompoundTag) foreign).get();
|
||||
}
|
||||
return (net.minecraft.nbt.Tag) parent.fromNative(foreign);
|
||||
return parent.fromNative(foreign);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -605,7 +571,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
final Registry<Biome> registry = MinecraftServer
|
||||
.getServer()
|
||||
.registryAccess()
|
||||
.ownedRegistryOrThrow(Registry.BIOME_REGISTRY);
|
||||
.registryOrThrow(BIOME);
|
||||
ResourceLocation resourceLocation = ResourceLocation.tryParse(biomeType.getId());
|
||||
Biome biome = registry.get(resourceLocation);
|
||||
return registry.getId(biome);
|
||||
@ -616,8 +582,7 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) ((CraftServer) Bukkit.getServer())
|
||||
.getServer()
|
||||
.registryAccess()
|
||||
.ownedRegistryOrThrow(
|
||||
Registry.BIOME_REGISTRY);
|
||||
.registryOrThrow(BIOME);
|
||||
List<ResourceLocation> keys = biomeRegistry.stream()
|
||||
.map(biomeRegistry::getKey).filter(Objects::nonNull).toList();
|
||||
List<NamespacedKey> namespacedKeys = new ArrayList<>();
|
||||
@ -659,4 +624,16 @@ public final class PaperweightFaweAdapter extends FaweAdapter<net.minecraft.nbt.
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -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.math.IntPair;
|
||||
@ -15,14 +15,15 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.FullChunkStatus;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
|
||||
import 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.. :( )
|
||||
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;
|
||||
if (nextTick || cachedChanges.size() >= 1024) {
|
||||
if (nextTick) {
|
||||
@ -140,7 +141,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
|
||||
return false;
|
||||
}
|
||||
net.minecraft.nbt.Tag nativeTag = paperweightFaweAdapter.fromNativeBinary(tag);
|
||||
blockEntity.load((CompoundTag) nativeTag);
|
||||
blockEntity.loadWithComponents((CompoundTag) nativeTag, DedicatedServer.getServer().registryAccess());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -157,7 +158,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
|
||||
|
||||
@Override
|
||||
public boolean isChunkTicking(LevelChunk levelChunk) {
|
||||
return levelChunk.getFullStatus().isOrAfter(ChunkHolder.FullChunkStatus.TICKING);
|
||||
return levelChunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -181,7 +182,7 @@ public class PaperweightFaweWorldNativeAccess implements WorldNativeAccess<Level
|
||||
// Un-nest neighbour updating
|
||||
for (Direction direction : NEIGHBOUR_ORDER) {
|
||||
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()) {
|
@ -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.DelegateSemaphore;
|
||||
@ -20,7 +20,7 @@ import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_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.util.LogManagerCompat;
|
||||
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 io.papermc.lib.PaperLib;
|
||||
import io.papermc.paper.event.block.BeaconDeactivatedEvent;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.IdMap;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.core.*;
|
||||
import net.minecraft.nbt.IntTag;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.util.BitStorage;
|
||||
@ -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.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.DataLayer;
|
||||
import net.minecraft.world.level.chunk.HashMapPalette;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import net.minecraft.world.level.chunk.LinearPalette;
|
||||
import net.minecraft.world.level.chunk.Palette;
|
||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||
import net.minecraft.world.level.chunk.*;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.block.CraftBlock;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.block.CraftBlock;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Future;
|
||||
@ -83,13 +64,16 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.minecraft.core.registries.Registries.BIOME;
|
||||
|
||||
public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBlocks {
|
||||
|
||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||
|
||||
private static final Function<BlockPos, BlockVector3> posNms2We = v -> BlockVector3.at(v.getX(), v.getY(), v.getZ());
|
||||
private static final Function<BlockEntity, CompoundTag> nmsTile2We =
|
||||
tileEntity -> new PaperweightLazyCompoundTag(Suppliers.memoize(tileEntity::saveWithId));
|
||||
private static final Function<BlockEntity, CompoundTag> nmsTile2We = tileEntity -> new PaperweightLazyCompoundTag(
|
||||
Suppliers.memoize(() -> tileEntity.saveWithId(DedicatedServer.getServer().registryAccess()))
|
||||
);
|
||||
private final PaperweightFaweAdapter adapter = ((PaperweightFaweAdapter) WorldEditPlugin
|
||||
.getInstance()
|
||||
.getBukkitImplAdapter());
|
||||
@ -130,7 +114,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
this.maxSectionPosition = maxHeight >> 4;
|
||||
this.skyLight = new DataLayer[getSectionCount()];
|
||||
this.blockLight = new DataLayer[getSectionCount()];
|
||||
this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
||||
this.biomeRegistry = serverLevel.registryAccess().registryOrThrow(BIOME);
|
||||
this.biomeHolderIdMap = biomeRegistry.asHolderIdMap();
|
||||
}
|
||||
|
||||
@ -260,7 +244,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
if (blockEntity == null) {
|
||||
return null;
|
||||
}
|
||||
return new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId));
|
||||
return new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.saveWithId(DedicatedServer.getServer().registryAccess())));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -289,8 +273,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(
|
||||
LightLayer.BLOCK,
|
||||
sectionPos,
|
||||
dataLayer,
|
||||
true
|
||||
dataLayer
|
||||
);
|
||||
}
|
||||
skyLight[alayer] = dataLayer;
|
||||
@ -317,7 +300,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
Arrays.fill(LAYER_COUNT, (byte) 15);
|
||||
dataLayer = new DataLayer(LAYER_COUNT);
|
||||
((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(LightLayer.BLOCK, sectionPos,
|
||||
dataLayer, true
|
||||
dataLayer
|
||||
);
|
||||
}
|
||||
blockLight[alayer] = dataLayer;
|
||||
@ -334,7 +317,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
|
||||
@Override
|
||||
public CompoundTag getEntity(UUID uuid) {
|
||||
Entity entity = serverLevel.getEntity(uuid);
|
||||
ensureLoaded(serverLevel, chunkX, chunkZ);
|
||||
List<Entity> entities = PaperweightPlatformAdapter.getEntities(getChunk());
|
||||
Entity entity = null;
|
||||
for (Entity e : entities) {
|
||||
if (e.getUUID().equals(uuid)) {
|
||||
entity = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entity != null) {
|
||||
org.bukkit.entity.Entity bukkitEnt = entity.getBukkitEntity();
|
||||
return BukkitAdapter.adapt(bukkitEnt).getState().getNbtData();
|
||||
@ -349,6 +340,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
|
||||
@Override
|
||||
public Set<CompoundTag> getEntities() {
|
||||
ensureLoaded(serverLevel, chunkX, chunkZ);
|
||||
List<Entity> entities = PaperweightPlatformAdapter.getEntities(getChunk());
|
||||
if (entities.isEmpty()) {
|
||||
return Collections.emptySet();
|
||||
@ -385,7 +377,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
public Iterator<CompoundTag> iterator() {
|
||||
Iterable<CompoundTag> result = entities.stream().map(input -> {
|
||||
net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
|
||||
PaperweightPlatformAdapter.readEntityIntoTag(input, tag);
|
||||
input.save(tag);
|
||||
return (CompoundTag) adapter.toNative(tag);
|
||||
}).collect(Collectors.toList());
|
||||
return result.iterator();
|
||||
@ -474,7 +466,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
synchronized (super.sectionLocks[getSectionIndex]) {
|
||||
LevelChunkSection existingSection = levelChunkSections[getSectionIndex];
|
||||
if (createCopy && existingSection != null) {
|
||||
copy.storeBiomes(getSectionIndex, existingSection.getBiomes().copy());
|
||||
copy.storeBiomes(getSectionIndex, existingSection.getBiomes());
|
||||
}
|
||||
|
||||
if (existingSection == null) {
|
||||
@ -507,8 +499,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
}
|
||||
} else {
|
||||
PalettedContainer<Holder<Biome>> biomeData = existingSection.getBiomes();
|
||||
setBiomesToPalettedContainer(biomes[setSectionIndex], biomeData);
|
||||
setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -543,7 +534,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
System.arraycopy(tmpLoad, 0, copyArr, 0, 4096);
|
||||
copy.storeSection(getSectionIndex, copyArr);
|
||||
if (biomes != null && existingSection != null) {
|
||||
copy.storeBiomes(getSectionIndex, existingSection.getBiomes().copy());
|
||||
copy.storeBiomes(getSectionIndex, existingSection.getBiomes());
|
||||
}
|
||||
}
|
||||
|
||||
@ -555,8 +546,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
.getBukkitImplAdapter()
|
||||
.getInternalBiomeId(
|
||||
BiomeTypes.PLAINS)),
|
||||
PalettedContainer.Strategy.SECTION_BIOMES,
|
||||
null
|
||||
PalettedContainer.Strategy.SECTION_BIOMES
|
||||
) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap);
|
||||
newSection = PaperweightPlatformAdapter.newChunkSection(
|
||||
layerNo,
|
||||
@ -616,11 +606,11 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
sectionLock.writeLock().unlock();
|
||||
}
|
||||
|
||||
PalettedContainer<Holder<Biome>> biomeData = existingSection.getBiomes();
|
||||
|
||||
if (biomes != null && biomes[setSectionIndex] != null) {
|
||||
setBiomesToPalettedContainer(biomes[setSectionIndex], biomeData);
|
||||
}
|
||||
PalettedContainer<Holder<Biome>> biomeData = setBiomesToPalettedContainer(
|
||||
biomes,
|
||||
setSectionIndex,
|
||||
existingSection.getBiomes()
|
||||
);
|
||||
|
||||
newSection =
|
||||
PaperweightPlatformAdapter.newChunkSection(
|
||||
@ -705,7 +695,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
if (Settings.settings().EXPERIMENTAL.REMOVE_ENTITY_FROM_WORLD_ON_CHUNK_FAIL) {
|
||||
for (UUID uuid : entityRemoves) {
|
||||
Entity entity = nmsWorld.entityManager.getEntityGetter().get(uuid);
|
||||
Entity entity = nmsWorld.getEntities().get(uuid);
|
||||
if (entity != null) {
|
||||
removeEntity(entity);
|
||||
}
|
||||
@ -783,9 +773,9 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
for (final Map.Entry<BlockVector3, CompoundTag> entry : tiles.entrySet()) {
|
||||
final CompoundTag nativeTag = entry.getValue();
|
||||
final BlockVector3 blockHash = entry.getKey();
|
||||
final int x = blockHash.getX() + bx;
|
||||
final int y = blockHash.getY();
|
||||
final int z = blockHash.getZ() + bz;
|
||||
final int x = blockHash.x() + bx;
|
||||
final int y = blockHash.y();
|
||||
final int z = blockHash.z() + bz;
|
||||
final BlockPos pos = new BlockPos(x, y, z);
|
||||
|
||||
synchronized (nmsWorld) {
|
||||
@ -800,7 +790,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
tag.put("x", IntTag.valueOf(x));
|
||||
tag.put("y", IntTag.valueOf(y));
|
||||
tag.put("z", IntTag.valueOf(z));
|
||||
tileEntity.load(tag);
|
||||
tileEntity.loadWithComponents(tag, DedicatedServer.getServer().registryAccess());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1076,8 +1066,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
((LevelLightEngine) serverLevel.getChunkSource().getLightEngine()).queueSectionData(
|
||||
lightLayer,
|
||||
sectionPos,
|
||||
dataLayer,
|
||||
true
|
||||
dataLayer
|
||||
);
|
||||
}
|
||||
synchronized (dataLayer) {
|
||||
@ -1095,22 +1084,35 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
}
|
||||
|
||||
private void setBiomesToPalettedContainer(
|
||||
final BiomeType[] biomes,
|
||||
PalettedContainer<Holder<Biome>> data
|
||||
private PalettedContainer<Holder<Biome>> setBiomesToPalettedContainer(
|
||||
final BiomeType[][] biomes,
|
||||
final int sectionIndex,
|
||||
final PalettedContainerRO<Holder<Biome>> data
|
||||
) {
|
||||
int index = 0;
|
||||
if (biomes == null) {
|
||||
return;
|
||||
PalettedContainer<Holder<Biome>> biomeData;
|
||||
if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
|
||||
biomeData = palettedContainer;
|
||||
} else {
|
||||
LOGGER.warn(
|
||||
"Cannot correctly set biomes to world, existing biomes may be lost. Expected class " +
|
||||
"type {} but got {}",
|
||||
PalettedContainer.class.getSimpleName(),
|
||||
data.getClass().getSimpleName()
|
||||
);
|
||||
biomeData = data.recreate();
|
||||
}
|
||||
for (int y = 0; y < 4; y++) {
|
||||
BiomeType[] sectionBiomes;
|
||||
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
|
||||
return biomeData;
|
||||
}
|
||||
for (int y = 0, index = 0; y < 4; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int x = 0; x < 4; x++, index++) {
|
||||
BiomeType biomeType = biomes[index];
|
||||
BiomeType biomeType = sectionBiomes[index];
|
||||
if (biomeType == null) {
|
||||
continue;
|
||||
}
|
||||
data.set(
|
||||
biomeData.set(
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
@ -1122,6 +1124,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
|
||||
}
|
||||
}
|
||||
}
|
||||
return biomeData;
|
||||
}
|
||||
|
||||
@Override
|
@ -1,4 +1,4 @@
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||
|
||||
import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType;
|
||||
import com.fastasyncworldedit.core.queue.IBlocks;
|
||||
@ -8,19 +8,23 @@ import com.google.common.base.Suppliers;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt.PaperweightLazyCompoundTag;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt.PaperweightLazyCompoundTag;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||
import net.minecraft.world.level.chunk.PalettedContainerRO;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
@ -33,6 +37,8 @@ import java.util.concurrent.Future;
|
||||
|
||||
public class PaperweightGetBlocks_Copy implements IChunkGet {
|
||||
|
||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||
|
||||
private final Map<BlockVector3, CompoundTag> tiles = new HashMap<>();
|
||||
private final Set<CompoundTag> entities = new HashSet<>();
|
||||
private final char[][] blocks;
|
||||
@ -57,7 +63,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
|
||||
blockEntity.getBlockPos().getY(),
|
||||
blockEntity.getBlockPos().getZ()
|
||||
),
|
||||
new PaperweightLazyCompoundTag(Suppliers.memoize(blockEntity::saveWithId))
|
||||
new PaperweightLazyCompoundTag(Suppliers.memoize(() -> blockEntity.saveWithId(DedicatedServer.getServer().registryAccess())))
|
||||
);
|
||||
}
|
||||
|
||||
@ -76,7 +82,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
|
||||
protected void storeEntity(Entity entity) {
|
||||
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
|
||||
net.minecraft.nbt.CompoundTag compoundTag = new net.minecraft.nbt.CompoundTag();
|
||||
PaperweightPlatformAdapter.readEntityIntoTag(entity, compoundTag);
|
||||
entity.save(compoundTag);
|
||||
entities.add((CompoundTag) adapter.toNative(compoundTag));
|
||||
}
|
||||
|
||||
@ -166,11 +172,19 @@ public class PaperweightGetBlocks_Copy implements IChunkGet {
|
||||
blocks[layer] = data;
|
||||
}
|
||||
|
||||
protected void storeBiomes(int layer, PalettedContainer<Holder<Biome>> biomeData) {
|
||||
protected void storeBiomes(int layer, PalettedContainerRO<Holder<Biome>> biomeData) {
|
||||
if (biomes == null) {
|
||||
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
|
@ -1,4 +1,4 @@
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||
|
||||
import com.fastasyncworldedit.bukkit.adapter.MapChunkUtil;
|
||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||
@ -10,10 +10,10 @@ public class PaperweightMapChunkUtil extends MapChunkUtil<ClientboundLevelChunkW
|
||||
|
||||
public PaperweightMapChunkUtil() throws NoSuchFieldException {
|
||||
fieldX = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("TWO_MEGABYTES", "a"));
|
||||
fieldZ = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("x", "a"));
|
||||
fieldBitMask = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("z", "b"));
|
||||
fieldZ = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("x", "b"));
|
||||
fieldBitMask = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("z", "c"));
|
||||
fieldHeightMap = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("heightmaps", "b"));
|
||||
fieldChunkData = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("chunkData", "c"));
|
||||
fieldChunkData = ClientboundLevelChunkWithLightPacket.class.getDeclaredField(Refraction.pickName("chunkData", "d"));
|
||||
fieldBlockEntities = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("buffer", "c"));
|
||||
fieldFull = ClientboundLevelChunkPacketData.class.getDeclaredField(Refraction.pickName("blockEntitiesData", "d"));
|
||||
fieldX.setAccessible(true);
|
@ -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.DelegateSemaphore;
|
||||
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.BlockTypesCache;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import io.papermc.paper.world.ChunkEntitySlices;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.IdMap;
|
||||
@ -30,19 +32,19 @@ import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.level.TicketType;
|
||||
import net.minecraft.util.BitStorage;
|
||||
import net.minecraft.util.ExceptionCollector;
|
||||
import net.minecraft.util.SimpleBitStorage;
|
||||
import net.minecraft.util.ThreadingDetector;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.util.ZeroBitStorage;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.npc.AbstractVillager;
|
||||
import net.minecraft.world.item.trading.MerchantOffers;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.GlobalPalette;
|
||||
import net.minecraft.world.level.chunk.HashMapPalette;
|
||||
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.PalettedContainer;
|
||||
import net.minecraft.world.level.chunk.SingleValuePalette;
|
||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
import net.minecraft.world.level.entity.PersistentEntitySectionManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftChunk;
|
||||
import sun.misc.Unsafe;
|
||||
import org.bukkit.craftbukkit.CraftChunk;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -79,6 +83,9 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static java.lang.invoke.MethodType.methodType;
|
||||
import static net.minecraft.core.registries.Registries.BIOME;
|
||||
|
||||
public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
|
||||
public static final Field fieldData;
|
||||
@ -100,14 +107,23 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
private static final MethodHandle methodRemoveGameEventListener;
|
||||
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 Logger LOGGER = LogManagerCompat.getLogger();
|
||||
|
||||
static final boolean POST_CHUNK_REWRITE;
|
||||
private static Method PAPER_CHUNK_GEN_ALL_ENTITIES;
|
||||
private static Field LEVEL_CHUNK_ENTITIES;
|
||||
private static Field SERVER_LEVEL_ENTITY_MANAGER;
|
||||
|
||||
static {
|
||||
final MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
try {
|
||||
fieldData = PalettedContainer.class.getDeclaredField(Refraction.pickName("data", "d"));
|
||||
fieldData.setAccessible(true);
|
||||
@ -121,11 +137,11 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
fieldPalette = dataClazz.getDeclaredField(Refraction.pickName("palette", "c"));
|
||||
fieldPalette.setAccessible(true);
|
||||
|
||||
fieldTickingFluidCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "h"));
|
||||
fieldTickingFluidCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingFluidCount", "g"));
|
||||
fieldTickingFluidCount.setAccessible(true);
|
||||
fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "g"));
|
||||
fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f"));
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "f"));
|
||||
fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e"));
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
|
||||
Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName(
|
||||
@ -133,7 +149,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
"b"
|
||||
), long.class);
|
||||
getVisibleChunkIfPresent.setAccessible(true);
|
||||
methodGetVisibleChunk = MethodHandles.lookup().unreflect(getVisibleChunkIfPresent);
|
||||
methodGetVisibleChunk = lookup.unreflect(getVisibleChunkIfPresent);
|
||||
|
||||
if (!PaperLib.isPaper()) {
|
||||
fieldThreadingDetector = PalettedContainer.class.getDeclaredField(Refraction.pickName("threadingDetector", "f"));
|
||||
@ -147,31 +163,66 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
|
||||
Method removeGameEventListener = LevelChunk.class.getDeclaredMethod(
|
||||
Refraction.pickName("removeGameEventListener", "d"),
|
||||
BlockEntity.class
|
||||
Refraction.pickName("removeGameEventListener", "a"),
|
||||
BlockEntity.class,
|
||||
ServerLevel.class
|
||||
);
|
||||
removeGameEventListener.setAccessible(true);
|
||||
methodRemoveGameEventListener = MethodHandles.lookup().unreflect(removeGameEventListener);
|
||||
methodRemoveGameEventListener = lookup.unreflect(removeGameEventListener);
|
||||
|
||||
Method removeBlockEntityTicker = LevelChunk.class.getDeclaredMethod(
|
||||
Refraction.pickName(
|
||||
"removeBlockEntityTicker",
|
||||
"l"
|
||||
"k"
|
||||
), BlockPos.class
|
||||
);
|
||||
removeBlockEntityTicker.setAccessible(true);
|
||||
methodremoveTickingBlockEntity = MethodHandles.lookup().unreflect(removeBlockEntityTicker);
|
||||
methodremoveTickingBlockEntity = lookup.unreflect(removeBlockEntityTicker);
|
||||
|
||||
fieldRemove = BlockEntity.class.getDeclaredField(Refraction.pickName("remove", "p"));
|
||||
fieldRemove.setAccessible(true);
|
||||
|
||||
fieldOffers = AbstractVillager.class.getDeclaredField(Refraction.pickName("offers", "bW"));
|
||||
fieldOffers.setAccessible(true);
|
||||
} catch (RuntimeException e) {
|
||||
throw e;
|
||||
} catch (Throwable rethrow) {
|
||||
rethrow.printStackTrace();
|
||||
throw new RuntimeException(rethrow);
|
||||
boolean chunkRewrite;
|
||||
try {
|
||||
ServerLevel.class.getDeclaredMethod("getEntityLookup");
|
||||
chunkRewrite = true;
|
||||
PAPER_CHUNK_GEN_ALL_ENTITIES = ChunkEntitySlices.class.getDeclaredMethod("getAllEntities");
|
||||
PAPER_CHUNK_GEN_ALL_ENTITIES.setAccessible(true);
|
||||
} catch (NoSuchMethodException ignored) {
|
||||
chunkRewrite = false;
|
||||
}
|
||||
try {
|
||||
// Paper - Pre-Chunk-Update
|
||||
LEVEL_CHUNK_ENTITIES = LevelChunk.class.getDeclaredField("entities");
|
||||
LEVEL_CHUNK_ENTITIES.setAccessible(true);
|
||||
} catch (NoSuchFieldException ignored) {
|
||||
}
|
||||
try {
|
||||
// Non-Paper
|
||||
SERVER_LEVEL_ENTITY_MANAGER = ServerLevel.class.getDeclaredField(Refraction.pickName("entityManager", "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(
|
||||
@ -255,7 +306,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
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) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -265,9 +317,9 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
|
||||
private static void addTicket(ServerLevel serverLevel, int chunkX, int chunkZ) {
|
||||
// Ensure chunk is definitely loaded before applying a ticket
|
||||
net.minecraft.server.MCUtil.MAIN_EXECUTOR.execute(() -> serverLevel
|
||||
io.papermc.paper.util.MCUtil.MAIN_EXECUTOR.execute(() -> serverLevel
|
||||
.getChunkSource()
|
||||
.addRegionTicket(TicketType.PLUGIN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE));
|
||||
.addRegionTicket(TicketType.UNLOAD_COOLDOWN, new ChunkPos(chunkX, chunkZ), 0, Unit.INSTANCE));
|
||||
}
|
||||
|
||||
public static ChunkHolder getPlayerChunk(ServerLevel nmsWorld, final int chunkX, final int chunkZ) {
|
||||
@ -286,20 +338,19 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
return;
|
||||
}
|
||||
ChunkPos coordIntPair = new ChunkPos(chunkX, chunkZ);
|
||||
// UNLOADED_CHUNK
|
||||
Optional<LevelChunk> optional = ((Either) chunkHolder
|
||||
.getTickingChunkFuture()
|
||||
.getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left();
|
||||
LevelChunk levelChunk;
|
||||
if (PaperLib.isPaper()) {
|
||||
// getChunkAtIfLoadedImmediately is paper only
|
||||
optional = optional.or(() -> Optional.ofNullable(nmsWorld
|
||||
levelChunk = nmsWorld
|
||||
.getChunkSource()
|
||||
.getChunkAtIfLoadedImmediately(chunkX, chunkZ)));
|
||||
.getChunkAtIfLoadedImmediately(chunkX, chunkZ);
|
||||
} else {
|
||||
levelChunk = chunkHolder.getTickingChunkFuture()
|
||||
.getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK).orElse(null);
|
||||
}
|
||||
if (optional.isEmpty()) {
|
||||
if (levelChunk == null) {
|
||||
return;
|
||||
}
|
||||
LevelChunk levelChunk = optional.get();
|
||||
TaskManager.taskManager().task(() -> {
|
||||
ClientboundLevelChunkWithLightPacket packet;
|
||||
if (PaperLib.isPaper()) {
|
||||
@ -307,9 +358,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
false // last false is to not bother with x-ray
|
||||
null
|
||||
// last false is to not bother with x-ray
|
||||
);
|
||||
} else {
|
||||
// deprecated on paper - deprecation suppressed
|
||||
@ -317,8 +367,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
levelChunk,
|
||||
nmsWorld.getChunkSource().getLightEngine(),
|
||||
null,
|
||||
null,
|
||||
true
|
||||
null
|
||||
);
|
||||
}
|
||||
nearbyPlayers(nmsWorld, coordIntPair).forEach(p -> p.connection.send(packet));
|
||||
@ -424,12 +473,11 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
.getBukkitImplAdapter()
|
||||
.getInternalBiomeId(
|
||||
BiomeTypes.PLAINS)),
|
||||
PalettedContainer.Strategy.SECTION_BIOMES,
|
||||
null
|
||||
PalettedContainer.Strategy.SECTION_BIOMES
|
||||
);
|
||||
}
|
||||
|
||||
return new LevelChunkSection(layer, blockStatePalettedContainer, biomes);
|
||||
return new LevelChunkSection(blockStatePalettedContainer, biomes);
|
||||
} catch (final Throwable e) {
|
||||
throw e;
|
||||
} finally {
|
||||
@ -447,15 +495,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
@Nullable PalettedContainer<Holder<Biome>> biomes
|
||||
) {
|
||||
if (biomes == null) {
|
||||
return new LevelChunkSection(layer, biomeRegistry);
|
||||
return new LevelChunkSection(biomeRegistry);
|
||||
}
|
||||
PalettedContainer<net.minecraft.world.level.block.state.BlockState> dataPaletteBlocks = new PalettedContainer<>(
|
||||
Block.BLOCK_STATE_REGISTRY,
|
||||
Blocks.AIR.defaultBlockState(),
|
||||
PalettedContainer.Strategy.SECTION_STATES,
|
||||
null
|
||||
PalettedContainer.Strategy.SECTION_STATES
|
||||
);
|
||||
return new LevelChunkSection(layer, dataPaletteBlocks, biomes);
|
||||
return new LevelChunkSection(dataPaletteBlocks, biomes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -492,8 +539,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
PalettedContainer<Holder<Biome>> biomePalettedContainer = new PalettedContainer<>(
|
||||
biomeRegistry,
|
||||
biomeRegistry.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)),
|
||||
PalettedContainer.Strategy.SECTION_BIOMES,
|
||||
null
|
||||
PalettedContainer.Strategy.SECTION_BIOMES
|
||||
);
|
||||
|
||||
final Palette<Holder<Biome>> biomePalette;
|
||||
@ -571,7 +617,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
|
||||
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) {
|
||||
return biomeRegistry.asHolderIdMap().getId(biome) == -1 ? BiomeTypes.OCEAN
|
||||
: null;
|
||||
@ -581,13 +627,11 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
|
||||
static void removeBeacon(BlockEntity beacon, LevelChunk levelChunk) {
|
||||
try {
|
||||
// Do the method ourselves to avoid trying to reflect generic method parameters
|
||||
// similar to removeGameEventListener
|
||||
if (levelChunk.loaded || levelChunk.level.isClientSide()) {
|
||||
BlockEntity blockEntity = levelChunk.blockEntities.remove(beacon.getBlockPos());
|
||||
if (blockEntity != null) {
|
||||
if (!levelChunk.level.isClientSide) {
|
||||
methodRemoveGameEventListener.invoke(levelChunk, beacon);
|
||||
methodRemoveGameEventListener.invoke(levelChunk, beacon, levelChunk.level);
|
||||
}
|
||||
fieldRemove.set(beacon, true);
|
||||
}
|
||||
@ -599,30 +643,32 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
|
||||
}
|
||||
|
||||
static List<Entity> getEntities(LevelChunk chunk) {
|
||||
return chunk.level.entityManager.getEntities(chunk.getPos());
|
||||
}
|
||||
|
||||
public static void readEntityIntoTag(Entity entity, net.minecraft.nbt.CompoundTag compoundTag) {
|
||||
boolean isVillager = entity instanceof AbstractVillager && !Fawe.isMainThread();
|
||||
boolean unset = false;
|
||||
if (isVillager) {
|
||||
ExceptionCollector<RuntimeException> collector = new ExceptionCollector<>();
|
||||
if (PaperLib.isPaper()) {
|
||||
if (POST_CHUNK_REWRITE) {
|
||||
try {
|
||||
if (fieldOffers.get(entity) != null) {
|
||||
fieldOffers.set(entity, OFFERS);
|
||||
unset = true;
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Failed to set offers field to villager to avoid async catcher.", e);
|
||||
//noinspection unchecked
|
||||
return (List<Entity>) PAPER_CHUNK_GEN_ALL_ENTITIES.invoke(chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ));
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=true]", e);
|
||||
}
|
||||
}
|
||||
entity.save(compoundTag);
|
||||
if (unset) {
|
||||
try {
|
||||
fieldOffers.set(entity, null);
|
||||
EntityList entityList = (EntityList) LEVEL_CHUNK_ENTITIES.get(chunk);
|
||||
return List.of(entityList.getRawData());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Failed to set offers field to null again on villager.", e);
|
||||
collector.add(new RuntimeException("Failed to lookup entities [POST_CHUNK_REWRITE=false]", e));
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
try {
|
||||
//noinspection unchecked
|
||||
return ((PersistentEntitySectionManager<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> {
|
@ -1,4 +1,4 @@
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.extent.processor.ProcessorScope;
|
@ -1,14 +1,14 @@
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||
|
||||
import com.fastasyncworldedit.bukkit.adapter.StarlightRelighter;
|
||||
import com.fastasyncworldedit.core.configuration.Settings;
|
||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||
import net.minecraft.server.MCUtil;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.TicketType;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@ -18,7 +18,7 @@ import java.util.function.IntConsumer;
|
||||
public class PaperweightStarlightRelighter extends StarlightRelighter<ServerLevel, ChunkPos> {
|
||||
|
||||
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) {
|
||||
super(serverLevel, queue);
|
@ -1,4 +1,4 @@
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2;
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4;
|
||||
|
||||
import com.fastasyncworldedit.core.extent.processor.lighting.NullRelighter;
|
||||
import com.fastasyncworldedit.core.extent.processor.lighting.RelightMode;
|
||||
@ -7,7 +7,7 @@ import com.fastasyncworldedit.core.extent.processor.lighting.RelighterFactory;
|
||||
import com.fastasyncworldedit.core.queue.IQueueExtent;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.nbt;
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.nbt;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.LazyCompoundTag;
|
@ -1,17 +1,15 @@
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.regen;
|
||||
package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.regen;
|
||||
|
||||
import com.fastasyncworldedit.bukkit.adapter.Regenerator;
|
||||
import com.fastasyncworldedit.core.Fawe;
|
||||
import com.fastasyncworldedit.core.queue.IChunkCache;
|
||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
import com.fastasyncworldedit.core.util.ReflectionUtils;
|
||||
import com.fastasyncworldedit.core.util.TaskManager;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
|
||||
import com.sk89q.worldedit.bukkit.adapter.Refraction;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_18_R2.PaperweightGetBlocks;
|
||||
import com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4.PaperweightGetBlocks;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
@ -20,14 +18,19 @@ import com.sk89q.worldedit.world.RegenOptions;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ChunkTaskPriorityQueueSorter.Message;
|
||||
import net.minecraft.server.level.ServerChunkCache;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ThreadedLevelLightEngine;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
import net.minecraft.util.thread.ProcessorHandle;
|
||||
import net.minecraft.util.thread.ProcessorMailbox;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
@ -37,31 +40,34 @@ import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.FixedBiomeSource;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.ChunkGeneratorStructureState;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||
import net.minecraft.world.level.chunk.UpgradeData;
|
||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.status.WorldGenContext;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.FlatLevelSource;
|
||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||
import net.minecraft.world.level.levelgen.WorldOptions;
|
||||
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
||||
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.PrimaryLevelData;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_18_R2.generator.CustomChunkGenerator;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.generator.CustomChunkGenerator;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
@ -74,6 +80,8 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static net.minecraft.core.registries.Registries.BIOME;
|
||||
|
||||
public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, LevelChunk, PaperweightRegen.ChunkStatusWrap> {
|
||||
|
||||
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 delegateField;
|
||||
private static final Field chunkSourceField;
|
||||
private static final Field generatorStructureStateField;
|
||||
private static final Field ringPositionsField;
|
||||
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_REFERENCES,
|
||||
Concurrency.FULL
|
||||
Concurrency.NONE
|
||||
); // 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.SURFACE, Concurrency.NONE); // surface: radius 0, requires NONE
|
||||
chunkStati.put(ChunkStatus.CARVERS, Concurrency.NONE); // carvers: radius 0, but RADIUS and FULL change results
|
||||
chunkStati.put(
|
||||
ChunkStatus.LIQUID_CARVERS,
|
||||
Concurrency.NONE
|
||||
); // liquid carvers: radius 0, but RADIUS and FULL change results
|
||||
chunkStati.put(ChunkStatus.FEATURES, Concurrency.NONE); // features: uses unsynchronized maps
|
||||
chunkStati.put(
|
||||
ChunkStatus.INITIALIZE_LIGHT,
|
||||
Concurrency.FULL
|
||||
); // initialize_light: radius 0
|
||||
chunkStati.put(
|
||||
ChunkStatus.LIGHT,
|
||||
Concurrency.FULL
|
||||
); // light: radius 1, but no writes to other chunks, only current chunk
|
||||
chunkStati.put(ChunkStatus.SPAWN, Concurrency.FULL); // spawn: radius 0
|
||||
chunkStati.put(ChunkStatus.HEIGHTMAPS, Concurrency.FULL); // heightmaps: radius 0
|
||||
chunkStati.put(ChunkStatus.SPAWN, Concurrency.NONE); // spawn: radius 0
|
||||
|
||||
try {
|
||||
serverWorldsField = CraftServer.class.getDeclaredField("worlds");
|
||||
@ -134,22 +142,27 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
flatBedrockField = tmpFlatBedrockField;
|
||||
|
||||
generatorSettingBaseSupplierField = NoiseBasedChunkGenerator.class.getDeclaredField(Refraction.pickName(
|
||||
"settings", "h"));
|
||||
"settings", "e"));
|
||||
generatorSettingBaseSupplierField.setAccessible(true);
|
||||
|
||||
generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "g"));
|
||||
generatorSettingFlatField = FlatLevelSource.class.getDeclaredField(Refraction.pickName("settings", "d"));
|
||||
generatorSettingFlatField.setAccessible(true);
|
||||
|
||||
delegateField = CustomChunkGenerator.class.getDeclaredField("delegate");
|
||||
delegateField.setAccessible(true);
|
||||
|
||||
chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "K"));
|
||||
chunkSourceField = ServerLevel.class.getDeclaredField(Refraction.pickName("chunkSource", "I"));
|
||||
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);
|
||||
|
||||
hasGeneratedPositionsField = ChunkGenerator.class.getDeclaredField(Refraction.pickName("hasGeneratedPositions", "i"));
|
||||
hasGeneratedPositionsField = ChunkGeneratorStructureState.class.getDeclaredField(
|
||||
Refraction.pickName("hasGeneratedPositions", "h")
|
||||
);
|
||||
hasGeneratedPositionsField.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@ -162,9 +175,10 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
private ServerLevel freshWorld;
|
||||
private ServerChunkCache freshChunkProvider;
|
||||
private LevelStorageSource.LevelStorageAccess session;
|
||||
private StructureManager structureManager;
|
||||
private StructureTemplateManager structureTemplateManager;
|
||||
private ThreadedLevelLightEngine threadedLevelLightEngine;
|
||||
private ChunkGenerator chunkGenerator;
|
||||
private WorldGenContext worldGenContext;
|
||||
|
||||
private Path tempDir;
|
||||
|
||||
@ -207,12 +221,10 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
session = levelStorageSource.createAccess("faweregentempworld", levelStemResourceKey);
|
||||
PrimaryLevelData originalWorldData = originalServerWorld.serverLevelData;
|
||||
|
||||
BiomeProvider biomeProvider = getBiomeProvider();
|
||||
|
||||
MinecraftServer server = originalServerWorld.getCraftServer().getServer();
|
||||
WorldGenSettings originalOpts = originalWorldData.worldGenSettings();
|
||||
WorldGenSettings newOpts = options.getSeed().isPresent()
|
||||
? originalOpts.withSeed(originalWorldData.isHardcore(), OptionalLong.of(seed))
|
||||
WorldOptions originalOpts = originalWorldData.worldGenOptions();
|
||||
WorldOptions newOpts = options.getSeed().isPresent()
|
||||
? originalOpts.withSeed(OptionalLong.of(seed))
|
||||
: originalOpts;
|
||||
LevelSettings newWorldSettings = new LevelSettings(
|
||||
"faweregentempworld",
|
||||
@ -221,9 +233,19 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
originalWorldData.settings.difficulty(),
|
||||
originalWorldData.settings.allowCommands(),
|
||||
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
|
||||
freshWorld = Fawe.instance().getQueueHandler().sync((Supplier<ServerLevel>) () -> new ServerLevel(
|
||||
@ -232,66 +254,70 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
session,
|
||||
newWorldData,
|
||||
originalServerWorld.dimension(),
|
||||
originalServerWorld.dimensionTypeRegistration(),
|
||||
DedicatedServer.getServer().registryAccess().registry(Registries.LEVEL_STEM).orElseThrow()
|
||||
.getOrThrow(levelStemResourceKey),
|
||||
new RegenNoOpWorldLoadListener(),
|
||||
// placeholder. Required for new ChunkProviderServer, but we create and then set it later
|
||||
newOpts.dimensions().getOrThrow(levelStemResourceKey).generator(),
|
||||
originalServerWorld.isDebug(),
|
||||
seed,
|
||||
ImmutableList.of(),
|
||||
false,
|
||||
originalServerWorld.getRandomSequences(),
|
||||
environment,
|
||||
generator,
|
||||
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())
|
||||
) : null;
|
||||
|
||||
@Override
|
||||
public void tick(BooleanSupplier shouldKeepTicking) { //no ticking
|
||||
public void tick(@NotNull BooleanSupplier shouldKeepTicking) { //no ticking
|
||||
}
|
||||
|
||||
@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()) {
|
||||
return singleBiome;
|
||||
}
|
||||
return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome(biomeX, biomeY, biomeZ,
|
||||
PaperweightRegen.this.chunkGenerator.climateSampler()
|
||||
return PaperweightRegen.this.chunkGenerator.getBiomeSource().getNoiseBiome(
|
||||
biomeX, biomeY, biomeZ, getChunkSource().randomState().sampler()
|
||||
);
|
||||
}
|
||||
|
||||
}).get();
|
||||
freshWorld.noSave = true;
|
||||
removeWorldFromWorldsMap();
|
||||
newWorldData.checkName(originalServerWorld.serverLevelData.getLevelName()); //rename to original world name
|
||||
if (paperConfigField != null) {
|
||||
paperConfigField.set(freshWorld, originalServerWorld.paperConfig);
|
||||
paperConfigField.set(freshWorld, originalServerWorld.paperConfig());
|
||||
}
|
||||
|
||||
//generator
|
||||
ChunkGenerator originalGenerator = originalChunkProvider.getGenerator();
|
||||
if (originalGenerator instanceof FlatLevelSource flatLevelSource) {
|
||||
FlatLevelGeneratorSettings generatorSettingFlat = flatLevelSource.settings();
|
||||
chunkGenerator = new FlatLevelSource(originalGenerator.structureSets, generatorSettingFlat);
|
||||
chunkGenerator = new FlatLevelSource(generatorSettingFlat);
|
||||
} else if (originalGenerator instanceof NoiseBasedChunkGenerator noiseBasedChunkGenerator) {
|
||||
Holder<NoiseGeneratorSettings> generatorSettingBaseSupplier =
|
||||
(Holder<NoiseGeneratorSettings>) generatorSettingBaseSupplierField
|
||||
.get(originalGenerator);
|
||||
Holder<NoiseGeneratorSettings> generatorSettingBaseSupplier = (Holder<NoiseGeneratorSettings>)
|
||||
generatorSettingBaseSupplierField.get(noiseBasedChunkGenerator);
|
||||
BiomeSource biomeSource;
|
||||
if (options.hasBiomeType()) {
|
||||
biomeSource = new FixedBiomeSource(BuiltinRegistries.BIOME
|
||||
.asHolderIdMap()
|
||||
.byId(WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())));
|
||||
biomeSource = new FixedBiomeSource(
|
||||
DedicatedServer.getServer().registryAccess()
|
||||
.registryOrThrow(BIOME).asHolderIdMap().byIdOrThrow(
|
||||
WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBiomeId(options.getBiomeType())
|
||||
)
|
||||
);
|
||||
} else {
|
||||
biomeSource = originalGenerator.getBiomeSource();
|
||||
}
|
||||
chunkGenerator = new NoiseBasedChunkGenerator(originalGenerator.structureSets, noiseBasedChunkGenerator.noises,
|
||||
biomeSource, seed,
|
||||
chunkGenerator = new NoiseBasedChunkGenerator(
|
||||
biomeSource,
|
||||
generatorSettingBaseSupplier
|
||||
);
|
||||
} else if (originalGenerator instanceof CustomChunkGenerator customChunkGenerator) {
|
||||
chunkGenerator = customChunkGenerator.delegate;
|
||||
chunkGenerator = customChunkGenerator.getDelegate();
|
||||
} else {
|
||||
LOGGER.error("Unsupported generator type {}", originalGenerator.getClass().getName());
|
||||
return false;
|
||||
@ -300,22 +326,8 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
chunkGenerator = new CustomChunkGenerator(freshWorld, chunkGenerator, generator);
|
||||
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(
|
||||
freshWorld,
|
||||
session,
|
||||
@ -333,7 +345,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
) {
|
||||
// redirect to LevelChunks created in #createChunks
|
||||
@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);
|
||||
if (chunkAccess == null && create) {
|
||||
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);
|
||||
//let's start then
|
||||
structureManager = server.getStructureManager();
|
||||
threadedLevelLightEngine = freshChunkProvider.getLightEngine();
|
||||
structureTemplateManager = server.getStructureManager();
|
||||
threadedLevelLightEngine = new NoOpLightEngine(freshChunkProvider);
|
||||
|
||||
this.worldGenContext = new WorldGenContext(freshWorld, chunkGenerator, structureTemplateManager,
|
||||
threadedLevelLightEngine
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -362,7 +395,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
Fawe.instance().getQueueHandler().sync(() -> {
|
||||
try {
|
||||
freshChunkProvider.close(false);
|
||||
} catch (IOException e) {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
@ -385,7 +418,7 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
@Override
|
||||
protected ProtoChunk createProtoChunk(int x, int z) {
|
||||
return new FastProtoChunk(new ChunkPos(x, z), UpgradeData.EMPTY, freshWorld,
|
||||
this.freshWorld.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), null
|
||||
this.freshWorld.registryAccess().registryOrThrow(BIOME), null
|
||||
);
|
||||
}
|
||||
|
||||
@ -411,7 +444,11 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
@Override
|
||||
protected void populate(LevelChunk levelChunk, Random random, BlockPopulator blockPopulator) {
|
||||
// BlockPopulator#populate has to be called synchronously for TileEntity access
|
||||
TaskManager.taskManager().task(() -> blockPopulator.populate(freshWorld.getWorld(), random, levelChunk.getBukkitChunk()));
|
||||
TaskManager.taskManager().task(() -> {
|
||||
final CraftWorld world = freshWorld.getWorld();
|
||||
final Chunk chunk = world.getChunkAt(levelChunk.locX, levelChunk.locZ);
|
||||
blockPopulator.populate(world, random, chunk);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -427,14 +464,12 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
//util
|
||||
@SuppressWarnings("unchecked")
|
||||
private void removeWorldFromWorldsMap() {
|
||||
Fawe.instance().getQueueHandler().sync(() -> {
|
||||
try {
|
||||
Map<String, org.bukkit.World> map = (Map<String, org.bukkit.World>) serverWorldsField.get(Bukkit.getServer());
|
||||
map.remove("faweregentempworld");
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ResourceKey<LevelStem> getWorldDimKey(org.bukkit.World.Environment env) {
|
||||
@ -451,11 +486,15 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSpawnPos(ChunkPos spawnPos) {
|
||||
public void updateSpawnPos(@NotNull ChunkPos spawnPos) {
|
||||
}
|
||||
|
||||
@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
|
||||
@ -487,15 +526,14 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
|
||||
// avoid warning on paper
|
||||
|
||||
// compatibility with spigot
|
||||
|
||||
@SuppressWarnings("unused") // compatibility with spigot
|
||||
public boolean generateFlatBedrock() {
|
||||
return generateFlatBedrock;
|
||||
}
|
||||
|
||||
// no one will ever see the entities!
|
||||
@Override
|
||||
public List<CompoundTag> getEntities() {
|
||||
public @NotNull List<CompoundTag> getEntities() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@ -516,23 +554,41 @@ public class PaperweightRegen extends Regenerator<ChunkAccess, ProtoChunk, Level
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return chunkStatus.getName();
|
||||
return chunkStatus.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> processChunk(List<ChunkAccess> accessibleChunks) {
|
||||
return chunkStatus.generate(
|
||||
Runnable::run, // TODO revisit, we might profit from this somehow?
|
||||
freshWorld,
|
||||
chunkGenerator,
|
||||
structureManager,
|
||||
threadedLevelLightEngine,
|
||||
c -> CompletableFuture.completedFuture(Either.left(c)),
|
||||
accessibleChunks,
|
||||
true
|
||||
worldGenContext,
|
||||
Runnable::run,
|
||||
CompletableFuture::completedFuture,
|
||||
accessibleChunks
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A light engine that does nothing. As light is calculated after pasting anyway, we can avoid
|
||||
* work this way.
|
||||
*/
|
||||
static class NoOpLightEngine extends ThreadedLevelLightEngine {
|
||||
|
||||
private static final ProcessorMailbox<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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -36,6 +36,7 @@ repositories {
|
||||
name = "Glaremasters"
|
||||
url = uri("https://repo.glaremasters.me/repository/towny/")
|
||||
}
|
||||
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") // TODO Remove when 4.17.0 is released
|
||||
flatDir { dir(File("src/main/resources")) }
|
||||
}
|
||||
|
||||
@ -169,7 +170,7 @@ tasks.named<ShadowJar>("shadowJar") {
|
||||
include(dependency("it.unimi.dsi:fastutil"))
|
||||
}
|
||||
relocate("org.incendo.serverlib", "com.fastasyncworldedit.serverlib") {
|
||||
include(dependency("dev.notmyfault.serverlib:ServerLib:2.3.4"))
|
||||
include(dependency("dev.notmyfault.serverlib:ServerLib:2.3.6"))
|
||||
}
|
||||
relocate("com.intellectualsites.paster", "com.fastasyncworldedit.paster") {
|
||||
include(dependency("com.intellectualsites.paster:Paster"))
|
||||
@ -178,7 +179,7 @@ tasks.named<ShadowJar>("shadowJar") {
|
||||
include(dependency("org.lz4:lz4-java:1.8.0"))
|
||||
}
|
||||
relocate("net.kyori", "com.fastasyncworldedit.core.adventure") {
|
||||
include(dependency("net.kyori:adventure-nbt:4.16.0"))
|
||||
include(dependency("net.kyori:adventure-nbt:4.17.0"))
|
||||
}
|
||||
relocate("com.zaxxer", "com.fastasyncworldedit.core.math") {
|
||||
include(dependency("com.zaxxer:SparseBitSet:1.3"))
|
||||
@ -210,7 +211,7 @@ tasks {
|
||||
versionNumber.set("${project.version}")
|
||||
versionType.set("release")
|
||||
uploadFile.set(file("build/libs/${rootProject.name}-Bukkit-${project.version}.jar"))
|
||||
gameVersions.addAll(listOf("1.20.4", "1.20.3", "1.20.2", "1.20.1", "1.20", "1.19.4", "1.18.2"))
|
||||
gameVersions.addAll(listOf("1.20.6", "1.20.5", "1.20.3", "1.20.2", "1.20.1", "1.20", "1.19.4"))
|
||||
loaders.addAll(listOf("paper", "spigot"))
|
||||
changelog.set("The changelog is available on GitHub: https://github.com/IntellectualSites/" +
|
||||
"FastAsyncWorldEdit/releases/tag/${project.version}")
|
||||
|
@ -31,6 +31,8 @@ import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Registry;
|
||||
import org.bukkit.TreeType;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
@ -97,7 +99,7 @@ public interface IBukkitAdapter {
|
||||
checkNotNull(position);
|
||||
return new org.bukkit.Location(
|
||||
world,
|
||||
position.getX(), position.getY(), position.getZ()
|
||||
position.x(), position.y(), position.z()
|
||||
);
|
||||
}
|
||||
|
||||
@ -117,7 +119,7 @@ public interface IBukkitAdapter {
|
||||
checkNotNull(location);
|
||||
return new org.bukkit.Location(
|
||||
world,
|
||||
location.getX(), location.getY(), location.getZ(),
|
||||
location.x(), location.y(), location.z(),
|
||||
location.getYaw(),
|
||||
location.getPitch()
|
||||
);
|
||||
@ -186,10 +188,12 @@ public interface IBukkitAdapter {
|
||||
}
|
||||
|
||||
default org.bukkit.entity.EntityType adapt(EntityType entityType) {
|
||||
if (!entityType.getId().startsWith("minecraft:")) {
|
||||
throw new IllegalArgumentException("Bukkit only supports vanilla entities");
|
||||
NamespacedKey entityKey = NamespacedKey.fromString(entityType.toString());
|
||||
if (entityKey == null) {
|
||||
throw new IllegalArgumentException("Entity key '" + entityType + "' does not map to Bukkit");
|
||||
}
|
||||
return org.bukkit.entity.EntityType.fromName(entityType.getId().substring(10).toLowerCase(Locale.ROOT));
|
||||
|
||||
return Registry.ENTITY_TYPE.get(entityKey);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -343,7 +347,7 @@ public interface IBukkitAdapter {
|
||||
* @return WorldEdit EntityType
|
||||
*/
|
||||
default EntityType adapt(org.bukkit.entity.EntityType entityType) {
|
||||
return EntityTypes.get(entityType.getName().toLowerCase(Locale.ROOT));
|
||||
return EntityTypes.get(entityType.getKey().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,6 +5,7 @@ import com.fastasyncworldedit.core.queue.IChunkCache;
|
||||
import com.fastasyncworldedit.core.queue.IChunkGet;
|
||||
import com.fastasyncworldedit.core.queue.implementation.SingleThreadQueueExtent;
|
||||
import com.fastasyncworldedit.core.util.MathMan;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
@ -24,11 +25,16 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
import it.unimi.dsi.fastutil.longs.LongList;
|
||||
import jdk.jfr.Category;
|
||||
import jdk.jfr.Event;
|
||||
import jdk.jfr.Label;
|
||||
import jdk.jfr.Name;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.WorldInfo;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@ -36,6 +42,7 @@ import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@ -62,7 +69,7 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
||||
protected final RegenOptions options;
|
||||
|
||||
//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 Long2ObjectOpenHashMap<Chunk> chunks = new Long2ObjectOpenHashMap<>();
|
||||
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, ...)?
|
||||
//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
|
||||
Int2ObjectOpenHashMap<long[]> chunkCoordsForRadius = new Int2ObjectOpenHashMap<>();
|
||||
chunkStatuses.keySet().stream().mapToInt(ChunkStatusWrapper::requiredNeighborChunkRadius0).distinct().forEach(radius -> {
|
||||
if (radius == -1) { //ignore ChunkStatus.EMPTY
|
||||
return;
|
||||
// to get the chunks we need to generate in the nth chunk status, we need to know how many chunks
|
||||
// we need to generate in the n + 1 th chunk status. Summing up the margin solves that
|
||||
LinkedHashMap<ChunkStatus, long[]> chunkCoordsForChunkStatus = new LinkedHashMap<>();
|
||||
int borderSum = 1;
|
||||
// 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
|
||||
for (long xz : chunkCoordsForRadius.get(0)) {
|
||||
// TODO (j21): use SequencedMap#firstEntry().getKey()
|
||||
for (long xz : chunkCoordsForChunkStatus.get(chunkStatuses.keySet().iterator().next())) {
|
||||
ProtoChunk chunk = createProtoChunk(MathMan.unpairIntX(xz), MathMan.unpairIntY(xz));
|
||||
protoChunks.put(xz, chunk);
|
||||
}
|
||||
|
||||
//generate lists for RegionLimitedWorldAccess, need to be square with odd length (e.g. 17x17), 17 = 1 middle chunk + 8 border chunks * 2
|
||||
Int2ObjectOpenHashMap<Long2ObjectOpenHashMap<List<IChunkAccess>>> worldLimits = new Int2ObjectOpenHashMap<>();
|
||||
chunkStatuses.keySet().stream().mapToInt(ChunkStatusWrapper::requiredNeighborChunkRadius0).distinct().forEach(radius -> {
|
||||
if (radius == -1) { //ignore ChunkStatus.EMPTY
|
||||
return;
|
||||
// a memory-efficient, lightweight "list" that calculates index -> ChunkAccess
|
||||
// as needed when accessed
|
||||
class LazyChunkList extends AbstractList<IChunkAccess> {
|
||||
private final int size;
|
||||
private final int minX;
|
||||
private final int minZ;
|
||||
private final int sizeSqrt;
|
||||
|
||||
LazyChunkList(int radius, int centerX, int centerZ) {
|
||||
this.sizeSqrt = radius + 1 + radius; // length of one side
|
||||
this.size = this.sizeSqrt * this.sizeSqrt;
|
||||
this.minX = centerX - radius;
|
||||
this.minZ = centerZ - radius;
|
||||
}
|
||||
Long2ObjectOpenHashMap<List<IChunkAccess>> map = new Long2ObjectOpenHashMap<>();
|
||||
for (long xz : chunkCoordsForRadius.get(radius)) {
|
||||
int x = MathMan.unpairIntX(xz);
|
||||
int z = MathMan.unpairIntY(xz);
|
||||
List<IChunkAccess> l = new ArrayList<>((radius + 1 + radius) * (radius + 1 + radius));
|
||||
for (int zz = z - radius; zz <= z + radius; zz++) { //order is important, first z then x
|
||||
for (int xx = x - radius; xx <= x + radius; xx++) {
|
||||
l.add(protoChunks.get(MathMan.pairInt(xx, zz)));
|
||||
@Override
|
||||
public IChunkAccess get(final int index) {
|
||||
Objects.checkIndex(index, size);
|
||||
int absX = (index % sizeSqrt) + minX;
|
||||
int absZ = (index / sizeSqrt) + minZ;
|
||||
return protoChunks.get(MathMan.pairInt(absX, absZ));
|
||||
}
|
||||
|
||||
@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
|
||||
for (Map.Entry<ChunkStatus, Concurrency> entry : chunkStatuses.entrySet()) {
|
||||
ChunkStatus chunkStatus = entry.getKey();
|
||||
int radius = chunkStatus.requiredNeighborChunkRadius0();
|
||||
final RegenerationEvent event = new RegenerationEvent();
|
||||
event.begin();
|
||||
event.chunkStatus = chunkStatus.name();
|
||||
int radius = Math.max(1, chunkStatus.requiredNeighborChunkRadius0());
|
||||
|
||||
long[] coords = chunkCoordsForRadius.get(radius);
|
||||
Long2ObjectOpenHashMap<List<IChunkAccess>> limitsForRadius = worldLimits.get(radius);
|
||||
long[] coords = chunkCoordsForChunkStatus.get(chunkStatus);
|
||||
event.chunksToProcess = coords.length;
|
||||
if (this.generateConcurrent && entry.getValue() == Concurrency.RADIUS) {
|
||||
SequentialTasks<ConcurrentTasks<LongList>> tasks = getChunkStatusTaskRows(coords, radius);
|
||||
for (ConcurrentTasks<LongList> para : tasks) {
|
||||
@ -224,7 +250,8 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
||||
for (LongList row : para) {
|
||||
scheduled.add(() -> {
|
||||
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
|
||||
List<Runnable> scheduled = new ArrayList<>(coords.length);
|
||||
for (long xz : coords) {
|
||||
scheduled.add(() -> chunkStatus.processChunkSave(xz, limitsForRadius.get(xz)));
|
||||
scheduled.add(() -> chunkStatus.processChunkSave(xz, new LazyChunkList(radius, MathMan.unpairIntX(xz),
|
||||
MathMan.unpairIntY(xz))));
|
||||
}
|
||||
runAndWait(scheduled);
|
||||
} else { // Concurrency.NONE or generateConcurrent == false
|
||||
@ -242,28 +270,33 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
||||
// running regen on the main thread otherwise triggers async-only events on the main thread
|
||||
executor.submit(() -> {
|
||||
for (long xz : coords) {
|
||||
chunkStatus.processChunkSave(xz, limitsForRadius.get(xz));
|
||||
chunkStatus.processChunkSave(xz, new LazyChunkList(radius, MathMan.unpairIntX(xz),
|
||||
MathMan.unpairIntY(xz)));
|
||||
}
|
||||
}).get(); // wait until finished this step
|
||||
}
|
||||
event.commit();
|
||||
}
|
||||
|
||||
//convert to proper chunks
|
||||
for (long xz : chunkCoordsForRadius.get(0)) {
|
||||
// TODO (j21): use SequencedMap#firstEntry().getValue()
|
||||
for (long xz : chunkCoordsForChunkStatus.values().iterator().next()) {
|
||||
ProtoChunk proto = protoChunks.get(xz);
|
||||
chunks.put(xz, createChunk(proto));
|
||||
}
|
||||
|
||||
//final chunkstatus
|
||||
ChunkStatus FULL = getFullChunkStatus();
|
||||
for (long xz : chunkCoordsForRadius.get(0)) { //FULL.requiredNeighbourChunkRadius() == 0!
|
||||
// TODO (j21): use SequencedMap#firstEntry().getValue()
|
||||
for (long xz : chunkCoordsForChunkStatus.values().iterator().next()) { //FULL.requiredNeighbourChunkRadius() == 0!
|
||||
Chunk chunk = chunks.get(xz);
|
||||
FULL.processChunkSave(xz, List.of(chunk));
|
||||
}
|
||||
|
||||
//populate
|
||||
List<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 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,
|
||||
BukkitWorld.HAS_MIN_Y ? originalBukkitWorld.getMaxHeight() : 256);
|
||||
source = new SingleThreadQueueExtent(
|
||||
BukkitWorld.HAS_MIN_Y ? originalBukkitWorld.getMinHeight() : 0,
|
||||
BukkitWorld.HAS_MIN_Y ? originalBukkitWorld.getMaxHeight() : 256
|
||||
);
|
||||
source.init(target, initSourceQueueCache(), null);
|
||||
return true;
|
||||
}
|
||||
@ -319,7 +354,7 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
||||
|
||||
@Override
|
||||
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
|
||||
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()))
|
||||
&& extent.setBiome(set.getX(), set.getY(), set.getZ(), biomeGetter.apply(get));
|
||||
return extent.setBlock(set.x(), set.y(), set.z(), source.getFullBlock(get.x(), get.y(), get.z()))
|
||||
&& 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
|
||||
BlockVector3 oldMin = region.getMinimumPoint();
|
||||
BlockVector3 newMin = BlockVector3.at(
|
||||
(oldMin.getX() >> 4 << 4) - border * 16,
|
||||
oldMin.getY(),
|
||||
(oldMin.getZ() >> 4 << 4) - border * 16
|
||||
(oldMin.x() >> 4 << 4) - border * 16,
|
||||
oldMin.y(),
|
||||
(oldMin.z() >> 4 << 4) - border * 16
|
||||
);
|
||||
BlockVector3 oldMax = region.getMaximumPoint();
|
||||
BlockVector3 newMax = BlockVector3.at(
|
||||
(oldMax.getX() >> 4 << 4) + (border + 1) * 16 - 1,
|
||||
oldMax.getY(),
|
||||
(oldMax.getZ() >> 4 << 4) + (border + 1) * 16 - 1
|
||||
(oldMax.x() >> 4 << 4) + (border + 1) * 16 - 1,
|
||||
oldMax.y(),
|
||||
(oldMax.z() >> 4 << 4) + (border + 1) * 16 - 1
|
||||
);
|
||||
Region adjustedRegion = new CuboidRegion(newMin, newMax);
|
||||
return adjustedRegion.getChunks().stream()
|
||||
.sorted(Comparator
|
||||
.comparingInt(BlockVector2::getZ)
|
||||
.thenComparingInt(BlockVector2::getX)) //needed for RegionLimitedWorldAccess
|
||||
.mapToLong(c -> MathMan.pairInt(c.getX(), c.getZ()))
|
||||
.comparingInt(BlockVector2::z)
|
||||
.thenComparingInt(BlockVector2::x)) //needed for RegionLimitedWorldAccess
|
||||
.mapToLong(c -> MathMan.pairInt(c.x(), c.z()))
|
||||
.toArray();
|
||||
}
|
||||
|
||||
@ -503,7 +538,7 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
||||
int numlists = Math.min(requiredNeighbors * 2 + 1, maxZ - minZ + 1);
|
||||
|
||||
Int2ObjectOpenHashMap<LongList> byZ = new Int2ObjectOpenHashMap<>();
|
||||
int expectedListLength = (coordsCount + 1) / (maxZ - minZ);
|
||||
int expectedListLength = (coordsCount + 1) / (maxZ - minZ + 2);
|
||||
|
||||
//init lists
|
||||
for (int i = minZ; i <= maxZ; i++) {
|
||||
@ -581,13 +616,16 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
|
||||
try {
|
||||
processChunk(accessibleChunks).get();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(
|
||||
"Error while running " + name() + " on chunk " + MathMan.unpairIntX(xz) + "/" + MathMan.unpairIntY(xz),
|
||||
e
|
||||
);
|
||||
LOGGER.error("Error while running {} on chunk {}/{}",
|
||||
name(), MathMan.unpairIntX(xz), MathMan.unpairIntY(xz), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class SequentialTasks<T> extends Tasks<T> {
|
||||
|
@ -135,7 +135,7 @@ public abstract class ChunkListener implements Listener {
|
||||
@Deprecated(since = "2.0.0")
|
||||
public void cleanup(Chunk chunk) {
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
if (entity.getType() == EntityType.DROPPED_ITEM) {
|
||||
if (entity.getType() == EntityType.ITEM) {
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public class WorldGuardFeature extends BukkitMaskManager implements Listener {
|
||||
if (region instanceof ProtectedPolygonalRegion casted) {
|
||||
BlockVector3 max = region.getMaximumPoint();
|
||||
BlockVector3 min = region.getMinimumPoint();
|
||||
return new Polygonal2DRegion(null, casted.getPoints(), min.getBlockY(), max.getBlockY());
|
||||
return new Polygonal2DRegion(null, casted.getPoints(), min.y(), max.y());
|
||||
}
|
||||
return new AdaptedRegion(region);
|
||||
}
|
||||
|
@ -94,15 +94,15 @@ public class FaweDelegateSchematicHandler {
|
||||
return;
|
||||
}
|
||||
BlockVector3 dimension = schematic.getClipboard().getDimensions();
|
||||
final int WIDTH = dimension.getX();
|
||||
final int LENGTH = dimension.getZ();
|
||||
final int HEIGHT = dimension.getY();
|
||||
final int WIDTH = dimension.x();
|
||||
final int LENGTH = dimension.z();
|
||||
final int HEIGHT = dimension.y();
|
||||
final int worldHeight = plot.getArea().getMaxGenHeight() - plot.getArea().getMinGenHeight() + 1;
|
||||
// Validate dimensions
|
||||
CuboidRegion region = plot.getLargestRegion();
|
||||
boolean sizeMismatch =
|
||||
((region.getMaximumPoint().getX() - region.getMinimumPoint().getX() + xOffset + 1) < WIDTH) || (
|
||||
(region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ() + zOffset + 1) < LENGTH) || (HEIGHT
|
||||
((region.getMaximumPoint().x() - region.getMinimumPoint().x() + xOffset + 1) < WIDTH) || (
|
||||
(region.getMaximumPoint().z() - region.getMinimumPoint().z() + zOffset + 1) < LENGTH) || (HEIGHT
|
||||
> worldHeight);
|
||||
if (!Settings.Schematics.PASTE_MISMATCHES && sizeMismatch) {
|
||||
if (actor != null) {
|
||||
@ -111,8 +111,8 @@ public class FaweDelegateSchematicHandler {
|
||||
TaskManager.runTask(whenDone);
|
||||
return;
|
||||
}
|
||||
if (((region.getMaximumPoint().getX() - region.getMinimumPoint().getX() + xOffset + 1) < WIDTH) || (
|
||||
(region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ() + zOffset + 1) < LENGTH) || (HEIGHT
|
||||
if (((region.getMaximumPoint().x() - region.getMinimumPoint().x() + xOffset + 1) < WIDTH) || (
|
||||
(region.getMaximumPoint().z() - region.getMinimumPoint().z() + zOffset + 1) < LENGTH) || (HEIGHT
|
||||
> worldHeight)) {
|
||||
if (whenDone != null) {
|
||||
TaskManager.runTask(whenDone);
|
||||
@ -141,7 +141,7 @@ public class FaweDelegateSchematicHandler {
|
||||
} else {
|
||||
y_offset_actual = yOffset + pw.getMinBuildHeight() + editSession.getHighestTerrainBlock(region
|
||||
.getMinimumPoint()
|
||||
.getX() + 1, region.getMinimumPoint().getZ() + 1, pw.getMinGenHeight(), pw.getMaxGenHeight()
|
||||
.x() + 1, region.getMinimumPoint().z() + 1, pw.getMinGenHeight(), pw.getMaxGenHeight()
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -150,7 +150,7 @@ public class FaweDelegateSchematicHandler {
|
||||
}
|
||||
|
||||
final BlockVector3 to = BlockVector3
|
||||
.at(region.getMinimumPoint().getX() + xOffset, y_offset_actual, region.getMinimumPoint().getZ() + zOffset);
|
||||
.at(region.getMinimumPoint().x() + xOffset, y_offset_actual, region.getMinimumPoint().z() + zOffset);
|
||||
final Clipboard clipboard = schematic.getClipboard();
|
||||
clipboard.setOrigin(clipboard.getRegion().getMinimumPoint());
|
||||
clipboard.paste(editSession, to, true, false, true);
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.fastasyncworldedit.bukkit.regions.plotsquared;
|
||||
|
||||
import com.fastasyncworldedit.core.FaweAPI;
|
||||
import com.fastasyncworldedit.core.configuration.Caption;
|
||||
import com.fastasyncworldedit.core.regions.FaweMask;
|
||||
import com.fastasyncworldedit.core.regions.FaweMaskManager;
|
||||
@ -159,8 +158,8 @@ public class PlotSquaredFeature extends FaweMaskManager {
|
||||
regions = WEManager.getMask(pp);
|
||||
if (regions.size() == 1) {
|
||||
CuboidRegion region = regions.iterator().next();
|
||||
if (region.getMinimumPoint().getX() == Integer.MIN_VALUE
|
||||
&& region.getMaximumPoint().getX() == Integer.MAX_VALUE) {
|
||||
if (region.getMinimumPoint().x() == Integer.MIN_VALUE
|
||||
&& region.getMaximumPoint().x() == Integer.MAX_VALUE) {
|
||||
regions.clear();
|
||||
}
|
||||
}
|
||||
@ -174,22 +173,21 @@ public class PlotSquaredFeature extends FaweMaskManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
Region maskedRegion;
|
||||
if (regions.size() == 1) {
|
||||
final World world = player.getWorld();
|
||||
int min = area != null ? area.getMinBuildHeight() : world.getMinY();
|
||||
// PlotSquared uses exclusive max height, WorldEdit uses inclusive max height -> subtract 1
|
||||
int max = area != null ? Math.min(world.getMaxY(), area.getMaxBuildHeight() - 1) : world.getMaxY();
|
||||
Region maskedRegion;
|
||||
if (regions.size() == 1) {
|
||||
|
||||
final CuboidRegion region = regions.iterator().next();
|
||||
final BlockVector3 pos1 = BlockVector3.at(region.getMinimumX(), min, region.getMinimumZ());
|
||||
final BlockVector3 pos2 = BlockVector3.at(region.getMaximumX(), max, region.getMaximumZ());
|
||||
maskedRegion = new CuboidRegion(pos1, pos2);
|
||||
} else {
|
||||
World world = FaweAPI.getWorld(area.getWorldName());
|
||||
List<Region> weRegions = regions.stream().map(
|
||||
r -> new CuboidRegion(world, BlockVector3.at(r.getMinimumX(), r.getMinimumY(), r.getMinimumZ()),
|
||||
BlockVector3.at(r.getMaximumX(), r.getMaximumY(), r.getMaximumZ())
|
||||
r -> new CuboidRegion(world, BlockVector3.at(r.getMinimumX(), min, r.getMinimumZ()),
|
||||
BlockVector3.at(r.getMaximumX(), max, r.getMaximumZ())
|
||||
)).collect(Collectors.toList());
|
||||
maskedRegion = new RegionIntersection(world, weRegions);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
package com.sk89q.bukkit.util;
|
||||
|
||||
import com.sk89q.util.ReflectionUtil;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
@ -96,12 +97,11 @@ public class CommandRegistration {
|
||||
return fallbackCommands;
|
||||
}
|
||||
|
||||
CommandMap commandMap = ReflectionUtil.getField(plugin.getServer().getPluginManager(), "commandMap");
|
||||
CommandMap commandMap = PaperLib.isPaper() ? Bukkit.getCommandMap() : ReflectionUtil.getField(plugin.getServer().getPluginManager(), "commandMap");
|
||||
if (commandMap == null) {
|
||||
Bukkit.getServer().getLogger().severe(plugin.getDescription().getName()
|
||||
+ ": Could not retrieve server CommandMap, using fallback instead!");
|
||||
fallbackCommands = commandMap = new SimpleCommandMap(Bukkit.getServer());
|
||||
Bukkit.getServer().getPluginManager().registerEvents(new FallbackRegistrationListener(fallbackCommands), plugin);
|
||||
+ ": Could not retrieve server CommandMap");
|
||||
throw new IllegalStateException("Failed to retrieve command map, make sure you are running supported server software");
|
||||
} else {
|
||||
serverCommandMap = commandMap;
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ public enum BukkitAdapter {
|
||||
Vector3 position = location;
|
||||
return new org.bukkit.Location(
|
||||
adapt((World) location.getExtent()),
|
||||
position.getX(), position.getY(), position.getZ(),
|
||||
position.x(), position.y(), position.z(),
|
||||
location.getYaw(),
|
||||
location.getPitch()
|
||||
);
|
||||
@ -258,7 +258,7 @@ public enum BukkitAdapter {
|
||||
checkNotNull(position);
|
||||
return new org.bukkit.Location(
|
||||
world,
|
||||
position.getX(), position.getY(), position.getZ()
|
||||
position.x(), position.y(), position.z()
|
||||
);
|
||||
}
|
||||
|
||||
@ -274,7 +274,7 @@ public enum BukkitAdapter {
|
||||
checkNotNull(position);
|
||||
return new org.bukkit.Location(
|
||||
world,
|
||||
position.getX(), position.getY(), position.getZ()
|
||||
position.x(), position.y(), position.z()
|
||||
);
|
||||
}
|
||||
|
||||
@ -290,7 +290,7 @@ public enum BukkitAdapter {
|
||||
checkNotNull(location);
|
||||
return new org.bukkit.Location(
|
||||
world,
|
||||
location.getX(), location.getY(), location.getZ(),
|
||||
location.x(), location.y(), location.z(),
|
||||
location.getYaw(),
|
||||
location.getPitch()
|
||||
);
|
||||
|
@ -242,9 +242,9 @@ public class BukkitPlayer extends AbstractPlayerActor {
|
||||
//FAWE end
|
||||
return TaskManager.taskManager().sync(() -> player.teleport(new Location(
|
||||
finalWorld,
|
||||
pos.getX(),
|
||||
pos.getY(),
|
||||
pos.getZ(),
|
||||
pos.x(),
|
||||
pos.y(),
|
||||
pos.z(),
|
||||
yaw,
|
||||
pitch
|
||||
)));
|
||||
@ -422,7 +422,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
|
||||
|
||||
@Override
|
||||
public <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) {
|
||||
player.sendBlockChange(loc, player.getWorld().getBlockAt(loc).getBlockData());
|
||||
} else {
|
||||
|
@ -247,7 +247,7 @@ public class BukkitWorld extends AbstractWorld {
|
||||
//FAWE start - safe edit region
|
||||
testCoords(pt);
|
||||
//FAWE end
|
||||
return getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).getLightLevel();
|
||||
return getWorld().getBlockAt(pt.x(), pt.y(), pt.z()).getLightLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -284,7 +284,7 @@ public class BukkitWorld extends AbstractWorld {
|
||||
return false;
|
||||
}
|
||||
|
||||
Block block = getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
Block block = getWorld().getBlockAt(pt.x(), pt.y(), pt.z());
|
||||
BlockState state = PaperLib.getBlockState(block, false).getState();
|
||||
if (!(state instanceof InventoryHolder)) {
|
||||
return false;
|
||||
@ -363,8 +363,8 @@ public class BukkitWorld extends AbstractWorld {
|
||||
//FAWE end
|
||||
World world = getWorld();
|
||||
//FAWE start
|
||||
int X = pt.getBlockX() >> 4;
|
||||
int Z = pt.getBlockZ() >> 4;
|
||||
int X = pt.x() >> 4;
|
||||
int Z = pt.z() >> 4;
|
||||
if (Fawe.isMainThread()) {
|
||||
world.getChunkAt(X, Z);
|
||||
} else if (PaperLib.isPaper()) {
|
||||
@ -413,7 +413,7 @@ public class BukkitWorld extends AbstractWorld {
|
||||
public void fixAfterFastMode(Iterable<BlockVector2> chunks) {
|
||||
World world = getWorld();
|
||||
for (BlockVector2 chunkPos : chunks) {
|
||||
world.refreshChunk(chunkPos.getBlockX(), chunkPos.getBlockZ());
|
||||
world.refreshChunk(chunkPos.x(), chunkPos.z());
|
||||
}
|
||||
}
|
||||
|
||||
@ -495,13 +495,13 @@ public class BukkitWorld extends AbstractWorld {
|
||||
//FAWE start - safe edit region
|
||||
testCoords(pt);
|
||||
//FAWE end
|
||||
getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).breakNaturally();
|
||||
getWorld().getBlockAt(pt.x(), pt.y(), pt.z()).breakNaturally();
|
||||
}
|
||||
|
||||
//FAWE start
|
||||
@Override
|
||||
public Collection<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());
|
||||
}
|
||||
//FAWE end
|
||||
@ -538,7 +538,7 @@ public class BukkitWorld extends AbstractWorld {
|
||||
}
|
||||
}
|
||||
if (WorldEditPlugin.getInstance().getLocalConfiguration().unsupportedVersionEditing) {
|
||||
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
|
||||
Block bukkitBlock = getWorld().getBlockAt(position.x(), position.y(), position.z());
|
||||
return BukkitAdapter.adapt(bukkitBlock.getBlockData());
|
||||
} else {
|
||||
throw new RuntimeException(new UnsupportedVersionEditException());
|
||||
@ -562,7 +562,7 @@ public class BukkitWorld extends AbstractWorld {
|
||||
}
|
||||
}
|
||||
}
|
||||
Block bukkitBlock = getWorld().getBlockAt(position.getBlockX(), position.getBlockY(), position.getBlockZ());
|
||||
Block bukkitBlock = getWorld().getBlockAt(position.x(), position.y(), position.z());
|
||||
bukkitBlock.setBlockData(BukkitAdapter.adapt(block), sideEffects.doesApplyAny());
|
||||
return true;
|
||||
}
|
||||
@ -584,8 +584,8 @@ public class BukkitWorld extends AbstractWorld {
|
||||
if (!Settings.settings().REGION_RESTRICTIONS_OPTIONS.RESTRICT_TO_SAFE_RANGE) {
|
||||
return;
|
||||
}
|
||||
int x = position.getX();
|
||||
int z = position.getZ();
|
||||
int x = position.x();
|
||||
int z = position.z();
|
||||
if (x > 30000000 || z > 30000000 || x < -30000000 || z < -30000000) {
|
||||
throw FaweCache.OUTSIDE_SAFE_REGION;
|
||||
}
|
||||
@ -636,9 +636,9 @@ public class BukkitWorld extends AbstractWorld {
|
||||
testCoords(position);
|
||||
//FAWE end
|
||||
if (HAS_3D_BIOMES) {
|
||||
return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ()));
|
||||
return BukkitAdapter.adapt(getWorld().getBiome(position.x(), position.y(), position.z()));
|
||||
} else {
|
||||
return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockZ()));
|
||||
return BukkitAdapter.adapt(getWorld().getBiome(position.x(), position.z()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -649,9 +649,9 @@ public class BukkitWorld extends AbstractWorld {
|
||||
testCoords(position);
|
||||
//FAWE end
|
||||
if (HAS_3D_BIOMES) {
|
||||
getWorld().setBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ(), BukkitAdapter.adapt(biome));
|
||||
getWorld().setBiome(position.x(), position.y(), position.z(), BukkitAdapter.adapt(biome));
|
||||
} else {
|
||||
getWorld().setBiome(position.getBlockX(), position.getBlockZ(), BukkitAdapter.adapt(biome));
|
||||
getWorld().setBiome(position.x(), position.z(), BukkitAdapter.adapt(biome));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -120,7 +120,6 @@ public class WorldEditPlugin extends JavaPlugin {
|
||||
public void onLoad() {
|
||||
|
||||
//FAWE start
|
||||
this.bukkitConsoleCommandSender = new BukkitCommandSender(this, Bukkit.getConsoleSender());
|
||||
// This is already covered by Spigot, however, a more pesky warning with a proper explanation over "Ambiguous plugin name..." can't hurt.
|
||||
Plugin[] plugins = Bukkit.getServer().getPluginManager().getPlugins();
|
||||
for (Plugin p : plugins) {
|
||||
@ -138,6 +137,14 @@ public class WorldEditPlugin extends JavaPlugin {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
getDataFolder().mkdirs();
|
||||
|
||||
//FAWE start - Modify WorldEdit config name
|
||||
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "worldedit-config.yml"), true), this);
|
||||
// Load config before we say we've loaded platforms as it is used in listeners of the event
|
||||
// Load config in onLoad to ensure it is loaded before FAWE settings to allow (inelegant) copying of values across
|
||||
// where needed
|
||||
config.load();
|
||||
//FAWE end
|
||||
|
||||
WorldEdit worldEdit = WorldEdit.getInstance();
|
||||
|
||||
// Setup platform
|
||||
@ -148,14 +155,14 @@ public class WorldEditPlugin extends JavaPlugin {
|
||||
migrateLegacyConfig();
|
||||
//FAWE end
|
||||
|
||||
//FAWE start - Modify WorldEdit config name
|
||||
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "worldedit-config.yml"), true), this);
|
||||
//FAWE end
|
||||
|
||||
//FAWE start - Setup permission attachments
|
||||
permissionAttachmentManager = new BukkitPermissionAttachmentManager(this);
|
||||
//FAWE end
|
||||
|
||||
//FAWE start - initialise bukkitConsoleCommandSender later
|
||||
this.bukkitConsoleCommandSender = new BukkitCommandSender(this, Bukkit.getConsoleSender());
|
||||
//FAWE end
|
||||
|
||||
Path delChunks = Paths.get(getDataFolder().getPath(), DELCHUNKS_FILE_NAME);
|
||||
if (Files.exists(delChunks)) {
|
||||
ChunkDeleter.runFromFile(delChunks, true);
|
||||
@ -189,8 +196,6 @@ public class WorldEditPlugin extends JavaPlugin {
|
||||
new FaweBukkit(this);
|
||||
//FAWE end
|
||||
|
||||
config.load(); // Load config before we say we've loaded platforms as it is used in listeners of the event
|
||||
|
||||
WorldEdit.getInstance().getEventBus().post(new PlatformsRegisteredEvent());
|
||||
|
||||
PermissionsResolverManager.initialize(this); // Setup permission resolver
|
||||
|
@ -24,11 +24,13 @@ limits:
|
||||
max-polygonal-points:
|
||||
default: -1
|
||||
maximum: 20
|
||||
# radius, superpickaxe, brush radius are ignored, use FAWE config limits
|
||||
max-radius: -1
|
||||
max-super-pickaxe-size: 5
|
||||
max-brush-radius: 100
|
||||
butcher-radius:
|
||||
default: -1
|
||||
# Ignored, use FAWE config limits
|
||||
maximum: -1
|
||||
disallowed-blocks:
|
||||
- "minecraft:wheat"
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* The following classes are FAWE additions:
|
||||
*
|
||||
* @see com.sk89q.worldedit.cli.AccessPoint
|
||||
* {@link com.sk89q.worldedit.cli.AccessPoint}
|
||||
*/
|
||||
package com.sk89q.worldedit.cli;
|
||||
|
@ -1,16 +1,12 @@
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "1.8.20"
|
||||
kotlin("jvm") version "1.9.23"
|
||||
application
|
||||
}
|
||||
|
||||
applyCommonConfiguration()
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = "17"
|
||||
}
|
||||
|
||||
application.mainClass.set("com.sk89q.worldedit.internal.util.DocumentationPrinter")
|
||||
tasks.named<JavaExec>("run") {
|
||||
workingDir = rootProject.projectDir
|
||||
|
@ -339,11 +339,11 @@ public class FaweAPI {
|
||||
final BlockVector3 bot = selection.getMinimumPoint();
|
||||
final BlockVector3 top = selection.getMaximumPoint();
|
||||
|
||||
final int minX = bot.getBlockX() >> 4;
|
||||
final int minZ = bot.getBlockZ() >> 4;
|
||||
final int minX = bot.x() >> 4;
|
||||
final int minZ = bot.z() >> 4;
|
||||
|
||||
final int maxX = top.getBlockX() >> 4;
|
||||
final int maxZ = top.getBlockZ() >> 4;
|
||||
final int maxX = top.x() >> 4;
|
||||
final int maxZ = top.z() >> 4;
|
||||
|
||||
int count = 0;
|
||||
|
||||
|
@ -50,9 +50,9 @@ public class BlendBall implements Brush {
|
||||
final int outsetSize = (int) (size + 1);
|
||||
double brushSizeSquared = size * size;
|
||||
|
||||
int tx = position.getBlockX();
|
||||
int ty = position.getBlockY();
|
||||
int tz = position.getBlockZ();
|
||||
int tx = position.x();
|
||||
int ty = position.y();
|
||||
int tz = position.z();
|
||||
|
||||
int[] frequency = new int[BlockTypes.size()];
|
||||
|
||||
|
@ -81,9 +81,9 @@ public class CatenaryBrush implements Brush, ResettableTool {
|
||||
return pos1.add(pos2).divide(2).toBlockPoint();
|
||||
}
|
||||
double curveLen = pos1.distance(pos2) * lenPercent;
|
||||
double dy = pos2.getY() - pos1.getY();
|
||||
double dx = pos2.getX() - pos1.getX();
|
||||
double dz = pos2.getZ() - pos1.getZ();
|
||||
double dy = pos2.y() - pos1.y();
|
||||
double dx = pos2.x() - pos1.x();
|
||||
double dz = pos2.z() - pos1.z();
|
||||
double dh = Math.sqrt(dx * dx + dz * dz);
|
||||
double g = Math.sqrt(curveLen * curveLen - dy * dy) / 2;
|
||||
double a = 0.00001;
|
||||
|
@ -54,9 +54,9 @@ public class CommandBrush implements Brush {
|
||||
position.subtract(radius, radius, radius),
|
||||
position.add(radius, radius, radius)
|
||||
);
|
||||
String replaced = command.replace("{x}", Integer.toString(position.getBlockX()))
|
||||
.replace("{y}", Integer.toString(position.getBlockY()))
|
||||
.replace("{z}", Integer.toString(position.getBlockZ()))
|
||||
String replaced = command.replace("{x}", Integer.toString(position.x()))
|
||||
.replace("{y}", Integer.toString(position.y()))
|
||||
.replace("{z}", Integer.toString(position.z()))
|
||||
.replace("{world}", editSession.getWorld().getName())
|
||||
.replace("{size}", Integer.toString(radius));
|
||||
|
||||
|
@ -65,11 +65,11 @@ public class CopyPastaBrush implements Brush, ResettableTool {
|
||||
mask = Masks.alwaysTrue();
|
||||
}
|
||||
final ResizableClipboardBuilder builder = new ResizableClipboardBuilder(editSession.getWorld());
|
||||
final int minY = position.getBlockY();
|
||||
final int minY = position.y();
|
||||
mask = new AbstractDelegateMask(mask) {
|
||||
@Override
|
||||
public boolean test(BlockVector3 vector) {
|
||||
if (super.test(vector) && vector.getBlockY() >= minY) {
|
||||
if (super.test(vector) && vector.y() >= minY) {
|
||||
BaseBlock block = editSession.getFullBlock(vector);
|
||||
if (!block.getBlockType().getMaterial().isAir()) {
|
||||
builder.add(vector, BlockTypes.AIR.getDefaultState().toBaseBlock(), block);
|
||||
|
@ -63,9 +63,9 @@ public class ErodeBrush implements Brush {
|
||||
Clipboard buffer1 = new CPUOptimizedClipboard(region);
|
||||
Clipboard buffer2 = new CPUOptimizedClipboard(region);
|
||||
|
||||
final int bx = target.getBlockX();
|
||||
final int by = target.getBlockY();
|
||||
final int bz = target.getBlockZ();
|
||||
final int bx = target.x();
|
||||
final int by = target.y();
|
||||
final int bz = target.z();
|
||||
|
||||
for (int x = -brushSize, relx = 0; x <= brushSize && relx < buffer1.getWidth(); x++, relx++) {
|
||||
int x0 = x + bx;
|
||||
@ -106,7 +106,7 @@ public class ErodeBrush implements Brush {
|
||||
|
||||
for (BlockVector3 pos : finalBuffer) {
|
||||
BlockState block = pos.getBlock(finalBuffer);
|
||||
es.setBlock(pos.getX() + bx - brushSize, pos.getY() + by - brushSize, pos.getZ() + bz - brushSize, block);
|
||||
es.setBlock(pos.x() + bx - brushSize, pos.y() + by - brushSize, pos.z() + bz - brushSize, block);
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,9 +139,9 @@ public class ErodeBrush implements Brush {
|
||||
int highest = 1;
|
||||
for (BlockVector3 offs : FACES_TO_CHECK) {
|
||||
BaseBlock next = current.getFullBlock(
|
||||
relx + offs.getBlockX(),
|
||||
rely + offs.getBlockY(),
|
||||
relz + offs.getBlockZ()
|
||||
relx + offs.x(),
|
||||
rely + offs.y(),
|
||||
relz + offs.z()
|
||||
);
|
||||
if (!next.getBlockType().getMaterial().isMovementBlocker()) {
|
||||
continue;
|
||||
@ -190,9 +190,9 @@ public class ErodeBrush implements Brush {
|
||||
int total = 0;
|
||||
for (BlockVector3 offs : FACES_TO_CHECK) {
|
||||
BaseBlock next = current.getFullBlock(
|
||||
relx + offs.getBlockX(),
|
||||
rely + offs.getBlockY(),
|
||||
relz + offs.getBlockZ()
|
||||
relx + offs.x(),
|
||||
rely + offs.y(),
|
||||
relz + offs.z()
|
||||
);
|
||||
if (next.getMaterial().isMovementBlocker()) {
|
||||
continue;
|
||||
|
@ -12,9 +12,9 @@ public class FallingSphere implements Brush {
|
||||
@Override
|
||||
public void build(EditSession editSession, BlockVector3 position, Pattern pattern, double size) throws
|
||||
MaxChangedBlocksException {
|
||||
int px = position.getBlockX();
|
||||
int py = position.getBlockY();
|
||||
int pz = position.getBlockZ();
|
||||
int px = position.x();
|
||||
int py = position.y();
|
||||
int pz = position.z();
|
||||
int maxY = editSession.getMaxY();
|
||||
int minY = editSession.getMinY();
|
||||
|
||||
|
@ -14,7 +14,6 @@ import com.sk89q.worldedit.command.tool.BrushTool;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.Vector3;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
@ -25,7 +24,6 @@ import com.sk89q.worldedit.util.formatting.text.event.HoverEvent;
|
||||
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
@ -80,9 +78,9 @@ public class InspectBrush extends BrushTool {
|
||||
return true;
|
||||
}
|
||||
BlockVector3 target = targetVector.toBlockPoint();
|
||||
final int x = target.getBlockX();
|
||||
final int y = target.getBlockY();
|
||||
final int z = target.getBlockZ();
|
||||
final int x = target.x();
|
||||
final int y = target.y();
|
||||
final int z = target.z();
|
||||
World world = player.getWorld();
|
||||
RollbackDatabase db = DBHandler.dbHandler().getDatabase(world);
|
||||
int count = 0;
|
||||
|
@ -35,7 +35,7 @@ public record RecurseBrush(boolean dfs) implements Brush {
|
||||
DFSRecursiveVisitor visitor = new DFSRecursiveVisitor(mask, replace, Integer.MAX_VALUE, Integer.MAX_VALUE) {
|
||||
@Override
|
||||
public boolean isVisitable(BlockVector3 from, BlockVector3 to) {
|
||||
int y = to.getBlockY();
|
||||
int y = to.y();
|
||||
return y < maxY && radMask.test(to) && super.isVisitable(from, to);
|
||||
}
|
||||
};
|
||||
@ -45,7 +45,7 @@ public record RecurseBrush(boolean dfs) implements Brush {
|
||||
RecursiveVisitor visitor = new RecursiveVisitor(mask, replace, radius, editSession.getMinY(), editSession.getMaxY()) {
|
||||
@Override
|
||||
public boolean isVisitable(BlockVector3 from, BlockVector3 to) {
|
||||
int y = to.getBlockY();
|
||||
int y = to.y();
|
||||
return y < maxY && super.isVisitable(from, to);
|
||||
}
|
||||
};
|
||||
|
@ -19,15 +19,15 @@ public record RockBrush(double amplitude, double frequency, Vector3 radius) impl
|
||||
double seedY = ThreadLocalRandom.current().nextDouble();
|
||||
double seedZ = ThreadLocalRandom.current().nextDouble();
|
||||
|
||||
int px = position.getBlockX();
|
||||
int py = position.getBlockY();
|
||||
int pz = position.getBlockZ();
|
||||
int px = position.x();
|
||||
int py = position.y();
|
||||
int pz = position.z();
|
||||
|
||||
double distort = this.frequency / size;
|
||||
|
||||
double modX = 1D / radius.getX();
|
||||
double modY = 1D / radius.getY();
|
||||
double modZ = 1D / radius.getZ();
|
||||
double modX = 1D / radius.x();
|
||||
double modY = 1D / radius.y();
|
||||
double modZ = 1D / radius.z();
|
||||
|
||||
int radiusSqr = (int) (size * size);
|
||||
int sizeInt = (int) size * 2;
|
||||
|
@ -5,6 +5,7 @@ import com.fastasyncworldedit.core.function.mask.RadiusMask;
|
||||
import com.fastasyncworldedit.core.function.mask.SurfaceMask;
|
||||
import com.fastasyncworldedit.core.math.BlockVectorSet;
|
||||
import com.fastasyncworldedit.core.math.LocalBlockVectorSet;
|
||||
import com.fastasyncworldedit.core.util.collection.BlockVector3Set;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
||||
@ -64,16 +65,17 @@ public class ScatterBrush implements Brush {
|
||||
length = 1;
|
||||
visited.add(position);
|
||||
}
|
||||
LocalBlockVectorSet placed = new LocalBlockVectorSet();
|
||||
placed.setOffset(position.getX(), position.getZ());
|
||||
BlockVector3 patternSize = pattern.size();
|
||||
BlockVector3Set placed = BlockVector3Set.getAppropriateVectorSet(patternSize.add(distance, distance, distance));
|
||||
placed.setOffset(position.x(), position.y(), position.z());
|
||||
int maxFails = 1000;
|
||||
for (int i = 0; i < count; i++) {
|
||||
int index = ThreadLocalRandom.current().nextInt(length);
|
||||
BlockVector3 pos = visited.get(index);
|
||||
if (pos != null && canApply(pos)) {
|
||||
int x = pos.getBlockX();
|
||||
int y = pos.getBlockY();
|
||||
int z = pos.getBlockZ();
|
||||
int x = pos.x();
|
||||
int y = pos.y();
|
||||
int z = pos.z();
|
||||
if (placed.containsRadius(x, y, z, distance)) {
|
||||
if (maxFails-- <= 0) {
|
||||
break;
|
||||
@ -88,7 +90,20 @@ public class ScatterBrush implements Brush {
|
||||
finish(editSession, placed, position, pattern, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link ScatterBrush#finish(EditSession, BlockVector3Set, BlockVector3, Pattern, double)}
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "2.9.2")
|
||||
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) {
|
||||
@ -99,8 +114,23 @@ public class ScatterBrush implements Brush {
|
||||
return surface.direction(pt);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link ScatterBrush#apply(EditSession, BlockVector3Set, BlockVector3, Pattern, double)}
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "2.9.2")
|
||||
public void apply(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pt, Pattern p, double size) throws
|
||||
MaxChangedBlocksException {
|
||||
apply(editSession, (BlockVector3Set) placed, pt, p, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
@ -45,9 +45,9 @@ public class ScatterCommand extends ScatterBrush {
|
||||
position.subtract(radius, radius, radius),
|
||||
position.add(radius, radius, radius)
|
||||
);
|
||||
String replaced = command.replace("{x}", Integer.toString(position.getBlockX()))
|
||||
.replace("{y}", Integer.toString(position.getBlockY()))
|
||||
.replace("{z}", Integer.toString(position.getBlockZ()))
|
||||
String replaced = command.replace("{x}", Integer.toString(position.x()))
|
||||
.replace("{y}", Integer.toString(position.y()))
|
||||
.replace("{z}", Integer.toString(position.z()))
|
||||
.replace("{world}", editSession.getWorld().getName())
|
||||
.replace("{size}", Integer.toString(radius));
|
||||
|
||||
|
@ -16,9 +16,9 @@ public class ScatterOverlayBrush extends ScatterBrush {
|
||||
@Override
|
||||
public void apply(EditSession editSession, LocalBlockVectorSet placed, BlockVector3 pt, Pattern p, double size) throws
|
||||
MaxChangedBlocksException {
|
||||
final int x = pt.getBlockX();
|
||||
final int y = pt.getBlockY();
|
||||
final int z = pt.getBlockZ();
|
||||
final int x = pt.x();
|
||||
final int y = pt.y();
|
||||
final int z = pt.z();
|
||||
BlockVector3 dir = getDirection(pt);
|
||||
if (dir == null) {
|
||||
getDir:
|
||||
@ -37,7 +37,7 @@ public class ScatterOverlayBrush extends ScatterBrush {
|
||||
return;
|
||||
}
|
||||
}
|
||||
editSession.setBlock(x + dir.getBlockX(), y + dir.getBlockY(), z + dir.getBlockZ(), p);
|
||||
editSession.setBlock(x + dir.x(), y + dir.y(), z + dir.z(), p);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.fastasyncworldedit.core.command.tool.brush;
|
||||
import com.fastasyncworldedit.core.function.mask.SurfaceMask;
|
||||
import com.fastasyncworldedit.core.math.LocalBlockVectorSet;
|
||||
import com.fastasyncworldedit.core.math.MutableBlockVector3;
|
||||
import com.fastasyncworldedit.core.util.collection.BlockVector3Set;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
@ -24,7 +25,7 @@ public class ShatterBrush extends ScatterBrush {
|
||||
@Override
|
||||
public void apply(
|
||||
final EditSession editSession,
|
||||
final LocalBlockVectorSet placed,
|
||||
final BlockVector3Set placed,
|
||||
final BlockVector3 position,
|
||||
Pattern p,
|
||||
double size
|
||||
@ -34,7 +35,7 @@ public class ShatterBrush extends ScatterBrush {
|
||||
@Override
|
||||
public void finish(
|
||||
EditSession editSession,
|
||||
LocalBlockVectorSet placed,
|
||||
BlockVector3Set placed,
|
||||
final BlockVector3 position,
|
||||
Pattern pattern,
|
||||
double size
|
||||
@ -79,13 +80,13 @@ public class ShatterBrush extends ScatterBrush {
|
||||
}
|
||||
for (int i1 = 0; i1 < BreadthFirstSearch.DIAGONAL_DIRECTIONS.length; i1++) {
|
||||
BlockVector3 direction = BreadthFirstSearch.DIAGONAL_DIRECTIONS[i1];
|
||||
int x2 = x + direction.getBlockX();
|
||||
int y2 = y + direction.getBlockY();
|
||||
int z2 = z + direction.getBlockZ();
|
||||
int x2 = x + direction.x();
|
||||
int y2 = y + direction.y();
|
||||
int z2 = z + direction.z();
|
||||
// Check boundary
|
||||
int dx = position.getBlockX() - x2;
|
||||
int dy = position.getBlockY() - y2;
|
||||
int dz = position.getBlockZ() - z2;
|
||||
int dx = position.x() - x2;
|
||||
int dy = position.y() - y2;
|
||||
int dz = position.z() - z2;
|
||||
int dSqr = (dx * dx) + (dy * dy) + (dz * dz);
|
||||
if (dSqr <= radius2) {
|
||||
BlockVector3 bv = mutable.setComponents(x2, y2, z2);
|
||||
|
@ -130,9 +130,9 @@ public class SplineBrush implements Brush, ResettableTool {
|
||||
private Vector3 getCentroid(Collection<BlockVector3> points) {
|
||||
MutableVector3 sum = new MutableVector3();
|
||||
for (BlockVector3 p : points) {
|
||||
sum.mutX(sum.getX() + p.getX());
|
||||
sum.mutY(sum.getY() + p.getY());
|
||||
sum.mutZ(sum.getZ() + p.getZ());
|
||||
sum.mutX(sum.x() + p.x());
|
||||
sum.mutY(sum.y() + p.y());
|
||||
sum.mutZ(sum.z() + p.z());
|
||||
}
|
||||
return sum.multiply(1.0 / points.size());
|
||||
}
|
||||
|
@ -38,16 +38,16 @@ public class SurfaceSpline implements Brush {
|
||||
int minY = editSession.getMinY();
|
||||
if (path.isEmpty() || !pos.equals(path.get(path.size() - 1))) {
|
||||
int max = editSession.getNearestSurfaceTerrainBlock(
|
||||
pos.getBlockX(),
|
||||
pos.getBlockZ(),
|
||||
pos.getBlockY(),
|
||||
pos.x(),
|
||||
pos.z(),
|
||||
pos.y(),
|
||||
minY,
|
||||
maxY
|
||||
);
|
||||
if (max == -1) {
|
||||
return;
|
||||
}
|
||||
path.add(BlockVector3.at(pos.getBlockX(), max, pos.getBlockZ()));
|
||||
path.add(BlockVector3.at(pos.x(), max, pos.z()));
|
||||
if (editSession.getActor() != null) {
|
||||
editSession.getActor().print(Caption.of("fawe.worldedit.brush.spline.primary.2"));
|
||||
}
|
||||
@ -69,9 +69,9 @@ public class SurfaceSpline implements Brush {
|
||||
LocalBlockVectorSet vset = new LocalBlockVectorSet();
|
||||
for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) {
|
||||
final Vector3 tipv = interpol.getPosition(loop);
|
||||
final int tipx = MathMan.roundInt(tipv.getX());
|
||||
final int tipz = (int) tipv.getZ();
|
||||
int tipy = MathMan.roundInt(tipv.getY());
|
||||
final int tipx = MathMan.roundInt(tipv.x());
|
||||
final int tipz = (int) tipv.z();
|
||||
int tipy = MathMan.roundInt(tipv.y());
|
||||
tipy = editSession.getNearestSurfaceTerrainBlock(tipx, tipz, tipy, minY, maxY, Integer.MIN_VALUE, Integer.MAX_VALUE);
|
||||
if (tipy == Integer.MIN_VALUE || tipy == Integer.MAX_VALUE) {
|
||||
continue;
|
||||
@ -88,15 +88,15 @@ public class SurfaceSpline implements Brush {
|
||||
LocalBlockVectorSet newSet = new LocalBlockVectorSet();
|
||||
final int ceilrad = (int) Math.ceil(radius);
|
||||
for (BlockVector3 v : vset) {
|
||||
final int tipx = v.getBlockX();
|
||||
final int tipz = v.getBlockZ();
|
||||
final int tipx = v.x();
|
||||
final int tipz = v.z();
|
||||
for (int loopx = tipx - ceilrad; loopx <= tipx + ceilrad; loopx++) {
|
||||
for (int loopz = tipz - ceilrad; loopz <= tipz + ceilrad; loopz++) {
|
||||
if (MathMan.hypot2(loopx - tipx, 0, loopz - tipz) <= radius2) {
|
||||
int y = editSession.getNearestSurfaceTerrainBlock(
|
||||
loopx,
|
||||
loopz,
|
||||
v.getBlockY(),
|
||||
v.y(),
|
||||
minY,
|
||||
maxY,
|
||||
Integer.MIN_VALUE,
|
||||
|
@ -13,7 +13,7 @@ public class ScrollRange extends Scroll {
|
||||
|
||||
@Override
|
||||
public boolean increment(Player player, int amount) {
|
||||
int max = WorldEdit.getInstance().getConfiguration().maxBrushRadius;
|
||||
int max = player.getLimit().MAX_BRUSH_RADIUS;
|
||||
int newSize = MathMan.wrap(getTool().getRange() + amount, (int) (getTool().getSize() + 1), max);
|
||||
getTool().setRange(newSize);
|
||||
return true;
|
||||
|
@ -12,7 +12,7 @@ public class ScrollSize extends Scroll {
|
||||
|
||||
@Override
|
||||
public boolean increment(Player player, int amount) {
|
||||
int max = WorldEdit.getInstance().getConfiguration().maxRadius;
|
||||
int max = player.getLimit().MAX_RADIUS;
|
||||
double newSize = Math.max(0, Math.min(max == -1 ? 4095 : max, getTool().getSize() + amount));
|
||||
getTool().setSize(newSize);
|
||||
return true;
|
||||
|
@ -83,7 +83,7 @@ public class ClipboardSpline extends Spline {
|
||||
Region region = clipboard.getRegion();
|
||||
BlockVector3 origin = clipboard.getOrigin();
|
||||
// center = region.getCenter().setY(origin.getY() - 1);
|
||||
center = region.getCenter().withY(origin.getY() - 1).toBlockPoint();
|
||||
center = region.getCenter().withY(origin.y() - 1).toBlockPoint();
|
||||
this.centerOffset = center.subtract(center.round());
|
||||
this.center = center.subtract(centerOffset);
|
||||
this.transform = transform;
|
||||
@ -108,15 +108,15 @@ public class ClipboardSpline extends Spline {
|
||||
clipboardHolder.setTransform(transform);
|
||||
|
||||
BlockVector3 functionOffset = target.subtract(clipboard.getOrigin());
|
||||
final int offX = functionOffset.getBlockX();
|
||||
final int offY = functionOffset.getBlockY();
|
||||
final int offZ = functionOffset.getBlockZ();
|
||||
final int offX = functionOffset.x();
|
||||
final int offY = functionOffset.y();
|
||||
final int offZ = functionOffset.z();
|
||||
|
||||
Operation operation = clipboardHolder
|
||||
.createPaste(editSession)
|
||||
.to(target)
|
||||
.ignoreAirBlocks(true)
|
||||
.filter(v -> buffer.add(v.getBlockX() + offX, v.getBlockY() + offY, v.getBlockZ() + offZ))
|
||||
.filter(v -> buffer.add(v.x() + offX, v.y() + offY, v.z() + offZ))
|
||||
.build();
|
||||
Operations.completeLegacy(operation);
|
||||
|
||||
|
@ -121,7 +121,7 @@ public abstract class Spline {
|
||||
* 2 dimensional "cross" product. cross2D(v1, v2) = |v1|*|v2|*sin(theta) or v1 X v2 taking Y to be 0
|
||||
*/
|
||||
private double cross2D(Vector2 v1, Vector2 v2) {
|
||||
return v1.getX() * v2.getZ() - v2.getX() * v1.getZ();
|
||||
return v1.x() * v2.z() - v2.x() * v1.z();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,7 +144,7 @@ public abstract class Spline {
|
||||
// Calculate rotation from spline
|
||||
|
||||
Vector3 deriv = interpolation.get1stDerivative(position);
|
||||
Vector2 deriv2D = Vector2.at(deriv.getX(), deriv.getZ()).normalize();
|
||||
Vector2 deriv2D = Vector2.at(deriv.x(), deriv.z()).normalize();
|
||||
double angle = Math.toDegrees(
|
||||
-Math.atan2(cross2D(direction, deriv2D), direction.dot(deriv2D))
|
||||
);
|
||||
|
@ -79,13 +79,13 @@ public class SweepBrush implements Brush, ResettableTool {
|
||||
Clipboard clipboard = holder.getClipboard();
|
||||
|
||||
BlockVector3 dimensions = clipboard.getDimensions();
|
||||
double quality = Math.max(dimensions.getBlockX(), dimensions.getBlockZ());
|
||||
double quality = Math.max(dimensions.x(), dimensions.z());
|
||||
|
||||
AffineTransform transform = new AffineTransform();
|
||||
|
||||
ClipboardSpline spline = new ClipboardSpline(editSession, holder, interpol, transform, nodes.size());
|
||||
|
||||
if (dimensions.getBlockX() > dimensions.getBlockZ()) {
|
||||
if (dimensions.x() > dimensions.z()) {
|
||||
spline.setDirection(Vector2.at(0, 1));
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.configuration;
|
||||
|
||||
import com.fastasyncworldedit.core.configuration.file.YamlConfiguration;
|
||||
import com.fastasyncworldedit.core.util.StringMan;
|
||||
import com.sk89q.util.StringUtil;
|
||||
import com.sk89q.worldedit.internal.util.LogManagerCompat;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@ -14,8 +15,10 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@ -27,6 +30,9 @@ public class Config {
|
||||
|
||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||
|
||||
private final Map<String, Object> removedKeyVals = new HashMap<>();
|
||||
private List<String> existingMigrateNodes = null;
|
||||
|
||||
public Config() {
|
||||
save(new PrintWriter(new ByteArrayOutputStream(0)), getClass(), this, 0);
|
||||
}
|
||||
@ -43,7 +49,8 @@ public class Config {
|
||||
try {
|
||||
return (T) field.get(instance);
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
LOGGER.error("Failed to get config option: {}", key, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,6 +74,10 @@ public class Config {
|
||||
if (field.getAnnotation(Final.class) != null) {
|
||||
return;
|
||||
}
|
||||
Migrate migrate = field.getAnnotation(Migrate.class);
|
||||
if (existingMigrateNodes != null && migrate != null) {
|
||||
existingMigrateNodes.add(migrate.value());
|
||||
}
|
||||
if (field.getType() == String.class && !(value instanceof String)) {
|
||||
value = value + "";
|
||||
}
|
||||
@ -74,17 +85,22 @@ public class Config {
|
||||
field.set(instance, value);
|
||||
return;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
LOGGER.error("Failed to set config option: {}", key);
|
||||
}
|
||||
}
|
||||
}
|
||||
LOGGER.error("Failed to set config option: {}: {} | {} | {}.yml", key, value, instance, root.getSimpleName());
|
||||
removedKeyVals.put(key, value);
|
||||
LOGGER.error(
|
||||
"Failed to set config option: {}: {} | {} | {}.yml. This is likely because it was removed.",
|
||||
key,
|
||||
value,
|
||||
instance,
|
||||
root.getSimpleName()
|
||||
);
|
||||
}
|
||||
|
||||
public boolean load(File file) {
|
||||
if (!file.exists()) {
|
||||
return false;
|
||||
}
|
||||
existingMigrateNodes = new ArrayList<>();
|
||||
YamlConfiguration yml = YamlConfiguration.loadConfiguration(file);
|
||||
for (String key : yml.getKeys(true)) {
|
||||
Object value = yml.get(key);
|
||||
@ -93,6 +109,10 @@ public class Config {
|
||||
}
|
||||
set(key, value, getClass());
|
||||
}
|
||||
for (String node : existingMigrateNodes) {
|
||||
removedKeyVals.remove(node);
|
||||
}
|
||||
existingMigrateNodes = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -113,7 +133,7 @@ public class Config {
|
||||
save(writer, getClass(), instance, 0);
|
||||
writer.close();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
LOGGER.error("Failed to save config file: {}", file, e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,6 +186,19 @@ public class Config {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates that a field should be instantiated / created.
|
||||
*
|
||||
* @since 2.10.0
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD})
|
||||
public @interface Migrate {
|
||||
|
||||
String value();
|
||||
|
||||
}
|
||||
|
||||
@Ignore // This is not part of the config
|
||||
public static class ConfigBlock<T> {
|
||||
|
||||
@ -222,7 +255,6 @@ public class Config {
|
||||
try {
|
||||
String CTRF = System.lineSeparator();
|
||||
String spacing = StringMan.repeat(" ", indent);
|
||||
HashMap<Class<?>, Object> instances = new HashMap<>();
|
||||
for (Field field : clazz.getFields()) {
|
||||
if (field.getAnnotation(Ignore.class) != null) {
|
||||
continue;
|
||||
@ -239,31 +271,14 @@ public class Config {
|
||||
}
|
||||
if (current == ConfigBlock.class) {
|
||||
current = (Class<?>) ((ParameterizedType) (field.getGenericType())).getActualTypeArguments()[0];
|
||||
comment = current.getAnnotation(Comment.class);
|
||||
if (comment != null) {
|
||||
for (String commentLine : comment.value()) {
|
||||
writer.write(spacing + "# " + commentLine + CTRF);
|
||||
}
|
||||
}
|
||||
BlockName blockNames = current.getAnnotation(BlockName.class);
|
||||
if (blockNames != null) {
|
||||
writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF);
|
||||
ConfigBlock configBlock = (ConfigBlock) field.get(instance);
|
||||
if (configBlock == null || configBlock.getInstances().isEmpty()) {
|
||||
configBlock = new ConfigBlock();
|
||||
field.set(instance, configBlock);
|
||||
for (String blockName : blockNames.value()) {
|
||||
configBlock.put(blockName, current.getDeclaredConstructor().newInstance());
|
||||
}
|
||||
}
|
||||
// Save each instance
|
||||
for (Map.Entry<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);
|
||||
}
|
||||
}
|
||||
handleConfigBlockSave(writer, instance, indent, field, spacing, CTRF, current);
|
||||
continue;
|
||||
} else if (!removedKeyVals.isEmpty()) {
|
||||
Migrate migrate = field.getAnnotation(Migrate.class);
|
||||
Object value;
|
||||
if (migrate != null && (value = removedKeyVals.remove(migrate.value())) != null) {
|
||||
field.set(instance, value);
|
||||
}
|
||||
}
|
||||
Create create = field.getAnnotation(Create.class);
|
||||
if (create != null) {
|
||||
@ -281,7 +296,6 @@ public class Config {
|
||||
writer.write(spacing + toNodeName(current.getSimpleName()) + ":" + CTRF);
|
||||
if (value == null) {
|
||||
field.set(instance, value = current.getDeclaredConstructor().newInstance());
|
||||
instances.put(current, value);
|
||||
}
|
||||
save(writer, current, value, indent + 2);
|
||||
} else {
|
||||
@ -292,7 +306,42 @@ public class Config {
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
LOGGER.error("Failed to save config file", e);
|
||||
}
|
||||
}
|
||||
|
||||
private <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;
|
||||
} catch (Throwable ignored) {
|
||||
LOGGER.warn(
|
||||
"Invalid config field: {} for {}",
|
||||
"Invalid config field: {} for {}. It is possible this is because it has been removed.",
|
||||
StringMan.join(split, "."),
|
||||
toNodeName(instance.getClass().getSimpleName())
|
||||
);
|
||||
@ -379,7 +428,7 @@ public class Config {
|
||||
return null;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
LOGGER.error("Failed retrieving instance for config node: {}", StringUtil.joinString(split, "."), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.fastasyncworldedit.core.configuration;
|
||||
|
||||
import com.fastasyncworldedit.core.limit.FaweLimit;
|
||||
import com.fastasyncworldedit.core.limit.PropertyRemap;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.world.block.BlockTypesCache;
|
||||
@ -79,6 +80,8 @@ public class Settings extends Config {
|
||||
@Create
|
||||
public REGION_RESTRICTIONS_OPTIONS REGION_RESTRICTIONS_OPTIONS;
|
||||
@Create
|
||||
public GENERAL GENERAL;
|
||||
@Create
|
||||
public ConfigBlock<LIMITS> LIMITS;
|
||||
|
||||
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_ITERATIONS = Math.max(
|
||||
limit.MAX_ITERATIONS,
|
||||
newLimit.MAX_ITERATIONS != -1 ? newLimit.MAX_ITERATIONS : Integer.MAX_VALUE
|
||||
limit.MAX_ITERATIONS, newLimit.MAX_ITERATIONS != -1 ? newLimit.MAX_ITERATIONS : Integer.MAX_VALUE);
|
||||
limit.MAX_RADIUS = Math.max(
|
||||
limit.MAX_RADIUS,
|
||||
newLimit.MAX_RADIUS != -1 ? newLimit.MAX_RADIUS : Integer.MAX_VALUE
|
||||
);
|
||||
limit.MAX_SUPER_PICKAXE_SIZE = Math.max(
|
||||
limit.MAX_SUPER_PICKAXE_SIZE,
|
||||
newLimit.MAX_SUPER_PICKAXE_SIZE != -1 ? newLimit.MAX_SUPER_PICKAXE_SIZE : Integer.MAX_VALUE
|
||||
);
|
||||
limit.MAX_BRUSH_RADIUS = Math.max(
|
||||
limit.MAX_BRUSH_RADIUS,
|
||||
newLimit.MAX_BRUSH_RADIUS != -1 ? newLimit.MAX_BRUSH_RADIUS : Integer.MAX_VALUE
|
||||
);
|
||||
limit.MAX_BUTCHER_RADIUS = Math.max(
|
||||
limit.MAX_BUTCHER_RADIUS,
|
||||
newLimit.MAX_BUTCHER_RADIUS != -1 ? newLimit.MAX_BUTCHER_RADIUS : Integer.MAX_VALUE
|
||||
);
|
||||
limit.MAX_HISTORY = Math.max(
|
||||
limit.MAX_HISTORY,
|
||||
newLimit.MAX_HISTORY_MB != -1 ? newLimit.MAX_HISTORY_MB : Integer.MAX_VALUE
|
||||
);
|
||||
limit.SCHEM_FILE_NUM_LIMIT = Math.max(
|
||||
limit.SCHEM_FILE_NUM_LIMIT,
|
||||
newLimit.SCHEM_FILE_NUM_LIMIT != -1 ? newLimit.SCHEM_FILE_NUM_LIMIT : Integer.MAX_VALUE
|
||||
);
|
||||
limit.SCHEM_FILE_SIZE_LIMIT = Math.max(
|
||||
limit.SCHEM_FILE_SIZE_LIMIT,
|
||||
newLimit.SCHEM_FILE_SIZE_LIMIT != -1 ? newLimit.SCHEM_FILE_SIZE_LIMIT : Integer.MAX_VALUE
|
||||
);
|
||||
limit.MAX_EXPRESSION_MS = Math.max(
|
||||
limit.MAX_EXPRESSION_MS,
|
||||
newLimit.MAX_EXPRESSION_MS != -1 ? newLimit.MAX_EXPRESSION_MS : Integer.MAX_VALUE
|
||||
@ -342,6 +367,14 @@ public class Settings extends Config {
|
||||
public int MAX_ITERATIONS = 1000;
|
||||
@Comment("Max allowed entities (e.g. cows)")
|
||||
public int MAX_ENTITIES = 1337;
|
||||
@Comment("Max allowed radius (e.g. for //sphere)")
|
||||
public int MAX_RADIUS = LocalConfiguration.MAX_RADIUS;
|
||||
@Comment("Max allowed superpickaxe size")
|
||||
public int MAX_SUPER_PICKAXE_SIZE = LocalConfiguration.MAX_SUPER_RADIUS;
|
||||
@Comment("Max allowed brush radius")
|
||||
public int MAX_BRUSH_RADIUS = LocalConfiguration.MAX_BRUSH_RADIUS;
|
||||
@Comment("Max allowed butcher radius")
|
||||
public int MAX_BUTCHER_RADIUS = LocalConfiguration.MAX_BUTCHER_RADIUS;
|
||||
@Comment({
|
||||
"Blockstates include Banner, Beacon, BrewingStand, Chest, CommandBlock, ",
|
||||
"CreatureSpawner, Dispenser, Dropper, EndGateway, Furnace, Hopper, Jukebox, ",
|
||||
@ -353,6 +386,18 @@ public class Settings extends Config {
|
||||
" - History on disk or memory will be deleted",
|
||||
})
|
||||
public int MAX_HISTORY_MB = -1;
|
||||
@Comment({
|
||||
"Sets a maximum limit (in kb) for the size of a player's schematics directory (per-player mode only)",
|
||||
"Set to -1 to disable"
|
||||
})
|
||||
@Migrate("experimental.per-player-file-size-limit")
|
||||
public int SCHEM_FILE_SIZE_LIMIT = -1;
|
||||
@Comment({
|
||||
"Sets a maximum limit for the amount of schematics in a player's schematics directory (per-player mode only)",
|
||||
"Set to -1 to disable"
|
||||
})
|
||||
@Migrate("experimental.per-player-file-num-limit")
|
||||
public int SCHEM_FILE_NUM_LIMIT = -1;
|
||||
@Comment("Maximum time in milliseconds //calc can execute")
|
||||
public int MAX_EXPRESSION_MS = 50;
|
||||
@Comment({
|
||||
@ -615,18 +660,6 @@ public class Settings extends Config {
|
||||
})
|
||||
public boolean ALLOW_TICK_FLUIDS = false;
|
||||
|
||||
@Comment({
|
||||
"Sets a maximum limit (in kb) for the size of a player's schematics directory (per-player mode only)",
|
||||
"Set to -1 to disable"
|
||||
})
|
||||
public int PER_PLAYER_FILE_SIZE_LIMIT = -1;
|
||||
|
||||
@Comment({
|
||||
"Sets a maximum limit for the amount of schematics in a player's schematics directory (per-player mode only)",
|
||||
"Set to -1 to disable"
|
||||
})
|
||||
public int PER_PLAYER_FILE_NUM_LIMIT = -1;
|
||||
|
||||
}
|
||||
|
||||
@Comment({"Web/HTTP connection related settings"})
|
||||
@ -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",})
|
||||
public String URL = "https://schem.intellectualsites.com/fawe/";
|
||||
|
||||
@Comment({"The url of the backend server (Arkitektonika)"})
|
||||
public String ARKITEKTONIKA_BACKEND_URL = "https://api.schematic.cloud/";
|
||||
@Comment({"The url used to generate a download link from.", "{key} will be replaced with the generated key"})
|
||||
public String ARKITEKTONIKA_DOWNLOAD_URL = "https://schematic.cloud/download/{key}";
|
||||
@Comment({"The url used to generate a deletion link from.", "{key} will be replaced with the generated key"})
|
||||
public String ARKITEKTONIKA_DELETE_URL = "https://schematic.cloud/delete/{key}";
|
||||
|
||||
@Comment("The maximum amount of time in seconds the plugin can attempt to load images for.")
|
||||
public int MAX_IMAGE_LOAD_TIME = 5;
|
||||
|
||||
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -179,13 +179,13 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
||||
}
|
||||
try (PreparedStatement stmt = connection.prepareStatement(stmtStr.formatted(this.prefix))) {
|
||||
stmt.setInt(1, (int) (minTime / 1000));
|
||||
stmt.setInt(2, pos1.getBlockX());
|
||||
stmt.setInt(3, pos2.getBlockX());
|
||||
stmt.setInt(4, pos1.getBlockZ());
|
||||
stmt.setInt(5, pos2.getBlockZ());
|
||||
stmt.setInt(2, pos1.x());
|
||||
stmt.setInt(3, pos2.x());
|
||||
stmt.setInt(4, pos1.z());
|
||||
stmt.setInt(5, pos2.z());
|
||||
// Keep 128 offset for backwards-compatibility
|
||||
stmt.setInt(6, pos1.getBlockY() - 128);
|
||||
stmt.setInt(7, pos2.getBlockY() - 128);
|
||||
stmt.setInt(6, pos1.y() - 128);
|
||||
stmt.setInt(7, pos2.y() - 128);
|
||||
if (uuid != null) {
|
||||
byte[] uuidBytes = toBytes(uuid);
|
||||
stmt.setBytes(8, uuidBytes);
|
||||
@ -210,13 +210,13 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
||||
.array();
|
||||
stmt.setBytes(1, uuidBytes);
|
||||
stmt.setInt(2, (int) (minTime / 1000));
|
||||
stmt.setInt(3, pos1.getBlockX());
|
||||
stmt.setInt(4, pos2.getBlockX());
|
||||
stmt.setInt(5, pos1.getBlockZ());
|
||||
stmt.setInt(6, pos2.getBlockZ());
|
||||
stmt.setInt(3, pos1.x());
|
||||
stmt.setInt(4, pos2.x());
|
||||
stmt.setInt(5, pos1.z());
|
||||
stmt.setInt(6, pos2.z());
|
||||
// Keep 128 offset for backwards-compatibility
|
||||
stmt.setInt(7, pos1.getBlockY() - 128);
|
||||
stmt.setInt(8, pos2.getBlockY() - 128);
|
||||
stmt.setInt(7, pos1.y() - 128);
|
||||
stmt.setInt(8, pos2.y() - 128);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
@ -262,13 +262,13 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
||||
BlockVector3 pos1 = change.getMinimumPoint();
|
||||
BlockVector3 pos2 = change.getMaximumPoint();
|
||||
|
||||
stmt.setInt(4, pos1.getX());
|
||||
stmt.setInt(5, pos2.getX());
|
||||
stmt.setInt(6, pos1.getZ());
|
||||
stmt.setInt(7, pos2.getZ());
|
||||
stmt.setInt(4, pos1.x());
|
||||
stmt.setInt(5, pos2.x());
|
||||
stmt.setInt(6, pos1.z());
|
||||
stmt.setInt(7, pos2.z());
|
||||
// Keep 128 offset for backwards-compatibility
|
||||
stmt.setInt(8, pos1.getY() - 128);
|
||||
stmt.setInt(9, pos2.getY() - 128);
|
||||
stmt.setInt(8, pos1.y() - 128);
|
||||
stmt.setInt(9, pos2.y() - 128);
|
||||
stmt.setString(10, change.getCommand());
|
||||
stmt.setInt(11, change.size());
|
||||
stmt.executeUpdate();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
||||
|
||||
}
|
@ -24,7 +24,7 @@ public final class BlockTranslateExtent extends AbstractDelegateExtent {
|
||||
|
||||
@Override
|
||||
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
|
||||
@ -49,7 +49,7 @@ public final class BlockTranslateExtent extends AbstractDelegateExtent {
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 location) {
|
||||
return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
return getBlock(location.x(), location.y(), location.z());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -64,11 +64,11 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc
|
||||
|
||||
@Override
|
||||
public final boolean contains(BlockVector3 p) {
|
||||
return contains(p.getBlockX(), p.getBlockY(), p.getBlockZ());
|
||||
return contains(p.x(), p.y(), p.z());
|
||||
}
|
||||
|
||||
public final boolean contains(BlockVector2 p) {
|
||||
return contains(p.getBlockX(), p.getBlockZ());
|
||||
return contains(p.x(), p.z());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -96,7 +96,7 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(BlockVector3 position) {
|
||||
return getBiomeType(position.getX(), position.getY(), position.getZ());
|
||||
return getBiomeType(position.x(), position.y(), position.z());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -112,7 +112,7 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
return getFullBlock(position.getX(), position.getY(), position.getZ());
|
||||
return getFullBlock(position.x(), position.y(), position.z());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -128,7 +128,7 @@ public abstract class FaweRegionExtent extends ResettableExtent implements IBatc
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
return getBlock(position.getX(), position.getY(), position.getZ());
|
||||
return getBlock(position.x(), position.y(), position.z());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,7 +66,7 @@ public final class HistoryExtent extends AbstractDelegateExtent {
|
||||
|
||||
@Override
|
||||
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
|
||||
@ -111,7 +111,7 @@ public final class HistoryExtent extends AbstractDelegateExtent {
|
||||
public boolean setBiome(BlockVector3 position, BiomeType newBiome) {
|
||||
BiomeType oldBiome = this.getBiome(position);
|
||||
if (!oldBiome.getId().equals(newBiome.getId())) {
|
||||
this.changeSet.addBiomeChange(position.getBlockX(), position.getBlockY(), position.getBlockZ(), oldBiome, newBiome);
|
||||
this.changeSet.addBiomeChange(position.x(), position.y(), position.z(), oldBiome, newBiome);
|
||||
return getExtent().setBiome(position, newBiome);
|
||||
} else {
|
||||
return false;
|
||||
|
@ -373,12 +373,12 @@ public final class LimitExtent extends AbstractDelegateExtent {
|
||||
size = ((Collection<BlockVector3>) positions).size();
|
||||
} else if (positions instanceof Region) {
|
||||
BlockVector3 dim = ((Region) positions).getDimensions();
|
||||
size = dim.getX() * dim.getY() * dim.getZ();
|
||||
size = dim.x() * dim.y() * dim.z();
|
||||
} else if (positions instanceof Extent) {
|
||||
BlockVector3 min = ((Extent) positions).getMinimumPoint();
|
||||
BlockVector3 max = ((Extent) positions).getMinimumPoint();
|
||||
BlockVector3 dim = max.subtract(min).add(BlockVector3.ONE);
|
||||
size = dim.getX() * dim.getY() * dim.getZ();
|
||||
size = dim.x() * dim.y() * dim.z();
|
||||
} else {
|
||||
ExtentFilterBlock block = new ExtentFilterBlock(this);
|
||||
for (BlockVector3 pos : positions) {
|
||||
|
@ -38,9 +38,9 @@ public final class PositionTransformExtent extends ResettableExtent {
|
||||
if (min == null) {
|
||||
min = pos;
|
||||
}
|
||||
mutable.mutX(pos.getX() - min.getX());
|
||||
mutable.mutY(pos.getY() - min.getY());
|
||||
mutable.mutZ(pos.getZ() - min.getZ());
|
||||
mutable.mutX(pos.x() - min.x());
|
||||
mutable.mutY(pos.y() - min.y());
|
||||
mutable.mutZ(pos.z() - min.z());
|
||||
MutableVector3 tmp = new MutableVector3(transform.apply(mutable.toVector3()));
|
||||
return min.add(tmp.roundHalfUp().toBlockPoint());
|
||||
}
|
||||
@ -49,9 +49,9 @@ public final class PositionTransformExtent extends ResettableExtent {
|
||||
if (min == null) {
|
||||
min = BlockVector3.at(x, y, z);
|
||||
}
|
||||
mutable.mutX(x - min.getX());
|
||||
mutable.mutY(y - min.getY());
|
||||
mutable.mutZ(z - min.getZ());
|
||||
mutable.mutX(x - min.x());
|
||||
mutable.mutY(y - min.y());
|
||||
mutable.mutZ(z - min.z());
|
||||
MutableVector3 tmp = new MutableVector3(transform.apply(mutable.toVector3()));
|
||||
return min.add(tmp.roundHalfUp().toBlockPoint());
|
||||
}
|
||||
@ -73,10 +73,10 @@ public final class PositionTransformExtent extends ResettableExtent {
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(BlockVector3 position) {
|
||||
mutable.mutX(position.getBlockX());
|
||||
mutable.mutZ(position.getBlockZ());
|
||||
mutable.mutY(position.getBlockY());
|
||||
return super.getBiome(getPos(mutable.getX(), mutable.getY(), mutable.getZ()));
|
||||
mutable.mutX(position.x());
|
||||
mutable.mutZ(position.z());
|
||||
mutable.mutY(position.y());
|
||||
return super.getBiome(getPos(mutable.x(), mutable.y(), mutable.z()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -92,10 +92,10 @@ public final class PositionTransformExtent extends ResettableExtent {
|
||||
|
||||
@Override
|
||||
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||
mutable.mutX(position.getBlockX());
|
||||
mutable.mutZ(position.getBlockZ());
|
||||
mutable.mutY(position.getBlockY());
|
||||
return super.setBiome(getPos(mutable.getX(), mutable.getY(), mutable.getZ()), biome);
|
||||
mutable.mutX(position.x());
|
||||
mutable.mutZ(position.z());
|
||||
mutable.mutY(position.y());
|
||||
return super.setBiome(getPos(mutable.x(), mutable.y(), mutable.z()), biome);
|
||||
}
|
||||
|
||||
public void setTransform(Transform transform) {
|
||||
|
@ -80,12 +80,12 @@ public final class ProcessedWEExtent extends AbstractDelegateExtent {
|
||||
@Override
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 location) {
|
||||
return getBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
return getBlock(location.x(), location.y(), location.z());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -41,8 +41,8 @@ public final class SourceMaskExtent extends TemporalExtent {
|
||||
|
||||
@Override
|
||||
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block) throws WorldEditException {
|
||||
set(location.getBlockX(), location.getBlockY(), location.getBlockZ(), block);
|
||||
return mask.test(location) && super.setBlock(location.getX(), location.getY(), location.getZ(), block);
|
||||
set(location.x(), location.y(), location.z(), block);
|
||||
return mask.test(location) && super.setBlock(location.x(), location.y(), location.z(), block);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -44,7 +44,7 @@ public abstract class TemporalExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public BlockState getBlock(BlockVector3 position) {
|
||||
if (position.getX() == x && position.getY() == y && position.getZ() == z) {
|
||||
if (position.x() == x && position.y() == y && position.z() == z) {
|
||||
return block.toImmutableState();
|
||||
}
|
||||
return super.getBlock(position);
|
||||
@ -60,7 +60,7 @@ public abstract class TemporalExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(BlockVector3 position) {
|
||||
if (position.getX() == x && position.getY() == y && position.getZ() == z) {
|
||||
if (position.x() == x && position.y() == y && position.z() == z) {
|
||||
if (block instanceof BaseBlock) {
|
||||
return (BaseBlock) block;
|
||||
} else {
|
||||
@ -72,7 +72,7 @@ public abstract class TemporalExtent extends PassthroughExtent {
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(BlockVector3 position) {
|
||||
if (position.getX() == bx && position.getZ() == bz) {
|
||||
if (position.x() == bx && position.z() == bz) {
|
||||
return biome;
|
||||
}
|
||||
return super.getBiome(position);
|
||||
|
@ -41,7 +41,7 @@ public class CPUOptimizedClipboard extends LinearClipboard {
|
||||
|
||||
@Override
|
||||
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||
return setBiome(position.getX(), position.getY(), position.getZ(), biome);
|
||||
return setBiome(position.x(), position.y(), position.z(), biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -92,7 +92,7 @@ public class CPUOptimizedClipboard extends LinearClipboard {
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(BlockVector3 position) {
|
||||
return getBiome(getBiomeIndex(position.getX(), position.getY(), position.getZ()));
|
||||
return getBiome(getBiomeIndex(position.x(), position.y(), position.z()));
|
||||
}
|
||||
|
||||
public void convertTilesToIndex() {
|
||||
|
@ -359,7 +359,7 @@ public class DiskOptimizedClipboard extends LinearClipboard {
|
||||
|
||||
@Override
|
||||
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||
return setBiome(position.getX(), position.getY(), position.getZ(), biome);
|
||||
return setBiome(position.x(), position.y(), position.z(), biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -417,7 +417,7 @@ public class DiskOptimizedClipboard extends LinearClipboard {
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(BlockVector3 position) {
|
||||
return getBiome(getBiomeIndex(position.getX(), position.getY(), position.getZ()));
|
||||
return getBiome(getBiomeIndex(position.x(), position.y(), position.z()));
|
||||
}
|
||||
|
||||
public BlockArrayClipboard toClipboard() {
|
||||
@ -438,9 +438,9 @@ public class DiskOptimizedClipboard extends LinearClipboard {
|
||||
super.setOrigin(origin);
|
||||
origin = origin.subtract(offset);
|
||||
try {
|
||||
byteBuffer.putShort(10, (short) origin.getBlockX());
|
||||
byteBuffer.putShort(12, (short) origin.getBlockY());
|
||||
byteBuffer.putShort(14, (short) origin.getBlockZ());
|
||||
byteBuffer.putShort(10, (short) origin.x());
|
||||
byteBuffer.putShort(12, (short) origin.y());
|
||||
byteBuffer.putShort(14, (short) origin.z());
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -450,9 +450,9 @@ public class DiskOptimizedClipboard extends LinearClipboard {
|
||||
protected void setOffset(BlockVector3 offset) {
|
||||
super.setOffset(offset);
|
||||
try {
|
||||
byteBuffer.putShort(16, (short) offset.getBlockX());
|
||||
byteBuffer.putShort(18, (short) offset.getBlockY());
|
||||
byteBuffer.putShort(20, (short) offset.getBlockZ());
|
||||
byteBuffer.putShort(16, (short) offset.x());
|
||||
byteBuffer.putShort(18, (short) offset.y());
|
||||
byteBuffer.putShort(20, (short) offset.z());
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -588,9 +588,9 @@ public class DiskOptimizedClipboard extends LinearClipboard {
|
||||
CompoundTag data = entity.getState().getNbtData();
|
||||
HashMap<String, Tag> value = new HashMap<>(data.getValue());
|
||||
List<DoubleTag> pos = new ArrayList<>(3);
|
||||
pos.add(new DoubleTag(entity.getLocation().getX()));
|
||||
pos.add(new DoubleTag(entity.getLocation().getX()));
|
||||
pos.add(new DoubleTag(entity.getLocation().getX()));
|
||||
pos.add(new DoubleTag(entity.getLocation().x()));
|
||||
pos.add(new DoubleTag(entity.getLocation().x()));
|
||||
pos.add(new DoubleTag(entity.getLocation().x()));
|
||||
value.put("Pos", new ListTag(DoubleTag.class, pos));
|
||||
nbtOS.writeTag(new CompoundTag(value));
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ public class MemoryOptimizedClipboard extends LinearClipboard {
|
||||
|
||||
@Override
|
||||
public boolean setBiome(BlockVector3 position, BiomeType biome) {
|
||||
return setBiome(position.getX(), position.getY(), position.getZ(), biome);
|
||||
return setBiome(position.x(), position.y(), position.z(), biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -115,7 +115,7 @@ public class MemoryOptimizedClipboard extends LinearClipboard {
|
||||
|
||||
@Override
|
||||
public BiomeType getBiome(BlockVector3 position) {
|
||||
return getBiome(getBiomeIndex(position.getX(), position.getY(), position.getZ()));
|
||||
return getBiome(getBiomeIndex(position.x(), position.y(), position.z()));
|
||||
}
|
||||
|
||||
private int getOrdinal(int index) {
|
||||
|
@ -70,17 +70,17 @@ public abstract class SimpleClipboard implements Clipboard {
|
||||
|
||||
@Override
|
||||
public final int getWidth() {
|
||||
return size.getBlockX();
|
||||
return size.x();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getHeight() {
|
||||
return size.getBlockY();
|
||||
return size.y();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int getLength() {
|
||||
return size.getBlockZ();
|
||||
return size.z();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren